From 48c3f47196636fa3a1f13760e4b0bf33437cace9 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sat, 16 Nov 2024 17:55:43 -0800 Subject: [PATCH 1/2] Make doc attribute override comment --- src/node.rs | 2 +- src/parser.rs | 8 ++++++++ src/recipe.rs | 16 +++++++++++---- tests/json.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 5 deletions(-) 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..90e76002ad 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(|doc| doc.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..26cfb24908 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,15 @@ 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() + .find(|attribute| matches!(attribute, Attribute::Doc(_))) + .is_none() + { + if let Some(doc) = &self.doc { + writeln!(f, "# {doc}")?; + } } for attribute in &self.attributes { diff --git a/tests/json.rs b/tests/json.rs index 3819c0405a..d3ea7d5626 100644 --- a/tests/json.rs +++ b/tests/json.rs @@ -1429,3 +1429,58 @@ fn recipes_with_private_attribute_are_private() { }), ); } + +#[test] +fn doc_attribute_overrides_comment() { + case( + " + # COMMENT + [doc('ATTRIBUTE')] + foo: + ", + 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, + "shell": null, + "tempdir" : null, + "unstable": false, + "windows_powershell": false, + "windows_shell": null, + "working_directory" : null, + }, + "unexports": [], + "warnings": [], + }), + ); +} From f9ab6c33077adc991d0d01d9810fc5078b20e634 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sat, 16 Nov 2024 17:59:36 -0800 Subject: [PATCH 2/2] Amend --- src/parser.rs | 2 +- src/recipe.rs | 5 ++--- tests/fmt.rs | 24 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 90e76002ad..229f5aea81 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -936,7 +936,7 @@ impl<'run, 'src> Parser<'run, 'src> { let private = name.lexeme().starts_with('_') || attributes.contains(&Attribute::Private); - let mut doc = doc.map(|doc| doc.to_owned()); + let mut doc = doc.map(ToOwned::to_owned); for attribute in &attributes { if let Attribute::Doc(attribute_doc) = attribute { diff --git a/src/recipe.rs b/src/recipe.rs index 26cfb24908..d57bc93852 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -476,11 +476,10 @@ 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 self + if !self .attributes .iter() - .find(|attribute| matches!(attribute, Attribute::Doc(_))) - .is_none() + .any(|attribute| matches!(attribute, Attribute::Doc(_))) { if let Some(doc) = &self.doc { writeln!(f, "# {doc}")?; 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(); +}