Add [confirm]
attribute (#1723)
This commit is contained in:
parent
59ea5de781
commit
9415bee16b
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.idea
|
.idea
|
||||||
/.vagrant
|
/.vagrant
|
||||||
|
/.vscode
|
||||||
/README.html
|
/README.html
|
||||||
/book/en/build
|
/book/en/build
|
||||||
/book/en/src
|
/book/en/src
|
||||||
|
24
README.md
24
README.md
@ -1251,13 +1251,14 @@ Recipes may be annotated with attributes that change their behavior.
|
|||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
| ----------------------------------- | ----------------------------------------------- |
|
| ----------------------------------- | ----------------------------------------------- |
|
||||||
| `[no-cd]`<sup>1.9.0</sup> | Don't change directory before executing recipe. |
|
| `[confirm]`<sup>master</sup> | Require confirmation prior to executing recipe. |
|
||||||
| `[no-exit-message]`<sup>1.7.0</sup> | Don't print an error message if recipe fails. |
|
|
||||||
| `[linux]`<sup>1.8.0</sup> | Enable recipe on Linux. |
|
| `[linux]`<sup>1.8.0</sup> | Enable recipe on Linux. |
|
||||||
| `[macos]`<sup>1.8.0</sup> | Enable recipe on MacOS. |
|
| `[macos]`<sup>1.8.0</sup> | Enable recipe on MacOS. |
|
||||||
|
| `[no-cd]`<sup>1.9.0</sup> | Don't change directory before executing recipe. |
|
||||||
|
| `[no-exit-message]`<sup>1.7.0</sup> | Don't print an error message if recipe fails. |
|
||||||
|
| `[private]`<sup>1.10.0</sup> | See [Private Recipes](#private-recipes). |
|
||||||
| `[unix]`<sup>1.8.0</sup> | Enable recipe on Unixes. (Includes MacOS). |
|
| `[unix]`<sup>1.8.0</sup> | Enable recipe on Unixes. (Includes MacOS). |
|
||||||
| `[windows]`<sup>1.8.0</sup> | Enable recipe on Windows. |
|
| `[windows]`<sup>1.8.0</sup> | Enable recipe on Windows. |
|
||||||
| `[private]`<sup>1.10.0</sup> | See [Private Recipes](#private-recipes). |
|
|
||||||
|
|
||||||
A recipe can have multiple attributes, either on multiple lines:
|
A recipe can have multiple attributes, either on multiple lines:
|
||||||
|
|
||||||
@ -1321,6 +1322,23 @@ Can be used with paths that are relative to the current directory, because
|
|||||||
`[no-cd]` prevents `just` from changing the current directory when executing
|
`[no-cd]` prevents `just` from changing the current directory when executing
|
||||||
`commit`.
|
`commit`.
|
||||||
|
|
||||||
|
### Requiring Confirmation for Recipes<sup>master</sup>
|
||||||
|
|
||||||
|
`just` normally executes all recipes unless there is an error. The `[confirm]`
|
||||||
|
attribute allows recipes require confirmation in the terminal prior to running.
|
||||||
|
This can be overridden by passing `--yes` to `just`, which will automatically
|
||||||
|
confirm any recipes marked by this attribute.
|
||||||
|
|
||||||
|
Recipes dependent on a recipe that requires confirmation will not be run if the
|
||||||
|
relied upon recipe is not confirmed, as well as recipes passed after any recipe
|
||||||
|
that requires confirmation.
|
||||||
|
|
||||||
|
```just
|
||||||
|
[confirm]
|
||||||
|
delete all:
|
||||||
|
rm -rf *
|
||||||
|
```
|
||||||
|
|
||||||
### Command Evaluation Using Backticks
|
### Command Evaluation Using Backticks
|
||||||
|
|
||||||
Backticks can be used to store the result of commands:
|
Backticks can be used to store the result of commands:
|
||||||
|
@ -20,7 +20,7 @@ _just() {
|
|||||||
|
|
||||||
case "${cmd}" in
|
case "${cmd}" in
|
||||||
just)
|
just)
|
||||||
opts=" -n -q -u -v -e -l -h -V -f -d -c -s --check --dry-run --highlight --no-dotenv --no-highlight --quiet --shell-command --clear-shell-args --unsorted --unstable --verbose --changelog --choose --dump --edit --evaluate --fmt --init --list --summary --variables --help --version --chooser --color --command-color --dump-format --list-heading --list-prefix --justfile --set --shell --shell-arg --working-directory --command --completions --show --dotenv-filename --dotenv-path <ARGUMENTS>... "
|
opts=" -n -q -u -v -e -l -h -V -f -d -c -s --check --yes --dry-run --highlight --no-dotenv --no-highlight --quiet --shell-command --clear-shell-args --unsorted --unstable --verbose --changelog --choose --dump --edit --evaluate --fmt --init --list --summary --variables --help --version --chooser --color --command-color --dump-format --list-heading --list-prefix --justfile --set --shell --shell-arg --working-directory --command --completions --show --dotenv-filename --dotenv-path <ARGUMENTS>... "
|
||||||
if [[ ${cur} == -* ]] ; then
|
if [[ ${cur} == -* ]] ; then
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||||
return 0
|
return 0
|
||||||
|
@ -35,6 +35,7 @@ edit:completion:arg-completer[just] = [@words]{
|
|||||||
cand --dotenv-filename 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
cand --dotenv-filename 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
||||||
cand --dotenv-path 'Load environment file at <DOTENV-PATH> instead of searching for one'
|
cand --dotenv-path 'Load environment file at <DOTENV-PATH> instead of searching for one'
|
||||||
cand --check 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
cand --check 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
||||||
|
cand --yes 'Automatically confirm all recipes.'
|
||||||
cand -n 'Print what just would do without doing it'
|
cand -n 'Print what just would do without doing it'
|
||||||
cand --dry-run 'Print what just would do without doing it'
|
cand --dry-run 'Print what just would do without doing it'
|
||||||
cand --highlight 'Highlight echoed recipe lines in bold'
|
cand --highlight 'Highlight echoed recipe lines in bold'
|
||||||
|
@ -52,6 +52,7 @@ complete -c just -n "__fish_use_subcommand" -s s -l show -d 'Show information ab
|
|||||||
complete -c just -n "__fish_use_subcommand" -l dotenv-filename -d 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
complete -c just -n "__fish_use_subcommand" -l dotenv-filename -d 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
||||||
complete -c just -n "__fish_use_subcommand" -l dotenv-path -d 'Load environment file at <DOTENV-PATH> instead of searching for one'
|
complete -c just -n "__fish_use_subcommand" -l dotenv-path -d 'Load environment file at <DOTENV-PATH> instead of searching for one'
|
||||||
complete -c just -n "__fish_use_subcommand" -l check -d 'Run `--fmt` in \'check\' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
complete -c just -n "__fish_use_subcommand" -l check -d 'Run `--fmt` in \'check\' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
||||||
|
complete -c just -n "__fish_use_subcommand" -l yes -d 'Automatically confirm all recipes.'
|
||||||
complete -c just -n "__fish_use_subcommand" -s n -l dry-run -d 'Print what just would do without doing it'
|
complete -c just -n "__fish_use_subcommand" -s n -l dry-run -d 'Print what just would do without doing it'
|
||||||
complete -c just -n "__fish_use_subcommand" -l highlight -d 'Highlight echoed recipe lines in bold'
|
complete -c just -n "__fish_use_subcommand" -l highlight -d 'Highlight echoed recipe lines in bold'
|
||||||
complete -c just -n "__fish_use_subcommand" -l no-dotenv -d 'Don\'t load `.env` file'
|
complete -c just -n "__fish_use_subcommand" -l no-dotenv -d 'Don\'t load `.env` file'
|
||||||
|
@ -40,6 +40,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
|||||||
[CompletionResult]::new('--dotenv-filename', 'dotenv-filename', [CompletionResultType]::ParameterName, 'Search for environment file named <DOTENV-FILENAME> instead of `.env`')
|
[CompletionResult]::new('--dotenv-filename', 'dotenv-filename', [CompletionResultType]::ParameterName, 'Search for environment file named <DOTENV-FILENAME> instead of `.env`')
|
||||||
[CompletionResult]::new('--dotenv-path', 'dotenv-path', [CompletionResultType]::ParameterName, 'Load environment file at <DOTENV-PATH> instead of searching for one')
|
[CompletionResult]::new('--dotenv-path', 'dotenv-path', [CompletionResultType]::ParameterName, 'Load environment file at <DOTENV-PATH> instead of searching for one')
|
||||||
[CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.')
|
[CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.')
|
||||||
|
[CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Automatically confirm all recipes.')
|
||||||
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
||||||
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
||||||
[CompletionResult]::new('--highlight', 'highlight', [CompletionResultType]::ParameterName, 'Highlight echoed recipe lines in bold')
|
[CompletionResult]::new('--highlight', 'highlight', [CompletionResultType]::ParameterName, 'Highlight echoed recipe lines in bold')
|
||||||
|
@ -36,6 +36,7 @@ _just() {
|
|||||||
'(--dotenv-path)--dotenv-filename=[Search for environment file named <DOTENV-FILENAME> instead of `.env`]' \
|
'(--dotenv-path)--dotenv-filename=[Search for environment file named <DOTENV-FILENAME> instead of `.env`]' \
|
||||||
'--dotenv-path=[Load environment file at <DOTENV-PATH> instead of searching for one]' \
|
'--dotenv-path=[Load environment file at <DOTENV-PATH> instead of searching for one]' \
|
||||||
'--check[Run `--fmt` in '\''check'\'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.]' \
|
'--check[Run `--fmt` in '\''check'\'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.]' \
|
||||||
|
'--yes[Automatically confirm all recipes.]' \
|
||||||
'(-q --quiet)-n[Print what just would do without doing it]' \
|
'(-q --quiet)-n[Print what just would do without doing it]' \
|
||||||
'(-q --quiet)--dry-run[Print what just would do without doing it]' \
|
'(-q --quiet)--dry-run[Print what just would do without doing it]' \
|
||||||
'--highlight[Highlight echoed recipe lines in bold]' \
|
'--highlight[Highlight echoed recipe lines in bold]' \
|
||||||
|
@ -6,6 +6,7 @@ use super::*;
|
|||||||
#[strum(serialize_all = "kebab-case")]
|
#[strum(serialize_all = "kebab-case")]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub(crate) enum Attribute {
|
pub(crate) enum Attribute {
|
||||||
|
Confirm,
|
||||||
Linux,
|
Linux,
|
||||||
Macos,
|
Macos,
|
||||||
NoCd,
|
NoCd,
|
||||||
|
@ -33,6 +33,7 @@ pub(crate) struct Config {
|
|||||||
pub(crate) unsorted: bool,
|
pub(crate) unsorted: bool,
|
||||||
pub(crate) unstable: bool,
|
pub(crate) unstable: bool,
|
||||||
pub(crate) verbosity: Verbosity,
|
pub(crate) verbosity: Verbosity,
|
||||||
|
pub(crate) yes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
mod cmd {
|
mod cmd {
|
||||||
@ -106,6 +107,7 @@ mod arg {
|
|||||||
pub(crate) const UNSTABLE: &str = "UNSTABLE";
|
pub(crate) const UNSTABLE: &str = "UNSTABLE";
|
||||||
pub(crate) const VERBOSE: &str = "VERBOSE";
|
pub(crate) const VERBOSE: &str = "VERBOSE";
|
||||||
pub(crate) const WORKING_DIRECTORY: &str = "WORKING-DIRECTORY";
|
pub(crate) const WORKING_DIRECTORY: &str = "WORKING-DIRECTORY";
|
||||||
|
pub(crate) const YES: &str = "YES";
|
||||||
|
|
||||||
pub(crate) const COLOR_ALWAYS: &str = "always";
|
pub(crate) const COLOR_ALWAYS: &str = "always";
|
||||||
pub(crate) const COLOR_AUTO: &str = "auto";
|
pub(crate) const COLOR_AUTO: &str = "auto";
|
||||||
@ -168,6 +170,7 @@ impl Config {
|
|||||||
.possible_values(arg::COMMAND_COLOR_VALUES)
|
.possible_values(arg::COMMAND_COLOR_VALUES)
|
||||||
.help("Echo recipe lines in <COMMAND-COLOR>"),
|
.help("Echo recipe lines in <COMMAND-COLOR>"),
|
||||||
)
|
)
|
||||||
|
.arg(Arg::with_name(arg::YES).long("yes").help("Automatically confirm all recipes."))
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(arg::DRY_RUN)
|
Arg::with_name(arg::DRY_RUN)
|
||||||
.short("n")
|
.short("n")
|
||||||
@ -622,14 +625,14 @@ impl Config {
|
|||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
check: matches.is_present(arg::CHECK),
|
check: matches.is_present(arg::CHECK),
|
||||||
|
color,
|
||||||
|
command_color,
|
||||||
|
dotenv_filename: matches.value_of(arg::DOTENV_FILENAME).map(str::to_owned),
|
||||||
|
dotenv_path: matches.value_of(arg::DOTENV_PATH).map(PathBuf::from),
|
||||||
dry_run: matches.is_present(arg::DRY_RUN),
|
dry_run: matches.is_present(arg::DRY_RUN),
|
||||||
dump_format: Self::dump_format_from_matches(matches)?,
|
dump_format: Self::dump_format_from_matches(matches)?,
|
||||||
highlight: !matches.is_present(arg::NO_HIGHLIGHT),
|
highlight: !matches.is_present(arg::NO_HIGHLIGHT),
|
||||||
shell: matches.value_of(arg::SHELL).map(str::to_owned),
|
invocation_directory,
|
||||||
load_dotenv: !matches.is_present(arg::NO_DOTENV),
|
|
||||||
shell_command: matches.is_present(arg::SHELL_COMMAND),
|
|
||||||
unsorted: matches.is_present(arg::UNSORTED),
|
|
||||||
unstable,
|
|
||||||
list_heading: matches
|
list_heading: matches
|
||||||
.value_of(arg::LIST_HEADING)
|
.value_of(arg::LIST_HEADING)
|
||||||
.unwrap_or("Available recipes:\n")
|
.unwrap_or("Available recipes:\n")
|
||||||
@ -638,15 +641,16 @@ impl Config {
|
|||||||
.value_of(arg::LIST_PREFIX)
|
.value_of(arg::LIST_PREFIX)
|
||||||
.unwrap_or(" ")
|
.unwrap_or(" ")
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
color,
|
load_dotenv: !matches.is_present(arg::NO_DOTENV),
|
||||||
command_color,
|
|
||||||
invocation_directory,
|
|
||||||
search_config,
|
search_config,
|
||||||
|
shell: matches.value_of(arg::SHELL).map(str::to_owned),
|
||||||
shell_args,
|
shell_args,
|
||||||
|
shell_command: matches.is_present(arg::SHELL_COMMAND),
|
||||||
subcommand,
|
subcommand,
|
||||||
dotenv_filename: matches.value_of(arg::DOTENV_FILENAME).map(str::to_owned),
|
unsorted: matches.is_present(arg::UNSORTED),
|
||||||
dotenv_path: matches.value_of(arg::DOTENV_PATH).map(PathBuf::from),
|
unstable,
|
||||||
verbosity,
|
verbosity,
|
||||||
|
yes: matches.is_present(arg::YES),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/error.rs
12
src/error.rs
@ -88,6 +88,9 @@ pub(crate) enum Error<'src> {
|
|||||||
function: Name<'src>,
|
function: Name<'src>,
|
||||||
message: String,
|
message: String,
|
||||||
},
|
},
|
||||||
|
GetConfirmation {
|
||||||
|
io_error: io::Error,
|
||||||
|
},
|
||||||
IncludeMissingPath {
|
IncludeMissingPath {
|
||||||
file: PathBuf,
|
file: PathBuf,
|
||||||
line: usize,
|
line: usize,
|
||||||
@ -111,6 +114,9 @@ pub(crate) enum Error<'src> {
|
|||||||
},
|
},
|
||||||
NoChoosableRecipes,
|
NoChoosableRecipes,
|
||||||
NoRecipes,
|
NoRecipes,
|
||||||
|
NotConfirmed {
|
||||||
|
recipe: &'src str,
|
||||||
|
},
|
||||||
RegexCompile {
|
RegexCompile {
|
||||||
source: regex::Error,
|
source: regex::Error,
|
||||||
},
|
},
|
||||||
@ -329,6 +335,9 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
let function = function.lexeme();
|
let function = function.lexeme();
|
||||||
write!(f, "Call to function `{function}` failed: {message}")?;
|
write!(f, "Call to function `{function}` failed: {message}")?;
|
||||||
}
|
}
|
||||||
|
GetConfirmation { io_error } => {
|
||||||
|
write!(f, "Failed to read confirmation from stdin: {io_error}")?;
|
||||||
|
}
|
||||||
IncludeMissingPath { file: justfile, line } => {
|
IncludeMissingPath { file: justfile, line } => {
|
||||||
let line = line.ordinal();
|
let line = line.ordinal();
|
||||||
let justfile = justfile.display();
|
let justfile = justfile.display();
|
||||||
@ -357,6 +366,9 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
}
|
}
|
||||||
NoChoosableRecipes => write!(f, "Justfile contains no choosable recipes.")?,
|
NoChoosableRecipes => write!(f, "Justfile contains no choosable recipes.")?,
|
||||||
NoRecipes => write!(f, "Justfile contains no recipes.")?,
|
NoRecipes => write!(f, "Justfile contains no recipes.")?,
|
||||||
|
NotConfirmed { recipe } => {
|
||||||
|
write!(f, "Recipe `{recipe}` was not confirmed")?;
|
||||||
|
}
|
||||||
RegexCompile { source } => write!(f, "{source}")?,
|
RegexCompile { source } => write!(f, "{source}")?,
|
||||||
Search { search_error } => Display::fmt(search_error, f)?,
|
Search { search_error } => Display::fmt(search_error, f)?,
|
||||||
Shebang { recipe, command, argument, io_error} => {
|
Shebang { recipe, command, argument, io_error} => {
|
||||||
|
@ -290,6 +290,12 @@ impl<'src> Justfile<'src> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !context.config.yes && !recipe.confirm()? {
|
||||||
|
return Err(Error::NotConfirmed {
|
||||||
|
recipe: recipe.name(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let (outer, positional) = Evaluator::evaluate_parameters(
|
let (outer, positional) = Evaluator::evaluate_parameters(
|
||||||
context.config,
|
context.config,
|
||||||
dotenv,
|
dotenv,
|
||||||
|
@ -63,6 +63,20 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
self.name.line
|
self.name.line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn confirm(&self) -> RunResult<'src, bool> {
|
||||||
|
if self.attributes.contains(&Attribute::Confirm) {
|
||||||
|
eprint!("Run recipe `{}`? ", self.name);
|
||||||
|
let mut line = String::new();
|
||||||
|
std::io::stdin()
|
||||||
|
.read_line(&mut line)
|
||||||
|
.map_err(|io_error| Error::GetConfirmation { io_error })?;
|
||||||
|
let line = line.trim().to_lowercase();
|
||||||
|
Ok(line == "y" || line == "yes")
|
||||||
|
} else {
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn public(&self) -> bool {
|
pub(crate) fn public(&self) -> bool {
|
||||||
!self.private && !self.attributes.contains(&Attribute::Private)
|
!self.private && !self.attributes.contains(&Attribute::Private)
|
||||||
}
|
}
|
||||||
|
105
tests/confirm.rs
Normal file
105
tests/confirm.rs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn confirm_recipe_arg() {
|
||||||
|
Test::new()
|
||||||
|
.arg("--yes")
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
[confirm]
|
||||||
|
requires_confirmation:
|
||||||
|
echo confirmed
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.stderr("echo confirmed\n")
|
||||||
|
.stdout("confirmed\n")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn recipe_with_confirm_recipe_dependency_arg() {
|
||||||
|
Test::new()
|
||||||
|
.arg("--yes")
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
dep_confirmation: requires_confirmation
|
||||||
|
echo confirmed2
|
||||||
|
|
||||||
|
[confirm]
|
||||||
|
requires_confirmation:
|
||||||
|
echo confirmed
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.stderr("echo confirmed\necho confirmed2\n")
|
||||||
|
.stdout("confirmed\nconfirmed2\n")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn confirm_recipe() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
[confirm]
|
||||||
|
requires_confirmation:
|
||||||
|
echo confirmed
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.stderr("Run recipe `requires_confirmation`? echo confirmed\n")
|
||||||
|
.stdout("confirmed\n")
|
||||||
|
.stdin("y")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn recipe_with_confirm_recipe_dependency() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
dep_confirmation: requires_confirmation
|
||||||
|
echo confirmed2
|
||||||
|
|
||||||
|
[confirm]
|
||||||
|
requires_confirmation:
|
||||||
|
echo confirmed
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.stderr("Run recipe `requires_confirmation`? echo confirmed\necho confirmed2\n")
|
||||||
|
.stdout("confirmed\nconfirmed2\n")
|
||||||
|
.stdin("y")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn do_not_confirm_recipe() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
[confirm]
|
||||||
|
requires_confirmation:
|
||||||
|
echo confirmed
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.stderr("Run recipe `requires_confirmation`? error: Recipe `requires_confirmation` was not confirmed\n")
|
||||||
|
.stdout("")
|
||||||
|
.status(1)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn do_not_confirm_recipe_with_confirm_recipe_dependency() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
dep_confirmation: requires_confirmation
|
||||||
|
echo mistake
|
||||||
|
|
||||||
|
[confirm]
|
||||||
|
requires_confirmation:
|
||||||
|
echo confirmed
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.stderr("Run recipe `requires_confirmation`? error: Recipe `requires_confirmation` was not confirmed\n")
|
||||||
|
.status(1)
|
||||||
|
.run();
|
||||||
|
}
|
@ -42,6 +42,7 @@ mod choose;
|
|||||||
mod command;
|
mod command;
|
||||||
mod completions;
|
mod completions;
|
||||||
mod conditional;
|
mod conditional;
|
||||||
|
mod confirm;
|
||||||
mod delimiters;
|
mod delimiters;
|
||||||
mod dotenv;
|
mod dotenv;
|
||||||
mod edit;
|
mod edit;
|
||||||
|
Loading…
Reference in New Issue
Block a user