]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/rustc_tools_util/src/lib.rs
New upstream version 1.52.1+dfsg1
[rustc.git] / src / tools / clippy / rustc_tools_util / src / lib.rs
1 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
2
3 use std::env;
4
5 #[macro_export]
6 macro_rules! get_version_info {
7 () => {{
8 let major = env!("CARGO_PKG_VERSION_MAJOR").parse::<u8>().unwrap();
9 let minor = env!("CARGO_PKG_VERSION_MINOR").parse::<u8>().unwrap();
10 let patch = env!("CARGO_PKG_VERSION_PATCH").parse::<u16>().unwrap();
11 let crate_name = String::from(env!("CARGO_PKG_NAME"));
12
13 let host_compiler = option_env!("RUSTC_RELEASE_CHANNEL").map(str::to_string);
14 let commit_hash = option_env!("GIT_HASH").map(str::to_string);
15 let commit_date = option_env!("COMMIT_DATE").map(str::to_string);
16
17 VersionInfo {
18 major,
19 minor,
20 patch,
21 host_compiler,
22 commit_hash,
23 commit_date,
24 crate_name,
25 }
26 }};
27 }
28
29 // some code taken and adapted from RLS and cargo
30 pub struct VersionInfo {
31 pub major: u8,
32 pub minor: u8,
33 pub patch: u16,
34 pub host_compiler: Option<String>,
35 pub commit_hash: Option<String>,
36 pub commit_date: Option<String>,
37 pub crate_name: String,
38 }
39
40 impl std::fmt::Display for VersionInfo {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 let hash = self.commit_hash.clone().unwrap_or_default();
43 let hash_trimmed = hash.trim();
44
45 let date = self.commit_date.clone().unwrap_or_default();
46 let date_trimmed = date.trim();
47
48 if (hash_trimmed.len() + date_trimmed.len()) > 0 {
49 write!(
50 f,
51 "{} {}.{}.{} ({} {})",
52 self.crate_name, self.major, self.minor, self.patch, hash_trimmed, date_trimmed,
53 )?;
54 } else {
55 write!(f, "{} {}.{}.{}", self.crate_name, self.major, self.minor, self.patch)?;
56 }
57
58 Ok(())
59 }
60 }
61
62 impl std::fmt::Debug for VersionInfo {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 write!(
65 f,
66 "VersionInfo {{ crate_name: \"{}\", major: {}, minor: {}, patch: {}",
67 self.crate_name, self.major, self.minor, self.patch,
68 )?;
69 if self.commit_hash.is_some() {
70 write!(
71 f,
72 ", commit_hash: \"{}\", commit_date: \"{}\" }}",
73 self.commit_hash.clone().unwrap_or_default().trim(),
74 self.commit_date.clone().unwrap_or_default().trim()
75 )?;
76 } else {
77 write!(f, " }}")?;
78 }
79
80 Ok(())
81 }
82 }
83
84 #[must_use]
85 pub fn get_commit_hash() -> Option<String> {
86 std::process::Command::new("git")
87 .args(&["rev-parse", "--short", "HEAD"])
88 .output()
89 .ok()
90 .and_then(|r| String::from_utf8(r.stdout).ok())
91 }
92
93 #[must_use]
94 pub fn get_commit_date() -> Option<String> {
95 std::process::Command::new("git")
96 .args(&["log", "-1", "--date=short", "--pretty=format:%cd"])
97 .output()
98 .ok()
99 .and_then(|r| String::from_utf8(r.stdout).ok())
100 }
101
102 #[must_use]
103 pub fn get_channel() -> Option<String> {
104 match env::var("CFG_RELEASE_CHANNEL") {
105 Ok(channel) => Some(channel),
106 Err(_) => {
107 // if that failed, try to ask rustc -V, do some parsing and find out
108 match std::process::Command::new("rustc")
109 .arg("-V")
110 .output()
111 .ok()
112 .and_then(|r| String::from_utf8(r.stdout).ok())
113 {
114 Some(rustc_output) => {
115 if rustc_output.contains("beta") {
116 Some(String::from("beta"))
117 } else if rustc_output.contains("stable") {
118 Some(String::from("stable"))
119 } else {
120 // default to nightly if we fail to parse
121 Some(String::from("nightly"))
122 }
123 },
124 // default to nightly
125 None => Some(String::from("nightly")),
126 }
127 },
128 }
129 }
130
131 #[cfg(test)]
132 mod test {
133 use super::*;
134
135 #[test]
136 fn test_struct_local() {
137 let vi = get_version_info!();
138 assert_eq!(vi.major, 0);
139 assert_eq!(vi.minor, 2);
140 assert_eq!(vi.patch, 0);
141 assert_eq!(vi.crate_name, "rustc_tools_util");
142 // hard to make positive tests for these since they will always change
143 assert!(vi.commit_hash.is_none());
144 assert!(vi.commit_date.is_none());
145 }
146
147 #[test]
148 fn test_display_local() {
149 let vi = get_version_info!();
150 assert_eq!(vi.to_string(), "rustc_tools_util 0.2.0");
151 }
152
153 #[test]
154 fn test_debug_local() {
155 let vi = get_version_info!();
156 let s = format!("{:?}", vi);
157 assert_eq!(
158 s,
159 "VersionInfo { crate_name: \"rustc_tools_util\", major: 0, minor: 2, patch: 0 }"
160 );
161 }
162 }