Skip to content

Commit

Permalink
Only use cygpath on shebang if it contains /
Browse files Browse the repository at this point in the history
On Windows, skip conversion if a shebang path does not include `/`. In
this case it is not a Unix path, and does not need to be converted to a
Windows path before running.
  • Loading branch information
casey committed Jun 26, 2020
1 parent 863fb53 commit 7e62ced
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
19 changes: 19 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,25 @@ Yo from a shell script!
Hello from ruby!
```

==== Shebang Recipe Execution on Windows

On Windows, shebang interpreter paths containing a `/` are translated from Unix-style
paths to Windows-style paths using `cygpath`, a utility that ships with http://www.cygwin.com[Cygwin].

For example, to execute this recipe on Windows:

```make
echo:
#!/bin/sh

echo "Hello!"
```

The interpreter path `/bin/sh` will be translated to a Windows-style path using
`cygpath` before being executed.

If the interpreter path does not contain a `/` and does not start with a `~`, it will be executed without being translated. This is useful if `cygpath` is not available, or you wish to use a Windows style path to the interpreter.

=== Multi-line Constructs

Recipes without an initial shebang are evaluated and run line-by-line, which means that multi-line constructs probably won't do what you want.
Expand Down
23 changes: 16 additions & 7 deletions src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,28 @@ impl PlatformInterface for Platform {
command: &str,
argument: Option<&str>,
) -> Result<Command, OutputError> {
// Translate path to the interpreter from unix style to windows style
let mut cygpath = Command::new("cygpath");
cygpath.current_dir(working_directory);
cygpath.arg("--windows");
cygpath.arg(command);

let mut cmd = Command::new(output(cygpath)?);
// If the path contains forward slashes…
let command = if command.contains('/') || command.starts_with('~') {
// …translate path to the interpreter from unix style to windows style
let mut cygpath = Command::new("cygpath");
cygpath.current_dir(working_directory);
cygpath.arg("--windows");
cygpath.arg(command);

Cow::Owned(output(cygpath)?)
} else {
// otherwise use it as-is
Cow::Borrowed(command)
};

let mut cmd = Command::new(command.as_ref());

cmd.current_dir(working_directory);

if let Some(argument) = argument {
cmd.arg(argument);
}

cmd.arg(path);
Ok(cmd)
}
Expand Down
12 changes: 12 additions & 0 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2635,3 +2635,15 @@ test! {
status: 127,
shell: false,
}

#[cfg(windows)]
test! {
name: windows_interpreter_path_no_base
justfile: r#"
foo:
#!powershell
exit 0
"#,
args: (),
}

0 comments on commit 7e62ced

Please sign in to comment.