build.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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 =
  28. if is_debug_build() {
  29. format!("{}\nv{} \\1;31m(pre-release debug build!)\\0m\n\\1;4;34m{}\\0m", tagline, cargo_version(), url)
  30. }
  31. else if is_development_version() {
  32. format!("{}\nv{} [{}] built on {} \\1;31m(pre-release!)\\0m\n\\1;4;34m{}\\0m", tagline, cargo_version(), git_hash(), build_date(), url)
  33. }
  34. else {
  35. format!("{}\nv{}\n\\1;4;34m{}\\0m", tagline, cargo_version(), url)
  36. };
  37. // We need to create these files in the Cargo output directory.
  38. let out = PathBuf::from(env::var("OUT_DIR").unwrap());
  39. // The bits .txt files contain ANSI escape codes, ish.
  40. let control_code = Regex::new(r##"\\.+?m"##).unwrap();
  41. // Pretty version text
  42. let mut f = File::create(&out.join("version.pretty.txt"))?;
  43. write!(f, "{}\n", ver.replace("\\", "\x1B["))?;
  44. // Bland version text
  45. let mut f = File::create(&out.join("version.bland.txt"))?;
  46. write!(f, "{}\n", control_code.replace_all(&ver, ""))?;
  47. // Pretty usage text
  48. let mut f = File::create(&out.join("usage.pretty.txt"))?;
  49. write!(f, "{}\n\n{}", tagline.replace("\\", "\x1B["), usage.replace("\\", "\x1B["))?;
  50. // Bland usage text
  51. let mut f = File::create(&out.join("usage.bland.txt"))?;
  52. write!(f, "{}\n\n{}", control_code.replace_all(tagline, ""), control_code.replace_all(usage, ""))?;
  53. Ok(())
  54. }
  55. /// Retrieve the project’s current Git hash, as a string.
  56. fn git_hash() -> String {
  57. use std::process::Command;
  58. String::from_utf8_lossy(
  59. &Command::new("git")
  60. .args(&["rev-parse", "--short", "HEAD"])
  61. .output().unwrap()
  62. .stdout).trim().to_string()
  63. }
  64. /// Whether we should show pre-release info in the version string.
  65. ///
  66. /// Both weekly releases and actual releases are --release releases,
  67. /// but actual releases will have a proper version number.
  68. fn is_development_version() -> bool {
  69. cargo_version().ends_with("-pre") || env::var("PROFILE").unwrap() == "debug"
  70. }
  71. /// Whether we are building in debug mode.
  72. fn is_debug_build() -> bool {
  73. env::var("PROFILE").unwrap() == "debug"
  74. }
  75. /// Retrieves the [package] version in Cargo.toml as a string.
  76. fn cargo_version() -> String {
  77. env::var("CARGO_PKG_VERSION").unwrap()
  78. }
  79. /// Formats the current date as an ISO 8601 string.
  80. fn build_date() -> String {
  81. let now = LocalDateTime::now();
  82. format!("{}", now.date().iso())
  83. }