build.rs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. //! This build script gets run during every build. Its purpose is to put
  2. //! together the files used for the `--help` and `--version`, which need to
  3. //! come in both coloured and non-coloured variants. The main usage text is
  4. //! contained in `src/usage.txt`; to make it easier to edit, backslashes (\)
  5. //! are used instead of the beginning of ANSI escape codes.
  6. //!
  7. //! The version string is quite complex: we want to show the version,
  8. //! current Git hash, and compilation date when building *debug*
  9. //! versions, but just the version for *release* versions.
  10. //!
  11. //! This script generates the string from the environment variables
  12. //! that Cargo adds (http://doc.crates.io/environment-variables.html)
  13. //! and runs `git` to get the SHA1 hash. It then writes the strings
  14. //! into files, which we can include during compilation.
  15. use std::env;
  16. use std::fs::File;
  17. use std::io::{self, Write};
  18. use std::path::PathBuf;
  19. use datetime::{LocalDateTime, ISO};
  20. use regex::Regex;
  21. /// The build script entry point.
  22. fn main() -> io::Result<()> {
  23. #![allow(clippy::write_with_newline)]
  24. let usage = include_str!("src/usage.txt");
  25. let tagline = "dog \\1;32m●\\0m command-line DNS client";
  26. let url = "https://dns.lookup.dog/";
  27. let ver = if is_development_version() {
  28. format!("{}\nv{} [{}] built on {} \\1;31m(pre-release!)\\0m\n\\1;4;34m{}\\0m", tagline, cargo_version(), git_hash(), build_date(), url)
  29. }
  30. else {
  31. format!("{}\nv{}\n\\1;4;34m{}\\0m", tagline, cargo_version(), url)
  32. };
  33. // We need to create these files in the Cargo output directory.
  34. let out = PathBuf::from(env::var("OUT_DIR").unwrap());
  35. // The bits .txt files contain ANSI escape codes, ish.
  36. let control_code = Regex::new(r##"\\.+?m"##).unwrap();
  37. // Pretty version text
  38. let mut f = File::create(&out.join("version.pretty.txt"))?;
  39. write!(f, "{}\n", ver.replace("\\", "\x1B["))?;
  40. // Bland version text
  41. let mut f = File::create(&out.join("version.bland.txt"))?;
  42. write!(f, "{}\n", control_code.replace_all(&ver, ""))?;
  43. // Pretty usage text
  44. let mut f = File::create(&out.join("usage.pretty.txt"))?;
  45. write!(f, "{}\n\n{}", tagline.replace("\\", "\x1B["), usage.replace("\\", "\x1B["))?;
  46. // Bland usage text
  47. let mut f = File::create(&out.join("usage.bland.txt"))?;
  48. write!(f, "{}\n\n{}", control_code.replace_all(tagline, ""), control_code.replace_all(usage, ""))?;
  49. Ok(())
  50. }
  51. /// Retrieve the project’s current Git hash, as a string.
  52. fn git_hash() -> String {
  53. use std::process::Command;
  54. String::from_utf8_lossy(
  55. &Command::new("git")
  56. .args(&["rev-parse", "--short", "HEAD"])
  57. .output().unwrap()
  58. .stdout).trim().to_string()
  59. }
  60. /// Whether we should show pre-release info in the version string.
  61. ///
  62. /// Both weekly releases and actual releases are --release releases,
  63. /// but actual releases will have a proper version number.
  64. fn is_development_version() -> bool {
  65. cargo_version().ends_with("-pre") || env::var("PROFILE").unwrap() == "debug"
  66. }
  67. /// Retrieves the [package] version in Cargo.toml as a string.
  68. fn cargo_version() -> String {
  69. env::var("CARGO_PKG_VERSION").unwrap()
  70. }
  71. /// Formats the current date as an ISO 8601 string.
  72. fn build_date() -> String {
  73. let now = LocalDateTime::now();
  74. format!("{}", now.date().iso())
  75. }