mirror of
https://github.com/nushell/nushell.git
synced 2025-05-20 18:00:49 +02:00
allow powershell scripts in the path to be executed (#15760)
# Description This PR fixes a bug where powershell scripts were only allowed to be executed if they were in the directory that you executed them from. This fix allows the scripts to be anywhere in the path. closes #15759 # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. -->
This commit is contained in:
parent
3d62753e80
commit
8c2b1a22d4
@ -110,46 +110,47 @@ impl Command for External {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// let's make sure it's a .ps1 script, but only on Windows
|
// let's make sure it's a .ps1 script, but only on Windows
|
||||||
let potential_powershell_script = if cfg!(windows) {
|
let (potential_powershell_script, path_to_ps1_executable) = if cfg!(windows) {
|
||||||
if let Some(executable) = which(&expanded_name, "", cwd.as_ref()) {
|
if let Some(executable) = which(&expanded_name, &paths, cwd.as_ref()) {
|
||||||
let ext = executable
|
let ext = executable
|
||||||
.extension()
|
.extension()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_uppercase();
|
.to_uppercase();
|
||||||
ext == "PS1"
|
(ext == "PS1", Some(executable))
|
||||||
} else {
|
} else {
|
||||||
false
|
(false, None)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
(false, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Find the absolute path to the executable. On Windows, set the
|
// Find the absolute path to the executable. On Windows, set the
|
||||||
// executable to "cmd.exe" if it's a CMD internal command. If the
|
// executable to "cmd.exe" if it's a CMD internal command. If the
|
||||||
// command is not found, display a helpful error message.
|
// command is not found, display a helpful error message.
|
||||||
let executable =
|
let executable = if cfg!(windows)
|
||||||
if cfg!(windows) && (is_cmd_internal_command(&name_str) || pathext_script_in_windows) {
|
&& (is_cmd_internal_command(&name_str) || pathext_script_in_windows)
|
||||||
PathBuf::from("cmd.exe")
|
{
|
||||||
} else if cfg!(windows) && potential_powershell_script {
|
PathBuf::from("cmd.exe")
|
||||||
// If we're on Windows and we're trying to run a PowerShell script, we'll use
|
} else if cfg!(windows) && potential_powershell_script && path_to_ps1_executable.is_some() {
|
||||||
// `powershell.exe` to run it. We shouldn't have to check for powershell.exe because
|
// If we're on Windows and we're trying to run a PowerShell script, we'll use
|
||||||
// it's automatically installed on all modern windows systems.
|
// `powershell.exe` to run it. We shouldn't have to check for powershell.exe because
|
||||||
PathBuf::from("powershell.exe")
|
// it's automatically installed on all modern windows systems.
|
||||||
} else {
|
PathBuf::from("powershell.exe")
|
||||||
// Determine the PATH to be used and then use `which` to find it - though this has no
|
} else {
|
||||||
// effect if it's an absolute path already
|
// Determine the PATH to be used and then use `which` to find it - though this has no
|
||||||
let Some(executable) = which(&expanded_name, &paths, cwd.as_ref()) else {
|
// effect if it's an absolute path already
|
||||||
return Err(command_not_found(
|
let Some(executable) = which(&expanded_name, &paths, cwd.as_ref()) else {
|
||||||
&name_str,
|
return Err(command_not_found(
|
||||||
call.head,
|
&name_str,
|
||||||
engine_state,
|
call.head,
|
||||||
stack,
|
engine_state,
|
||||||
&cwd,
|
stack,
|
||||||
));
|
&cwd,
|
||||||
};
|
));
|
||||||
executable
|
|
||||||
};
|
};
|
||||||
|
executable
|
||||||
|
};
|
||||||
|
|
||||||
// Create the command.
|
// Create the command.
|
||||||
let mut command = std::process::Command::new(&executable);
|
let mut command = std::process::Command::new(&executable);
|
||||||
@ -174,20 +175,10 @@ impl Command for External {
|
|||||||
command.raw_arg(escape_cmd_argument(arg)?);
|
command.raw_arg(escape_cmd_argument(arg)?);
|
||||||
}
|
}
|
||||||
} else if potential_powershell_script {
|
} else if potential_powershell_script {
|
||||||
use nu_path::canonicalize_with;
|
command.args([
|
||||||
|
"-Command",
|
||||||
// canonicalize the path to the script so that tests pass
|
&path_to_ps1_executable.unwrap_or_default().to_string_lossy(),
|
||||||
let canon_path = if let Ok(cwd) = engine_state.cwd_as_string(None) {
|
]);
|
||||||
canonicalize_with(&expanded_name, cwd).map_err(|err| {
|
|
||||||
IoError::new(err.kind(), call.head, PathBuf::from(&expanded_name))
|
|
||||||
})?
|
|
||||||
} else {
|
|
||||||
// If we can't get the current working directory, just provide the expanded name
|
|
||||||
expanded_name
|
|
||||||
};
|
|
||||||
// The -Command flag followed by a script name instructs PowerShell to
|
|
||||||
// execute that script and quit.
|
|
||||||
command.args(["-Command", &canon_path.to_string_lossy()]);
|
|
||||||
for arg in &args {
|
for arg in &args {
|
||||||
command.raw_arg(arg.item.clone());
|
command.raw_arg(arg.item.clone());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user