mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 04:19:18 +00:00

Adds a new `ruff version` sub-command which displays long version information in the style of `cargo` and `rustc`. We include the number of commits since the last release tag if its a development build, in the style of Python's versioneer. ``` ❯ ruff version ruff 0.1.0+14 (947940e91 2023-10-18) ``` ``` ❯ ruff version --output-format json { "version": "0.1.0", "commit_info": { "short_commit_hash": "947940e91", "commit_hash": "947940e91269f20f6b3f8f8c7c63f8e914680e80", "commit_date": "2023-10-18", "last_tag": "v0.1.0", "commits_since_last_tag": 14 } }% ``` ``` ❯ cargo version cargo 1.72.1 (103a7ff2e 2023-08-15) ``` ## Test plan I've tested this manually locally, but want to at least add unit tests for the message formatting. We'd also want to check the next release to ensure the information is correct. I checked build behavior with a detached head and branches. ## Future work We could include rustc and cargo versions from the build, the current Python version, and other diagnostic information for bug reports. The `--version` and `-V` output is unchanged. However, we could update it to display the long ruff version without the rust and cargo versions (this is what cargo does). We'll need to be careful to ensure this does not break downstream packages which parse our version string. ``` ❯ ruff --version ruff 0.1.0 ``` The LSP should be updated to use `ruff version --output-format json` instead of parsing `ruff --version`.
80 lines
2.8 KiB
Rust
80 lines
2.8 KiB
Rust
use std::{fs, path::Path, process::Command};
|
|
|
|
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("..")
|
|
.join("..");
|
|
|
|
commit_info(&workspace_root);
|
|
|
|
#[allow(clippy::disallowed_methods)]
|
|
let target = std::env::var("TARGET").unwrap();
|
|
println!("cargo:rustc-env=RUST_HOST_TARGET={target}");
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
let git_head_path = git_dir.join("HEAD");
|
|
println!(
|
|
"cargo:rerun-if-changed={}",
|
|
git_head_path.as_path().display()
|
|
);
|
|
|
|
let git_head_contents = fs::read_to_string(git_head_path);
|
|
if let Ok(git_head_contents) = git_head_contents {
|
|
// The contents are either a commit or a reference in the following formats
|
|
// - "<commit>" when the head is detached
|
|
// - "ref <ref>" when working on a branch
|
|
// If a commit, checking if the HEAD file has changed is sufficient
|
|
// If a ref, we need to add the head file for that ref to rebuild on commit
|
|
let mut git_ref_parts = git_head_contents.split_whitespace();
|
|
git_ref_parts.next();
|
|
if let Some(git_ref) = git_ref_parts.next() {
|
|
let git_ref_path = git_dir.join(git_ref);
|
|
println!(
|
|
"cargo:rerun-if-changed={}",
|
|
git_ref_path.as_path().display()
|
|
);
|
|
}
|
|
}
|
|
|
|
let output = match Command::new("git")
|
|
.arg("log")
|
|
.arg("-1")
|
|
.arg("--date=short")
|
|
.arg("--abbrev=9")
|
|
.arg("--format=%H %h %cd %(describe)")
|
|
.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=RUFF_COMMIT_HASH={}", next());
|
|
println!("cargo:rustc-env=RUFF_COMMIT_SHORT_HASH={}", next());
|
|
println!("cargo:rustc-env=RUFF_COMMIT_DATE={}", next());
|
|
|
|
// Describe can fail for some commits
|
|
// https://git-scm.com/docs/pretty-formats#Documentation/pretty-formats.txt-emdescribeoptionsem
|
|
if let Some(describe) = parts.next() {
|
|
let mut describe_parts = describe.split('-');
|
|
println!(
|
|
"cargo:rustc-env=RUFF_LAST_TAG={}",
|
|
describe_parts.next().unwrap()
|
|
);
|
|
// If this is the tagged commit, this component will be missing
|
|
println!(
|
|
"cargo:rustc-env=RUFF_LAST_TAG_DISTANCE={}",
|
|
describe_parts.next().unwrap_or("0")
|
|
);
|
|
}
|
|
}
|