Skip to content

Commit

Permalink
Add ignore-recipe-comments setting
Browse files Browse the repository at this point in the history
Add a new setting "ignore-recipe-comments". If set, this causes lines
internal to a non-shebang recipe beginning with the character '#' (other
than '#!' itself) to be treated as comments of the justfile itself. They will
not be echoed to stderr when the recipe executes.
  • Loading branch information
neunenak committed Sep 8, 2022
1 parent 3135db5 commit 09ba6d3
Show file tree
Hide file tree
Showing 14 changed files with 120 additions and 34 deletions.
1 change: 1 addition & 0 deletions GRAMMAR.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export : 'export' assignment

setting : 'set' 'dotenv-load' boolean?
| 'set' 'export' boolean?
| 'set' 'ignore-recipe-comments' boolean?
| 'set' 'positional-arguments' boolean?
| 'set' 'allow-duplicate-recipes' boolean?
| 'set' 'windows-powershell' boolean?
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,7 @@ foo:
| `allow-duplicate-recipes` | boolean | Allow recipes appearing later in a `justfile` to override earlier recipes with the same name. |
| `dotenv-load` | boolean | Load a `.env` file, if present. |
| `export` | boolean | Export all variables as environment variables. |
| `ignore-recipe-comments' | boolean | Treat lines beginning with a '#' in the body of a recipe as comments, and do not print them. |
| `positional-arguments` | boolean | Pass positional arguments. |
| `shell` | `[COMMAND, ARGS…]` | Set the command used to invoke recipes and evaluate backticks. |
| `windows-shell` | `[COMMAND, ARGS…]` | Set the command used to invoke recipes and evaluate backticks. |
Expand Down
3 changes: 3 additions & 0 deletions src/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ impl<'src> Analyzer<'src> {
Setting::Export(export) => {
settings.export = export;
}
Setting::IgnoreRecipeComments(ignore) => {
settings.ignore_recipe_comments = ignore;
}
Setting::PositionalArguments(positional_arguments) => {
settings.positional_arguments = positional_arguments;
}
Expand Down
2 changes: 1 addition & 1 deletion src/justfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ impl<'src> Justfile<'src> {
)?;
}

recipe.run(context, dotenv, scope.child(), search, &positional)?;
recipe.run(context, dotenv, scope.child(), search, &positional, &self.settings)?;

{
let mut ran = BTreeSet::new();
Expand Down
1 change: 1 addition & 0 deletions src/keyword.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub(crate) enum Keyword {
Export,
False,
If,
IgnoreRecipeComments,
PositionalArguments,
Set,
Shell,
Expand Down
10 changes: 10 additions & 0 deletions src/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ impl<'src> Line<'src> {
self.fragments.is_empty()
}

pub(crate) fn is_comment(&self) -> bool {
match self.fragments.first() {
Some(Fragment::Text { token }) => {
let lexeme = token.lexeme();
lexeme.starts_with("#") && !lexeme.starts_with("#!")
},
_ => false
}
}

pub(crate) fn is_continuation(&self) -> bool {
match self.fragments.last() {
Some(Fragment::Text { token }) => token.lexeme().ends_with('\\'),
Expand Down
3 changes: 2 additions & 1 deletion src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ impl<'src> Node<'src> for Set<'src> {
| Setting::DotenvLoad(value)
| Setting::Export(value)
| Setting::PositionalArguments(value)
| Setting::WindowsPowerShell(value) => {
| Setting::WindowsPowerShell(value)
| Setting::IgnoreRecipeComments(value) => {
set.push_mut(value.to_string());
}
Setting::Shell(Shell { command, arguments })
Expand Down
47 changes: 17 additions & 30 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,36 +748,23 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
let name = Name::from_identifier(self.presume(Identifier)?);
let lexeme = name.lexeme();

if Keyword::AllowDuplicateRecipes == lexeme {
let value = self.parse_set_bool()?;
return Ok(Set {
value: Setting::AllowDuplicateRecipes(value),
name,
});
} else if Keyword::DotenvLoad == lexeme {
let value = self.parse_set_bool()?;
return Ok(Set {
value: Setting::DotenvLoad(value),
name,
});
} else if Keyword::Export == lexeme {
let value = self.parse_set_bool()?;
return Ok(Set {
value: Setting::Export(value),
name,
});
} else if Keyword::PositionalArguments == lexeme {
let value = self.parse_set_bool()?;
return Ok(Set {
value: Setting::PositionalArguments(value),
name,
});
} else if Keyword::WindowsPowershell == lexeme {
let value = self.parse_set_bool()?;
return Ok(Set {
value: Setting::WindowsPowerShell(value),
name,
});
let set_bool: Option<Setting> = match Keyword::from_lexeme(lexeme) {
Some(kw) => match kw {
Keyword::AllowDuplicateRecipes => Some(Setting::AllowDuplicateRecipes(self.parse_set_bool()?)),
Keyword::DotenvLoad => Some(Setting::DotenvLoad(self.parse_set_bool()?)),
Keyword::Export => Some(Setting::Export(self.parse_set_bool()?)),
Keyword::IgnoreRecipeComments => Some(Setting::IgnoreRecipeComments(self.parse_set_bool()?)),
Keyword::PositionalArguments => Some(Setting::PositionalArguments(self.parse_set_bool()?)),
Keyword::WindowsPowershell => Some(Setting::WindowsPowerShell(self.parse_set_bool()?)),
_ => None,
},
None => None
};

if let Some(value) = set_bool {
return Ok(Set {
value, name
});
}

self.expect(ColonEquals)?;
Expand Down
12 changes: 10 additions & 2 deletions src/recipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl<'src, D> Recipe<'src, D> {
scope: Scope<'src, 'run>,
search: &'run Search,
positional: &[String],
settings: &Settings,
) -> RunResult<'src, ()> {
let config = &context.config;

Expand All @@ -91,18 +92,19 @@ impl<'src, D> Recipe<'src, D> {
if self.shebang {
self.run_shebang(context, dotenv, &scope, positional, config, evaluator)
} else {
self.run_linewise(context, dotenv, &scope, positional, config, evaluator)
self.run_linewise(context, dotenv, &scope, positional, config, evaluator, settings)
}
}

pub(crate) fn run_linewise<'run>(
fn run_linewise<'run>(
&self,
context: &RecipeContext<'src, 'run>,
dotenv: &BTreeMap<String, String>,
scope: &Scope<'src, 'run>,
positional: &[String],
config: &Config,
mut evaluator: Evaluator<'src, 'run>,
settings: &Settings,
) -> RunResult<'src, ()> {
let mut lines = self.body.iter().peekable();
let mut line_number = self.line_number() + 1;
Expand All @@ -114,6 +116,8 @@ impl<'src, D> Recipe<'src, D> {
let mut continued = false;
let quiet_command = lines.peek().map_or(false, |line| line.is_quiet());
let infallible_command = lines.peek().map_or(false, |line| line.is_infallible());
let comment_line = lines.peek().map_or(false, |line| line.is_comment());

loop {
if lines.peek().is_none() {
break;
Expand All @@ -138,6 +142,10 @@ impl<'src, D> Recipe<'src, D> {
command = &command[1..];
}

if comment_line && settings.ignore_recipe_comments {
continue;
}

if command.is_empty() {
continue;
}
Expand Down
2 changes: 2 additions & 0 deletions src/setting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub(crate) enum Setting<'src> {
AllowDuplicateRecipes(bool),
DotenvLoad(bool),
Export(bool),
IgnoreRecipeComments(bool),
PositionalArguments(bool),
Shell(Shell<'src>),
WindowsPowerShell(bool),
Expand All @@ -16,6 +17,7 @@ impl<'src> Display for Setting<'src> {
match self {
Setting::AllowDuplicateRecipes(value)
| Setting::DotenvLoad(value)
| Setting::IgnoreRecipeComments(value)
| Setting::Export(value)
| Setting::PositionalArguments(value)
| Setting::WindowsPowerShell(value) => write!(f, "{}", value),
Expand Down
2 changes: 2 additions & 0 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub(crate) struct Settings<'src> {
pub(crate) allow_duplicate_recipes: bool,
pub(crate) dotenv_load: Option<bool>,
pub(crate) export: bool,
pub(crate) ignore_recipe_comments: bool,
pub(crate) positional_arguments: bool,
pub(crate) shell: Option<Shell<'src>>,
pub(crate) windows_powershell: bool,
Expand All @@ -22,6 +23,7 @@ impl<'src> Settings<'src> {
allow_duplicate_recipes: false,
dotenv_load: None,
export: false,
ignore_recipe_comments: false,
positional_arguments: false,
shell: None,
windows_powershell: false,
Expand Down
53 changes: 53 additions & 0 deletions tests/ignore_recipe_comments.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use super::*;

#[test]
fn ignore_recipe_comments() {
Test::new()
.justfile(
"
set ignore-recipe-comments
some_recipe:
# A recipe-internal comment
echo something-useful
",
)
.stdout("something-useful\n")
.stderr("echo something-useful\n")
.run();
}

#[test]
fn dont_ignore_recipe_comments() {
Test::new()
.justfile(
"
set ignore-recipe-comments := false
some_recipe:
# A recipe-internal comment
echo something-useful
",
)
.stdout("something-useful\n")
.stderr("# A recipe-internal comment\necho something-useful\n")
.run();
}

#[test]
fn ignore_recipe_comments_with_shell_setting() {
Test::new()
.justfile(
"
set shell := ['echo', '-n']
set ignore-recipe-comments
some_recipe:
# Alternate shells still ignore comments
echo something-useful
",
)
.stdout("something-useful\n")
.stderr("echo something-useful\n")
.run();
}
16 changes: 16 additions & 0 deletions tests/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ fn alias() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -71,6 +72,7 @@ fn assignment() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -113,6 +115,7 @@ fn body() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -165,6 +168,7 @@ fn dependencies() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -254,6 +258,7 @@ fn dependency_argument() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -307,6 +312,7 @@ fn duplicate_recipes() {
"allow_duplicate_recipes": true,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -342,6 +348,7 @@ fn doc_comment() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand All @@ -365,6 +372,7 @@ fn empty_justfile() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -497,6 +505,7 @@ fn parameters() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -568,6 +577,7 @@ fn priors() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -603,6 +613,7 @@ fn private() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -638,6 +649,7 @@ fn quiet() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -665,6 +677,7 @@ fn settings() {
set dotenv-load
set export
set positional-arguments
set ignore-recipe-comments := true
set shell := ['a', 'b', 'c']
foo:
Expand All @@ -691,6 +704,7 @@ fn settings() {
"allow_duplicate_recipes": false,
"dotenv_load": true,
"export": true,
"ignore_recipe_comments": true,
"positional_arguments": true,
"shell": {
"arguments": ["b", "c"],
Expand Down Expand Up @@ -732,6 +746,7 @@ fn shebang() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down Expand Up @@ -767,6 +782,7 @@ fn simple() {
"allow_duplicate_recipes": false,
"dotenv_load": null,
"export": false,
"ignore_recipe_comments": false,
"positional_arguments": false,
"shell": null,
"windows_powershell": false,
Expand Down
1 change: 1 addition & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ mod export;
mod fall_back_to_parent;
mod fmt;
mod functions;
mod ignore_recipe_comments;
mod init;
#[cfg(unix)]
mod interrupts;
Expand Down

0 comments on commit 09ba6d3

Please sign in to comment.