Use ShellKind::try_quote whenever we need to quote shell args (#41104)

Re-reverts
https://github.com/zed-industries/zed/commit/8f4646d6c357409cfc286104088b4d21f2bea851
with fixes

Release Notes:

- N/A
This commit is contained in:
Jakub Konka
2025-10-24 18:19:53 +02:00
committed by GitHub
parent f213f4bcc8
commit bcbc6a330e
22 changed files with 310 additions and 228 deletions
+26 -77
View File
@@ -3,7 +3,6 @@
mod adapter_schema;
mod debug_format;
mod serde_helpers;
mod shell_builder;
pub mod static_source;
mod task_template;
mod vscode_debug_format;
@@ -12,23 +11,22 @@ mod vscode_format;
use anyhow::Context as _;
use collections::{HashMap, HashSet, hash_map};
use gpui::SharedString;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::path::PathBuf;
use std::str::FromStr;
use util::get_system_shell;
pub use adapter_schema::{AdapterSchema, AdapterSchemas};
pub use debug_format::{
AttachRequest, BuildTaskDefinition, DebugRequest, DebugScenario, DebugTaskFile, LaunchRequest,
Request, TcpArgumentsTemplate, ZedDebugConfig,
};
pub use shell_builder::{ShellBuilder, ShellKind};
pub use task_template::{
DebugArgsRequest, HideStrategy, RevealStrategy, TaskTemplate, TaskTemplates,
substitute_variables_in_map, substitute_variables_in_str,
};
pub use util::shell::{Shell, ShellKind};
pub use util::shell_builder::ShellBuilder;
pub use vscode_debug_format::VsCodeDebugTaskFile;
pub use vscode_format::VsCodeTaskFile;
pub use zed_actions::RevealTarget;
@@ -318,81 +316,32 @@ pub struct TaskContext {
#[derive(Clone, Debug)]
pub struct RunnableTag(pub SharedString);
/// Shell configuration to open the terminal with.
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Hash)]
#[serde(rename_all = "snake_case")]
pub enum Shell {
/// Use the system's default terminal configuration in /etc/passwd
#[default]
System,
/// Use a specific program with no arguments.
Program(String),
/// Use a specific program with arguments.
WithArguments {
/// The program to run.
program: String,
/// The arguments to pass to the program.
args: Vec<String>,
/// An optional string to override the title of the terminal tab
title_override: Option<SharedString>,
},
pub fn shell_from_proto(proto: proto::Shell) -> anyhow::Result<Shell> {
let shell_type = proto.shell_type.context("invalid shell type")?;
let shell = match shell_type {
proto::shell::ShellType::System(_) => Shell::System,
proto::shell::ShellType::Program(program) => Shell::Program(program),
proto::shell::ShellType::WithArguments(program) => Shell::WithArguments {
program: program.program,
args: program.args,
title_override: None,
},
};
Ok(shell)
}
impl Shell {
pub fn program(&self) -> String {
match self {
Shell::Program(program) => program.clone(),
Shell::WithArguments { program, .. } => program.clone(),
Shell::System => get_system_shell(),
}
}
pub fn program_and_args(&self) -> (String, &[String]) {
match self {
Shell::Program(program) => (program.clone(), &[]),
Shell::WithArguments { program, args, .. } => (program.clone(), args),
Shell::System => (get_system_shell(), &[]),
}
}
pub fn shell_kind(&self, is_windows: bool) -> ShellKind {
match self {
Shell::Program(program) => ShellKind::new(program, is_windows),
Shell::WithArguments { program, .. } => ShellKind::new(program, is_windows),
Shell::System => ShellKind::system(),
}
}
pub fn from_proto(proto: proto::Shell) -> anyhow::Result<Self> {
let shell_type = proto.shell_type.context("invalid shell type")?;
let shell = match shell_type {
proto::shell::ShellType::System(_) => Self::System,
proto::shell::ShellType::Program(program) => Self::Program(program),
proto::shell::ShellType::WithArguments(program) => Self::WithArguments {
program: program.program,
args: program.args,
title_override: None,
},
};
Ok(shell)
}
pub fn to_proto(self) -> proto::Shell {
let shell_type = match self {
Shell::System => proto::shell::ShellType::System(proto::System {}),
Shell::Program(program) => proto::shell::ShellType::Program(program),
Shell::WithArguments {
program,
args,
title_override: _,
} => proto::shell::ShellType::WithArguments(proto::shell::WithArguments {
program,
args,
}),
};
proto::Shell {
shell_type: Some(shell_type),
}
pub fn shell_to_proto(shell: Shell) -> proto::Shell {
let shell_type = match shell {
Shell::System => proto::shell::ShellType::System(proto::System {}),
Shell::Program(program) => proto::shell::ShellType::Program(program),
Shell::WithArguments {
program,
args,
title_override: _,
} => proto::shell::ShellType::WithArguments(proto::shell::WithArguments { program, args }),
};
proto::Shell {
shell_type: Some(shell_type),
}
}