diff --git a/README.md b/README.md index b318a5dbcb..622f417054 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ most Windows users.) npm rust-just - npm install rust-just + npm install -g rust-just PyPI @@ -1851,6 +1851,24 @@ for details. `requirement`, e.g., `">=0.1.0"`, returning `"true"` if so and `"false"` otherwise. +#### Style + +- `style(name)`master - Return a named terminal display attribute + escape sequence used by `just`. Unlike terminal display attribute escape + sequence constants, which contain standard colors and styles, `style(name)` + returns an escape sequence used by `just` itself, and can be used to make + recipe output match `just`'s own output. + + Recognized values for `name` are `'command'`, for echoed recipe lines, + `error`, and `warning`. + + For example, to style an error message: + + ```just + scary: + @echo '{{ style("error") }}OH NO{{ NORMAL }}' + ``` + ##### XDG Directories1.23.0 These functions return paths to user-specific directories for things like @@ -2755,8 +2773,9 @@ scripts interpreted by `COMMAND`. This avoids some of the issues with shebang recipes, such as the use of `cygpath` on Windows, the need to use `/usr/bin/env`, and inconsistences in shebang line splitting across Unix OSs. -Recipes with an empty `[script]` attribute are executed with the value of -`set script-interpreter := […]`1.33.0, defaulting to `sh -eu`. +Recipes with an empty `[script]` attribute are executed with the value of `set +script-interpreter := […]`1.33.0, defaulting to `sh -eu`, and *not* +the value of `set shell`. The body of the recipe is evaluated, written to disk in the temporary directory, and run by passing its path as an argument to `COMMAND`. diff --git "a/README.\344\270\255\346\226\207.md" "b/README.\344\270\255\346\226\207.md" index 936fb18303..f586f78e22 100644 --- "a/README.\344\270\255\346\226\207.md" +++ "b/README.\344\270\255\346\226\207.md" @@ -220,6 +220,22 @@ list: asdf install just <version> + + Various + PyPI + rust-just + + pipx install rust-just
+ + + + Various + npm + rust-just + + npm install -g rust-just
+ + Debian and Ubuntu derivatives MPR diff --git a/src/analyzer.rs b/src/analyzer.rs index 0929294c5d..1cdbf53189 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -182,6 +182,7 @@ impl<'run, 'src> Analyzer<'run, 'src> { unstable_features.insert(UnstableFeature::ScriptInterpreterSetting); } + let source = root.canonicalize().unwrap(); let root = paths.get(root).unwrap(); Ok(Justfile { @@ -205,7 +206,7 @@ impl<'run, 'src> Analyzer<'run, 'src> { name, recipes, settings, - source: root.into(), + source, unexports: self.unexports, unstable_features, warnings: self.warnings, diff --git a/src/color.rs b/src/color.rs index ba437effeb..7742597be4 100644 --- a/src/color.rs +++ b/src/color.rs @@ -35,7 +35,6 @@ impl Color { Self::default() } - #[cfg(test)] pub(crate) fn always() -> Self { Self { use_color: UseColor::Always, @@ -67,7 +66,7 @@ impl Color { } pub(crate) fn doc_backtick(self) -> Self { - self.restyle(Style::new().fg(White).on(Black)) + self.restyle(Style::new().fg(Cyan)) } pub(crate) fn error(self) -> Self { diff --git a/src/function.rs b/src/function.rs index a714a8d0fd..abeae94368 100644 --- a/src/function.rs +++ b/src/function.rs @@ -98,6 +98,7 @@ pub(crate) fn get(name: &str) -> Option { "snakecase" => Unary(snakecase), "source_directory" => Nullary(source_directory), "source_file" => Nullary(source_file), + "style" => Unary(style), "titlecase" => Unary(titlecase), "trim" => Unary(trim), "trim_end" => Unary(trim_end), @@ -623,6 +624,20 @@ fn source_file(context: Context) -> FunctionResult { }) } +fn style(context: Context, s: &str) -> FunctionResult { + match s { + "command" => Ok( + Color::always() + .command(context.evaluator.context.config.command_color) + .prefix() + .to_string(), + ), + "error" => Ok(Color::always().error().prefix().to_string()), + "warning" => Ok(Color::always().warning().prefix().to_string()), + _ => Err(format!("unknown style: `{s}`")), + } +} + fn titlecase(_context: Context, s: &str) -> FunctionResult { Ok(s.to_title_case()) } diff --git a/src/justfile.rs b/src/justfile.rs index c846900a7c..aa6ea38796 100644 --- a/src/justfile.rs +++ b/src/justfile.rs @@ -23,7 +23,6 @@ pub(crate) struct Justfile<'src> { pub(crate) name: Option>, pub(crate) recipes: Table<'src, Rc>>, pub(crate) settings: Settings<'src>, - #[serde(skip)] pub(crate) source: PathBuf, pub(crate) unexports: HashSet, #[serde(skip)] diff --git a/src/node.rs b/src/node.rs index f8788c4dc1..6bfb042af8 100644 --- a/src/node.rs +++ b/src/node.rs @@ -197,7 +197,7 @@ impl<'src> Node<'src> for UnresolvedRecipe<'src> { t.push_mut("quiet"); } - if let Some(doc) = self.doc { + if let Some(doc) = &self.doc { t.push_mut(Tree::string(doc)); } diff --git a/src/parser.rs b/src/parser.rs index 00246bf3e7..229f5aea81 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -936,6 +936,14 @@ impl<'run, 'src> Parser<'run, 'src> { let private = name.lexeme().starts_with('_') || attributes.contains(&Attribute::Private); + let mut doc = doc.map(ToOwned::to_owned); + + for attribute in &attributes { + if let Attribute::Doc(attribute_doc) = attribute { + doc = attribute_doc.as_ref().map(|doc| doc.cooked.clone()); + } + } + Ok(Recipe { shebang: shebang || script, attributes, diff --git a/src/recipe.rs b/src/recipe.rs index 05516225a6..d57bc93852 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -22,7 +22,7 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> { pub(crate) attributes: BTreeSet>, pub(crate) body: Vec>, pub(crate) dependencies: Vec, - pub(crate) doc: Option<&'src str>, + pub(crate) doc: Option, #[serde(skip)] pub(crate) file_depth: u32, #[serde(skip)] @@ -465,7 +465,8 @@ impl<'src, D> Recipe<'src, D> { return doc.as_ref().map(|s| s.cooked.as_ref()); } } - self.doc + + self.doc.as_deref() } pub(crate) fn subsequents(&self) -> impl Iterator { @@ -475,8 +476,14 @@ impl<'src, D> Recipe<'src, D> { impl<'src, D: Display> ColorDisplay for Recipe<'src, D> { fn fmt(&self, f: &mut Formatter, color: Color) -> fmt::Result { - if let Some(doc) = self.doc { - writeln!(f, "# {doc}")?; + if !self + .attributes + .iter() + .any(|attribute| matches!(attribute, Attribute::Doc(_))) + { + if let Some(doc) = &self.doc { + writeln!(f, "# {doc}")?; + } } for attribute in &self.attributes { diff --git a/tests/fmt.rs b/tests/fmt.rs index 013c0a27d2..110b6e5948 100644 --- a/tests/fmt.rs +++ b/tests/fmt.rs @@ -1096,3 +1096,27 @@ fn multi_argument_attribute() { ) .run(); } + +#[test] +fn doc_attribute_suppresses_comment() { + Test::new() + .justfile( + " + set unstable + + # COMMENT + [doc('ATTRIBUTE')] + foo: + ", + ) + .arg("--dump") + .stdout( + " + set unstable := true + + [doc('ATTRIBUTE')] + foo: + ", + ) + .run(); +} diff --git a/tests/functions.rs b/tests/functions.rs index 76964b74b4..d68b3946b0 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -1183,3 +1183,78 @@ bar: .args(["foo", "bar"]) .run(); } + +#[test] +fn style_command_default() { + Test::new() + .justfile( + r#" + foo: + @echo '{{ style("command") }}foo{{NORMAL}}' + "#, + ) + .stdout("\x1b[1mfoo\x1b[0m\n") + .run(); +} + +#[test] +fn style_command_non_default() { + Test::new() + .justfile( + r#" + foo: + @echo '{{ style("command") }}foo{{NORMAL}}' + "#, + ) + .args(["--command-color", "red"]) + .stdout("\x1b[1;31mfoo\x1b[0m\n") + .run(); +} + +#[test] +fn style_error() { + Test::new() + .justfile( + r#" + foo: + @echo '{{ style("error") }}foo{{NORMAL}}' + "#, + ) + .stdout("\x1b[1;31mfoo\x1b[0m\n") + .run(); +} + +#[test] +fn style_warning() { + Test::new() + .justfile( + r#" + foo: + @echo '{{ style("warning") }}foo{{NORMAL}}' + "#, + ) + .stdout("\x1b[1;33mfoo\x1b[0m\n") + .run(); +} + +#[test] +fn style_unknown() { + Test::new() + .justfile( + r#" + foo: + @echo '{{ style("hippo") }}foo{{NORMAL}}' + "#, + ) + .stderr( + r#" + error: Call to function `style` failed: unknown style: `hippo` + ——▶ justfile:2:13 + │ + 2 │ @echo '{{ style("hippo") }}foo{{NORMAL}}' + │ ^^^^^ + "#, + ) + .status(EXIT_FAILURE) + .run(); +} diff --git a/tests/json.rs b/tests/json.rs index 3819c0405a..094837a894 100644 --- a/tests/json.rs +++ b/tests/json.rs @@ -1,22 +1,30 @@ use super::*; -fn case(justfile: &str, value: Value) { +fn case Value>(justfile: &str, value: F) { Test::new() .justfile(justfile) .args(["--dump", "--dump-format", "json"]) - .stdout(format!("{}\n", serde_json::to_string(&value).unwrap())) + .stdout_with_tempdir(|dir| format!("{}\n", serde_json::to_string(&value(dir.path())).unwrap())) .run(); } #[test] fn alias() { - case( + let test = Test::new().justfile( " alias f := foo foo: ", - json!({ + ); + let source = test + .tempdir + .path() + .join("justfile") + .to_str() + .unwrap() + .to_owned(); + let json = json!({ "first": "foo", "doc": null, "aliases": { @@ -66,14 +74,18 @@ fn alias() { }, "unexports": [], "warnings": [], - }), - ); + "source": source, + }); + test + .args(["--dump", "--dump-format", "json"]) + .stdout(format!("{}\n", serde_json::to_string(&json).unwrap())) + .run(); } #[test] fn assignment() { - case( - "foo := 'bar'", + case("foo := 'bar'", |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); json!({ "aliases": {}, "assignments": { @@ -110,8 +122,9 @@ fn assignment() { }, "unexports": [], "warnings": [], - }), - ); + "source": source, + }) + }); } #[test] @@ -122,49 +135,53 @@ fn private_assignment() { [private] bar := 'bar' ", - json!({ - "aliases": {}, - "assignments": { - "_foo": { - "export": false, - "name": "_foo", - "value": "foo", - "private": true, + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "assignments": { + "_foo": { + "export": false, + "name": "_foo", + "value": "foo", + "private": true, + }, + "bar": { + "export": false, + "name": "bar", + "value": "bar", + "private": true, + }, }, - "bar": { + "first": null, + "doc": null, + "groups": [], + "modules": {}, + "recipes": {}, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, "export": false, - "name": "bar", - "value": "bar", - "private": true, + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, + "quiet": false, + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, }, - }, - "first": null, - "doc": null, - "groups": [], - "modules": {}, - "recipes": {}, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), + "unexports": [], + "warnings": [], + "source": source, + }) + }, ); } @@ -176,53 +193,57 @@ fn body() { bar abc{{ 'xyz' }}def ", - json!({ - "aliases": {}, - "assignments": {}, - "first": "foo", - "doc": null, - "groups": [], - "modules": {}, - "recipes": { - "foo": { - "attributes": [], - "body": [ - ["bar"], - ["abc", ["xyz"], "def"], - ], - "dependencies": [], - "doc": null, - "name": "foo", - "namepath": "foo", - "parameters": [], - "priors": 0, - "private": false, + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "assignments": {}, + "first": "foo", + "doc": null, + "groups": [], + "modules": {}, + "recipes": { + "foo": { + "attributes": [], + "body": [ + ["bar"], + ["abc", ["xyz"], "def"], + ], + "dependencies": [], + "doc": null, + "name": "foo", + "namepath": "foo", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + } + }, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, "quiet": false, - "shebang": false, - } - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source, + }) + }, ); } @@ -233,66 +254,70 @@ fn dependencies() { foo: bar: foo ", - json!({ - "aliases": {}, - "assignments": {}, - "first": "foo", - "doc": null, - "groups": [], - "modules": {}, - "recipes": { - "bar": { - "attributes": [], - "doc": null, - "name": "bar", - "namepath": "bar", - "body": [], - "dependencies": [{ - "arguments": [], - "recipe": "foo" - }], - "parameters": [], - "priors": 1, - "private": false, - "quiet": false, - "shebang": false, + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "assignments": {}, + "first": "foo", + "doc": null, + "groups": [], + "modules": {}, + "recipes": { + "bar": { + "attributes": [], + "doc": null, + "name": "bar", + "namepath": "bar", + "body": [], + "dependencies": [{ + "arguments": [], + "recipe": "foo" + }], + "parameters": [], + "priors": 1, + "private": false, + "quiet": false, + "shebang": false, + }, + "foo": { + "body": [], + "dependencies": [], + "doc": null, + "name": "foo", + "namepath": "foo", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + } }, - "foo": { - "body": [], - "dependencies": [], - "doc": null, - "name": "foo", - "namepath": "foo", - "parameters": [], - "priors": 0, - "private": false, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, "quiet": false, - "shebang": false, - "attributes": [], - } - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source, + }) + }, ); } @@ -316,91 +341,95 @@ fn dependency_argument() { replace('a', 'b', 'c') ) ", - json!({ - "aliases": {}, - "first": "foo", - "doc": null, - "assignments": { - "x": { - "export": false, - "name": "x", - "value": "foo", - "private": false, + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "first": "foo", + "doc": null, + "assignments": { + "x": { + "export": false, + "name": "x", + "value": "foo", + "private": false, + }, }, - }, - "groups": [], - "modules": {}, - "recipes": { - "bar": { - "doc": null, - "name": "bar", - "namepath": "bar", - "body": [], - "dependencies": [{ - "arguments": [ - "baz", - "baz", - ["concatenate", "a", "b"], - ["evaluate", "echo"], - ["variable", "x"], - ["if", ["==", "a", "b"], "c", "d"], - ["call", "arch"], - ["call", "env_var", "foo"], - ["call", "join", "a", "b"], - ["call", "replace", "a", "b", "c"], + "groups": [], + "modules": {}, + "recipes": { + "bar": { + "doc": null, + "name": "bar", + "namepath": "bar", + "body": [], + "dependencies": [{ + "arguments": [ + "baz", + "baz", + ["concatenate", "a", "b"], + ["evaluate", "echo"], + ["variable", "x"], + ["if", ["==", "a", "b"], "c", "d"], + ["call", "arch"], + ["call", "env_var", "foo"], + ["call", "join", "a", "b"], + ["call", "replace", "a", "b", "c"], + ], + "recipe": "foo" + }], + "parameters": [], + "priors": 1, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + }, + "foo": { + "body": [], + "dependencies": [], + "doc": null, + "name": "foo", + "namepath": "foo", + "parameters": [ + { + "name": "args", + "export": false, + "default": null, + "kind": "star", + } ], - "recipe": "foo" - }], - "parameters": [], - "priors": 1, - "private": false, - "quiet": false, - "shebang": false, - "attributes": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + } }, - "foo": { - "body": [], - "dependencies": [], - "doc": null, - "name": "foo", - "namepath": "foo", - "parameters": [ - { - "name": "args", - "export": false, - "default": null, - "kind": "star", - } - ], - "priors": 0, - "private": false, - "quiet": false, - "shebang": false, - "attributes": [], - } - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, + "quiet": false, + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source, + }) + }, ); } @@ -414,63 +443,67 @@ fn duplicate_recipes() { foo: foo bar: ", - json!({ - "first": "foo", - "doc": null, - "aliases": { - "f": { - "attributes": [], - "name": "f", - "target": "foo", - } - }, - "assignments": {}, - "groups": [], - "modules": {}, - "recipes": { - "foo": { - "body": [], - "dependencies": [], - "doc": null, - "name": "foo", - "namepath": "foo", - "parameters": [ - { - "name": "bar", - "export": false, - "default": null, - "kind": "singular", - }, - ], - "priors": 0, - "private": false, + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "first": "foo", + "doc": null, + "aliases": { + "f": { + "attributes": [], + "name": "f", + "target": "foo", + } + }, + "assignments": {}, + "groups": [], + "modules": {}, + "recipes": { + "foo": { + "body": [], + "dependencies": [], + "doc": null, + "name": "foo", + "namepath": "foo", + "parameters": [ + { + "name": "bar", + "export": false, + "default": null, + "kind": "singular", + }, + ], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + } + }, + "settings": { + "allow_duplicate_recipes": true, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, "quiet": false, - "shebang": false, - "attributes": [], - } - }, - "settings": { - "allow_duplicate_recipes": true, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source, + }) + }, ); } @@ -482,50 +515,54 @@ fn duplicate_variables() { x := 'foo' x := 'bar' ", - json!({ - "aliases": {}, - "assignments": { - "x": { + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "assignments": { + "x": { + "export": false, + "name": "x", + "value": "bar", + "private": false, + } + }, + "first": null, + "doc": null, + "groups": [], + "modules": {}, + "recipes": {}, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": true, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, "export": false, - "name": "x", - "value": "bar", - "private": false, - } - }, - "first": null, - "doc": null, - "groups": [], - "modules": {}, - "recipes": {}, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": true, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, + "quiet": false, + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source, + }) + }, ); } #[test] fn doc_comment() { - case( - "# hello\nfoo:", + case("# hello\nfoo:", |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); json!({ "aliases": {}, "first": "foo", @@ -569,14 +606,15 @@ fn doc_comment() { }, "unexports": [], "warnings": [], - }), - ); + "source": source, + }) + }); } #[test] fn empty_justfile() { - case( - "", + case("", |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); json!({ "aliases": {}, "assignments": {}, @@ -606,8 +644,9 @@ fn empty_justfile() { }, "unexports": [], "warnings": [], - }), - ); + "source": source, + }) + }); } #[test] @@ -621,150 +660,154 @@ fn parameters() { e *x: f $x: ", - json!({ - "aliases": {}, - "first": "a", - "doc": null, - "assignments": {}, - "groups": [], - "modules": {}, - "recipes": { - "a": { - "attributes": [], - "body": [], - "dependencies": [], - "doc": null, - "name": "a", - "namepath": "a", - "parameters": [], - "priors": 0, - "private": false, - "quiet": false, - "shebang": false, + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "first": "a", + "doc": null, + "assignments": {}, + "groups": [], + "modules": {}, + "recipes": { + "a": { + "attributes": [], + "body": [], + "dependencies": [], + "doc": null, + "name": "a", + "namepath": "a", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + }, + "b": { + "body": [], + "dependencies": [], + "doc": null, + "name": "b", + "namepath": "b", + "parameters": [ + { + "name": "x", + "export": false, + "default": null, + "kind": "singular", + }, + ], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + }, + "c": { + "body": [], + "dependencies": [], + "doc": null, + "name": "c", + "namepath": "c", + "parameters": [ + { + "name": "x", + "export": false, + "default": "y", + "kind": "singular", + } + ], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + }, + "d": { + "body": [], + "dependencies": [], + "doc": null, + "name": "d", + "namepath": "d", + "parameters": [ + { + "name": "x", + "export": false, + "default": null, + "kind": "plus", + } + ], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + }, + "e": { + "body": [], + "dependencies": [], + "doc": null, + "name": "e", + "namepath": "e", + "parameters": [ + { + "name": "x", + "export": false, + "default": null, + "kind": "star", + } + ], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + }, + "f": { + "body": [], + "dependencies": [], + "doc": null, + "name": "f", + "namepath": "f", + "parameters": [ + { + "name": "x", + "export": true, + "default": null, + "kind": "singular", + } + ], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + }, }, - "b": { - "body": [], - "dependencies": [], - "doc": null, - "name": "b", - "namepath": "b", - "parameters": [ - { - "name": "x", - "export": false, - "default": null, - "kind": "singular", - }, - ], - "priors": 0, - "private": false, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, "quiet": false, - "shebang": false, - "attributes": [], + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, }, - "c": { - "body": [], - "dependencies": [], - "doc": null, - "name": "c", - "namepath": "c", - "parameters": [ - { - "name": "x", - "export": false, - "default": "y", - "kind": "singular", - } - ], - "priors": 0, - "private": false, - "quiet": false, - "shebang": false, - "attributes": [], - }, - "d": { - "body": [], - "dependencies": [], - "doc": null, - "name": "d", - "namepath": "d", - "parameters": [ - { - "name": "x", - "export": false, - "default": null, - "kind": "plus", - } - ], - "priors": 0, - "private": false, - "quiet": false, - "shebang": false, - "attributes": [], - }, - "e": { - "body": [], - "dependencies": [], - "doc": null, - "name": "e", - "namepath": "e", - "parameters": [ - { - "name": "x", - "export": false, - "default": null, - "kind": "star", - } - ], - "priors": 0, - "private": false, - "quiet": false, - "shebang": false, - "attributes": [], - }, - "f": { - "body": [], - "dependencies": [], - "doc": null, - "name": "f", - "namepath": "f", - "parameters": [ - { - "name": "x", - "export": true, - "default": null, - "kind": "singular", - } - ], - "priors": 0, - "private": false, - "quiet": false, - "shebang": false, - "attributes": [], - }, - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), + "unexports": [], + "warnings": [], + "source": source, + }) + }, ); } @@ -776,283 +819,116 @@ fn priors() { b: a && c c: ", - json!({ - "aliases": {}, - "assignments": {}, - "first": "a", - "doc": null, - "groups": [], - "modules": {}, - "recipes": { - "a": { - "body": [], - "dependencies": [], - "doc": null, - "name": "a", - "namepath": "a", - "parameters": [], - "priors": 0, - "private": false, - "quiet": false, - "shebang": false, - "attributes": [], - }, - "b": { - "body": [], - "dependencies": [ - { - "arguments": [], - "recipe": "a", - }, - { - "arguments": [], - "recipe": "c", - } - ], - "doc": null, - "name": "b", - "namepath": "b", - "private": false, - "quiet": false, - "shebang": false, - "attributes": [], - "parameters": [], - "priors": 1, - }, - "c": { - "body": [], - "dependencies": [], - "doc": null, - "name": "c", - "namepath": "c", - "parameters": [], - "private": false, - "quiet": false, - "shebang": false, - "attributes": [], - "parameters": [], - "priors": 0, + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "assignments": {}, + "first": "a", + "doc": null, + "groups": [], + "modules": {}, + "recipes": { + "a": { + "body": [], + "dependencies": [], + "doc": null, + "name": "a", + "namepath": "a", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + }, + "b": { + "body": [], + "dependencies": [ + { + "arguments": [], + "recipe": "a", + }, + { + "arguments": [], + "recipe": "c", + } + ], + "doc": null, + "name": "b", + "namepath": "b", + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + "parameters": [], + "priors": 1, + }, + "c": { + "body": [], + "dependencies": [], + "doc": null, + "name": "c", + "namepath": "c", + "parameters": [], + "private": false, + "quiet": false, + "shebang": false, + "attributes": [], + "parameters": [], + "priors": 0, + }, }, - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), - ); -} - -#[test] -fn private() { - case( - "_foo:", - json!({ - "aliases": {}, - "assignments": {}, - "first": "_foo", - "doc": null, - "groups": [], - "modules": {}, - "recipes": { - "_foo": { - "body": [], - "dependencies": [], - "doc": null, - "name": "_foo", - "namepath": "_foo", - "parameters": [], - "priors": 0, - "private": true, - "quiet": false, - "shebang": false, - "attributes": [], - } - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), - ); -} - -#[test] -fn quiet() { - case( - "@foo:", - json!({ - "aliases": {}, - "assignments": {}, - "first": "foo", - "doc": null, - "groups": [], - "modules": {}, - "recipes": { - "foo": { - "body": [], - "dependencies": [], - "doc": null, - "name": "foo", - "namepath": "foo", - "parameters": [], - "priors": 0, - "private": false, - "quiet": true, - "shebang": false, - "attributes": [], - } - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), - ); -} - -#[test] -fn settings() { - case( - " - set dotenv-load - set dotenv-filename := \"filename\" - set dotenv-path := \"path\" - set export - set fallback - set positional-arguments - set quiet - set ignore-comments - set shell := ['a', 'b', 'c'] - foo: - #!bar - ", - json!({ - "aliases": {}, - "assignments": {}, - "first": "foo", - "doc": null, - "groups": [], - "modules": {}, - "recipes": { - "foo": { - "body": [["#!bar"]], - "dependencies": [], - "doc": null, - "name": "foo", - "namepath": "foo", - "parameters": [], - "priors": 0, - "private": false, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, "quiet": false, - "shebang": true, - "attributes": [], - } - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": "filename", - "dotenv_load": true, - "dotenv_path": "path", - "dotenv_required": false, - "export": true, - "fallback": true, - "ignore_comments": true, - "positional_arguments": true, - "quiet": true, - "shell": { - "arguments": ["b", "c"], - "command": "a", + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, }, - "tempdir": null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), - ); -} - -#[test] -fn shebang() { - case( - " - foo: - #!bar - ", + "unexports": [], + "warnings": [], + "source": source, + }) + }, + ); +} + +#[test] +fn private() { + case("_foo:", |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); json!({ "aliases": {}, "assignments": {}, - "first": "foo", + "first": "_foo", "doc": null, "groups": [], "modules": {}, "recipes": { - "foo": { - "body": [["#!bar"]], + "_foo": { + "body": [], "dependencies": [], "doc": null, - "name": "foo", - "namepath": "foo", + "name": "_foo", + "namepath": "_foo", "parameters": [], "priors": 0, - "private": false, + "private": true, "quiet": false, - "shebang": true, + "shebang": false, "attributes": [], } }, @@ -1069,7 +945,7 @@ fn shebang() { "positional_arguments": false, "quiet": false, "shell": null, - "tempdir": null, + "tempdir" : null, "unstable": false, "windows_powershell": false, "windows_shell": null, @@ -1077,14 +953,15 @@ fn shebang() { }, "unexports": [], "warnings": [], - }), - ); + "source": source, + }) + }); } #[test] -fn simple() { - case( - "foo:", +fn quiet() { + case("@foo:", |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); json!({ "aliases": {}, "assignments": {}, @@ -1102,7 +979,7 @@ fn simple() { "parameters": [], "priors": 0, "private": false, - "quiet": false, + "quiet": true, "shebang": false, "attributes": [], } @@ -1120,7 +997,7 @@ fn simple() { "positional_arguments": false, "quiet": false, "shell": null, - "tempdir": null, + "tempdir" : null, "unstable": false, "windows_powershell": false, "windows_shell": null, @@ -1128,17 +1005,143 @@ fn simple() { }, "unexports": [], "warnings": [], - }), + "source": source, + }) + }); +} + +#[test] +fn settings() { + case( + " + set dotenv-load + set dotenv-filename := \"filename\" + set dotenv-path := \"path\" + set export + set fallback + set positional-arguments + set quiet + set ignore-comments + set shell := ['a', 'b', 'c'] + foo: + #!bar + ", + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "assignments": {}, + "first": "foo", + "doc": null, + "groups": [], + "modules": {}, + "recipes": { + "foo": { + "body": [["#!bar"]], + "dependencies": [], + "doc": null, + "name": "foo", + "namepath": "foo", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": true, + "attributes": [], + } + }, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": "filename", + "dotenv_load": true, + "dotenv_path": "path", + "dotenv_required": false, + "export": true, + "fallback": true, + "ignore_comments": true, + "positional_arguments": true, + "quiet": true, + "shell": { + "arguments": ["b", "c"], + "command": "a", + }, + "tempdir": null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source, + }) + }, ); } #[test] -fn attribute() { +fn shebang() { case( " - [no-exit-message] foo: + #!bar ", + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "assignments": {}, + "first": "foo", + "doc": null, + "groups": [], + "modules": {}, + "recipes": { + "foo": { + "body": [["#!bar"]], + "dependencies": [], + "doc": null, + "name": "foo", + "namepath": "foo", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": true, + "attributes": [], + } + }, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, + "quiet": false, + "shell": null, + "tempdir": null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source, + }) + }, + ); +} + +#[test] +fn simple() { + case("foo:", |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); json!({ "aliases": {}, "assignments": {}, @@ -1148,7 +1151,6 @@ fn attribute() { "modules": {}, "recipes": { "foo": { - "attributes": ["no-exit-message"], "body": [], "dependencies": [], "doc": null, @@ -1159,6 +1161,7 @@ fn attribute() { "private": false, "quiet": false, "shebang": false, + "attributes": [], } }, "settings": { @@ -1170,90 +1173,54 @@ fn attribute() { "dotenv_required": false, "export": false, "fallback": false, + "ignore_comments": false, "positional_arguments": false, "quiet": false, "shell": null, - "tempdir" : null, + "tempdir": null, "unstable": false, - "ignore_comments": false, "windows_powershell": false, "windows_shell": null, "working_directory" : null, }, "unexports": [], "warnings": [], - }), - ); + "source": source, + }) + }); } #[test] -fn module() { - Test::new() - .justfile( - " - # hello - mod foo +fn attribute() { + case( + " + [no-exit-message] + foo: ", - ) - .tree(tree! { - "foo.just": "bar:", - }) - .args(["--dump", "--dump-format", "json"]) - .stdout(format!( - "{}\n", - serde_json::to_string(&json!({ + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ "aliases": {}, "assignments": {}, - "first": null, + "first": "foo", "doc": null, "groups": [], - "modules": { + "modules": {}, + "recipes": { "foo": { - "aliases": {}, - "assignments": {}, - "first": "bar", - "doc": "hello", - "groups": [], - "modules": {}, - "recipes": { - "bar": { - "attributes": [], - "body": [], - "dependencies": [], - "doc": null, - "name": "bar", - "namepath": "foo::bar", - "parameters": [], - "priors": 0, - "private": false, - "quiet": false, - "shebang": false, - } - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "ignore_comments": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }, + "attributes": ["no-exit-message"], + "body": [], + "dependencies": [], + "doc": null, + "name": "foo", + "namepath": "foo", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + } }, - "recipes": {}, "settings": { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, @@ -1275,9 +1242,110 @@ fn module() { }, "unexports": [], "warnings": [], - })) - .unwrap() - )) + "source": source, + }) + }, + ); +} + +#[test] +fn module() { + Test::new() + .justfile( + " + # hello + mod foo + ", + ) + .tree(tree! { + "foo.just": "bar:", + }) + .args(["--dump", "--dump-format", "json"]) + .stdout_with_tempdir(|dir| { + let source = dir.path().join("justfile").to_str().unwrap().to_owned(); + let foo_just = dir.path().join("foo.just").to_str().unwrap().to_owned(); + format!( + "{}\n", + serde_json::to_string(&json!({ + "aliases": {}, + "assignments": {}, + "first": null, + "doc": null, + "groups": [], + "modules": { + "foo": { + "aliases": {}, + "assignments": {}, + "first": "bar", + "doc": "hello", + "groups": [], + "modules": {}, + "recipes": { + "bar": { + "attributes": [], + "body": [], + "dependencies": [], + "doc": null, + "name": "bar", + "namepath": "foo::bar", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + } + }, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "positional_arguments": false, + "quiet": false, + "shell": null, + "tempdir" : null, + "unstable": false, + "ignore_comments": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": foo_just + }, + }, + "recipes": {}, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "positional_arguments": false, + "quiet": false, + "shell": null, + "tempdir" : null, + "unstable": false, + "ignore_comments": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source + })) + .unwrap() + ) + }) .run(); } @@ -1294,61 +1362,125 @@ fn module_group() { "foo.just": "bar:", }) .args(["--dump", "--dump-format", "json"]) - .stdout(format!( - "{}\n", - serde_json::to_string(&json!({ + .stdout_with_tempdir(|dir| { + let source = dir.path().join("justfile").to_str().unwrap().to_owned(); + let foo_just = dir.path().join("foo.just").to_str().unwrap().to_owned(); + format!( + "{}\n", + serde_json::to_string(&json!({ + "aliases": {}, + "assignments": {}, + "first": null, + "doc": null, + "groups": [], + "modules": { + "foo": { + "aliases": {}, + "assignments": {}, + "first": "bar", + "doc": null, + "groups": ["alpha"], + "modules": {}, + "recipes": { + "bar": { + "attributes": [], + "body": [], + "dependencies": [], + "doc": null, + "name": "bar", + "namepath": "foo::bar", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + } + }, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "positional_arguments": false, + "quiet": false, + "shell": null, + "tempdir" : null, + "unstable": false, + "ignore_comments": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": foo_just, + }, + }, + "recipes": {}, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "positional_arguments": false, + "quiet": false, + "shell": null, + "tempdir" : null, + "unstable": false, + "ignore_comments": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source, + })) + .unwrap() + ) + }) + .run(); +} + +#[test] +fn recipes_with_private_attribute_are_private() { + case( + " + [private] + foo: + ", + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ "aliases": {}, "assignments": {}, - "first": null, + "first": "foo", "doc": null, "groups": [], - "modules": { + "modules": {}, + "recipes": { "foo": { - "aliases": {}, - "assignments": {}, - "first": "bar", + "attributes": ["private"], + "body": [], + "dependencies": [], "doc": null, - "groups": ["alpha"], - "modules": {}, - "recipes": { - "bar": { - "attributes": [], - "body": [], - "dependencies": [], - "doc": null, - "name": "bar", - "namepath": "foo::bar", - "parameters": [], - "priors": 0, - "private": false, - "quiet": false, - "shebang": false, - } - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "ignore_comments": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }, + "name": "foo", + "namepath": "foo", + "parameters": [], + "priors": 0, + "private": true, + "quiet": false, + "shebang": false, + } }, - "recipes": {}, "settings": { "allow_duplicate_recipes": false, "allow_duplicate_variables": false, @@ -1358,74 +1490,79 @@ fn module_group() { "dotenv_required": false, "export": false, "fallback": false, + "ignore_comments": false, "positional_arguments": false, "quiet": false, "shell": null, "tempdir" : null, "unstable": false, - "ignore_comments": false, "windows_powershell": false, "windows_shell": null, "working_directory" : null, }, "unexports": [], "warnings": [], - })) - .unwrap() - )) - .run(); + "source": source, + }) + }, + ); } #[test] -fn recipes_with_private_attribute_are_private() { +fn doc_attribute_overrides_comment() { case( " - [private] + # COMMENT + [doc('ATTRIBUTE')] foo: ", - json!({ - "aliases": {}, - "assignments": {}, - "first": "foo", - "doc": null, - "groups": [], - "modules": {}, - "recipes": { - "foo": { - "attributes": ["private"], - "body": [], - "dependencies": [], - "doc": null, - "name": "foo", - "namepath": "foo", - "parameters": [], - "priors": 0, - "private": true, + |dir| { + let source = dir.join("justfile").to_str().unwrap().to_owned(); + json!({ + "aliases": {}, + "assignments": {}, + "first": "foo", + "doc": null, + "groups": [], + "modules": {}, + "recipes": { + "foo": { + "attributes": [{"doc": "ATTRIBUTE"}], + "body": [], + "dependencies": [], + "doc": "ATTRIBUTE", + "name": "foo", + "namepath": "foo", + "parameters": [], + "priors": 0, + "private": false, + "quiet": false, + "shebang": false, + } + }, + "settings": { + "allow_duplicate_recipes": false, + "allow_duplicate_variables": false, + "dotenv_filename": null, + "dotenv_load": false, + "dotenv_path": null, + "dotenv_required": false, + "export": false, + "fallback": false, + "ignore_comments": false, + "positional_arguments": false, "quiet": false, - "shebang": false, - } - }, - "settings": { - "allow_duplicate_recipes": false, - "allow_duplicate_variables": false, - "dotenv_filename": null, - "dotenv_load": false, - "dotenv_path": null, - "dotenv_required": false, - "export": false, - "fallback": false, - "ignore_comments": false, - "positional_arguments": false, - "quiet": false, - "shell": null, - "tempdir" : null, - "unstable": false, - "windows_powershell": false, - "windows_shell": null, - "working_directory" : null, - }, - "unexports": [], - "warnings": [], - }), + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + "source": source + }) + }, ); } diff --git a/tests/list.rs b/tests/list.rs index f7ea7528af..53a1c7372c 100644 --- a/tests/list.rs +++ b/tests/list.rs @@ -452,7 +452,7 @@ fn backticks_highlighted() { .stdout( " Available recipes: - recipe \u{1b}[34m#\u{1b}[0m \u{1b}[34mComment \u{1b}[0m\u{1b}[40;37m``\u{1b}[0m\u{1b}[34m \u{1b}[0m\u{1b}[40;37m`with backticks`\u{1b}[0m\u{1b}[34m and trailing text\u{1b}[0m + recipe \u{1b}[34m#\u{1b}[0m \u{1b}[34mComment \u{1b}[0m\u{1b}[36m``\u{1b}[0m\u{1b}[34m \u{1b}[0m\u{1b}[36m`with backticks`\u{1b}[0m\u{1b}[34m and trailing text\u{1b}[0m ") .run(); } @@ -470,7 +470,7 @@ fn unclosed_backticks() { .stdout( " Available recipes: - recipe \u{1b}[34m#\u{1b}[0m \u{1b}[34mComment \u{1b}[0m\u{1b}[40;37m`with unclosed backick\u{1b}[0m + recipe \u{1b}[34m#\u{1b}[0m \u{1b}[34mComment \u{1b}[0m\u{1b}[36m`with unclosed backick\u{1b}[0m ") .run(); } diff --git a/tests/test.rs b/tests/test.rs index a1c65ac201..5dbadeaa2d 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -167,6 +167,11 @@ impl Test { self } + pub(crate) fn stdout_with_tempdir(mut self, stdout_fn: impl Fn(&TempDir) -> String) -> Self { + self.stdout = stdout_fn(&self.tempdir); + self + } + pub(crate) fn stdout_regex(mut self, stdout_regex: impl AsRef) -> Self { self.stdout_regex = Some(Regex::new(&format!("^{}$", stdout_regex.as_ref())).unwrap()); self