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 itertools::Itertools;
|
||||
use jj_lib::settings::ConfigResultExt as _;
|
||||
use regex::{Captures, Regex};
|
||||
use thiserror::Error;
|
||||
use tracing::instrument;
|
||||
|
||||
|
@ -661,12 +662,22 @@ impl CommandNameAndArgs {
|
|||
|
||||
/// Returns process builder configured with this.
|
||||
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 mut cmd = Command::new(name.as_ref());
|
||||
if let CommandNameAndArgs::Structured { env, .. } = self {
|
||||
cmd.envs(env);
|
||||
}
|
||||
cmd.args(args.as_ref());
|
||||
cmd.args(interpolate_variables(&args, variables));
|
||||
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.
|
||||
// Based on https://github.com/serde-rs/serde/issues/939
|
||||
#[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::repo_path::RepoPath;
|
||||
use pollster::FutureExt;
|
||||
use regex::{Captures, Regex};
|
||||
use thiserror::Error;
|
||||
|
||||
use super::diff_working_copies::{
|
||||
check_out_trees, new_utf8_temp_dir, set_readonly_recursively, DiffEditWorkingCopies, DiffSide,
|
||||
};
|
||||
use super::{ConflictResolveError, DiffEditError, DiffGenerateError};
|
||||
use crate::config::CommandNameAndArgs;
|
||||
use crate::config::{find_all_variables, interpolate_variables, CommandNameAndArgs};
|
||||
use crate::ui::Ui;
|
||||
|
||||
/// Merge/diff tool loaded from the settings.
|
||||
|
@ -220,41 +219,6 @@ pub fn run_mergetool_external(
|
|||
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(
|
||||
editor: &ExternalMergeTool,
|
||||
left_tree: &MergedTree,
|
||||
|
|
Loading…
Reference in a new issue