windows: Fix rust
tasks (#13413)
https://github.com/zed-industries/zed/assets/14981363/56c208da-132c-438a-92b3-e31505859262 Release Notes: - N/A
This commit is contained in:
parent
bdba8b23fa
commit
bef2586eed
3 changed files with 140 additions and 5 deletions
|
@ -575,12 +575,11 @@ fn retrieve_package_id_and_bin_name_from_metadata(
|
|||
metadata: CargoMetadata,
|
||||
abs_path: &Path,
|
||||
) -> Option<(String, String)> {
|
||||
let abs_path = abs_path.to_str()?;
|
||||
|
||||
for package in metadata.packages {
|
||||
for target in package.targets {
|
||||
let is_bin = target.kind.iter().any(|kind| kind == "bin");
|
||||
if target.src_path == abs_path && is_bin {
|
||||
let target_path = PathBuf::from(target.src_path);
|
||||
if target_path == abs_path && is_bin {
|
||||
return Some((package.id, target.name));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,6 +268,48 @@ pub enum Shell {
|
|||
},
|
||||
}
|
||||
|
||||
impl Shell {
|
||||
pub fn retrieve_system_shell() -> Option<String> {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
use anyhow::Context;
|
||||
use util::ResultExt;
|
||||
|
||||
return std::env::var("SHELL")
|
||||
.context("Error finding SHELL in env.")
|
||||
.log_err();
|
||||
}
|
||||
// `alacritty_terminal` uses this as default on Windows. See:
|
||||
// https://github.com/alacritty/alacritty/blob/0d4ab7bca43213d96ddfe40048fc0f922543c6f8/alacritty_terminal/src/tty/windows/mod.rs#L130
|
||||
#[cfg(target_os = "windows")]
|
||||
return Some("powershell".to_owned());
|
||||
}
|
||||
|
||||
/// Convert unix-shell variable syntax to windows-shell syntax.
|
||||
/// `powershell` and `cmd` are considered valid here.
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn to_windows_shell_variable(shell_type: WindowsShellType, input: String) -> String {
|
||||
match shell_type {
|
||||
WindowsShellType::Powershell => to_powershell_variable(input),
|
||||
WindowsShellType::Cmd => to_cmd_variable(input),
|
||||
WindowsShellType::Other => input,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn to_windows_shell_type(shell: &str) -> WindowsShellType {
|
||||
if shell == "powershell" || shell.ends_with("powershell.exe") {
|
||||
WindowsShellType::Powershell
|
||||
} else if shell == "cmd" || shell.ends_with("cmd.exe") {
|
||||
WindowsShellType::Cmd
|
||||
} else {
|
||||
// Someother shell detected, the user might install and use a
|
||||
// unix-like shell.
|
||||
WindowsShellType::Other
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AlternateScroll {
|
||||
|
@ -299,3 +341,55 @@ pub struct ToolbarContent {
|
|||
/// Default: true
|
||||
pub title: Option<bool>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum WindowsShellType {
|
||||
Powershell,
|
||||
Cmd,
|
||||
Other,
|
||||
}
|
||||
|
||||
/// Convert `${SOME_VAR}`, `$SOME_VAR` to `%SOME_VAR%`.
|
||||
#[inline]
|
||||
#[cfg(target_os = "windows")]
|
||||
fn to_cmd_variable(input: String) -> String {
|
||||
if let Some(var_str) = input.strip_prefix("${") {
|
||||
if var_str.find(':').is_none() {
|
||||
// If the input starts with "${", remove the trailing "}"
|
||||
format!("%{}%", &var_str[..var_str.len() - 1])
|
||||
} else {
|
||||
// `${SOME_VAR:-SOME_DEFAULT}`, we currently do not handle this situation,
|
||||
// which will result in the task failing to run in such cases.
|
||||
input
|
||||
}
|
||||
} else if let Some(var_str) = input.strip_prefix('$') {
|
||||
// If the input starts with "$", directly append to "$env:"
|
||||
format!("%{}%", var_str)
|
||||
} else {
|
||||
// If no prefix is found, return the input as is
|
||||
input
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert `${SOME_VAR}`, `$SOME_VAR` to `$env:SOME_VAR`.
|
||||
#[inline]
|
||||
#[cfg(target_os = "windows")]
|
||||
fn to_powershell_variable(input: String) -> String {
|
||||
if let Some(var_str) = input.strip_prefix("${") {
|
||||
if var_str.find(':').is_none() {
|
||||
// If the input starts with "${", remove the trailing "}"
|
||||
format!("$env:{}", &var_str[..var_str.len() - 1])
|
||||
} else {
|
||||
// `${SOME_VAR:-SOME_DEFAULT}`, we currently do not handle this situation,
|
||||
// which will result in the task failing to run in such cases.
|
||||
input
|
||||
}
|
||||
} else if let Some(var_str) = input.strip_prefix('$') {
|
||||
// If the input starts with "$", directly append to "$env:"
|
||||
format!("$env:{}", var_str)
|
||||
} else {
|
||||
// If no prefix is found, return the input as is
|
||||
input
|
||||
}
|
||||
}
|
||||
|
|
|
@ -350,24 +350,66 @@ impl TerminalPanel {
|
|||
let mut spawn_task = spawn_in_terminal.clone();
|
||||
// Set up shell args unconditionally, as tasks are always spawned inside of a shell.
|
||||
let Some((shell, mut user_args)) = (match TerminalSettings::get_global(cx).shell.clone() {
|
||||
Shell::System => std::env::var("SHELL").ok().map(|shell| (shell, Vec::new())),
|
||||
Shell::System => Shell::retrieve_system_shell().map(|shell| (shell, Vec::new())),
|
||||
Shell::Program(shell) => Some((shell, Vec::new())),
|
||||
Shell::WithArguments { program, args } => Some((program, args)),
|
||||
}) else {
|
||||
return;
|
||||
};
|
||||
#[cfg(target_os = "windows")]
|
||||
let windows_shell_type = Shell::to_windows_shell_type(&shell);
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
spawn_task.command_label = format!("{shell} -i -c `{}`", spawn_task.command_label);
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use terminal::terminal_settings::WindowsShellType;
|
||||
|
||||
match windows_shell_type {
|
||||
WindowsShellType::Powershell => {
|
||||
spawn_task.command_label = format!("{shell} -C `{}`", spawn_task.command_label)
|
||||
}
|
||||
WindowsShellType::Cmd => {
|
||||
spawn_task.command_label = format!("{shell} /C `{}`", spawn_task.command_label)
|
||||
}
|
||||
WindowsShellType::Other => {
|
||||
spawn_task.command_label =
|
||||
format!("{shell} -i -c `{}`", spawn_task.command_label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spawn_task.command_label = format!("{shell} -i -c `{}`", spawn_task.command_label);
|
||||
let task_command = std::mem::replace(&mut spawn_task.command, shell);
|
||||
let task_args = std::mem::take(&mut spawn_task.args);
|
||||
let combined_command = task_args
|
||||
.into_iter()
|
||||
.fold(task_command, |mut command, arg| {
|
||||
command.push(' ');
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
command.push_str(&arg);
|
||||
#[cfg(target_os = "windows")]
|
||||
command.push_str(&Shell::to_windows_shell_variable(windows_shell_type, arg));
|
||||
command
|
||||
});
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
user_args.extend(["-i".to_owned(), "-c".to_owned(), combined_command]);
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use terminal::terminal_settings::WindowsShellType;
|
||||
|
||||
match windows_shell_type {
|
||||
WindowsShellType::Powershell => {
|
||||
user_args.extend(["-C".to_owned(), combined_command])
|
||||
}
|
||||
WindowsShellType::Cmd => user_args.extend(["/C".to_owned(), combined_command]),
|
||||
WindowsShellType::Other => {
|
||||
user_args.extend(["-i".to_owned(), "-c".to_owned(), combined_command])
|
||||
}
|
||||
}
|
||||
}
|
||||
spawn_task.args = user_args;
|
||||
let spawn_task = spawn_task;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue