Add set quiet and [no-quiet] (#1704)

This commit is contained in:
David Harrigan 2024-01-12 20:38:23 +00:00 committed by GitHub
parent 53cea2f823
commit 5bbc89b718
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 193 additions and 5 deletions

View File

@ -69,6 +69,7 @@ setting : 'set' 'allow-duplicate-recipes' boolean?
| 'set' 'fallback' boolean? | 'set' 'fallback' boolean?
| 'set' 'ignore-comments' boolean? | 'set' 'ignore-comments' boolean?
| 'set' 'positional-arguments' boolean? | 'set' 'positional-arguments' boolean?
| 'set' 'quiet' boolean?
| 'set' 'shell' ':=' '[' string (',' string)* ','? ']' | 'set' 'shell' ':=' '[' string (',' string)* ','? ']'
| 'set' 'tempdir ':=' string | 'set' 'tempdir ':=' string
| 'set' 'windows-powershell' boolean? | 'set' 'windows-powershell' boolean?

View File

@ -1460,6 +1460,7 @@ Recipes may be annotated with attributes that change their behavior.
| `[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-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. | | `[no-exit-message]`<sup>1.7.0</sup> | Don't print an error message if recipe fails. |
| `[no-quiet]`<sup>master</sup> | Override globally quiet recipes and always echo out the recipe. |
| `[private]`<sup>1.10.0</sup> | See [Private Recipes](#private-recipes). | | `[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. |
@ -2496,6 +2497,31 @@ goodbye
# all done! # all done!
``` ```
All recipes in a Justfile can be made quiet with `set quiet`:
```just
set quiet
foo:
echo "This is quiet"
@foo2:
echo "This is also quiet"
```
The `[no-quiet]` attribute overrides this setting:
```just
set quiet
foo:
echo "This is quiet"
[no-quiet]
foo2:
echo "This is not quiet"
```
Shebang recipes are quiet by default: Shebang recipes are quiet by default:
```just ```just

View File

@ -12,6 +12,7 @@ pub(crate) enum Attribute {
NoCd, NoCd,
NoExitMessage, NoExitMessage,
Private, Private,
NoQuiet,
Unix, Unix,
Windows, Windows,
} }

View File

@ -17,6 +17,7 @@ pub(crate) enum Keyword {
Import, Import,
Mod, Mod,
PositionalArguments, PositionalArguments,
Quiet,
Set, Set,
Shell, Shell,
Tempdir, Tempdir,

View File

@ -269,6 +269,7 @@ impl<'src> Node<'src> for Set<'src> {
| Setting::Export(value) | Setting::Export(value)
| Setting::Fallback(value) | Setting::Fallback(value)
| Setting::PositionalArguments(value) | Setting::PositionalArguments(value)
| Setting::Quiet(value)
| Setting::WindowsPowerShell(value) | Setting::WindowsPowerShell(value)
| Setting::IgnoreComments(value) => { | Setting::IgnoreComments(value) => {
set.push_mut(value.to_string()); set.push_mut(value.to_string());

View File

@ -852,6 +852,7 @@ impl<'run, 'src> Parser<'run, 'src> {
Keyword::Fallback => Some(Setting::Fallback(self.parse_set_bool()?)), Keyword::Fallback => Some(Setting::Fallback(self.parse_set_bool()?)),
Keyword::IgnoreComments => Some(Setting::IgnoreComments(self.parse_set_bool()?)), Keyword::IgnoreComments => Some(Setting::IgnoreComments(self.parse_set_bool()?)),
Keyword::PositionalArguments => Some(Setting::PositionalArguments(self.parse_set_bool()?)), Keyword::PositionalArguments => Some(Setting::PositionalArguments(self.parse_set_bool()?)),
Keyword::Quiet => Some(Setting::Quiet(self.parse_set_bool()?)),
Keyword::WindowsPowershell => Some(Setting::WindowsPowerShell(self.parse_set_bool()?)), Keyword::WindowsPowershell => Some(Setting::WindowsPowerShell(self.parse_set_bool()?)),
_ => None, _ => None,
}; };
@ -1927,6 +1928,24 @@ mod tests {
tree: (justfile (set positional_arguments true)), tree: (justfile (set positional_arguments true)),
} }
test! {
name: set_quiet_implicit,
text: "set quiet",
tree: (justfile (set quiet true)),
}
test! {
name: set_quiet_true,
text: "set quiet := true",
tree: (justfile (set quiet true)),
}
test! {
name: set_quiet_false,
text: "set quiet := false",
tree: (justfile (set quiet false)),
}
test! { test! {
name: set_positional_arguments_false, name: set_positional_arguments_false,
text: "set positional-arguments := false", text: "set positional-arguments := false",

View File

@ -134,6 +134,10 @@ impl<'src, D> Recipe<'src, D> {
} }
} }
fn no_quiet(&self) -> bool {
self.attributes.contains(&Attribute::NoQuiet)
}
pub(crate) fn run<'run>( pub(crate) fn run<'run>(
&self, &self,
context: &RecipeContext<'src, 'run>, context: &RecipeContext<'src, 'run>,
@ -181,8 +185,8 @@ impl<'src, D> Recipe<'src, D> {
} }
let mut evaluated = String::new(); let mut evaluated = String::new();
let mut continued = false; let mut continued = false;
let quiet_command = lines.peek().map_or(false, |line| line.is_quiet()); let quiet_line = lines.peek().map_or(false, |line| line.is_quiet());
let infallible_command = lines.peek().map_or(false, |line| line.is_infallible()); let infallible_line = lines.peek().map_or(false, |line| line.is_infallible());
let comment_line = let comment_line =
context.settings.ignore_comments && lines.peek().map_or(false, |line| line.is_comment()); context.settings.ignore_comments && lines.peek().map_or(false, |line| line.is_comment());
@ -210,7 +214,7 @@ impl<'src, D> Recipe<'src, D> {
let mut command = evaluated.as_str(); let mut command = evaluated.as_str();
let sigils = usize::from(infallible_command) + usize::from(quiet_command); let sigils = usize::from(infallible_line) + usize::from(quiet_line);
command = &command[sigils..]; command = &command[sigils..];
@ -220,7 +224,9 @@ impl<'src, D> Recipe<'src, D> {
if config.dry_run if config.dry_run
|| config.verbosity.loquacious() || config.verbosity.loquacious()
|| !((quiet_command ^ self.quiet) || config.verbosity.quiet()) || !((quiet_line ^ self.quiet)
|| (context.settings.quiet && !self.no_quiet())
|| config.verbosity.quiet())
{ {
let color = if config.highlight { let color = if config.highlight {
config.color.command(config.command_color) config.color.command(config.command_color)
@ -257,7 +263,7 @@ impl<'src, D> Recipe<'src, D> {
match InterruptHandler::guard(|| cmd.status()) { match InterruptHandler::guard(|| cmd.status()) {
Ok(exit_status) => { Ok(exit_status) => {
if let Some(code) = exit_status.code() { if let Some(code) = exit_status.code() {
if code != 0 && !infallible_command { if code != 0 && !infallible_line {
return Err(Error::Code { return Err(Error::Code {
recipe: self.name(), recipe: self.name(),
line_number: Some(line_number), line_number: Some(line_number),

View File

@ -10,6 +10,7 @@ pub(crate) enum Setting<'src> {
Fallback(bool), Fallback(bool),
IgnoreComments(bool), IgnoreComments(bool),
PositionalArguments(bool), PositionalArguments(bool),
Quiet(bool),
Shell(Shell<'src>), Shell(Shell<'src>),
Tempdir(String), Tempdir(String),
WindowsPowerShell(bool), WindowsPowerShell(bool),
@ -25,6 +26,7 @@ impl<'src> Display for Setting<'src> {
| Setting::Fallback(value) | Setting::Fallback(value)
| Setting::IgnoreComments(value) | Setting::IgnoreComments(value)
| Setting::PositionalArguments(value) | Setting::PositionalArguments(value)
| Setting::Quiet(value)
| Setting::WindowsPowerShell(value) => write!(f, "{value}"), | Setting::WindowsPowerShell(value) => write!(f, "{value}"),
Setting::Shell(shell) | Setting::WindowsShell(shell) => write!(f, "{shell}"), Setting::Shell(shell) | Setting::WindowsShell(shell) => write!(f, "{shell}"),
Setting::DotenvFilename(value) | Setting::DotenvPath(value) | Setting::Tempdir(value) => { Setting::DotenvFilename(value) | Setting::DotenvPath(value) | Setting::Tempdir(value) => {

View File

@ -15,6 +15,7 @@ pub(crate) struct Settings<'src> {
pub(crate) fallback: bool, pub(crate) fallback: bool,
pub(crate) ignore_comments: bool, pub(crate) ignore_comments: bool,
pub(crate) positional_arguments: bool, pub(crate) positional_arguments: bool,
pub(crate) quiet: bool,
pub(crate) shell: Option<Shell<'src>>, pub(crate) shell: Option<Shell<'src>>,
pub(crate) tempdir: Option<String>, pub(crate) tempdir: Option<String>,
pub(crate) windows_powershell: bool, pub(crate) windows_powershell: bool,
@ -51,6 +52,9 @@ impl<'src> Settings<'src> {
Setting::PositionalArguments(positional_arguments) => { Setting::PositionalArguments(positional_arguments) => {
settings.positional_arguments = positional_arguments; settings.positional_arguments = positional_arguments;
} }
Setting::Quiet(quiet) => {
settings.quiet = quiet;
}
Setting::Shell(shell) => { Setting::Shell(shell) => {
settings.shell = Some(shell); settings.shell = Some(shell);
} }

View File

@ -50,6 +50,7 @@ fn alias() {
"export": false, "export": false,
"fallback": false, "fallback": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"ignore_comments": false, "ignore_comments": false,
@ -86,6 +87,7 @@ fn assignment() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -136,6 +138,7 @@ fn body() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -198,6 +201,7 @@ fn dependencies() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -297,6 +301,7 @@ fn dependency_argument() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -359,6 +364,7 @@ fn duplicate_recipes() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -402,6 +408,7 @@ fn doc_comment() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -431,6 +438,7 @@ fn empty_justfile() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -581,6 +589,7 @@ fn parameters() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -664,6 +673,7 @@ fn priors() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -707,6 +717,7 @@ fn private() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -750,6 +761,7 @@ fn quiet() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"windows_powershell": false, "windows_powershell": false,
@ -770,6 +782,7 @@ fn settings() {
set export set export
set fallback set fallback
set positional-arguments set positional-arguments
set quiet
set ignore-comments set ignore-comments
set shell := ['a', 'b', 'c'] set shell := ['a', 'b', 'c']
foo: foo:
@ -804,6 +817,7 @@ fn settings() {
"fallback": true, "fallback": true,
"ignore_comments": true, "ignore_comments": true,
"positional_arguments": true, "positional_arguments": true,
"quiet": true,
"shell": { "shell": {
"arguments": ["b", "c"], "arguments": ["b", "c"],
"command": "a", "command": "a",
@ -853,6 +867,7 @@ fn shebang() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir": null, "tempdir": null,
"windows_powershell": false, "windows_powershell": false,
@ -896,6 +911,7 @@ fn simple() {
"fallback": false, "fallback": false,
"ignore_comments": false, "ignore_comments": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir": null, "tempdir": null,
"windows_powershell": false, "windows_powershell": false,
@ -941,6 +957,7 @@ fn attribute() {
"export": false, "export": false,
"fallback": false, "fallback": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"ignore_comments": false, "ignore_comments": false,
@ -1000,6 +1017,7 @@ fn module() {
"export": false, "export": false,
"fallback": false, "fallback": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"ignore_comments": false, "ignore_comments": false,
@ -1018,6 +1036,7 @@ fn module() {
"export": false, "export": false,
"fallback": false, "fallback": false,
"positional_arguments": false, "positional_arguments": false,
"quiet": false,
"shell": null, "shell": null,
"tempdir" : null, "tempdir" : null,
"ignore_comments": false, "ignore_comments": false,

View File

@ -129,3 +129,111 @@ test! {
", ",
args: ("--quiet"), args: ("--quiet"),
} }
#[test]
fn no_quiet_setting() {
Test::new()
.justfile(
"
foo:
echo FOO
",
)
.stdout("FOO\n")
.stderr("echo FOO\n")
.run();
}
#[test]
fn quiet_setting() {
Test::new()
.justfile(
"
set quiet
foo:
echo FOO
",
)
.stdout("FOO\n")
.run();
}
#[test]
fn quiet_setting_with_no_quiet_attribute() {
Test::new()
.justfile(
"
set quiet
[no-quiet]
foo:
echo FOO
",
)
.stdout("FOO\n")
.stderr("echo FOO\n")
.run();
}
#[test]
fn quiet_setting_with_quiet_recipe() {
Test::new()
.justfile(
"
set quiet
@foo:
echo FOO
",
)
.stdout("FOO\n")
.run();
}
#[test]
fn quiet_setting_with_quiet_line() {
Test::new()
.justfile(
"
set quiet
foo:
@echo FOO
",
)
.stdout("FOO\n")
.run();
}
#[test]
fn quiet_setting_with_no_quiet_attribute_and_quiet_recipe() {
Test::new()
.justfile(
"
set quiet
[no-quiet]
@foo:
echo FOO
",
)
.stdout("FOO\n")
.run();
}
#[test]
fn quiet_setting_with_no_quiet_attribute_and_quiet_line() {
Test::new()
.justfile(
"
set quiet
[no-quiet]
foo:
@echo FOO
",
)
.stdout("FOO\n")
.run();
}