about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-06-02 18:14:38 +0200
committerLukas Wirth <lukastw97@gmail.com>2022-06-02 18:36:02 +0200
commita2a3ea86eaafdc3bb6287e836a42deadcd02637b (patch)
tree639119066d199ed8d8a77ebca2b370ae30b78af7
parent88024c7ec2d44a8be8bf05a6580409200cf726fc (diff)
downloadrust-a2a3ea86eaafdc3bb6287e836a42deadcd02637b.tar.gz
rust-a2a3ea86eaafdc3bb6287e836a42deadcd02637b.zip
Bring the version command output in line with other rust tools
-rw-r--r--crates/rust-analyzer/build.rs67
-rw-r--r--crates/rust-analyzer/src/bin/main.rs6
-rw-r--r--crates/rust-analyzer/src/cli/lsif.rs3
-rw-r--r--crates/rust-analyzer/src/dispatch.rs5
-rw-r--r--crates/rust-analyzer/src/lib.rs28
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs2
-rw-r--r--crates/rust-analyzer/src/version.rs57
-rw-r--r--xtask/src/dist.rs3
8 files changed, 105 insertions, 66 deletions
diff --git a/crates/rust-analyzer/build.rs b/crates/rust-analyzer/build.rs
index 99780343fd2..292a7ad70ae 100644
--- a/crates/rust-analyzer/build.rs
+++ b/crates/rust-analyzer/build.rs
@@ -4,11 +4,14 @@ use std::{env, path::PathBuf, process::Command};
 
 fn main() {
     set_rerun();
-    println!("cargo:rustc-env=REV={}", rev());
+    set_commit_info();
+    if option_env!("CFG_RELEASE").is_none() {
+        println!("cargo:rustc-env=POKE_RA_DEVS=1");
+    }
 }
 
 fn set_rerun() {
-    println!("cargo:rerun-if-env-changed=RUST_ANALYZER_REV");
+    println!("cargo:rerun-if-env-changed=CFG_RELEASE");
 
     let mut manifest_dir = PathBuf::from(
         env::var("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` is always set by cargo."),
@@ -27,47 +30,21 @@ fn set_rerun() {
     println!("cargo:warning=Could not find `.git/HEAD` from manifest dir!");
 }
 
-fn rev() -> String {
-    if let Ok(rev) = env::var("RUST_ANALYZER_REV") {
-        return rev;
-    }
-
-    if let Some(commit_hash) = commit_hash() {
-        let mut buf = commit_hash;
-
-        if let Some(date) = build_date() {
-            buf.push(' ');
-            buf.push_str(&date);
-        }
-
-        let channel = env::var("RUST_ANALYZER_CHANNEL").unwrap_or_else(|_| "dev".to_string());
-        buf.push(' ');
-        buf.push_str(&channel);
-
-        return buf;
-    }
-
-    "???????".to_string()
-}
-
-fn commit_hash() -> Option<String> {
-    exec("git rev-parse --short HEAD").ok()
-}
-
-fn build_date() -> Option<String> {
-    exec("date -u +%Y-%m-%d").ok()
-}
-
-fn exec(command: &str) -> std::io::Result<String> {
-    let args = command.split_ascii_whitespace().collect::<Vec<_>>();
-    let output = Command::new(args[0]).args(&args[1..]).output()?;
-    if !output.status.success() {
-        return Err(std::io::Error::new(
-            std::io::ErrorKind::InvalidData,
-            format!("command {:?} returned non-zero code", command,),
-        ));
-    }
-    let stdout = String::from_utf8(output.stdout)
-        .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
-    Ok(stdout.trim().to_string())
+fn set_commit_info() {
+    let output = match Command::new("git")
+        .arg("log")
+        .arg("-1")
+        .arg("--date=short")
+        .arg("--format=%H %h %cd")
+        .output()
+    {
+        Ok(output) if output.status.success() => output,
+        _ => return,
+    };
+    let stdout = String::from_utf8(output.stdout).unwrap();
+    let mut parts = stdout.split_whitespace();
+    let mut next = || parts.next().unwrap();
+    println!("cargo:rustc-env=RA_COMMIT_HASH={}", next());
+    println!("cargo:rustc-env=RA_COMMIT_SHORT_HASH={}", next());
+    println!("cargo:rustc-env=RA_COMMIT_DATE={}", next())
 }
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index a9e79cc7c3e..fd155068616 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -70,7 +70,7 @@ fn try_main() -> Result<()> {
                 return Ok(());
             }
             if cmd.version {
-                println!("rust-analyzer {}", env!("REV"));
+                println!("rust-analyzer {}", rust_analyzer::version());
                 return Ok(());
             }
             if cmd.help {
@@ -150,7 +150,7 @@ fn with_extra_thread(
 }
 
 fn run_server() -> Result<()> {
-    tracing::info!("server version {} will start", env!("REV"));
+    tracing::info!("server version {} will start", rust_analyzer::version());
 
     let (connection, io_threads) = Connection::stdio();
 
@@ -192,7 +192,7 @@ fn run_server() -> Result<()> {
         capabilities: server_capabilities,
         server_info: Some(lsp_types::ServerInfo {
             name: String::from("rust-analyzer"),
-            version: Some(String::from(env!("REV"))),
+            version: Some(rust_analyzer::version().to_string()),
         }),
         offset_encoding: if supports_utf8(config.caps()) {
             Some("utf-8".to_string())
diff --git a/crates/rust-analyzer/src/cli/lsif.rs b/crates/rust-analyzer/src/cli/lsif.rs
index 5e6d2869877..491c55a04f8 100644
--- a/crates/rust-analyzer/src/cli/lsif.rs
+++ b/crates/rust-analyzer/src/cli/lsif.rs
@@ -22,6 +22,7 @@ use crate::cli::{
 };
 use crate::line_index::{LineEndings, LineIndex, OffsetEncoding};
 use crate::to_proto;
+use crate::version::version;
 
 /// Need to wrap Snapshot to provide `Clone` impl for `map_with`
 struct Snap<DB>(DB);
@@ -312,7 +313,7 @@ impl flags::Lsif {
             tool_info: Some(lsp_types::lsif::ToolInfo {
                 name: "rust-analyzer".to_string(),
                 args: vec![],
-                version: Some(env!("REV").to_string()),
+                version: Some(version().to_string()),
             }),
         }));
         for file in si.files {
diff --git a/crates/rust-analyzer/src/dispatch.rs b/crates/rust-analyzer/src/dispatch.rs
index 4d94630a564..f16559148e6 100644
--- a/crates/rust-analyzer/src/dispatch.rs
+++ b/crates/rust-analyzer/src/dispatch.rs
@@ -8,6 +8,7 @@ use serde::{de::DeserializeOwned, Serialize};
 use crate::{
     global_state::{GlobalState, GlobalStateSnapshot},
     main_loop::Task,
+    version::version,
     LspError, Result,
 };
 
@@ -144,7 +145,7 @@ impl<'a> RequestDispatcher<'a> {
         match res {
             Ok(params) => {
                 let panic_context =
-                    format!("\nversion: {}\nrequest: {} {:#?}", env!("REV"), R::METHOD, params);
+                    format!("\nversion: {}\nrequest: {} {:#?}", version(), R::METHOD, params);
                 Some((req, params, panic_context))
             }
             Err(err) => {
@@ -248,7 +249,7 @@ impl<'a> NotificationDispatcher<'a> {
         };
         let _pctx = stdx::panic_context::enter(format!(
             "\nversion: {}\nnotification: {}",
-            env!("REV"),
+            version(),
             N::METHOD
         ));
         f(self.global_state, params)?;
diff --git a/crates/rust-analyzer/src/lib.rs b/crates/rust-analyzer/src/lib.rs
index d5bc8f65f82..e04df7dea42 100644
--- a/crates/rust-analyzer/src/lib.rs
+++ b/crates/rust-analyzer/src/lib.rs
@@ -16,26 +16,28 @@ macro_rules! eprintln {
     ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
 }
 
-mod global_state;
-mod reload;
-mod main_loop;
-mod dispatch;
-mod handlers;
 mod caps;
 mod cargo_target_spec;
-mod to_proto;
-mod from_proto;
-mod semantic_tokens;
-mod markdown;
 mod diagnostics;
+mod diff;
+mod dispatch;
+mod from_proto;
+mod global_state;
+mod handlers;
 mod line_index;
 mod lsp_utils;
-mod task_pool;
+mod main_loop;
+mod markdown;
 mod mem_docs;
-mod diff;
 mod op_queue;
-pub mod lsp_ext;
+mod reload;
+mod semantic_tokens;
+mod task_pool;
+mod to_proto;
+mod version;
+
 pub mod config;
+pub mod lsp_ext;
 
 #[cfg(test)]
 mod integrated_benchmarks;
@@ -44,7 +46,7 @@ use std::fmt;
 
 use serde::de::DeserializeOwned;
 
-pub use crate::{caps::server_capabilities, main_loop::main_loop};
+pub use crate::{caps::server_capabilities, main_loop::main_loop, version::version};
 
 pub type Error = Box<dyn std::error::Error + Send + Sync>;
 pub type Result<T, E = Error> = std::result::Result<T, E>;
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs
index 22bab8fa820..5a37cbe2e33 100644
--- a/crates/rust-analyzer/src/lsp_utils.rs
+++ b/crates/rust-analyzer/src/lsp_utils.rs
@@ -74,7 +74,7 @@ impl GlobalState {
     /// panicky is a good idea, let's see if we can keep our awesome bleeding
     /// edge users from being upset!
     pub(crate) fn poke_rust_analyzer_developer(&mut self, message: String) {
-        let from_source_build = env!("REV").contains("dev");
+        let from_source_build = option_env!("POKE_RA_DEVS").is_some();
         let profiling_enabled = std::env::var("RA_PROFILE").is_ok();
         if from_source_build || profiling_enabled {
             self.show_message(lsp_types::MessageType::ERROR, message)
diff --git a/crates/rust-analyzer/src/version.rs b/crates/rust-analyzer/src/version.rs
new file mode 100644
index 00000000000..1e829299e6f
--- /dev/null
+++ b/crates/rust-analyzer/src/version.rs
@@ -0,0 +1,57 @@
+//! Code for representing rust-analyzer's release version number.
+
+use std::fmt;
+
+/// Information about the git repository where rust-analyzer was built from.
+pub struct CommitInfo {
+    pub short_commit_hash: &'static str,
+    pub commit_hash: &'static str,
+    pub commit_date: &'static str,
+}
+
+/// Cargo's version.
+pub struct VersionInfo {
+    /// rust-analyzer's version, such as "1.57.0", "1.58.0-beta.1", "1.59.0-nightly", etc.
+    pub version: &'static str,
+    /// The release channel we were built for (stable/beta/nightly/dev).
+    ///
+    /// `None` if not built via rustbuild.
+    pub release_channel: Option<&'static str>,
+    /// Information about the Git repository we may have been built from.
+    ///
+    /// `None` if not built from a git repo.
+    pub commit_info: Option<CommitInfo>,
+}
+
+impl fmt::Display for VersionInfo {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.version)?;
+
+        if let Some(ci) = &self.commit_info {
+            write!(f, " ({} {})", ci.short_commit_hash, ci.commit_date)?;
+        };
+        Ok(())
+    }
+}
+
+/// Returns information about cargo's version.
+pub const fn version() -> VersionInfo {
+    let version = match option_env!("CFG_RELEASE") {
+        Some(x) => x,
+        None => "0.0.0",
+    };
+
+    let release_channel = option_env!("CFG_RELEASE_CHANNEL");
+    let commit_info = match (
+        option_env!("RA_COMMIT_SHORT_HASH"),
+        option_env!("RA_COMMIT_HASH"),
+        option_env!("RA_COMMIT_DATE"),
+    ) {
+        (Some(short_commit_hash), Some(commit_hash), Some(commit_date)) => {
+            Some(CommitInfo { short_commit_hash, commit_hash, commit_date })
+        }
+        _ => None,
+    };
+
+    VersionInfo { version, release_channel, commit_info }
+}
diff --git a/xtask/src/dist.rs b/xtask/src/dist.rs
index 2ea452377ee..c82867d3b4d 100644
--- a/xtask/src/dist.rs
+++ b/xtask/src/dist.rs
@@ -72,7 +72,8 @@ fn dist_client(
 }
 
 fn dist_server(sh: &Shell, release_channel: &str, target: &Target) -> anyhow::Result<()> {
-    let _e = sh.push_env("RUST_ANALYZER_CHANNEL", release_channel);
+    let _e = sh.push_env("CFG_RELEASE_CHANNEL", release_channel);
+    let _e = sh.push_env("CFG_RELEASE", "0.0.0");
     let _e = sh.push_env("CARGO_PROFILE_RELEASE_LTO", "thin");
 
     // Uncomment to enable debug info for releases. Note that: