diff --git a/README.md b/README.md index 1b5adc4..f0a6fcd 100644 --- a/README.md +++ b/README.md @@ -1079,6 +1079,27 @@ Available recipes: test # test stuff ``` +The `[doc]` attribute can be used to set or suppress a recipe's doc comment: + +```just +# This comment won't appear +[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 `{{…}}` @@ -1622,8 +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. | -| `[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('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. | | `[no-cd]`1.9.0 | Don't change directory before executing recipe. | diff --git a/src/attribute.rs b/src/attribute.rs index e650a90..bf657a0 100644 --- a/src/attribute.rs +++ b/src/attribute.rs @@ -10,6 +10,7 @@ use super::*; #[strum_discriminants(strum(serialize_all = "kebab-case"))] pub(crate) enum Attribute<'src> { Confirm(Option>), + Doc(Option>), Group(StringLiteral<'src>), Linux, Macos, @@ -24,7 +25,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 +73,7 @@ impl<'src> Attribute<'src> { Ok(match discriminant { Confirm => Self::Confirm(argument), + Doc => Self::Doc(argument), Group => Self::Group(argument.unwrap()), Linux => Self::Linux, Macos => Self::Macos, @@ -91,7 +93,8 @@ impl<'src> Attribute<'src> { fn argument(&self) -> Option<&StringLiteral> { match self { Self::Confirm(prompt) => prompt.as_ref(), - Self::Group(name) => Some(name), + Self::Doc(doc) => doc.as_ref(), + Self::Group(group) => Some(group), Self::Linux | Self::Macos | Self::NoCd @@ -107,7 +110,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 a6afe2f..f974e39 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -450,6 +450,15 @@ impl<'src, D> Recipe<'src, D> { }) .collect() } + + pub(crate) fn doc(&self) -> Option<&str> { + for attribute in &self.attributes { + if let Attribute::Doc(doc) = attribute { + return doc.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 18af7c0..f7733fc 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.doc().map(Cow::Borrowed) } else { Some(Cow::Owned(format!("alias for `{}`", recipe.name))) }; diff --git a/tests/attributes.rs b/tests/attributes.rs index 055ec9e..d527b0e 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 doc_attribute_suppress() { + Test::new() + .justfile( + " + # Non-document comment + [doc] + foo: + echo foo + ", + ) + .args(["--list"]) + .stdout( + " + Available recipes: + foo + ", + ) + .run(); +}