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
|
// 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 environment variables
|
||||||
export_env(&mut command, scope, exports)?;
|
export_env(&mut command, scope, exports)?;
|
||||||
@ -1300,6 +1301,7 @@ enum RunError<'a> {
|
|||||||
ArgumentCountMismatch{recipe: &'a str, found: usize, min: usize, max: usize},
|
ArgumentCountMismatch{recipe: &'a str, found: usize, min: usize, max: usize},
|
||||||
Backtick{token: Token<'a>, output_error: OutputError},
|
Backtick{token: Token<'a>, output_error: OutputError},
|
||||||
Code{recipe: &'a str, line_number: Option<usize>, code: i32},
|
Code{recipe: &'a str, line_number: Option<usize>, code: i32},
|
||||||
|
Cygpath{recipe: &'a str, output_error: OutputError},
|
||||||
InternalError{message: String},
|
InternalError{message: String},
|
||||||
IoError{recipe: &'a str, io_error: io::Error},
|
IoError{recipe: &'a str, io_error: io::Error},
|
||||||
Shebang{recipe: &'a str, command: String, argument: Option<String>, 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)?;
|
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} => {
|
Shebang{recipe, ref command, ref argument, ref io_error} => {
|
||||||
if let Some(ref argument) = *argument {
|
if let Some(ref argument) = *argument {
|
||||||
write!(f, "Recipe `{}` with shebang `#!{} {}` execution error: {}",
|
write!(f, "Recipe `{}` with shebang `#!{} {}` execution error: {}",
|
||||||
@ -1388,7 +1419,7 @@ impl<'a> Display for RunError<'a> {
|
|||||||
IoError{recipe, ref io_error} => {
|
IoError{recipe, ref io_error} => {
|
||||||
match io_error.kind() {
|
match io_error.kind() {
|
||||||
io::ErrorKind::NotFound => write!(f,
|
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),
|
recipe, io_error),
|
||||||
io::ErrorKind::PermissionDenied => write!(
|
io::ErrorKind::PermissionDenied => write!(
|
||||||
f, "Recipe `{}` could not be run because just could not run `sh`:\n{}",
|
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) => {
|
OutputError::Io(ref io_error) => {
|
||||||
match io_error.kind() {
|
match io_error.kind() {
|
||||||
io::ErrorKind::NotFound => write!(
|
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_error),
|
||||||
io::ErrorKind::PermissionDenied => write!(
|
io::ErrorKind::PermissionDenied => write!(
|
||||||
f, "Backtick could not be run because just could not run `sh`:\n{}", io_error),
|
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 {
|
pub trait PlatformInterface {
|
||||||
/// Construct a command equivelant to running the script at `path` with the
|
/// Construct a command equivelant to running the script at `path` with the
|
||||||
/// shebang line `shebang`
|
/// 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`
|
/// Set the execute permission on the file pointed to by `path`
|
||||||
fn set_execute_permission(path: &Path) -> Result<(), io::Error>;
|
fn set_execute_permission(path: &Path) -> Result<(), io::Error>;
|
||||||
@ -16,9 +17,11 @@ pub trait PlatformInterface {
|
|||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
impl PlatformInterface for Platform {
|
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
|
// 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> {
|
fn set_execute_permission(path: &Path) -> Result<(), io::Error> {
|
||||||
@ -43,28 +46,20 @@ impl PlatformInterface for Platform {
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
impl PlatformInterface for Platform {
|
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>)
|
||||||
let mut cmd = match env::var_os("EXEPATH") {
|
-> Result<process::Command, super::OutputError>
|
||||||
Some(exepath) => {
|
{
|
||||||
// On MinGW, `EXEPATH` is the root of the installation. Use it to
|
// Translate path to the interpreter from unix style to windows style
|
||||||
// construct a full windows path to the binary in the shebang line.
|
let mut cygpath = process::Command::new("cygpath");
|
||||||
let mut translated_command = PathBuf::from(exepath);
|
cygpath.arg("--windows");
|
||||||
for part in command.split("/") {
|
cygpath.arg(command);
|
||||||
translated_command.push(part);
|
|
||||||
}
|
let mut cmd = process::Command::new(super::output(cygpath)?);
|
||||||
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)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Some(argument) = argument {
|
if let Some(argument) = argument {
|
||||||
cmd.arg(argument);
|
cmd.arg(argument);
|
||||||
}
|
}
|
||||||
cmd.arg(path);
|
cmd.arg(path);
|
||||||
cmd
|
Ok(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_execute_permission(_path: &Path) -> Result<(), io::Error> {
|
fn set_execute_permission(_path: &Path) -> Result<(), io::Error> {
|
||||||
|
Loading…
Reference in New Issue
Block a user