Detailed changes
@@ -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<ExitStatus>;
+ 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<String>,
+ /// 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 {
@@ -5,7 +5,7 @@ use workspace::Workspace;
pub mod feedback_modal;
-mod system_specs;
+pub mod system_specs;
actions!(
zed,
@@ -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<AppCommitSha>,
+ 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<String> {
+ #[cfg(target_os = "linux")]
+ {
+ return std::process::Command::new("vulkaninfo")
+ .args(&["--summary"])
+ .output()
+ .ok()
+ .map(|output| {
+ [
+ "<details><summary>`vulkaninfo --summary` output</summary>",
+ "",
+ "```",
+ String::from_utf8_lossy(&output.stdout).as_ref(),
+ "```",
+ "</details>",
+ ]
+ .join("\n")
+ })
+ .or(Some("Failed to run `vulkaninfo --summary`".to_string()));
+ }
+ #[cfg(not(target_os = "linux"))]
+ {
+ return None;
+ }
+}
@@ -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<String>,
+ /// 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")]
@@ -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);
}
}