Add [doc] attribute to set and suppress documentation comments (#2050)

This commit is contained in:
Greg Shuflin 2024-05-25 02:26:04 -07:00 committed by GitHub
parent 7fb04761b7
commit dcbd07f9d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 81 additions and 6 deletions

View File

@ -1079,6 +1079,27 @@ Available recipes:
test # test stuff 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 and Substitution
Variables, strings, concatenation, path joining, and substitution using `{{…}}` Variables, strings, concatenation, path joining, and substitution using `{{…}}`
@ -1622,8 +1643,9 @@ Recipes may be annotated with attributes that change their behavior.
| Name | Description | | Name | Description |
|------|-------------| |------|-------------|
| `[confirm]`<sup>1.17.0</sup> | Require confirmation prior to executing recipe. | | `[confirm]`<sup>1.17.0</sup> | Require confirmation prior to executing recipe. |
| `[confirm('prompt')]`<sup>1.23.0</sup> | Require confirmation prior to executing recipe with a custom prompt. | | `[confirm('PROMPT')]`<sup>1.23.0</sup> | Require confirmation prior to executing recipe with a custom prompt. |
| `[group('NAME"']`<sup>master</sup> | Put recipe in [recipe group](#recipe-groups) `NAME`. | `[doc('DOC')]`<sup>master</sup> | Set recipe's [documentation comment](#documentation-comments) to `DOC`. |
| `[group('NAME"']`<sup>master</sup> | Put recipe in [recipe group](#recipe-groups) `NAME`. |
| `[linux]`<sup>1.8.0</sup> | Enable recipe on Linux. | | `[linux]`<sup>1.8.0</sup> | Enable recipe on Linux. |
| `[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. |

View File

@ -10,6 +10,7 @@ use super::*;
#[strum_discriminants(strum(serialize_all = "kebab-case"))] #[strum_discriminants(strum(serialize_all = "kebab-case"))]
pub(crate) enum Attribute<'src> { pub(crate) enum Attribute<'src> {
Confirm(Option<StringLiteral<'src>>), Confirm(Option<StringLiteral<'src>>),
Doc(Option<StringLiteral<'src>>),
Group(StringLiteral<'src>), Group(StringLiteral<'src>),
Linux, Linux,
Macos, Macos,
@ -24,7 +25,7 @@ pub(crate) enum Attribute<'src> {
impl AttributeDiscriminant { impl AttributeDiscriminant {
fn argument_range(self) -> RangeInclusive<usize> { fn argument_range(self) -> RangeInclusive<usize> {
match self { match self {
Self::Confirm => 0..=1, Self::Confirm | Self::Doc => 0..=1,
Self::Group => 1..=1, Self::Group => 1..=1,
Self::Linux Self::Linux
| Self::Macos | Self::Macos
@ -72,6 +73,7 @@ impl<'src> Attribute<'src> {
Ok(match discriminant { Ok(match discriminant {
Confirm => Self::Confirm(argument), Confirm => Self::Confirm(argument),
Doc => Self::Doc(argument),
Group => Self::Group(argument.unwrap()), Group => Self::Group(argument.unwrap()),
Linux => Self::Linux, Linux => Self::Linux,
Macos => Self::Macos, Macos => Self::Macos,
@ -91,7 +93,8 @@ impl<'src> Attribute<'src> {
fn argument(&self) -> Option<&StringLiteral> { fn argument(&self) -> Option<&StringLiteral> {
match self { match self {
Self::Confirm(prompt) => prompt.as_ref(), 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::Linux
| Self::Macos | Self::Macos
| Self::NoCd | Self::NoCd
@ -107,7 +110,6 @@ impl<'src> Attribute<'src> {
impl<'src> Display for Attribute<'src> { impl<'src> Display for Attribute<'src> {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.name())?; write!(f, "{}", self.name())?;
if let Some(argument) = self.argument() { if let Some(argument) = self.argument() {
write!(f, "({argument})")?; write!(f, "({argument})")?;
} }

View File

@ -450,6 +450,15 @@ impl<'src, D> Recipe<'src, D> {
}) })
.collect() .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> { impl<'src, D: Display> ColorDisplay for Recipe<'src, D> {

View File

@ -573,7 +573,7 @@ impl Subcommand {
); );
let doc = if i == 0 { let doc = if i == 0 {
recipe.doc.map(Cow::Borrowed) recipe.doc().map(Cow::Borrowed)
} else { } else {
Some(Cow::Owned(format!("alias for `{}`", recipe.name))) Some(Cow::Owned(format!("alias for `{}`", recipe.name)))
}; };

View File

@ -129,3 +129,45 @@ fn unexpected_attribute_argument() {
.status(1) .status(1)
.run(); .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();
}