pub_just/
platform.rs

1use super::*;
2
3pub struct Platform;
4
5#[cfg(unix)]
6impl PlatformInterface for Platform {
7  fn make_shebang_command(
8    path: &Path,
9    working_directory: Option<&Path>,
10    _shebang: Shebang,
11  ) -> Result<Command, OutputError> {
12    // shebang scripts can be executed directly on unix
13    let mut command = Command::new(path);
14
15    if let Some(working_directory) = working_directory {
16      command.current_dir(working_directory);
17    }
18
19    Ok(command)
20  }
21
22  fn set_execute_permission(path: &Path) -> io::Result<()> {
23    use std::os::unix::fs::PermissionsExt;
24
25    // get current permissions
26    let mut permissions = fs::metadata(path)?.permissions();
27
28    // set the execute bit
29    let current_mode = permissions.mode();
30    permissions.set_mode(current_mode | 0o100);
31
32    // set the new permissions
33    fs::set_permissions(path, permissions)
34  }
35
36  fn signal_from_exit_status(exit_status: ExitStatus) -> Option<i32> {
37    use std::os::unix::process::ExitStatusExt;
38    exit_status.signal()
39  }
40
41  fn convert_native_path(_working_directory: &Path, path: &Path) -> FunctionResult {
42    path
43      .to_str()
44      .map(str::to_string)
45      .ok_or_else(|| String::from("Error getting current directory: unicode decode error"))
46  }
47}
48
49#[cfg(windows)]
50impl PlatformInterface for Platform {
51  fn make_shebang_command(
52    path: &Path,
53    working_directory: Option<&Path>,
54    shebang: Shebang,
55  ) -> Result<Command, OutputError> {
56    use std::borrow::Cow;
57
58    // If the path contains forward slashes…
59    let command = if shebang.interpreter.contains('/') {
60      // …translate path to the interpreter from unix style to windows style.
61      let mut cygpath = Command::new("cygpath");
62      if let Some(working_directory) = working_directory {
63        cygpath.current_dir(working_directory);
64      }
65      cygpath.arg("--windows");
66      cygpath.arg(shebang.interpreter);
67
68      Cow::Owned(output(cygpath)?)
69    } else {
70      // …otherwise use it as-is.
71      Cow::Borrowed(shebang.interpreter)
72    };
73
74    let mut cmd = Command::new(command.as_ref());
75
76    if let Some(working_directory) = working_directory {
77      cmd.current_dir(working_directory);
78    }
79
80    if let Some(argument) = shebang.argument {
81      cmd.arg(argument);
82    }
83
84    cmd.arg(path);
85    Ok(cmd)
86  }
87
88  fn set_execute_permission(_path: &Path) -> io::Result<()> {
89    // it is not necessary to set an execute permission on a script on windows, so
90    // this is a nop
91    Ok(())
92  }
93
94  fn signal_from_exit_status(_exit_status: process::ExitStatus) -> Option<i32> {
95    // The rust standard library does not expose a way to extract a signal from a
96    // windows process exit status, so just return None
97    None
98  }
99
100  fn convert_native_path(working_directory: &Path, path: &Path) -> FunctionResult {
101    // Translate path from windows style to unix style
102    let mut cygpath = Command::new("cygpath");
103    cygpath.current_dir(working_directory);
104    cygpath.arg("--unix");
105    cygpath.arg(path);
106
107    match output(cygpath) {
108      Ok(shell_path) => Ok(shell_path),
109      Err(_) => path
110        .to_str()
111        .map(str::to_string)
112        .ok_or_else(|| String::from("Error getting current directory: unicode decode error")),
113    }
114  }
115}