From 8a82cef0dbc521243051ed2b5e1e77817188ecfd Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sat, 25 May 2024 01:24:58 -0700 Subject: [PATCH 1/4] Doc attribute --- src/attribute.rs | 10 ++++++++-- src/recipe.rs | 9 +++++++++ src/subcommand.rs | 2 +- tests/attributes.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/attribute.rs b/src/attribute.rs index e650a9078f..d25a7c5a74 100644 --- a/src/attribute.rs +++ b/src/attribute.rs @@ -10,6 +10,9 @@ use super::*; #[strum_discriminants(strum(serialize_all = "kebab-case"))] pub(crate) enum Attribute<'src> { Confirm(Option>), + Doc { + docstring: Option>, + }, Group(StringLiteral<'src>), Linux, Macos, @@ -24,7 +27,7 @@ pub(crate) enum Attribute<'src> { impl AttributeDiscriminant { fn argument_range(self) -> RangeInclusive { match self { - Self::Confirm => 0..=1, + Self::Confirm | Self::Doc => 0..=1, Self::Group => 1..=1, Self::Linux | Self::Macos @@ -72,6 +75,9 @@ impl<'src> Attribute<'src> { Ok(match discriminant { Confirm => Self::Confirm(argument), + Doc => Self::Doc { + docstring: argument, + }, Group => Self::Group(argument.unwrap()), Linux => Self::Linux, Macos => Self::Macos, @@ -91,6 +97,7 @@ impl<'src> Attribute<'src> { fn argument(&self) -> Option<&StringLiteral> { match self { Self::Confirm(prompt) => prompt.as_ref(), + Self::Doc { docstring } => docstring.as_ref(), Self::Group(name) => Some(name), Self::Linux | Self::Macos @@ -107,7 +114,6 @@ impl<'src> Attribute<'src> { impl<'src> Display for Attribute<'src> { fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { write!(f, "{}", self.name())?; - if let Some(argument) = self.argument() { write!(f, "({argument})")?; } diff --git a/src/recipe.rs b/src/recipe.rs index a6afe2f20a..4abc66d83c 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -450,6 +450,15 @@ impl<'src, D> Recipe<'src, D> { }) .collect() } + + pub(crate) fn docstring(&self) -> Option<&str> { + for attribute in &self.attributes { + if let Attribute::Doc { docstring } = attribute { + return docstring.as_ref().map(|s| s.cooked.as_ref()); + } + } + self.doc + } } impl<'src, D: Display> ColorDisplay for Recipe<'src, D> { diff --git a/src/subcommand.rs b/src/subcommand.rs index 18af7c0365..e0e628b88d 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -573,7 +573,7 @@ impl Subcommand { ); let doc = if i == 0 { - recipe.doc.map(Cow::Borrowed) + recipe.docstring().map(Cow::Borrowed) } else { Some(Cow::Owned(format!("alias for `{}`", recipe.name))) }; diff --git a/tests/attributes.rs b/tests/attributes.rs index 055ec9e603..1b5553d4ae 100644 --- a/tests/attributes.rs +++ b/tests/attributes.rs @@ -129,3 +129,45 @@ fn unexpected_attribute_argument() { .status(1) .run(); } + +#[test] +fn doc_attribute() { + Test::new() + .justfile( + " + # Non-document comment + [doc('The real docstring')] + foo: + echo foo + ", + ) + .args(["--list"]) + .stdout( + " + Available recipes: + foo # The real docstring + ", + ) + .run(); +} + +#[test] +fn suppress_doc_comment() { + Test::new() + .justfile( + " + # Non-document comment + [doc] + foo: + echo foo + ", + ) + .args(["--list"]) + .stdout( + " + Available recipes: + foo + ", + ) + .run(); +} From ba0a43e8e099fca63b11ba2b220962ce4a0eb989 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sat, 25 May 2024 01:37:17 -0700 Subject: [PATCH 2/4] README --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index cbfaa26b06..fbfee652d9 100644 --- a/README.md +++ b/README.md @@ -1079,6 +1079,30 @@ Available recipes: test # test stuff ``` +You can also add a documentation comment with the `doc` attribute. This suppresses +a pre-recipe comment from appearing in `just --list`: + +```just + +# This comment won't appear in the list output +[doc("Build stuff")] +build: + ./bin/build + +# This one won't either +[doc] +test: + ./bin/test +``` + +```sh +$ just --list +Available recipes: + build # Build stuff + test +``` + + ### Variables and Substitution Variables, strings, concatenation, path joining, and substitution using `{{…}}` @@ -1611,6 +1635,7 @@ Recipes may be annotated with attributes that change their behavior. |------|-------------| | `[confirm]`1.17.0 | Require confirmation prior to executing recipe. | | `[confirm('prompt')]`1.23.0 | Require confirmation prior to executing recipe with a custom prompt. | +| `[doc('documentation comment')]`1.27.0 | Add a [documentation comment](#documentation-comments). | | `[group('NAME"']`master | Put recipe in [recipe group](#recipe-groups) `NAME`. | `[linux]`1.8.0 | Enable recipe on Linux. | | `[macos]`1.8.0 | Enable recipe on MacOS. | From 61b2d9e3379dcef5b1d1f59b3c15eefcd7dd5c15 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sat, 25 May 2024 02:21:42 -0700 Subject: [PATCH 3/4] Modify --- README.md | 15 ++++++--------- src/attribute.rs | 12 ++++-------- src/recipe.rs | 6 +++--- src/subcommand.rs | 2 +- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index bbbfa85034..9ecb5aa7ac 100644 --- a/README.md +++ b/README.md @@ -1079,13 +1079,11 @@ Available recipes: test # test stuff ``` -You can also add a documentation comment with the `doc` attribute. This suppresses -a pre-recipe comment from appearing in `just --list`: +The `[doc]` attribute can be used to set or suppress a recipe's doc comment: ```just - -# This comment won't appear in the list output -[doc("Build stuff")] +# This comment won't appear +[doc('Build stuff')] build: ./bin/build @@ -1102,7 +1100,6 @@ Available recipes: test ``` - ### Variables and Substitution Variables, strings, concatenation, path joining, and substitution using `{{…}}` @@ -1646,9 +1643,9 @@ Recipes may be annotated with attributes that change their behavior. | Name | Description | |------|-------------| | `[confirm]`1.17.0 | Require confirmation prior to executing recipe. | -| `[confirm('prompt')]`1.23.0 | Require confirmation prior to executing recipe with a custom prompt. | -| `[doc('documentation comment')]`1.27.0 | Add a [documentation comment](#documentation-comments). | -| `[group('NAME"']`master | Put recipe in [recipe group](#recipe-groups) `NAME`. +| `[confirm('PROMPT')]`1.23.0 | Require confirmation prior to executing recipe with a custom prompt. | +| `[doc('COMMENT')]`master | Set recipe's [documentation comment](#documentation-comments) to COMMENT. | +| `[group('NAME"']`master | Put recipe in [recipe group](#recipe-groups) `NAME`. | | `[linux]`1.8.0 | Enable recipe on Linux. | | `[macos]`1.8.0 | Enable recipe on MacOS. | | `[no-cd]`1.9.0 | Don't change directory before executing recipe. | diff --git a/src/attribute.rs b/src/attribute.rs index d25a7c5a74..bf657a0689 100644 --- a/src/attribute.rs +++ b/src/attribute.rs @@ -10,9 +10,7 @@ use super::*; #[strum_discriminants(strum(serialize_all = "kebab-case"))] pub(crate) enum Attribute<'src> { Confirm(Option>), - Doc { - docstring: Option>, - }, + Doc(Option>), Group(StringLiteral<'src>), Linux, Macos, @@ -75,9 +73,7 @@ impl<'src> Attribute<'src> { Ok(match discriminant { Confirm => Self::Confirm(argument), - Doc => Self::Doc { - docstring: argument, - }, + Doc => Self::Doc(argument), Group => Self::Group(argument.unwrap()), Linux => Self::Linux, Macos => Self::Macos, @@ -97,8 +93,8 @@ impl<'src> Attribute<'src> { fn argument(&self) -> Option<&StringLiteral> { match self { Self::Confirm(prompt) => prompt.as_ref(), - Self::Doc { docstring } => docstring.as_ref(), - Self::Group(name) => Some(name), + Self::Doc(doc) => doc.as_ref(), + Self::Group(group) => Some(group), Self::Linux | Self::Macos | Self::NoCd diff --git a/src/recipe.rs b/src/recipe.rs index 4abc66d83c..9a90314f4d 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -451,10 +451,10 @@ impl<'src, D> Recipe<'src, D> { .collect() } - pub(crate) fn docstring(&self) -> Option<&str> { + pub(crate) fn doc(&self) -> Option<&str> { for attribute in &self.attributes { - if let Attribute::Doc { docstring } = attribute { - return docstring.as_ref().map(|s| s.cooked.as_ref()); + if let Attribute::Doc(comment) = attribute { + return comment.as_ref().map(|s| s.cooked.as_ref()); } } self.doc diff --git a/src/subcommand.rs b/src/subcommand.rs index e0e628b88d..f7733fc21e 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -573,7 +573,7 @@ impl Subcommand { ); let doc = if i == 0 { - recipe.docstring().map(Cow::Borrowed) + recipe.doc().map(Cow::Borrowed) } else { Some(Cow::Owned(format!("alias for `{}`", recipe.name))) }; From dc646ce5bd3e380f578ecb845d51480ab25e2a1d Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sat, 25 May 2024 02:23:24 -0700 Subject: [PATCH 4/4] Modify --- README.md | 2 +- src/recipe.rs | 4 ++-- tests/attributes.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9ecb5aa7ac..f0a6fcd5cd 100644 --- a/README.md +++ b/README.md @@ -1644,7 +1644,7 @@ Recipes may be annotated with attributes that change their behavior. |------|-------------| | `[confirm]`1.17.0 | Require confirmation prior to executing recipe. | | `[confirm('PROMPT')]`1.23.0 | Require confirmation prior to executing recipe with a custom prompt. | -| `[doc('COMMENT')]`master | Set recipe's [documentation comment](#documentation-comments) to COMMENT. | +| `[doc('DOC')]`master | Set recipe's [documentation comment](#documentation-comments) to `DOC`. | | `[group('NAME"']`master | Put recipe in [recipe group](#recipe-groups) `NAME`. | | `[linux]`1.8.0 | Enable recipe on Linux. | | `[macos]`1.8.0 | Enable recipe on MacOS. | diff --git a/src/recipe.rs b/src/recipe.rs index 9a90314f4d..f974e394fb 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -453,8 +453,8 @@ impl<'src, D> Recipe<'src, D> { pub(crate) fn doc(&self) -> Option<&str> { for attribute in &self.attributes { - if let Attribute::Doc(comment) = attribute { - return comment.as_ref().map(|s| s.cooked.as_ref()); + if let Attribute::Doc(doc) = attribute { + return doc.as_ref().map(|s| s.cooked.as_ref()); } } self.doc diff --git a/tests/attributes.rs b/tests/attributes.rs index 1b5553d4ae..d527b0efbf 100644 --- a/tests/attributes.rs +++ b/tests/attributes.rs @@ -152,7 +152,7 @@ fn doc_attribute() { } #[test] -fn suppress_doc_comment() { +fn doc_attribute_suppress() { Test::new() .justfile( "