forked from mirrors/jj
merge_tools: extract configuration error to separate type
write!(ui.hint(), ..) error is suppressed because it seemed weird if the configuration error had io::Error variant. The write error isn't important anyway.
This commit is contained in:
parent
003b40d276
commit
b926fd844a
3 changed files with 34 additions and 31 deletions
|
@ -88,6 +88,7 @@ use crate::git_util::{
|
||||||
};
|
};
|
||||||
use crate::merge_tools::{
|
use crate::merge_tools::{
|
||||||
ConflictResolveError, DiffEditError, DiffEditor, DiffGenerateError, MergeEditor,
|
ConflictResolveError, DiffEditError, DiffEditor, DiffGenerateError, MergeEditor,
|
||||||
|
MergeToolConfigError,
|
||||||
};
|
};
|
||||||
use crate::template_parser::{TemplateAliasesMap, TemplateParseError, TemplateParseErrorKind};
|
use crate::template_parser::{TemplateAliasesMap, TemplateParseError, TemplateParseErrorKind};
|
||||||
use crate::templater::Template;
|
use crate::templater::Template;
|
||||||
|
@ -353,6 +354,12 @@ impl From<ConflictResolveError> for CommandError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<MergeToolConfigError> for CommandError {
|
||||||
|
fn from(err: MergeToolConfigError) -> Self {
|
||||||
|
user_error_with_message("Failed to load tool configuration", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<git2::Error> for CommandError {
|
impl From<git2::Error> for CommandError {
|
||||||
fn from(err: git2::Error) -> Self {
|
fn from(err: git2::Error) -> Self {
|
||||||
user_error_with_message("Git operation failed", err)
|
user_error_with_message("Git operation failed", err)
|
||||||
|
@ -1110,13 +1117,13 @@ impl WorkspaceCommandHelper {
|
||||||
|
|
||||||
/// Loads diff editor from the settings.
|
/// Loads diff editor from the settings.
|
||||||
// TODO: override settings by --tool= option (#2575)
|
// TODO: override settings by --tool= option (#2575)
|
||||||
pub fn diff_editor(&self, ui: &Ui) -> Result<DiffEditor, DiffEditError> {
|
pub fn diff_editor(&self, ui: &Ui) -> Result<DiffEditor, MergeToolConfigError> {
|
||||||
DiffEditor::from_settings(ui, &self.settings)
|
DiffEditor::from_settings(ui, &self.settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads 3-way merge editor from the settings.
|
/// Loads 3-way merge editor from the settings.
|
||||||
// TODO: override settings by --tool= option (#2575)
|
// TODO: override settings by --tool= option (#2575)
|
||||||
pub fn merge_editor(&self, ui: &Ui) -> Result<MergeEditor, ConflictResolveError> {
|
pub fn merge_editor(&self, ui: &Ui) -> Result<MergeEditor, MergeToolConfigError> {
|
||||||
MergeEditor::from_settings(ui, &self.settings)
|
MergeEditor::from_settings(ui, &self.settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ use std::path::{Path, PathBuf};
|
||||||
use std::process::{Command, ExitStatus, Stdio};
|
use std::process::{Command, ExitStatus, Stdio};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use config::ConfigError;
|
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use jj_lib::backend::{FileId, MergedTreeId, TreeValue};
|
use jj_lib::backend::{FileId, MergedTreeId, TreeValue};
|
||||||
|
@ -107,13 +106,6 @@ impl ExternalMergeTool {
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ExternalToolError {
|
pub enum ExternalToolError {
|
||||||
#[error("Invalid config")]
|
|
||||||
Config(#[from] ConfigError),
|
|
||||||
#[error(
|
|
||||||
"To use `{tool_name}` as a merge tool, the config `merge-tools.{tool_name}.merge-args` \
|
|
||||||
must be defined (see docs for details)"
|
|
||||||
)]
|
|
||||||
MergeArgsNotConfigured { tool_name: String },
|
|
||||||
#[error("Error setting up temporary directory")]
|
#[error("Error setting up temporary directory")]
|
||||||
SetUpDir(#[source] std::io::Error),
|
SetUpDir(#[source] std::io::Error),
|
||||||
// TODO: Remove the "(run with --debug to see the exact invocation)"
|
// TODO: Remove the "(run with --debug to see the exact invocation)"
|
||||||
|
|
|
@ -150,6 +150,17 @@ pub fn edit_diff(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum MergeToolConfigError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Config(#[from] ConfigError),
|
||||||
|
#[error(
|
||||||
|
"To use `{tool_name}` as a merge tool, the config `merge-tools.{tool_name}.merge-args` \
|
||||||
|
must be defined (see docs for details)"
|
||||||
|
)]
|
||||||
|
MergeArgsNotConfigured { tool_name: String },
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum MergeTool {
|
pub enum MergeTool {
|
||||||
Builtin,
|
Builtin,
|
||||||
|
@ -161,7 +172,7 @@ fn editor_args_from_settings(
|
||||||
ui: &Ui,
|
ui: &Ui,
|
||||||
settings: &UserSettings,
|
settings: &UserSettings,
|
||||||
key: &str,
|
key: &str,
|
||||||
) -> Result<CommandNameAndArgs, ExternalToolError> {
|
) -> Result<CommandNameAndArgs, ConfigError> {
|
||||||
// TODO: Make this configuration have a table of possible editors and detect the
|
// TODO: Make this configuration have a table of possible editors and detect the
|
||||||
// best one here.
|
// best one here.
|
||||||
if let Some(args) = settings.config().get(key).optional()? {
|
if let Some(args) = settings.config().get(key).optional()? {
|
||||||
|
@ -173,7 +184,7 @@ fn editor_args_from_settings(
|
||||||
"Using default editor '{default_editor}'; run `jj config set --user {key} :builtin` \
|
"Using default editor '{default_editor}'; run `jj config set --user {key} :builtin` \
|
||||||
to disable this message."
|
to disable this message."
|
||||||
)
|
)
|
||||||
.map_err(ExternalToolError::Io)?;
|
.ok();
|
||||||
Ok(default_editor.into())
|
Ok(default_editor.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,11 +230,10 @@ pub struct DiffEditor {
|
||||||
|
|
||||||
impl DiffEditor {
|
impl DiffEditor {
|
||||||
/// Loads the default diff editor from the settings.
|
/// Loads the default diff editor from the settings.
|
||||||
// TODO: extract tool configuration error from DiffEditError
|
pub fn from_settings(ui: &Ui, settings: &UserSettings) -> Result<Self, MergeToolConfigError> {
|
||||||
pub fn from_settings(ui: &Ui, settings: &UserSettings) -> Result<Self, DiffEditError> {
|
|
||||||
let args = editor_args_from_settings(ui, settings, "ui.diff-editor")?;
|
let args = editor_args_from_settings(ui, settings, "ui.diff-editor")?;
|
||||||
let tool = if let CommandNameAndArgs::String(name) = &args {
|
let tool = if let CommandNameAndArgs::String(name) = &args {
|
||||||
get_tool_config(settings, name).map_err(ExternalToolError::Config)?
|
get_tool_config(settings, name)?
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -240,20 +250,18 @@ pub struct MergeEditor {
|
||||||
|
|
||||||
impl MergeEditor {
|
impl MergeEditor {
|
||||||
/// Loads the default 3-way merge editor from the settings.
|
/// Loads the default 3-way merge editor from the settings.
|
||||||
// TODO: extract tool configuration error from ConflictResolveError
|
pub fn from_settings(ui: &Ui, settings: &UserSettings) -> Result<Self, MergeToolConfigError> {
|
||||||
pub fn from_settings(ui: &Ui, settings: &UserSettings) -> Result<Self, ConflictResolveError> {
|
|
||||||
let args = editor_args_from_settings(ui, settings, "ui.merge-editor")?;
|
let args = editor_args_from_settings(ui, settings, "ui.merge-editor")?;
|
||||||
let tool = if let CommandNameAndArgs::String(name) = &args {
|
let tool = if let CommandNameAndArgs::String(name) = &args {
|
||||||
get_tool_config(settings, name).map_err(ExternalToolError::Config)?
|
get_tool_config(settings, name)?
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
.unwrap_or_else(|| MergeTool::External(ExternalMergeTool::with_merge_args(&args)));
|
.unwrap_or_else(|| MergeTool::External(ExternalMergeTool::with_merge_args(&args)));
|
||||||
if matches!(&tool, MergeTool::External(mergetool) if mergetool.merge_args.is_empty()) {
|
if matches!(&tool, MergeTool::External(mergetool) if mergetool.merge_args.is_empty()) {
|
||||||
return Err(ExternalToolError::MergeArgsNotConfigured {
|
return Err(MergeToolConfigError::MergeArgsNotConfigured {
|
||||||
tool_name: args.to_string(),
|
tool_name: args.to_string(),
|
||||||
}
|
});
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
Ok(MergeEditor { tool })
|
Ok(MergeEditor { tool })
|
||||||
}
|
}
|
||||||
|
@ -435,11 +443,9 @@ mod tests {
|
||||||
|
|
||||||
// Just program name
|
// Just program name
|
||||||
insta::assert_debug_snapshot!(get(r#"ui.merge-editor = "my-merge""#).unwrap_err(), @r###"
|
insta::assert_debug_snapshot!(get(r#"ui.merge-editor = "my-merge""#).unwrap_err(), @r###"
|
||||||
ExternalTool(
|
|
||||||
MergeArgsNotConfigured {
|
MergeArgsNotConfigured {
|
||||||
tool_name: "my-merge",
|
tool_name: "my-merge",
|
||||||
},
|
}
|
||||||
)
|
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// String args
|
// String args
|
||||||
|
@ -527,11 +533,9 @@ mod tests {
|
||||||
// List args should never be a merge-tools key
|
// List args should never be a merge-tools key
|
||||||
insta::assert_debug_snapshot!(
|
insta::assert_debug_snapshot!(
|
||||||
get(r#"ui.merge-editor = ["meld"]"#).unwrap_err(), @r###"
|
get(r#"ui.merge-editor = ["meld"]"#).unwrap_err(), @r###"
|
||||||
ExternalTool(
|
|
||||||
MergeArgsNotConfigured {
|
MergeArgsNotConfigured {
|
||||||
tool_name: "meld",
|
tool_name: "meld",
|
||||||
},
|
}
|
||||||
)
|
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// Invalid type
|
// Invalid type
|
||||||
|
|
Loading…
Reference in a new issue