about summary refs log tree commit diff
path: root/rustc_tools_util/src/lib.rs
blob: b2ec96122908fc3c566f1d58fb4b7522a891ffd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#![feature(tool_lints)]

use std::env;

#[macro_export]
macro_rules! get_version_info {
    () => {{
        let major = env!("CARGO_PKG_VERSION_MAJOR").parse::<u8>().unwrap();
        let minor = env!("CARGO_PKG_VERSION_MINOR").parse::<u8>().unwrap();
        let patch = env!("CARGO_PKG_VERSION_PATCH").parse::<u16>().unwrap();
        let crate_name = String::from(env!("CARGO_PKG_NAME"));

        let host_compiler = $crate::get_channel();
        let commit_hash = option_env!("GIT_HASH").map(|s| s.to_string());
        let commit_date = option_env!("COMMIT_DATE").map(|s| s.to_string());

        VersionInfo {
            major,
            minor,
            patch,
            host_compiler,
            commit_hash,
            commit_date,
            crate_name,
        }
    }};
}

// some code taken and adapted from RLS and cargo
pub struct VersionInfo {
    pub major: u8,
    pub minor: u8,
    pub patch: u16,
    pub host_compiler: Option<String>,
    pub commit_hash: Option<String>,
    pub commit_date: Option<String>,
    pub crate_name: String,
}

impl std::fmt::Display for VersionInfo {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self.commit_hash {
            Some(_) => {
                write!(
                    f,
                    "{} {}.{}.{} ({} {})",
                    self.crate_name,
                    self.major,
                    self.minor,
                    self.patch,
                    self.commit_hash.clone().unwrap_or_default().trim(),
                    self.commit_date.clone().unwrap_or_default().trim(),
                )?;
            },
            None => {
                write!(f, "{} {}.{}.{}", self.crate_name, self.major, self.minor, self.patch)?;
            },
        };
        Ok(())
    }
}

pub fn get_channel() -> Option<String> {
    if let Ok(channel) = env::var("CFG_RELEASE_CHANNEL") {
        Some(channel)
    } else {
        // we could ask ${RUSTC} -Vv and do some parsing and find out
        Some(String::from("nightly"))
    }
}

pub fn get_commit_hash() -> Option<String> {
    std::process::Command::new("git")
        .args(&["rev-parse", "--short", "HEAD"])
        .output()
        .ok()
        .and_then(|r| String::from_utf8(r.stdout).ok())
}

pub fn get_commit_date() -> Option<String> {
    std::process::Command::new("git")
        .args(&["log", "-1", "--date=short", "--pretty=format:%cd"])
        .output()
        .ok()
        .and_then(|r| String::from_utf8(r.stdout).ok())
}