/src/tools/clippy/rustc_tools_util/src/lib.rs

https://gitlab.com/rust-lang/rust · Rust · 162 lines · 139 code · 18 blank · 5 comment · 12 complexity · 0152267ce8660f844fe45d33a315c531 MD5 · raw file

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