diff --git a/crates/ruff/src/lib.rs b/crates/ruff/src/lib.rs index af7e0bc065..e91bb0354e 100644 --- a/crates/ruff/src/lib.rs +++ b/crates/ruff/src/lib.rs @@ -131,6 +131,7 @@ pub fn run( }: Args, ) -> Result { { + ruff_db::set_program_version(crate::version::version().to_string()).unwrap(); let default_panic_hook = std::panic::take_hook(); std::panic::set_hook(Box::new(move |info| { #[expect(clippy::print_stderr)] diff --git a/crates/ruff_db/src/lib.rs b/crates/ruff_db/src/lib.rs index b501956807..2a152ace72 100644 --- a/crates/ruff_db/src/lib.rs +++ b/crates/ruff_db/src/lib.rs @@ -28,6 +28,21 @@ pub use web_time::{Instant, SystemTime, SystemTimeError}; pub type FxDashMap = dashmap::DashMap>; pub type FxDashSet = dashmap::DashSet>; +static VERSION: std::sync::OnceLock = std::sync::OnceLock::new(); + +/// Returns the version of the executing program if set. +pub fn program_version() -> Option<&'static str> { + VERSION.get().map(|version| version.as_str()) +} + +/// Sets the version of the executing program. +/// +/// ## Errors +/// If the version has already been initialized (can only be set once). +pub fn set_program_version(version: String) -> Result<(), String> { + VERSION.set(version) +} + /// Most basic database that gives access to files, the host system, source code, and parsed AST. #[salsa::db] pub trait Db: salsa::Database { diff --git a/crates/ty/build.rs b/crates/ty/build.rs index 98df7eae01..1cb3dbc589 100644 --- a/crates/ty/build.rs +++ b/crates/ty/build.rs @@ -7,13 +7,25 @@ use std::{ fn main() { // The workspace root directory is not available without walking up the tree // https://github.com/rust-lang/cargo/issues/3946 - let workspace_root = Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()) - .join("..") + let ruff_workspace_root = Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()) .join("..") .join(".."); + let ty_workspace_root = ruff_workspace_root.join(".."); - version_info(&workspace_root); - commit_info(&workspace_root); + version_info(&ty_workspace_root); + + // If not in a git repository, do not attempt to retrieve commit information + let git_dir = ty_workspace_root.join(".git"); + if git_dir.exists() { + commit_info(&git_dir, &ty_workspace_root, false); + } else { + // Try if we're inside the ruff repository and, if so, use that commit hash. + let git_dir = ruff_workspace_root.join(".git"); + + if git_dir.exists() { + commit_info(&git_dir, &ruff_workspace_root, true); + } + } let target = std::env::var("TARGET").unwrap(); println!("cargo::rustc-env=RUST_HOST_TARGET={target}"); @@ -45,14 +57,8 @@ fn version_info(workspace_root: &Path) { } /// Retrieve commit information from the Git repository. -fn commit_info(workspace_root: &Path) { - // If not in a git repository, do not attempt to retrieve commit information - let git_dir = workspace_root.join(".git"); - if !git_dir.exists() { - return; - } - - if let Some(git_head_path) = git_head(&git_dir) { +fn commit_info(git_dir: &Path, workspace_root: &Path, is_ruff: bool) { + if let Some(git_head_path) = git_head(git_dir) { println!("cargo:rerun-if-changed={}", git_head_path.display()); let git_head_contents = fs::read_to_string(git_head_path); @@ -96,7 +102,10 @@ fn commit_info(workspace_root: &Path) { let mut describe_parts = describe.split('-'); let last_tag = describe_parts.next().unwrap(); - println!("cargo::rustc-env=TY_LAST_TAG={last_tag}"); + println!( + "cargo::rustc-env=TY_LAST_TAG={ruff}{last_tag}", + ruff = if is_ruff { "ruff/" } else { "" } + ); // If this is the tagged commit, this component will be missing println!( diff --git a/crates/ty/src/lib.rs b/crates/ty/src/lib.rs index 25f5085567..b9d7cbd8f9 100644 --- a/crates/ty/src/lib.rs +++ b/crates/ty/src/lib.rs @@ -33,6 +33,7 @@ use ty_server::run_server; pub fn run() -> anyhow::Result { setup_rayon(); + ruff_db::set_program_version(crate::version::version().to_string()).unwrap(); let args = wild::args_os(); let args = argfile::expand_args_from(args, argfile::parse_fromfile, argfile::PREFIX) diff --git a/crates/ty_project/src/lib.rs b/crates/ty_project/src/lib.rs index 79778d93fa..ffff0204f5 100644 --- a/crates/ty_project/src/lib.rs +++ b/crates/ty_project/src/lib.rs @@ -667,6 +667,13 @@ where arch = std::env::consts::ARCH ), )); + if let Some(version) = ruff_db::program_version() { + diagnostic.sub(SubDiagnostic::new( + Severity::Info, + format!("Version: {version}"), + )); + } + diagnostic.sub(SubDiagnostic::new( Severity::Info, format!( diff --git a/crates/ty_server/src/lib.rs b/crates/ty_server/src/lib.rs index 663565932c..f370e79c16 100644 --- a/crates/ty_server/src/lib.rs +++ b/crates/ty_server/src/lib.rs @@ -17,10 +17,6 @@ pub(crate) const DIAGNOSTIC_NAME: &str = "ty"; /// result type is needed. pub(crate) type Result = anyhow::Result; -pub(crate) fn version() -> &'static str { - env!("CARGO_PKG_VERSION") -} - pub fn run_server() -> anyhow::Result<()> { let four = NonZeroUsize::new(4).unwrap(); diff --git a/crates/ty_server/src/server.rs b/crates/ty_server/src/server.rs index 779564a88b..c4d5845f7e 100644 --- a/crates/ty_server/src/server.rs +++ b/crates/ty_server/src/server.rs @@ -57,12 +57,10 @@ impl Server { let server_capabilities = Self::server_capabilities(position_encoding, global_options.diagnostic_mode()); - let connection = connection.initialize_finish( - id, - &server_capabilities, - crate::SERVER_NAME, - crate::version(), - )?; + let version = ruff_db::program_version().unwrap_or("Unknown"); + + let connection = + connection.initialize_finish(id, &server_capabilities, crate::SERVER_NAME, version)?; // The number 32 was chosen arbitrarily. The main goal was to have enough capacity to queue // some responses before blocking. @@ -74,6 +72,8 @@ impl Server { global_options.tracing.log_file.as_deref(), ); + tracing::debug!("Version: {version}"); + let mut workspace_for_url = |url: Url| { let Some(workspace_settings) = workspace_options.as_mut() else { return (url, ClientOptions::default()); diff --git a/crates/ty_wasm/src/lib.rs b/crates/ty_wasm/src/lib.rs index 4533175828..4cf9662eaa 100644 --- a/crates/ty_wasm/src/lib.rs +++ b/crates/ty_wasm/src/lib.rs @@ -36,6 +36,8 @@ pub fn version() -> String { pub fn run() { use log::Level; + ruff_db::set_program_version(version()).unwrap(); + // When the `console_error_panic_hook` feature is enabled, we can call the // `set_panic_hook` function at least once during initialization, and then // we will get better error messages if our code ever panics.