Use cygpath to translate paths on windows (#188)
I was previous doing it manually, which failed when running in powershell in a Github Desktop for windows. Use the `cygpath` utility instead.
This commit is contained in:
parent
832cf7b357
commit
165e7951af
37
src/lib.rs
37
src/lib.rs
@ -368,7 +368,8 @@ impl<'a> Recipe<'a> {
|
||||
})?;
|
||||
|
||||
// create a command to run the script
|
||||
let mut command = Platform::make_shebang_command(&path, shebang_command, shebang_argument);
|
||||
let mut command = Platform::make_shebang_command(&path, shebang_command, shebang_argument)
|
||||
.map_err(|output_error| RunError::Cygpath{recipe: self.name, output_error: output_error})?;
|
||||
|
||||
// export environment variables
|
||||
export_env(&mut command, scope, exports)?;
|
||||
@ -1300,6 +1301,7 @@ enum RunError<'a> {
|
||||
ArgumentCountMismatch{recipe: &'a str, found: usize, min: usize, max: usize},
|
||||
Backtick{token: Token<'a>, output_error: OutputError},
|
||||
Code{recipe: &'a str, line_number: Option<usize>, code: i32},
|
||||
Cygpath{recipe: &'a str, output_error: OutputError},
|
||||
InternalError{message: String},
|
||||
IoError{recipe: &'a str, io_error: io::Error},
|
||||
Shebang{recipe: &'a str, command: String, argument: Option<String>, io_error: io::Error},
|
||||
@ -1363,6 +1365,35 @@ impl<'a> Display for RunError<'a> {
|
||||
write!(f, "Recipe `{}` failed with exit code {}", recipe, code)?;
|
||||
}
|
||||
},
|
||||
Cygpath{recipe, ref output_error} => match *output_error {
|
||||
OutputError::Code(code) => {
|
||||
write!(f, "Cygpath failed with exit code {} while translating recipe `{}` \
|
||||
shebang interpreter path", code, recipe)?;
|
||||
}
|
||||
OutputError::Signal(signal) => {
|
||||
write!(f, "Cygpath terminated by signal {} while translating recipe `{}` \
|
||||
shebang interpreter path", signal, recipe)?;
|
||||
}
|
||||
OutputError::Unknown => {
|
||||
write!(f, "Cygpath experienced an unknown failure while translating recipe `{}` \
|
||||
shebang interpreter path", recipe)?;
|
||||
}
|
||||
OutputError::Io(ref io_error) => {
|
||||
match io_error.kind() {
|
||||
io::ErrorKind::NotFound => write!(
|
||||
f, "Could not find `cygpath` executable to translate recipe `{}` \
|
||||
shebang interpreter path:\n{}", recipe, io_error),
|
||||
io::ErrorKind::PermissionDenied => write!(
|
||||
f, "Could not run `cygpath` executable to translate recipe `{}` \
|
||||
shebang interpreter path:\n{}", recipe, io_error),
|
||||
_ => write!(f, "Could not run `cygpath` executable:\n{}", io_error),
|
||||
}?;
|
||||
}
|
||||
OutputError::Utf8(ref utf8_error) => {
|
||||
write!(f, "Cygpath successfully translated recipe `{}` shebang interpreter path, \
|
||||
but output was not utf8: {}", recipe, utf8_error)?;
|
||||
}
|
||||
},
|
||||
Shebang{recipe, ref command, ref argument, ref io_error} => {
|
||||
if let Some(ref argument) = *argument {
|
||||
write!(f, "Recipe `{}` with shebang `#!{} {}` execution error: {}",
|
||||
@ -1388,7 +1419,7 @@ impl<'a> Display for RunError<'a> {
|
||||
IoError{recipe, ref io_error} => {
|
||||
match io_error.kind() {
|
||||
io::ErrorKind::NotFound => write!(f,
|
||||
"Recipe `{}` could not be run because just could not find `sh` the command:\n{}",
|
||||
"Recipe `{}` could not be run because just could not find `sh`:\n{}",
|
||||
recipe, io_error),
|
||||
io::ErrorKind::PermissionDenied => write!(
|
||||
f, "Recipe `{}` could not be run because just could not run `sh`:\n{}",
|
||||
@ -1417,7 +1448,7 @@ impl<'a> Display for RunError<'a> {
|
||||
OutputError::Io(ref io_error) => {
|
||||
match io_error.kind() {
|
||||
io::ErrorKind::NotFound => write!(
|
||||
f, "Backtick could not be run because just could not find `sh` the command:\n{}",
|
||||
f, "Backtick could not be run because just could not find `sh`:\n{}",
|
||||
io_error),
|
||||
io::ErrorKind::PermissionDenied => write!(
|
||||
f, "Backtick could not be run because just could not run `sh`:\n{}", io_error),
|
||||
|
@ -5,7 +5,8 @@ pub struct Platform;
|
||||
pub trait PlatformInterface {
|
||||
/// Construct a command equivelant to running the script at `path` with the
|
||||
/// shebang line `shebang`
|
||||
fn make_shebang_command(path: &Path, command: &str, argument: Option<&str>) -> process::Command;
|
||||
fn make_shebang_command(path: &Path, command: &str, argument: Option<&str>)
|
||||
-> Result<process::Command, super::OutputError>;
|
||||
|
||||
/// Set the execute permission on the file pointed to by `path`
|
||||
fn set_execute_permission(path: &Path) -> Result<(), io::Error>;
|
||||
@ -16,9 +17,11 @@ pub trait PlatformInterface {
|
||||
|
||||
#[cfg(unix)]
|
||||
impl PlatformInterface for Platform {
|
||||
fn make_shebang_command(path: &Path, _command: &str, _argument: Option<&str>) -> process::Command {
|
||||
fn make_shebang_command(path: &Path, _command: &str, _argument: Option<&str>)
|
||||
-> Result<process::Command, super::OutputError>
|
||||
{
|
||||
// shebang scripts can be executed directly on unix
|
||||
process::Command::new(path)
|
||||
Ok(process::Command::new(path))
|
||||
}
|
||||
|
||||
fn set_execute_permission(path: &Path) -> Result<(), io::Error> {
|
||||
@ -43,28 +46,20 @@ impl PlatformInterface for Platform {
|
||||
|
||||
#[cfg(windows)]
|
||||
impl PlatformInterface for Platform {
|
||||
fn make_shebang_command(path: &Path, command: &str, argument: Option<&str>) -> process::Command {
|
||||
let mut cmd = match env::var_os("EXEPATH") {
|
||||
Some(exepath) => {
|
||||
// On MinGW, `EXEPATH` is the root of the installation. Use it to
|
||||
// construct a full windows path to the binary in the shebang line.
|
||||
let mut translated_command = PathBuf::from(exepath);
|
||||
for part in command.split("/") {
|
||||
translated_command.push(part);
|
||||
}
|
||||
process::Command::new(translated_command)
|
||||
}
|
||||
None => {
|
||||
// We're not on MinGW >_< The path in the shebang might be a windows
|
||||
// path, in which case it'll work, so just use it and hope for the best.
|
||||
process::Command::new(command)
|
||||
}
|
||||
};
|
||||
fn make_shebang_command(path: &Path, command: &str, argument: Option<&str>)
|
||||
-> Result<process::Command, super::OutputError>
|
||||
{
|
||||
// Translate path to the interpreter from unix style to windows style
|
||||
let mut cygpath = process::Command::new("cygpath");
|
||||
cygpath.arg("--windows");
|
||||
cygpath.arg(command);
|
||||
|
||||
let mut cmd = process::Command::new(super::output(cygpath)?);
|
||||
if let Some(argument) = argument {
|
||||
cmd.arg(argument);
|
||||
}
|
||||
cmd.arg(path);
|
||||
cmd
|
||||
Ok(cmd)
|
||||
}
|
||||
|
||||
fn set_execute_permission(_path: &Path) -> Result<(), io::Error> {
|
||||
|
Loading…
Reference in New Issue
Block a user