Add [no-cd] attribute (#1400)
This commit is contained in:
parent
659b8211ad
commit
331f61f59c
26
README.md
26
README.md
@ -1204,8 +1204,9 @@ These functions can fail, for example if a path does not have an extension, whic
|
|||||||
Recipes may be annotated with attributes that change their behavior.
|
Recipes may be annotated with attributes that change their behavior.
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
| ------------------- | ------------------------------------------------- |
|
| ------------------- | ----------------------------------------------- |
|
||||||
| `[no-exit-message]` | Don't print an error message when a recipe fails. |
|
| `[no-cd]` | Don't change directory before executing recipe. |
|
||||||
|
| `[no-exit-message]` | Don't print an error message if recipe fails. |
|
||||||
| `[linux]` | Enable recipe on Linux. |
|
| `[linux]` | Enable recipe on Linux. |
|
||||||
| `[macos]` | Enable recipe on MacOS. |
|
| `[macos]` | Enable recipe on MacOS. |
|
||||||
| `[unix]` | Enable recipe on Unixes. |
|
| `[unix]` | Enable recipe on Unixes. |
|
||||||
@ -1235,6 +1236,27 @@ run:
|
|||||||
main.exe
|
main.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Disabling Changing Directory<sup>master</sup>
|
||||||
|
|
||||||
|
`just` normally executes recipes with the current directory set to the
|
||||||
|
directory that contains the `justfile`. This can be disabled using the
|
||||||
|
`[no-cd]` attribute. This can be used to create recipes which use paths
|
||||||
|
relative to the invocation directory, or which operate on the current
|
||||||
|
directory.
|
||||||
|
|
||||||
|
For exmaple, this `commit` recipe:
|
||||||
|
|
||||||
|
```make
|
||||||
|
[no-cd]
|
||||||
|
commit file:
|
||||||
|
git add {{file}}
|
||||||
|
git commit
|
||||||
|
```
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
### Command Evaluation Using Backticks
|
### Command Evaluation Using Backticks
|
||||||
|
|
||||||
Backticks can be used to store the result of commands:
|
Backticks can be used to store the result of commands:
|
||||||
|
@ -8,6 +8,7 @@ use super::*;
|
|||||||
pub(crate) enum Attribute {
|
pub(crate) enum Attribute {
|
||||||
Linux,
|
Linux,
|
||||||
Macos,
|
Macos,
|
||||||
|
NoCd,
|
||||||
NoExitMessage,
|
NoExitMessage,
|
||||||
Unix,
|
Unix,
|
||||||
Windows,
|
Windows,
|
||||||
|
@ -6,13 +6,15 @@ pub(crate) struct Platform;
|
|||||||
impl PlatformInterface for Platform {
|
impl PlatformInterface for Platform {
|
||||||
fn make_shebang_command(
|
fn make_shebang_command(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
working_directory: &Path,
|
working_directory: Option<&Path>,
|
||||||
_shebang: Shebang,
|
_shebang: Shebang,
|
||||||
) -> Result<Command, OutputError> {
|
) -> Result<Command, OutputError> {
|
||||||
// shebang scripts can be executed directly on unix
|
// shebang scripts can be executed directly on unix
|
||||||
let mut cmd = Command::new(path);
|
let mut cmd = Command::new(path);
|
||||||
|
|
||||||
|
if let Some(working_directory) = working_directory {
|
||||||
cmd.current_dir(working_directory);
|
cmd.current_dir(working_directory);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(cmd)
|
Ok(cmd)
|
||||||
}
|
}
|
||||||
@ -48,7 +50,7 @@ impl PlatformInterface for Platform {
|
|||||||
impl PlatformInterface for Platform {
|
impl PlatformInterface for Platform {
|
||||||
fn make_shebang_command(
|
fn make_shebang_command(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
working_directory: &Path,
|
working_directory: Option<&Path>,
|
||||||
shebang: Shebang,
|
shebang: Shebang,
|
||||||
) -> Result<Command, OutputError> {
|
) -> Result<Command, OutputError> {
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
@ -57,7 +59,9 @@ impl PlatformInterface for Platform {
|
|||||||
let command = if shebang.interpreter.contains('/') {
|
let command = if shebang.interpreter.contains('/') {
|
||||||
// …translate path to the interpreter from unix style to windows style.
|
// …translate path to the interpreter from unix style to windows style.
|
||||||
let mut cygpath = Command::new("cygpath");
|
let mut cygpath = Command::new("cygpath");
|
||||||
|
if let Some(working_directory) = working_directory {
|
||||||
cygpath.current_dir(working_directory);
|
cygpath.current_dir(working_directory);
|
||||||
|
}
|
||||||
cygpath.arg("--windows");
|
cygpath.arg("--windows");
|
||||||
cygpath.arg(shebang.interpreter);
|
cygpath.arg(shebang.interpreter);
|
||||||
|
|
||||||
@ -69,7 +73,9 @@ impl PlatformInterface for Platform {
|
|||||||
|
|
||||||
let mut cmd = Command::new(command.as_ref());
|
let mut cmd = Command::new(command.as_ref());
|
||||||
|
|
||||||
|
if let Some(working_directory) = working_directory {
|
||||||
cmd.current_dir(working_directory);
|
cmd.current_dir(working_directory);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(argument) = shebang.argument {
|
if let Some(argument) = shebang.argument {
|
||||||
cmd.arg(argument);
|
cmd.arg(argument);
|
||||||
|
@ -5,7 +5,7 @@ pub(crate) trait PlatformInterface {
|
|||||||
/// shebang line `shebang`
|
/// shebang line `shebang`
|
||||||
fn make_shebang_command(
|
fn make_shebang_command(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
working_directory: &Path,
|
working_directory: Option<&Path>,
|
||||||
shebang: Shebang,
|
shebang: Shebang,
|
||||||
) -> Result<Command, OutputError>;
|
) -> Result<Command, OutputError>;
|
||||||
|
|
||||||
|
@ -66,6 +66,10 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
!self.private
|
!self.private
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn change_directory(&self) -> bool {
|
||||||
|
!self.attributes.contains(&Attribute::NoCd)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn enabled(&self) -> bool {
|
pub(crate) fn enabled(&self) -> bool {
|
||||||
let windows = self.attributes.contains(&Attribute::Windows);
|
let windows = self.attributes.contains(&Attribute::Windows);
|
||||||
let linux = self.attributes.contains(&Attribute::Linux);
|
let linux = self.attributes.contains(&Attribute::Linux);
|
||||||
@ -190,7 +194,9 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
|
|
||||||
let mut cmd = context.settings.shell_command(config);
|
let mut cmd = context.settings.shell_command(config);
|
||||||
|
|
||||||
|
if self.change_directory() {
|
||||||
cmd.current_dir(&context.search.working_directory);
|
cmd.current_dir(&context.search.working_directory);
|
||||||
|
}
|
||||||
|
|
||||||
cmd.arg(command);
|
cmd.arg(command);
|
||||||
|
|
||||||
@ -322,13 +328,19 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// create a command to run the script
|
// create a command to run the script
|
||||||
let mut command =
|
let mut command = Platform::make_shebang_command(
|
||||||
Platform::make_shebang_command(&path, &context.search.working_directory, shebang).map_err(
|
&path,
|
||||||
|output_error| Error::Cygpath {
|
if self.change_directory() {
|
||||||
|
Some(&context.search.working_directory)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
shebang,
|
||||||
|
)
|
||||||
|
.map_err(|output_error| Error::Cygpath {
|
||||||
recipe: self.name(),
|
recipe: self.name(),
|
||||||
output_error,
|
output_error,
|
||||||
},
|
})?;
|
||||||
)?;
|
|
||||||
|
|
||||||
if context.settings.positional_arguments {
|
if context.settings.positional_arguments {
|
||||||
command.args(positional);
|
command.args(positional);
|
||||||
|
@ -60,6 +60,7 @@ mod json;
|
|||||||
mod line_prefixes;
|
mod line_prefixes;
|
||||||
mod misc;
|
mod misc;
|
||||||
mod multibyte_char;
|
mod multibyte_char;
|
||||||
|
mod no_cd;
|
||||||
mod no_exit_message;
|
mod no_exit_message;
|
||||||
mod os_attributes;
|
mod os_attributes;
|
||||||
mod parser;
|
mod parser;
|
||||||
|
43
tests/no_cd.rs
Normal file
43
tests/no_cd.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn linewise() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
[no-cd]
|
||||||
|
foo:
|
||||||
|
cat bar
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.current_dir("foo")
|
||||||
|
.tree(tree! {
|
||||||
|
foo: {
|
||||||
|
bar: "hello",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.stderr("cat bar\n")
|
||||||
|
.stdout("hello")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shebang() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
[no-cd]
|
||||||
|
foo:
|
||||||
|
#!/bin/sh
|
||||||
|
cat bar
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.current_dir("foo")
|
||||||
|
.tree(tree! {
|
||||||
|
foo: {
|
||||||
|
bar: "hello",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.stdout("hello")
|
||||||
|
.run();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user