build.rs 3.3 KB

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