]> git.lizzy.rs Git - rust.git/blob - crates/rust-analyzer/build.rs
Merge #9762
[rust.git] / crates / rust-analyzer / build.rs
1 //! Construct version in the `commit-hash date chanel` format
2
3 use std::{env, path::PathBuf, process::Command};
4
5 fn main() {
6     set_rerun();
7     println!("cargo:rustc-env=REV={}", rev())
8 }
9
10 fn set_rerun() {
11     println!("cargo:rerun-if-env-changed=RUST_ANALYZER_REV");
12
13     let mut manifest_dir = PathBuf::from(
14         env::var("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` is always set by cargo."),
15     );
16
17     while manifest_dir.parent().is_some() {
18         let head_ref = manifest_dir.join(".git/HEAD");
19         if head_ref.exists() {
20             println!("cargo:rerun-if-changed={}", head_ref.display());
21             return;
22         }
23
24         manifest_dir.pop();
25     }
26
27     println!("cargo:warning=Could not find `.git/HEAD` from manifest dir!");
28 }
29
30 fn rev() -> String {
31     if let Ok(rev) = env::var("RUST_ANALYZER_REV") {
32         return rev;
33     }
34
35     if let Some(commit_hash) = commit_hash() {
36         let mut buf = commit_hash;
37
38         if let Some(date) = build_date() {
39             buf.push(' ');
40             buf.push_str(&date);
41         }
42
43         let channel = env::var("RUST_ANALYZER_CHANNEL").unwrap_or_else(|_| "dev".to_string());
44         buf.push(' ');
45         buf.push_str(&channel);
46
47         return buf;
48     }
49
50     "???????".to_string()
51 }
52
53 fn commit_hash() -> Option<String> {
54     exec("git rev-parse --short HEAD").ok()
55 }
56
57 fn build_date() -> Option<String> {
58     exec("date -u +%Y-%m-%d").ok()
59 }
60
61 fn exec(command: &str) -> std::io::Result<String> {
62     let args = command.split_ascii_whitespace().collect::<Vec<_>>();
63     let output = Command::new(args[0]).args(&args[1..]).output()?;
64     if !output.status.success() {
65         return Err(std::io::Error::new(
66             std::io::ErrorKind::InvalidData,
67             format!("command {:?} returned non-zero code", command,),
68         ));
69     }
70     let stdout = String::from_utf8(output.stdout)
71         .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
72     Ok(stdout.trim().to_string())
73 }