mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-01 04:18:20 +00:00
Add version command to proc-macro-srv
This commit is contained in:
parent
218e00d0bb
commit
87625cc166
4 changed files with 139 additions and 18 deletions
|
|
@ -63,16 +63,25 @@ impl ProcMacroServerProcess {
|
|||
let mut srv = create_srv()?;
|
||||
tracing::info!("sending proc-macro server version check");
|
||||
match srv.version_check() {
|
||||
Ok(v) if v > version::CURRENT_API_VERSION => Err(io::Error::other(
|
||||
format!( "The version of the proc-macro server ({v}) in your Rust toolchain is newer than the version supported by your rust-analyzer ({}).
|
||||
This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain."
|
||||
,version::CURRENT_API_VERSION
|
||||
),
|
||||
)),
|
||||
Ok(v) if v > version::CURRENT_API_VERSION => {
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let process_version = Command::new(process_path)
|
||||
.arg("--version")
|
||||
.output()
|
||||
.map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned())
|
||||
.unwrap_or_else(|_| "unknown version".to_owned());
|
||||
Err(io::Error::other(format!(
|
||||
"Your installed proc-macro server is too new for your rust-analyzer. API version: {}, server version: {process_version}. \
|
||||
This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain.",
|
||||
version::CURRENT_API_VERSION
|
||||
)))
|
||||
}
|
||||
Ok(v) => {
|
||||
tracing::info!("Proc-macro server version: {v}");
|
||||
srv.version = v;
|
||||
if srv.version >= version::RUST_ANALYZER_SPAN_SUPPORT && let Ok(mode) = srv.enable_rust_analyzer_spans() {
|
||||
if srv.version >= version::RUST_ANALYZER_SPAN_SUPPORT
|
||||
&& let Ok(mode) = srv.enable_rust_analyzer_spans()
|
||||
{
|
||||
srv.protocol = Protocol::LegacyJson { mode };
|
||||
}
|
||||
tracing::info!("Proc-macro server protocol: {:?}", srv.protocol);
|
||||
|
|
@ -80,9 +89,7 @@ impl ProcMacroServerProcess {
|
|||
}
|
||||
Err(e) => {
|
||||
tracing::info!(%e, "proc-macro version check failed");
|
||||
Err(
|
||||
io::Error::other(format!("proc-macro server version check failed: {e}")),
|
||||
)
|
||||
Err(io::Error::other(format!("proc-macro server version check failed: {e}")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,49 @@
|
|||
//! This teaches cargo about our cfg(rust_analyzer)
|
||||
//! Construct version in the `commit-hash date channel` format
|
||||
|
||||
use std::{env, path::PathBuf, process::Command};
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rustc-check-cfg=cfg(rust_analyzer)");
|
||||
set_rerun();
|
||||
set_commit_info();
|
||||
println!("cargo::rustc-check-cfg=cfg(rust_analyzer)");
|
||||
}
|
||||
|
||||
fn set_rerun() {
|
||||
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."),
|
||||
);
|
||||
|
||||
while manifest_dir.parent().is_some() {
|
||||
let head_ref = manifest_dir.join(".git/HEAD");
|
||||
if head_ref.exists() {
|
||||
println!("cargo:rerun-if-changed={}", head_ref.display());
|
||||
return;
|
||||
}
|
||||
|
||||
manifest_dir.pop();
|
||||
}
|
||||
|
||||
println!("cargo:warning=Could not find `.git/HEAD` from manifest dir!");
|
||||
}
|
||||
|
||||
fn set_commit_info() {
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@
|
|||
//! Driver for proc macro server
|
||||
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
|
||||
#![cfg_attr(not(feature = "sysroot-abi"), allow(unused_crate_dependencies))]
|
||||
#![allow(clippy::print_stderr)]
|
||||
#![allow(clippy::print_stdout, clippy::print_stderr)]
|
||||
|
||||
#[cfg(feature = "in-rust-tree")]
|
||||
extern crate rustc_driver as _;
|
||||
|
||||
mod version;
|
||||
|
||||
#[cfg(any(feature = "sysroot-abi", rust_analyzer))]
|
||||
mod main_loop;
|
||||
use clap::{Command, ValueEnum};
|
||||
|
|
@ -25,12 +27,22 @@ fn main() -> std::io::Result<()> {
|
|||
std::process::exit(122);
|
||||
}
|
||||
let matches = Command::new("proc-macro-srv")
|
||||
.args(&[clap::Arg::new("format")
|
||||
.args(&[
|
||||
clap::Arg::new("format")
|
||||
.long("format")
|
||||
.action(clap::ArgAction::Set)
|
||||
.default_value("json")
|
||||
.value_parser(clap::builder::EnumValueParser::<ProtocolFormat>::new())])
|
||||
.value_parser(clap::builder::EnumValueParser::<ProtocolFormat>::new()),
|
||||
clap::Arg::new("version")
|
||||
.long("version")
|
||||
.action(clap::ArgAction::SetTrue)
|
||||
.help("Prints the version of the proc-macro-srv"),
|
||||
])
|
||||
.get_matches();
|
||||
if matches.get_flag("version") {
|
||||
println!("rust-analyzer-proc-macro-srv {}", version::version());
|
||||
return Ok(());
|
||||
}
|
||||
let &format =
|
||||
matches.get_one::<ProtocolFormat>("format").expect("format value should always be present");
|
||||
run(format)
|
||||
|
|
|
|||
58
crates/proc-macro-srv-cli/src/version.rs
Normal file
58
crates/proc-macro-srv-cli/src/version.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//! Code for representing rust-analyzer's release version number.
|
||||
#![expect(dead_code)]
|
||||
|
||||
use std::fmt;
|
||||
|
||||
/// Information about the git repository where rust-analyzer was built from.
|
||||
pub(crate) struct CommitInfo {
|
||||
pub(crate) short_commit_hash: &'static str,
|
||||
pub(crate) commit_hash: &'static str,
|
||||
pub(crate) commit_date: &'static str,
|
||||
}
|
||||
|
||||
/// Cargo's version.
|
||||
pub(crate) struct VersionInfo {
|
||||
/// rust-analyzer's version, such as "1.57.0", "1.58.0-beta.1", "1.59.0-nightly", etc.
|
||||
pub(crate) version: &'static str,
|
||||
/// The release channel we were built for (stable/beta/nightly/dev).
|
||||
///
|
||||
/// `None` if not built via bootstrap.
|
||||
pub(crate) 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(crate) 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(crate) 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 }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue