util: Use process spawn helpers in more places (#42976)

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Lukas Wirth
2025-11-18 14:31:39 +00:00
committed by GitHub
parent f1c2afdee0
commit 097024d46f
10 changed files with 53 additions and 37 deletions
+8 -7
View File
@@ -10,8 +10,8 @@ use paths::remote_servers_dir;
use release_channel::{AppCommitSha, ReleaseChannel};
use serde::{Deserialize, Serialize};
use settings::{RegisterSetting, Settings, SettingsStore};
use smol::fs::File;
use smol::{fs, io::AsyncReadExt};
use smol::{fs::File, process::Command};
use std::mem;
use std::{
env::{
@@ -23,6 +23,7 @@ use std::{
sync::Arc,
time::Duration,
};
use util::command::new_smol_command;
use workspace::Workspace;
const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification";
@@ -121,7 +122,7 @@ impl Drop for MacOsUnmounter<'_> {
let mount_path = mem::take(&mut self.mount_path);
self.background_executor
.spawn(async move {
let unmount_output = Command::new("hdiutil")
let unmount_output = new_smol_command("hdiutil")
.args(["detach", "-force"])
.arg(&mount_path)
.output()
@@ -799,7 +800,7 @@ async fn install_release_linux(
.await
.context("failed to create directory into which to extract update")?;
let output = Command::new("tar")
let output = new_smol_command("tar")
.arg("-xzf")
.arg(&downloaded_tar_gz)
.arg("-C")
@@ -834,7 +835,7 @@ async fn install_release_linux(
to = PathBuf::from(prefix);
}
let output = Command::new("rsync")
let output = new_smol_command("rsync")
.args(["-av", "--delete"])
.arg(&from)
.arg(&to)
@@ -866,7 +867,7 @@ async fn install_release_macos(
let mut mounted_app_path: OsString = mount_path.join(running_app_filename).into();
mounted_app_path.push("/");
let output = Command::new("hdiutil")
let output = new_smol_command("hdiutil")
.args(["attach", "-nobrowse"])
.arg(&downloaded_dmg)
.arg("-mountroot")
@@ -886,7 +887,7 @@ async fn install_release_macos(
background_executor: cx.background_executor(),
};
let output = Command::new("rsync")
let output = new_smol_command("rsync")
.args(["-av", "--delete"])
.arg(&mounted_app_path)
.arg(&running_app_path)
@@ -917,7 +918,7 @@ async fn cleanup_windows() -> Result<()> {
}
async fn install_release_windows(downloaded_installer: PathBuf) -> Result<Option<PathBuf>> {
let output = Command::new(downloaded_installer)
let output = new_smol_command(downloaded_installer)
.arg("/verysilent")
.arg("/update=true")
.arg("!desktopicon")
+3 -3
View File
@@ -1,7 +1,6 @@
use std::{
env,
path::{Path, PathBuf},
process::Command,
rc::Rc,
sync::Arc,
};
@@ -18,6 +17,7 @@ use anyhow::{Context as _, anyhow};
use calloop::{LoopSignal, channel::Channel};
use futures::channel::oneshot;
use util::ResultExt as _;
use util::command::{new_smol_command, new_std_command};
#[cfg(any(feature = "wayland", feature = "x11"))]
use xkbcommon::xkb::{self, Keycode, Keysym, State};
@@ -215,7 +215,7 @@ impl<P: LinuxClient + 'static> Platform for P {
clippy::disallowed_methods,
reason = "We are restarting ourselves, using std command thus is fine"
)]
let restart_process = Command::new("/usr/bin/env")
let restart_process = new_std_command("/usr/bin/env")
.arg("bash")
.arg("-c")
.arg(script)
@@ -422,7 +422,7 @@ impl<P: LinuxClient + 'static> Platform for P {
let path = path.to_owned();
self.background_executor()
.spawn(async move {
let _ = smol::process::Command::new("xdg-open")
let _ = new_smol_command("xdg-open")
.arg(path)
.spawn()
.context("invoking xdg-open")
+6 -4
View File
@@ -53,14 +53,16 @@ use std::{
ffi::{CStr, OsStr, c_void},
os::{raw::c_char, unix::ffi::OsStrExt},
path::{Path, PathBuf},
process::Command,
ptr,
rc::Rc,
slice, str,
sync::{Arc, OnceLock},
};
use strum::IntoEnumIterator;
use util::ResultExt;
use util::{
ResultExt,
command::{new_smol_command, new_std_command},
};
#[allow(non_upper_case_globals)]
const NSUTF8StringEncoding: NSUInteger = 4;
@@ -552,7 +554,7 @@ impl Platform for MacPlatform {
clippy::disallowed_methods,
reason = "We are restarting ourselves, using std command thus is fine"
)]
let restart_process = Command::new("/bin/bash")
let restart_process = new_std_command("/bin/bash")
.arg("-c")
.arg(script)
.arg(app_pid)
@@ -867,7 +869,7 @@ impl Platform for MacPlatform {
.lock()
.background_executor
.spawn(async move {
if let Some(mut child) = smol::process::Command::new("open")
if let Some(mut child) = new_smol_command("open")
.arg(path)
.spawn()
.context("invoking open command")
+7 -2
View File
@@ -67,10 +67,15 @@ impl RustLspAdapter {
#[cfg(target_os = "linux")]
async fn determine_libc_type() -> LibcType {
use futures::pin_mut;
use smol::process::Command;
async fn from_ldd_version() -> Option<LibcType> {
let ldd_output = Command::new("ldd").arg("--version").output().await.ok()?;
use util::command::new_smol_command;
let ldd_output = new_smol_command("ldd")
.arg("--version")
.output()
.await
.ok()?;
let ldd_version = String::from_utf8_lossy(&ldd_output.stdout);
if ldd_version.contains("GNU libc") || ldd_version.contains("GLIBC") {
@@ -3,13 +3,10 @@ use async_trait::async_trait;
use dap::{DapLocator, DebugRequest, adapters::DebugAdapterName};
use gpui::SharedString;
use serde_json::{Value, json};
use smol::{
Timer,
io::AsyncReadExt,
process::{Command, Stdio},
};
use smol::{Timer, io::AsyncReadExt, process::Stdio};
use std::time::Duration;
use task::{BuildTaskDefinition, DebugScenario, ShellBuilder, SpawnInTerminal, TaskTemplate};
use util::command::new_smol_command;
pub(crate) struct CargoLocator;
@@ -18,7 +15,7 @@ async fn find_best_executable(executables: &[String], test_name: &str) -> Option
return executables.first().cloned();
}
for executable in executables {
let Some(mut child) = Command::new(&executable)
let Some(mut child) = new_smol_command(&executable)
.arg("--list")
.stdout(Stdio::piped())
.spawn()
+2 -2
View File
@@ -6,7 +6,7 @@ use rpc::proto::{self, REMOTE_SERVER_PROJECT_ID};
use std::{collections::VecDeque, path::Path, sync::Arc};
use task::{Shell, shell_to_proto};
use terminal::terminal_settings::TerminalSettings;
use util::{ResultExt, rel_path::RelPath};
use util::{ResultExt, command::new_smol_command, rel_path::RelPath};
use worktree::Worktree;
use collections::HashMap;
@@ -389,7 +389,7 @@ async fn load_direnv_environment(
};
let args = &["export", "json"];
let direnv_output = smol::process::Command::new(&direnv_path)
let direnv_output = new_smol_command(&direnv_path)
.args(args)
.envs(env)
.env("TERM", "dumb")
+3 -3
View File
@@ -16,7 +16,7 @@ use task::{Shell, ShellBuilder, ShellKind, SpawnInTerminal};
use terminal::{
TaskState, TaskStatus, Terminal, TerminalBuilder, terminal_settings::TerminalSettings,
};
use util::{get_default_system_shell, maybe, rel_path::RelPath};
use util::{command::new_std_command, get_default_system_shell, maybe, rel_path::RelPath};
use crate::{Project, ProjectPath};
@@ -505,13 +505,13 @@ impl Project {
None,
None,
)?;
let mut command = std::process::Command::new(command_template.program);
let mut command = new_std_command(command_template.program);
command.args(command_template.args);
command.envs(command_template.env);
Ok(command)
}
None => {
let mut command = std::process::Command::new(command);
let mut command = new_std_command(command);
command.args(args);
command.envs(env);
if let Some(path) = path {
+14 -6
View File
@@ -124,6 +124,7 @@ async fn build_remote_server_from_source(
use smol::process::{Command, Stdio};
use std::env::VarError;
use std::path::Path;
use util::command::new_smol_command;
// By default, we make building remote server from source opt-out and we do not force artifact compression
// for quicker builds.
@@ -189,7 +190,7 @@ async fn build_remote_server_from_source(
delegate.set_status(Some("Building remote server binary from source"), cx);
log::info!("building remote server binary from source");
run_cmd(
Command::new("cargo")
new_smol_command("cargo")
.current_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/../.."))
.args([
"build",
@@ -219,12 +220,18 @@ async fn build_remote_server_from_source(
.context("rustup not found on $PATH, install rustup (see https://rustup.rs/)")?;
delegate.set_status(Some("Adding rustup target for cross-compilation"), cx);
log::info!("adding rustup target");
run_cmd(Command::new(rustup).args(["target", "add"]).arg(&triple)).await?;
run_cmd(
new_smol_command(rustup)
.args(["target", "add"])
.arg(&triple),
)
.await?;
if which("cargo-zigbuild", cx).await?.is_none() {
delegate.set_status(Some("Installing cargo-zigbuild for cross-compilation"), cx);
log::info!("installing cargo-zigbuild");
run_cmd(Command::new("cargo").args(["install", "--locked", "cargo-zigbuild"])).await?;
run_cmd(new_smol_command("cargo").args(["install", "--locked", "cargo-zigbuild"]))
.await?;
}
delegate.set_status(
@@ -235,7 +242,7 @@ async fn build_remote_server_from_source(
);
log::info!("building remote binary from source for {triple} with Zig");
run_cmd(
Command::new("cargo")
new_smol_command("cargo")
.args([
"zigbuild",
"--package",
@@ -262,12 +269,13 @@ async fn build_remote_server_from_source(
#[cfg(not(target_os = "windows"))]
{
run_cmd(Command::new("gzip").args(["-f", &bin_path.to_string_lossy()])).await?;
run_cmd(new_smol_command("gzip").args(["-f", &bin_path.to_string_lossy()])).await?;
}
#[cfg(target_os = "windows")]
{
// On Windows, we use 7z to compress the binary
let seven_zip = which("7z.exe",cx)
.await?
.context("7z.exe not found on $PATH, install it (e.g. with `winget install -e --id 7zip.7zip`) or, if you don't want this behaviour, set $env:ZED_BUILD_REMOTE_SERVER=\"nocompress\"")?;
@@ -275,7 +283,7 @@ async fn build_remote_server_from_source(
if smol::fs::metadata(&gz_path).await.is_ok() {
smol::fs::remove_file(&gz_path).await?;
}
run_cmd(Command::new(seven_zip).args([
run_cmd(new_smol_command(seven_zip).args([
"a",
"-tgzip",
&gz_path,
+4 -3
View File
@@ -16,6 +16,7 @@ use language::LanguageRegistry;
use node_runtime::{NodeBinaryOptions, NodeRuntime};
use paths::logs_dir;
use project::project_settings::ProjectSettings;
use util::command::new_smol_command;
use proto::CrashReport;
use release_channel::{AppVersion, RELEASE_CHANNEL, ReleaseChannel};
@@ -656,7 +657,7 @@ pub(crate) fn execute_proxy(
async fn kill_running_server(pid: u32, paths: &ServerPaths) -> Result<(), ExecuteProxyError> {
log::info!("killing existing server with PID {}", pid);
smol::process::Command::new("kill")
new_smol_command("kill")
.arg(pid.to_string())
.output()
.await
@@ -707,7 +708,7 @@ async fn spawn_server(paths: &ServerPaths) -> Result<(), SpawnServerError> {
}
let binary_name = std::env::current_exe().map_err(SpawnServerError::CurrentExe)?;
let mut server_process = smol::process::Command::new(binary_name);
let mut server_process = new_smol_command(binary_name);
server_process
.arg("run")
.arg("--log-file")
@@ -772,7 +773,7 @@ async fn check_pid_file(path: &Path) -> Result<Option<u32>, CheckPidError> {
};
log::debug!("Checking if process with PID {} exists...", pid);
match smol::process::Command::new("kill")
match new_smol_command("kill")
.arg("-0")
.arg(pid.to_string())
.output()
+3 -1
View File
@@ -34,11 +34,13 @@ async fn capture_unix(
) -> Result<collections::HashMap<String, String>> {
use std::os::unix::process::CommandExt;
use crate::command::new_std_command;
let shell_kind = ShellKind::new(shell_path, false);
let zed_path = super::get_shell_safe_zed_path(shell_kind)?;
let mut command_string = String::new();
let mut command = std::process::Command::new(shell_path);
let mut command = new_std_command(shell_path);
command.args(args);
// In some shells, file descriptors greater than 2 cannot be used in interactive mode,
// so file descriptor 0 (stdin) is used instead. This impacts zsh, old bash; perhaps others.