Skip to content

Commit

Permalink
Add no-exit-message Setting and [exit-message] attribute (#2568)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchieAtkinson authored Jan 22, 2025
1 parent ddc9103 commit ab3da9b
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 124 deletions.
6 changes: 5 additions & 1 deletion src/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use super::*;
pub(crate) enum Attribute<'src> {
Confirm(Option<StringLiteral<'src>>),
Doc(Option<StringLiteral<'src>>),
ExitMessage,
Extension(StringLiteral<'src>),
Group(StringLiteral<'src>),
Linux,
Expand All @@ -32,7 +33,8 @@ impl AttributeDiscriminant {
match self {
Self::Confirm | Self::Doc => 0..=1,
Self::Group | Self::Extension | Self::WorkingDirectory => 1..=1,
Self::Linux
Self::ExitMessage
| Self::Linux
| Self::Macos
| Self::NoCd
| Self::NoExitMessage
Expand Down Expand Up @@ -78,6 +80,7 @@ impl<'src> Attribute<'src> {
Ok(match discriminant {
AttributeDiscriminant::Confirm => Self::Confirm(arguments.into_iter().next()),
AttributeDiscriminant::Doc => Self::Doc(arguments.into_iter().next()),
AttributeDiscriminant::ExitMessage => Self::ExitMessage,
AttributeDiscriminant::Extension => Self::Extension(arguments.into_iter().next().unwrap()),
AttributeDiscriminant::Group => Self::Group(arguments.into_iter().next().unwrap()),
AttributeDiscriminant::Linux => Self::Linux,
Expand Down Expand Up @@ -129,6 +132,7 @@ impl Display for Attribute<'_> {
Self::Script(Some(shell)) => write!(f, "({shell})")?,
Self::Confirm(None)
| Self::Doc(None)
| Self::ExitMessage
| Self::Linux
| Self::Macos
| Self::NoCd
Expand Down
4 changes: 4 additions & 0 deletions src/compile_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ impl Display for CompileError<'_> {
DuplicateUnexport { variable } => {
write!(f, "Variable `{variable}` is unexported multiple times")
}
ExitMessageAndNoExitMessageAttribute { recipe } => write!(
f,
"Recipe `{recipe}` has both `[exit-message]` and `[no-exit-message]` attributes"
),
ExpectedKeyword { expected, found } => {
let expected = List::or_ticked(expected);
if found.kind == TokenKind::Identifier {
Expand Down
3 changes: 3 additions & 0 deletions src/compile_error_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ pub(crate) enum CompileErrorKind<'src> {
DuplicateUnexport {
variable: &'src str,
},
ExitMessageAndNoExitMessageAttribute {
recipe: &'src str,
},
ExpectedKeyword {
expected: Vec<Keyword>,
found: Token<'src>,
Expand Down
1 change: 1 addition & 0 deletions src/keyword.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub(crate) enum Keyword {
IgnoreComments,
Import,
Mod,
NoExitMessage,
PositionalArguments,
Quiet,
ScriptInterpreter,
Expand Down
1 change: 1 addition & 0 deletions src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ impl<'src> Node<'src> for Set<'src> {
| Setting::DotenvRequired(value)
| Setting::Export(value)
| Setting::Fallback(value)
| Setting::NoExitMessage(value)
| Setting::PositionalArguments(value)
| Setting::Quiet(value)
| Setting::Unstable(value)
Expand Down
17 changes: 14 additions & 3 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -951,16 +951,26 @@ impl<'run, 'src> Parser<'run, 'src> {
}));
}

let working_directory = attributes.contains(AttributeDiscriminant::WorkingDirectory);

if working_directory && attributes.contains(AttributeDiscriminant::NoCd) {
if attributes.contains(AttributeDiscriminant::WorkingDirectory)
&& attributes.contains(AttributeDiscriminant::NoCd)
{
return Err(
name.error(CompileErrorKind::NoCdAndWorkingDirectoryAttribute {
recipe: name.lexeme(),
}),
);
}

if attributes.contains(AttributeDiscriminant::ExitMessage)
&& attributes.contains(AttributeDiscriminant::NoExitMessage)
{
return Err(
name.error(CompileErrorKind::ExitMessageAndNoExitMessageAttribute {
recipe: name.lexeme(),
}),
);
}

let private =
name.lexeme().starts_with('_') || attributes.contains(AttributeDiscriminant::Private);

Expand Down Expand Up @@ -1093,6 +1103,7 @@ impl<'run, 'src> Parser<'run, 'src> {
Keyword::Export => Some(Setting::Export(self.parse_set_bool()?)),
Keyword::Fallback => Some(Setting::Fallback(self.parse_set_bool()?)),
Keyword::IgnoreComments => Some(Setting::IgnoreComments(self.parse_set_bool()?)),
Keyword::NoExitMessage => Some(Setting::NoExitMessage(self.parse_set_bool()?)),
Keyword::PositionalArguments => Some(Setting::PositionalArguments(self.parse_set_bool()?)),
Keyword::Quiet => Some(Setting::Quiet(self.parse_set_bool()?)),
Keyword::Unstable => Some(Setting::Unstable(self.parse_set_bool()?)),
Expand Down
18 changes: 12 additions & 6 deletions src/recipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,16 @@ impl<'src, D> Recipe<'src, D> {
|| (cfg!(windows) && windows)
}

fn print_exit_message(&self) -> bool {
!self
.attributes
.contains(AttributeDiscriminant::NoExitMessage)
fn print_exit_message(&self, settings: &Settings) -> bool {
if self.attributes.contains(AttributeDiscriminant::ExitMessage) {
true
} else if settings.no_exit_message {
false
} else {
!self
.attributes
.contains(AttributeDiscriminant::NoExitMessage)
}
}

fn working_directory<'a>(&'a self, context: &'a ExecutionContext) -> Option<PathBuf> {
Expand Down Expand Up @@ -304,7 +310,7 @@ impl<'src, D> Recipe<'src, D> {
recipe: self.name(),
line_number: Some(line_number),
code,
print_message: self.print_exit_message(),
print_message: self.print_exit_message(&context.module.settings),
});
}
} else {
Expand Down Expand Up @@ -449,7 +455,7 @@ impl<'src, D> Recipe<'src, D> {
recipe: self.name(),
line_number: None,
code,
print_message: self.print_exit_message(),
print_message: self.print_exit_message(&context.module.settings),
})
}
},
Expand Down
2 changes: 2 additions & 0 deletions src/setting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub(crate) enum Setting<'src> {
Export(bool),
Fallback(bool),
IgnoreComments(bool),
NoExitMessage(bool),
PositionalArguments(bool),
Quiet(bool),
ScriptInterpreter(Interpreter<'src>),
Expand All @@ -32,6 +33,7 @@ impl Display for Setting<'_> {
| Self::Export(value)
| Self::Fallback(value)
| Self::IgnoreComments(value)
| Self::NoExitMessage(value)
| Self::PositionalArguments(value)
| Self::Quiet(value)
| Self::Unstable(value)
Expand Down
4 changes: 4 additions & 0 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub(crate) struct Settings<'src> {
pub(crate) export: bool,
pub(crate) fallback: bool,
pub(crate) ignore_comments: bool,
pub(crate) no_exit_message: bool,
pub(crate) positional_arguments: bool,
pub(crate) quiet: bool,
#[serde(skip)]
Expand Down Expand Up @@ -61,6 +62,9 @@ impl<'src> Settings<'src> {
Setting::IgnoreComments(ignore_comments) => {
settings.ignore_comments = ignore_comments;
}
Setting::NoExitMessage(no_exit_message) => {
settings.no_exit_message = no_exit_message;
}
Setting::PositionalArguments(positional_arguments) => {
settings.positional_arguments = positional_arguments;
}
Expand Down
1 change: 1 addition & 0 deletions tests/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ struct Settings<'a> {
export: bool,
fallback: bool,
ignore_comments: bool,
no_exit_message: bool,
positional_arguments: bool,
quiet: bool,
shell: Option<Interpreter<'a>>,
Expand Down
Loading

0 comments on commit ab3da9b

Please sign in to comment.