mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-12 23:23:20 +00:00
lib: move command variable interpolation from merge tools to generic location
This commit is contained in:
parent
1ece76d128
commit
bbd9ba31df
2 changed files with 48 additions and 38 deletions
|
@ -22,6 +22,7 @@ use std::{env, fmt, slice};
|
||||||
use config::Source;
|
use config::Source;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use jj_lib::settings::ConfigResultExt as _;
|
use jj_lib::settings::ConfigResultExt as _;
|
||||||
|
use regex::{Captures, Regex};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
|
@ -661,12 +662,22 @@ impl CommandNameAndArgs {
|
||||||
|
|
||||||
/// Returns process builder configured with this.
|
/// Returns process builder configured with this.
|
||||||
pub fn to_command(&self) -> Command {
|
pub fn to_command(&self) -> Command {
|
||||||
|
let empty: HashMap<&str, &str> = HashMap::new();
|
||||||
|
self.to_command_with_variables(&empty)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns process builder configured with this after interpolating
|
||||||
|
/// variables into the arguments.
|
||||||
|
pub fn to_command_with_variables<V: AsRef<str>>(
|
||||||
|
&self,
|
||||||
|
variables: &HashMap<&str, V>,
|
||||||
|
) -> Command {
|
||||||
let (name, args) = self.split_name_and_args();
|
let (name, args) = self.split_name_and_args();
|
||||||
let mut cmd = Command::new(name.as_ref());
|
let mut cmd = Command::new(name.as_ref());
|
||||||
if let CommandNameAndArgs::Structured { env, .. } = self {
|
if let CommandNameAndArgs::Structured { env, .. } = self {
|
||||||
cmd.envs(env);
|
cmd.envs(env);
|
||||||
}
|
}
|
||||||
cmd.args(args.as_ref());
|
cmd.args(interpolate_variables(&args, variables));
|
||||||
cmd
|
cmd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -693,6 +704,41 @@ impl fmt::Display for CommandNameAndArgs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not interested in $UPPER_CASE_VARIABLES
|
||||||
|
static VARIABLE_REGEX: once_cell::sync::Lazy<Regex> =
|
||||||
|
once_cell::sync::Lazy::new(|| Regex::new(r"\$([a-z0-9_]+)\b").unwrap());
|
||||||
|
|
||||||
|
pub fn interpolate_variables<V: AsRef<str>>(
|
||||||
|
args: &[String],
|
||||||
|
variables: &HashMap<&str, V>,
|
||||||
|
) -> Vec<String> {
|
||||||
|
args.iter()
|
||||||
|
.map(|arg| {
|
||||||
|
VARIABLE_REGEX
|
||||||
|
.replace_all(arg, |caps: &Captures| {
|
||||||
|
let name = &caps[1];
|
||||||
|
if let Some(subst) = variables.get(name) {
|
||||||
|
subst.as_ref().to_owned()
|
||||||
|
} else {
|
||||||
|
caps[0].to_owned()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into_owned()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return all variable names found in the args, without the dollar sign
|
||||||
|
pub fn find_all_variables(args: &[String]) -> impl Iterator<Item = &str> {
|
||||||
|
let regex = &*VARIABLE_REGEX;
|
||||||
|
args.iter()
|
||||||
|
.flat_map(|arg| regex.find_iter(arg))
|
||||||
|
.map(|single_match| {
|
||||||
|
let s = single_match.as_str();
|
||||||
|
&s[1..]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Wrapper to reject an array without command name.
|
/// Wrapper to reject an array without command name.
|
||||||
// Based on https://github.com/serde-rs/serde/issues/939
|
// Based on https://github.com/serde-rs/serde/issues/939
|
||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, serde::Deserialize)]
|
#[derive(Clone, Debug, Eq, Hash, PartialEq, serde::Deserialize)]
|
||||||
|
|
|
@ -12,14 +12,13 @@ use jj_lib::merge::{Merge, MergedTreeValue};
|
||||||
use jj_lib::merged_tree::{MergedTree, MergedTreeBuilder};
|
use jj_lib::merged_tree::{MergedTree, MergedTreeBuilder};
|
||||||
use jj_lib::repo_path::RepoPath;
|
use jj_lib::repo_path::RepoPath;
|
||||||
use pollster::FutureExt;
|
use pollster::FutureExt;
|
||||||
use regex::{Captures, Regex};
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use super::diff_working_copies::{
|
use super::diff_working_copies::{
|
||||||
check_out_trees, new_utf8_temp_dir, set_readonly_recursively, DiffEditWorkingCopies, DiffSide,
|
check_out_trees, new_utf8_temp_dir, set_readonly_recursively, DiffEditWorkingCopies, DiffSide,
|
||||||
};
|
};
|
||||||
use super::{ConflictResolveError, DiffEditError, DiffGenerateError};
|
use super::{ConflictResolveError, DiffEditError, DiffGenerateError};
|
||||||
use crate::config::CommandNameAndArgs;
|
use crate::config::{find_all_variables, interpolate_variables, CommandNameAndArgs};
|
||||||
use crate::ui::Ui;
|
use crate::ui::Ui;
|
||||||
|
|
||||||
/// Merge/diff tool loaded from the settings.
|
/// Merge/diff tool loaded from the settings.
|
||||||
|
@ -220,41 +219,6 @@ pub fn run_mergetool_external(
|
||||||
Ok(new_tree)
|
Ok(new_tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not interested in $UPPER_CASE_VARIABLES
|
|
||||||
static VARIABLE_REGEX: once_cell::sync::Lazy<Regex> =
|
|
||||||
once_cell::sync::Lazy::new(|| Regex::new(r"\$([a-z0-9_]+)\b").unwrap());
|
|
||||||
|
|
||||||
fn interpolate_variables<V: AsRef<str>>(
|
|
||||||
args: &[String],
|
|
||||||
variables: &HashMap<&str, V>,
|
|
||||||
) -> Vec<String> {
|
|
||||||
args.iter()
|
|
||||||
.map(|arg| {
|
|
||||||
VARIABLE_REGEX
|
|
||||||
.replace_all(arg, |caps: &Captures| {
|
|
||||||
let name = &caps[1];
|
|
||||||
if let Some(subst) = variables.get(name) {
|
|
||||||
subst.as_ref().to_owned()
|
|
||||||
} else {
|
|
||||||
caps[0].to_owned()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into_owned()
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return all variable names found in the args, without the dollar sign
|
|
||||||
fn find_all_variables(args: &[String]) -> impl Iterator<Item = &str> {
|
|
||||||
let regex = &*VARIABLE_REGEX;
|
|
||||||
args.iter()
|
|
||||||
.flat_map(|arg| regex.find_iter(arg))
|
|
||||||
.map(|single_match| {
|
|
||||||
let s = single_match.as_str();
|
|
||||||
&s[1..]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn edit_diff_external(
|
pub fn edit_diff_external(
|
||||||
editor: &ExternalMergeTool,
|
editor: &ExternalMergeTool,
|
||||||
left_tree: &MergedTree,
|
left_tree: &MergedTree,
|
||||||
|
|
Loading…
Reference in a new issue