1
1
mirror of https://github.com/casey/just.git synced 2024-11-22 18:34:06 +03:00
This commit is contained in:
Ben Heidemann 2024-10-31 14:01:59 +00:00 committed by GitHub
commit 43d69b7914
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 109 additions and 6 deletions

View File

@ -1875,6 +1875,7 @@ Recipes, `mod` statements, and aliases may be annotated with attributes that cha
| `[script(COMMAND)]`<sup>1.32.0</sup> | recipe | Execute recipe as a script interpreted by `COMMAND`. See [script recipes](#script-recipes) for more details. |
| `[unix]`<sup>1.8.0</sup> | recipe | Enable recipe on Unixes. (Includes MacOS). |
| `[windows]`<sup>1.8.0</sup> | recipe | Enable recipe on Windows. |
| `[working-directory('bar')]`<sup>1.37.0</sup> | recipe | Set the working directory for the recipe, relative to the default working directory. |
A recipe can have multiple attributes, either on multiple lines:
@ -1938,6 +1939,23 @@ Can be used with paths that are relative to the current directory, because
`[no-cd]` prevents `just` from changing the current directory when executing
`commit`.
#### Changing Working Directory<sup>1.37.0</sup>
`just` normally executes recipes with the current directory set to the directory
that contains the `justfile`. The execution directory can be changed with the
`[working-directory('dir')]` attribute. This can be used to create recipes which
are executed in a directory relative to the default directory.
For example, this `example` recipe:
```just
[working-directory('dir')]
example:
echo "$(pwd)"
```
Which will run in the `dir` directory.
#### Requiring Confirmation for Recipes<sup>1.17.0</sup>
`just` normally executes all recipes unless there is an error. The `[confirm]`

View File

@ -23,13 +23,14 @@ pub(crate) enum Attribute<'src> {
Script(Option<Interpreter<'src>>),
Unix,
Windows,
WorkingDirectory(StringLiteral<'src>),
}
impl AttributeDiscriminant {
fn argument_range(self) -> RangeInclusive<usize> {
match self {
Self::Confirm | Self::Doc => 0..=1,
Self::Group | Self::Extension => 1..=1,
Self::Group | Self::Extension | Self::WorkingDirectory => 1..=1,
Self::Linux
| Self::Macos
| Self::NoCd
@ -93,6 +94,9 @@ impl<'src> Attribute<'src> {
}),
AttributeDiscriminant::Unix => Self::Unix,
AttributeDiscriminant::Windows => Self::Windows,
AttributeDiscriminant::WorkingDirectory => {
Self::WorkingDirectory(arguments.into_iter().next().unwrap())
}
})
}
@ -109,7 +113,8 @@ impl<'src> Display for Attribute<'src> {
Self::Confirm(Some(argument))
| Self::Doc(Some(argument))
| Self::Extension(argument)
| Self::Group(argument) => write!(f, "({argument})")?,
| Self::Group(argument)
| Self::WorkingDirectory(argument) => write!(f, "({argument})")?,
Self::Script(Some(shell)) => write!(f, "({shell})")?,
Self::Confirm(None)
| Self::Doc(None)

View File

@ -131,11 +131,24 @@ impl<'src, D> Recipe<'src, D> {
}
fn working_directory<'a>(&'a self, context: &'a ExecutionContext) -> Option<PathBuf> {
if self.change_directory() {
Some(context.working_directory())
} else {
None
if !self.change_directory() {
return None;
}
let working_dir = self
.attributes
.iter()
.filter_map(|attribute| match attribute {
Attribute::WorkingDirectory(dir) => Some(dir),
_ => None,
})
.last();
Some(
working_dir
.map(|dir| context.working_directory().join(dir.raw))
.unwrap_or(context.working_directory()),
)
}
fn no_quiet(&self) -> bool {

View File

@ -331,3 +331,70 @@ file := shell('cat file.txt')
.stdout("FILE\n")
.run();
}
#[test]
fn attribute() {
Test::new()
.justfile(
r#"
[working-directory('bar')]
print1:
echo "$(basename "$PWD")"
[working-directory('bar')]
[working-directory('baz')]
print2:
echo "$(basename "$PWD")"
[working-directory('bar')]
[no-cd]
print3:
echo "$(basename "$PWD")"
"#,
)
.current_dir("foo")
.tree(tree! {
foo: {},
bar: {},
baz: {},
})
.args(["print1", "print2", "print3"])
.stderr(
r#"echo "$(basename "$PWD")"
echo "$(basename "$PWD")"
echo "$(basename "$PWD")"
"#,
)
.stdout("bar\nbaz\nfoo\n")
.run();
}
#[test]
fn setting_and_attribute() {
Test::new()
.justfile(
r#"
set working-directory := 'bar'
[working-directory('baz')]
print1:
echo "$(basename "$PWD")"
echo "$(basename "$(dirname "$PWD")")"
"#,
)
.current_dir("foo")
.tree(tree! {
foo: {},
bar: {
baz: {},
},
})
.args(["print1"])
.stderr(
r#"echo "$(basename "$PWD")"
echo "$(basename "$(dirname "$PWD")")"
"#,
)
.stdout("baz\nbar\n")
.run();
}