Pass evaluated arguments as positional arguments (#810)
This commit is contained in:
parent
7889f10a6a
commit
2abdeb386e
@ -194,7 +194,7 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
|||||||
scope: &'run Scope<'src, 'run>,
|
scope: &'run Scope<'src, 'run>,
|
||||||
settings: &'run Settings,
|
settings: &'run Settings,
|
||||||
search: &'run Search,
|
search: &'run Search,
|
||||||
) -> RunResult<'src, Scope<'src, 'run>> {
|
) -> RunResult<'src, (Scope<'src, 'run>, Vec<String>)> {
|
||||||
let mut evaluator = Evaluator {
|
let mut evaluator = Evaluator {
|
||||||
assignments: None,
|
assignments: None,
|
||||||
scope: scope.child(),
|
scope: scope.child(),
|
||||||
@ -206,11 +206,15 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
|||||||
|
|
||||||
let mut scope = scope.child();
|
let mut scope = scope.child();
|
||||||
|
|
||||||
|
let mut positional = Vec::new();
|
||||||
|
|
||||||
let mut rest = arguments;
|
let mut rest = arguments;
|
||||||
for parameter in parameters {
|
for parameter in parameters {
|
||||||
let value = if rest.is_empty() {
|
let value = if rest.is_empty() {
|
||||||
if let Some(ref default) = parameter.default {
|
if let Some(ref default) = parameter.default {
|
||||||
evaluator.evaluate_expression(default)?
|
let value = evaluator.evaluate_expression(default)?;
|
||||||
|
positional.push(value.clone());
|
||||||
|
value
|
||||||
} else if parameter.kind == ParameterKind::Star {
|
} else if parameter.kind == ParameterKind::Star {
|
||||||
String::new()
|
String::new()
|
||||||
} else {
|
} else {
|
||||||
@ -219,18 +223,22 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if parameter.kind.is_variadic() {
|
} else if parameter.kind.is_variadic() {
|
||||||
|
for value in rest {
|
||||||
|
positional.push((*value).to_owned());
|
||||||
|
}
|
||||||
let value = rest.to_vec().join(" ");
|
let value = rest.to_vec().join(" ");
|
||||||
rest = &[];
|
rest = &[];
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
let value = rest[0].to_owned();
|
let value = rest[0].to_owned();
|
||||||
|
positional.push(value.clone());
|
||||||
rest = &rest[1..];
|
rest = &rest[1..];
|
||||||
value
|
value
|
||||||
};
|
};
|
||||||
scope.bind(parameter.export, parameter.name, value);
|
scope.bind(parameter.export, parameter.name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(scope)
|
Ok((scope, positional))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn recipe_evaluator(
|
pub(crate) fn recipe_evaluator(
|
||||||
|
@ -253,7 +253,7 @@ impl<'src> Justfile<'src> {
|
|||||||
search: &'run Search,
|
search: &'run Search,
|
||||||
ran: &mut BTreeSet<Vec<String>>,
|
ran: &mut BTreeSet<Vec<String>>,
|
||||||
) -> RunResult<'src, ()> {
|
) -> RunResult<'src, ()> {
|
||||||
let outer = Evaluator::evaluate_parameters(
|
let (outer, positional) = Evaluator::evaluate_parameters(
|
||||||
context.config,
|
context.config,
|
||||||
dotenv,
|
dotenv,
|
||||||
&recipe.parameters,
|
&recipe.parameters,
|
||||||
@ -285,7 +285,7 @@ impl<'src> Justfile<'src> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recipe.run(context, dotenv, scope.child(), search, arguments)?;
|
recipe.run(context, dotenv, scope.child(), search, &positional)?;
|
||||||
|
|
||||||
let mut invocation = vec![recipe.name().to_owned()];
|
let mut invocation = vec![recipe.name().to_owned()];
|
||||||
for argument in arguments.iter().cloned() {
|
for argument in arguments.iter().cloned() {
|
||||||
|
@ -74,7 +74,7 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
dotenv: &BTreeMap<String, String>,
|
dotenv: &BTreeMap<String, String>,
|
||||||
scope: Scope<'src, 'run>,
|
scope: Scope<'src, 'run>,
|
||||||
search: &'run Search,
|
search: &'run Search,
|
||||||
arguments: &[&'run str],
|
positional: &[String],
|
||||||
) -> RunResult<'src, ()> {
|
) -> RunResult<'src, ()> {
|
||||||
let config = &context.config;
|
let config = &context.config;
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
if context.settings.positional_arguments {
|
if context.settings.positional_arguments {
|
||||||
command.args(arguments);
|
command.args(positional);
|
||||||
}
|
}
|
||||||
|
|
||||||
command.export(context.settings, dotenv, &scope);
|
command.export(context.settings, dotenv, &scope);
|
||||||
@ -267,7 +267,7 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
|
|
||||||
if context.settings.positional_arguments {
|
if context.settings.positional_arguments {
|
||||||
cmd.arg(self.name.lexeme());
|
cmd.arg(self.name.lexeme());
|
||||||
cmd.args(arguments);
|
cmd.args(positional);
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.verbosity.quiet() {
|
if config.verbosity.quiet() {
|
||||||
|
@ -64,3 +64,43 @@ test! {
|
|||||||
args: ("foo", "a", "b", "c"),
|
args: ("foo", "a", "b", "c"),
|
||||||
stdout: "a\na b c\n",
|
stdout: "a\na b c\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test! {
|
||||||
|
name: default_arguments,
|
||||||
|
justfile: r#"
|
||||||
|
set positional-arguments
|
||||||
|
|
||||||
|
foo bar='baz':
|
||||||
|
echo $1
|
||||||
|
"#,
|
||||||
|
args: (),
|
||||||
|
stdout: "baz\n",
|
||||||
|
stderr: "echo $1\n",
|
||||||
|
}
|
||||||
|
|
||||||
|
test! {
|
||||||
|
name: empty_variadic_is_undefined,
|
||||||
|
justfile: r#"
|
||||||
|
set positional-arguments
|
||||||
|
|
||||||
|
foo *bar:
|
||||||
|
if [ -n "${1+1}" ]; then echo defined; else echo undefined; fi
|
||||||
|
"#,
|
||||||
|
args: (),
|
||||||
|
stdout: "undefined\n",
|
||||||
|
stderr: "if [ -n \"${1+1}\" ]; then echo defined; else echo undefined; fi\n",
|
||||||
|
}
|
||||||
|
|
||||||
|
test! {
|
||||||
|
name: variadic_arguments_are_separate,
|
||||||
|
justfile: r#"
|
||||||
|
set positional-arguments
|
||||||
|
|
||||||
|
foo *bar:
|
||||||
|
echo $1
|
||||||
|
echo $2
|
||||||
|
"#,
|
||||||
|
args: ("foo", "a", "b"),
|
||||||
|
stdout: "a\nb\n",
|
||||||
|
stderr: "echo $1\necho $2\n",
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user