fix: introduce ExtractHeredocError that implements PartialEq (#958)
This commit is contained in:
@@ -4,9 +4,9 @@ mod seek_sequence;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::str::Utf8Error;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use anyhow::Error;
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
pub use parser::Hunk;
|
pub use parser::Hunk;
|
||||||
pub use parser::ParseError;
|
pub use parser::ParseError;
|
||||||
@@ -15,6 +15,7 @@ use parser::UpdateFileChunk;
|
|||||||
pub use parser::parse_patch;
|
pub use parser::parse_patch;
|
||||||
use similar::TextDiff;
|
use similar::TextDiff;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use tree_sitter::LanguageError;
|
||||||
use tree_sitter::Parser;
|
use tree_sitter::Parser;
|
||||||
use tree_sitter_bash::LANGUAGE as BASH;
|
use tree_sitter_bash::LANGUAGE as BASH;
|
||||||
|
|
||||||
@@ -52,10 +53,10 @@ impl PartialEq for IoError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum MaybeApplyPatch {
|
pub enum MaybeApplyPatch {
|
||||||
Body(Vec<Hunk>),
|
Body(Vec<Hunk>),
|
||||||
ShellParseError(Error),
|
ShellParseError(ExtractHeredocError),
|
||||||
PatchParseError(ParseError),
|
PatchParseError(ParseError),
|
||||||
NotApplyPatch,
|
NotApplyPatch,
|
||||||
}
|
}
|
||||||
@@ -97,14 +98,14 @@ pub enum ApplyPatchFileChange {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum MaybeApplyPatchVerified {
|
pub enum MaybeApplyPatchVerified {
|
||||||
/// `argv` corresponded to an `apply_patch` invocation, and these are the
|
/// `argv` corresponded to an `apply_patch` invocation, and these are the
|
||||||
/// resulting proposed file changes.
|
/// resulting proposed file changes.
|
||||||
Body(ApplyPatchAction),
|
Body(ApplyPatchAction),
|
||||||
/// `argv` could not be parsed to determine whether it corresponds to an
|
/// `argv` could not be parsed to determine whether it corresponds to an
|
||||||
/// `apply_patch` invocation.
|
/// `apply_patch` invocation.
|
||||||
ShellParseError(Error),
|
ShellParseError(ExtractHeredocError),
|
||||||
/// `argv` corresponded to an `apply_patch` invocation, but it could not
|
/// `argv` corresponded to an `apply_patch` invocation, but it could not
|
||||||
/// be fulfilled due to the specified error.
|
/// be fulfilled due to the specified error.
|
||||||
CorrectnessError(ApplyPatchError),
|
CorrectnessError(ApplyPatchError),
|
||||||
@@ -112,26 +113,6 @@ pub enum MaybeApplyPatchVerified {
|
|||||||
NotApplyPatch,
|
NotApplyPatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for MaybeApplyPatchVerified {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
match (self, other) {
|
|
||||||
(MaybeApplyPatchVerified::Body(a), MaybeApplyPatchVerified::Body(b)) => a == b,
|
|
||||||
(
|
|
||||||
MaybeApplyPatchVerified::ShellParseError(a),
|
|
||||||
MaybeApplyPatchVerified::ShellParseError(b),
|
|
||||||
) => a.to_string() == b.to_string(),
|
|
||||||
(
|
|
||||||
MaybeApplyPatchVerified::CorrectnessError(a),
|
|
||||||
MaybeApplyPatchVerified::CorrectnessError(b),
|
|
||||||
) => a == b,
|
|
||||||
(MaybeApplyPatchVerified::NotApplyPatch, MaybeApplyPatchVerified::NotApplyPatch) => {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
/// ApplyPatchAction is the result of parsing an `apply_patch` command. By
|
/// ApplyPatchAction is the result of parsing an `apply_patch` command. By
|
||||||
/// construction, all paths should be absolute paths.
|
/// construction, all paths should be absolute paths.
|
||||||
@@ -225,19 +206,21 @@ pub fn maybe_parse_apply_patch_verified(argv: &[String], cwd: &Path) -> MaybeApp
|
|||||||
/// * `Ok(String)` - The heredoc body if the extraction is successful.
|
/// * `Ok(String)` - The heredoc body if the extraction is successful.
|
||||||
/// * `Err(anyhow::Error)` - An error if the extraction fails.
|
/// * `Err(anyhow::Error)` - An error if the extraction fails.
|
||||||
///
|
///
|
||||||
fn extract_heredoc_body_from_apply_patch_command(src: &str) -> anyhow::Result<String> {
|
fn extract_heredoc_body_from_apply_patch_command(
|
||||||
|
src: &str,
|
||||||
|
) -> std::result::Result<String, ExtractHeredocError> {
|
||||||
if !src.trim_start().starts_with("apply_patch") {
|
if !src.trim_start().starts_with("apply_patch") {
|
||||||
anyhow::bail!("expected command to start with 'apply_patch'");
|
return Err(ExtractHeredocError::CommandDidNotStartWithApplyPatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
let lang = BASH.into();
|
let lang = BASH.into();
|
||||||
let mut parser = Parser::new();
|
let mut parser = Parser::new();
|
||||||
parser
|
parser
|
||||||
.set_language(&lang)
|
.set_language(&lang)
|
||||||
.context("failed to load bash grammar")?;
|
.map_err(ExtractHeredocError::FailedToLoadBashGrammar)?;
|
||||||
let tree = parser
|
let tree = parser
|
||||||
.parse(src, None)
|
.parse(src, None)
|
||||||
.ok_or_else(|| anyhow::anyhow!("failed to parse patch into AST"))?;
|
.ok_or(ExtractHeredocError::FailedToParsePatchIntoAst)?;
|
||||||
|
|
||||||
let bytes = src.as_bytes();
|
let bytes = src.as_bytes();
|
||||||
let mut c = tree.root_node().walk();
|
let mut c = tree.root_node().walk();
|
||||||
@@ -247,7 +230,7 @@ fn extract_heredoc_body_from_apply_patch_command(src: &str) -> anyhow::Result<St
|
|||||||
if node.kind() == "heredoc_body" {
|
if node.kind() == "heredoc_body" {
|
||||||
let text = node
|
let text = node
|
||||||
.utf8_text(bytes)
|
.utf8_text(bytes)
|
||||||
.context("failed to interpret heredoc body as UTF-8")?;
|
.map_err(ExtractHeredocError::HeredocNotUtf8)?;
|
||||||
return Ok(text.trim_end_matches('\n').to_owned());
|
return Ok(text.trim_end_matches('\n').to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,12 +239,21 @@ fn extract_heredoc_body_from_apply_patch_command(src: &str) -> anyhow::Result<St
|
|||||||
}
|
}
|
||||||
while !c.goto_next_sibling() {
|
while !c.goto_next_sibling() {
|
||||||
if !c.goto_parent() {
|
if !c.goto_parent() {
|
||||||
anyhow::bail!("expected to find heredoc_body in patch candidate");
|
return Err(ExtractHeredocError::FailedToFindHeredocBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum ExtractHeredocError {
|
||||||
|
CommandDidNotStartWithApplyPatch,
|
||||||
|
FailedToLoadBashGrammar(LanguageError),
|
||||||
|
HeredocNotUtf8(Utf8Error),
|
||||||
|
FailedToParsePatchIntoAst,
|
||||||
|
FailedToFindHeredocBody,
|
||||||
|
}
|
||||||
|
|
||||||
/// Applies the patch and prints the result to stdout/stderr.
|
/// Applies the patch and prints the result to stdout/stderr.
|
||||||
pub fn apply_patch(
|
pub fn apply_patch(
|
||||||
patch: &str,
|
patch: &str,
|
||||||
|
|||||||
@@ -1080,7 +1080,7 @@ async fn handle_function_call(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
MaybeApplyPatchVerified::ShellParseError(error) => {
|
MaybeApplyPatchVerified::ShellParseError(error) => {
|
||||||
trace!("Failed to parse shell command, {error}");
|
trace!("Failed to parse shell command, {error:?}");
|
||||||
}
|
}
|
||||||
MaybeApplyPatchVerified::NotApplyPatch => (),
|
MaybeApplyPatchVerified::NotApplyPatch => (),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user