From c783fd072f8d4c1d97670099b9b51a8e6b14b607 Mon Sep 17 00:00:00 2001 From: Ben Kunkle Date: Fri, 21 Mar 2025 21:56:25 -0500 Subject: [PATCH] zed: Add `--system-specs` arg (#27285) Adds the `--system-specs` flag to the Zed binary, so that users who wish to report issues can retrieve their system specs, even if Zed is failing to launch Still TODO: - [x] Test and do best effort GPU info detection on Linux - [ ] Modify GitHub issue templates to tell users that the flag is available if they are unable to launch Zed Release Notes: - Added the `--system-specs` flag to the Zed binary (not the cli!), to retrieve the system specs we ask for in GitHub issues without needing to open Zed --- crates/cli/src/main.rs | 30 +++++++++++++ crates/feedback/src/feedback.rs | 2 +- crates/feedback/src/system_specs.rs | 69 ++++++++++++++++++++++++++--- crates/zed/src/main.rs | 15 +++++++ crates/zlog/src/zlog.rs | 1 - 5 files changed, 108 insertions(+), 9 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index c4451739dd..f18db8bac9 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -27,6 +27,7 @@ trait InstalledApp { fn zed_version_string(&self) -> String; fn launch(&self, ipc_url: String) -> anyhow::Result<()>; fn run_foreground(&self, ipc_url: String) -> io::Result; + fn path(&self) -> PathBuf; } #[derive(Parser, Debug)] @@ -73,6 +74,10 @@ struct Args { /// Run zed in dev-server mode #[arg(long)] dev_server_token: Option, + /// Not supported in Zed CLI, only supported on Zed binary + /// Will attempt to give the correct command to run + #[arg(long)] + system_specs: bool, /// Uninstall Zed from user system #[cfg(all( any(target_os = "linux", target_os = "macos"), @@ -140,6 +145,16 @@ fn main() -> Result<()> { return Ok(()); } + if args.system_specs { + let path = app.path(); + let msg = [ + "The `--system-specs` argument is not supported in the Zed CLI, only on Zed binary.", + "To retrieve the system specs on the command line, run the following command:", + &format!("{} --system-specs", path.display()), + ]; + return Err(anyhow::anyhow!(msg.join("\n"))); + } + #[cfg(all( any(target_os = "linux", target_os = "macos"), not(feature = "no-bundled-uninstall") @@ -437,6 +452,10 @@ mod linux { .arg(ipc_url) .status() } + + fn path(&self) -> PathBuf { + self.0.clone() + } } impl App { @@ -674,6 +693,10 @@ mod windows { .spawn()? .wait() } + + fn path(&self) -> PathBuf { + self.0.clone() + } } impl Detect { @@ -876,6 +899,13 @@ mod mac_os { std::process::Command::new(path).arg(ipc_url).status() } + + fn path(&self) -> PathBuf { + match self { + Bundle::App { app_bundle, .. } => app_bundle.join("Contents/MacOS/zed").clone(), + Bundle::LocalPath { executable, .. } => executable.clone(), + } + } } impl Bundle { diff --git a/crates/feedback/src/feedback.rs b/crates/feedback/src/feedback.rs index 0cfe9d3c21..69f98f8611 100644 --- a/crates/feedback/src/feedback.rs +++ b/crates/feedback/src/feedback.rs @@ -5,7 +5,7 @@ use workspace::Workspace; pub mod feedback_modal; -mod system_specs; +pub mod system_specs; actions!( zed, diff --git a/crates/feedback/src/system_specs.rs b/crates/feedback/src/system_specs.rs index 2d9a742140..c0919e1e16 100644 --- a/crates/feedback/src/system_specs.rs +++ b/crates/feedback/src/system_specs.rs @@ -1,5 +1,5 @@ use client::telemetry; -use gpui::{App, AppContext as _, Task, Window}; +use gpui::{App, AppContext as _, SemanticVersion, Task, Window}; use human_bytes::human_bytes; use release_channel::{AppCommitSha, AppVersion, ReleaseChannel}; use serde::Serialize; @@ -35,14 +35,12 @@ impl SystemSpecs { _ => None, }; - let gpu_specs = if let Some(specs) = window.gpu_specs() { - Some(format!( + let gpu_specs = window.gpu_specs().map(|specs| { + format!( "{} || {} || {}", specs.device_name, specs.driver_name, specs.driver_info - )) - } else { - None - }; + ) + }); cx.background_spawn(async move { let os_version = telemetry::os_version(); @@ -58,6 +56,37 @@ impl SystemSpecs { } }) } + + pub fn new_stateless( + app_version: SemanticVersion, + app_commit_sha: Option, + release_channel: ReleaseChannel, + ) -> Self { + let os_name = telemetry::os_name(); + let os_version = telemetry::os_version(); + let system = System::new_with_specifics( + RefreshKind::new().with_memory(MemoryRefreshKind::everything()), + ); + let memory = system.total_memory(); + let architecture = env::consts::ARCH; + let commit_sha = match release_channel { + ReleaseChannel::Dev | ReleaseChannel::Nightly => { + app_commit_sha.map(|sha| sha.0.clone()) + } + _ => None, + }; + + Self { + app_version: app_version.to_string(), + release_channel: release_channel.display_name(), + os_name, + os_version, + memory, + architecture, + commit_sha, + gpu_specs: try_determine_available_gpus(), + } + } } impl Display for SystemSpecs { @@ -94,3 +123,29 @@ impl Display for SystemSpecs { write!(f, "{system_specs}") } } + +fn try_determine_available_gpus() -> Option { + #[cfg(target_os = "linux")] + { + return std::process::Command::new("vulkaninfo") + .args(&["--summary"]) + .output() + .ok() + .map(|output| { + [ + "
`vulkaninfo --summary` output", + "", + "```", + String::from_utf8_lossy(&output.stdout).as_ref(), + "```", + "
", + ] + .join("\n") + }) + .or(Some("Failed to run `vulkaninfo --summary`".to_string())); + } + #[cfg(not(target_os = "linux"))] + { + return None; + } +} diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index dc883f8f1f..88fafd1abd 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -215,6 +215,16 @@ fn main() { session_id.clone(), ); + if args.system_specs { + let system_specs = feedback::system_specs::SystemSpecs::new_stateless( + app_version, + app_commit_sha.clone(), + *release_channel::RELEASE_CHANNEL, + ); + println!("Zed System Specs (from CLI):\n{}", system_specs); + return; + } + let (open_listener, mut open_rx) = OpenListener::new(); let failed_single_instance_check = if *db::ZED_STATELESS @@ -953,6 +963,11 @@ struct Args { #[arg(long)] dev_server_token: Option, + /// Prints system specs. Useful for submitting issues on GitHub when encountering a bug + /// that prevents Zed from starting, so you can't run `zed: copy system specs to clipboard` + #[arg(long)] + system_specs: bool, + /// Run zed in the foreground, only used on Windows, to match the behavior of the behavior on macOS. #[arg(long)] #[cfg(target_os = "windows")] diff --git a/crates/zlog/src/zlog.rs b/crates/zlog/src/zlog.rs index 3fbad6f4f3..1aeab2955a 100644 --- a/crates/zlog/src/zlog.rs +++ b/crates/zlog/src/zlog.rs @@ -400,7 +400,6 @@ pub mod scope_map { *map = Some(map_new.clone()); // note: hash update done here to ensure consistency with scope map } - eprintln!("Updated log scope settings :: map = {:?}", map_new); } }