1 // Copyright (c) 2016, 2018 vergen developers
2 //
3 // Licensed under the Apache License, Version 2.0
4 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
5 // license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. All files in the project carrying such notice may not be copied,
7 // modified, or distributed except according to those terms.
8 
9 //! Output types
10 use crate::constants::*;
11 use chrono::Utc;
12 use std::collections::HashMap;
13 use std::env;
14 use std::error::Error;
15 use std::process::Command;
16 
17 //pub mod codegen;
18 pub mod envvar;
19 
generate_build_info( flags: ConstantsFlags, ) -> Result<HashMap<VergenKey, String>, Box<dyn Error>>20 pub fn generate_build_info(
21   flags: ConstantsFlags,
22 ) -> Result<HashMap<VergenKey, String>, Box<dyn Error>> {
23   let mut build_info = HashMap::new();
24   let now = Utc::now();
25 
26   if flags.contains(ConstantsFlags::BUILD_TIMESTAMP) {
27     build_info.insert(VergenKey::BuildTimestamp, now.to_rfc3339());
28   }
29 
30   if flags.contains(ConstantsFlags::BUILD_DATE) {
31     build_info
32       .insert(VergenKey::BuildDate, now.format("%Y-%m-%d").to_string());
33   }
34 
35   if flags.contains(ConstantsFlags::SHA) {
36     let sha = run_command(Command::new("git").args(&["rev-parse", "HEAD"]));
37     build_info.insert(VergenKey::Sha, sha);
38   }
39 
40   if flags.contains(ConstantsFlags::SHA_SHORT) {
41     let sha =
42       run_command(Command::new("git").args(&["rev-parse", "--short", "HEAD"]));
43     build_info.insert(VergenKey::ShortSha, sha);
44   }
45 
46   if flags.contains(ConstantsFlags::COMMIT_DATE) {
47     let commit_date = run_command(Command::new("git").args(&[
48       "log",
49       "--pretty=format:'%ad'",
50       "-n1",
51       "--date=short",
52     ]));
53     build_info.insert(
54       VergenKey::CommitDate,
55       commit_date.trim_matches('\'').to_string(),
56     );
57   }
58 
59   if flags.contains(ConstantsFlags::TARGET_TRIPLE) {
60     let target_triple =
61       env::var("TARGET").unwrap_or_else(|_| "UNKNOWN".to_string());
62     build_info.insert(VergenKey::TargetTriple, target_triple);
63   }
64 
65   if flags.contains(ConstantsFlags::SEMVER) {
66     let describe = run_command(Command::new("git").args(&["describe"]));
67 
68     let semver = if describe.eq_ignore_ascii_case("UNKNOWN") {
69       env::var("CARGO_PKG_VERSION")?
70     } else {
71       describe
72     };
73     build_info.insert(VergenKey::Semver, semver);
74   } else if flags.contains(ConstantsFlags::SEMVER_FROM_CARGO_PKG) {
75     build_info.insert(VergenKey::Semver, env::var("CARGO_PKG_VERSION")?);
76   }
77 
78   if flags.contains(ConstantsFlags::SEMVER_LIGHTWEIGHT) {
79     let describe =
80       run_command(Command::new("git").args(&["describe", "--tags"]));
81 
82     let semver = if describe.eq_ignore_ascii_case("UNKNOWN") {
83       env::var("CARGO_PKG_VERSION")?
84     } else {
85       describe
86     };
87     build_info.insert(VergenKey::SemverLightweight, semver);
88   }
89 
90   Ok(build_info)
91 }
92 
run_command(command: &mut Command) -> String93 fn run_command(command: &mut Command) -> String {
94   if let Ok(o) = command.output() {
95     if o.status.success() {
96       return String::from_utf8_lossy(&o.stdout).trim().to_owned();
97     }
98   }
99   "UNKNOWN".to_owned()
100 }
101 
102 /// Build information keys.
103 #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
104 pub enum VergenKey {
105   /// The build timestamp. (VERGEN_BUILD_TIMESTAMP)
106   BuildTimestamp,
107   /// The build date. (VERGEN_BUILD_DATE)
108   BuildDate,
109   /// The latest commit SHA. (VERGEN_SHA)
110   Sha,
111   /// The latest commit short SHA. (VERGEN_SHA_SHORT)
112   ShortSha,
113   /// The commit date. (VERGEN_COMMIT_DATE).
114   CommitDate,
115   /// The target triple. (VERGEN_TARGET_TRIPLE)
116   TargetTriple,
117   /// The semver version from the last git tag. (VERGEN_SEMVER)
118   Semver,
119   /// The semver version from the last git tag, including lightweight.
120   /// (VERGEN_SEMVER_LIGHTWEIGHT)
121   SemverLightweight,
122 }
123 
124 impl VergenKey {
125   /// Get the name for the given key.
name(self) -> &'static str126   pub fn name(self) -> &'static str {
127     match self {
128       VergenKey::BuildTimestamp => BUILD_TIMESTAMP_NAME,
129       VergenKey::BuildDate => BUILD_DATE_NAME,
130       VergenKey::Sha => SHA_NAME,
131       VergenKey::ShortSha => SHA_SHORT_NAME,
132       VergenKey::CommitDate => COMMIT_DATE_NAME,
133       VergenKey::TargetTriple => TARGET_TRIPLE_NAME,
134       VergenKey::Semver => SEMVER_NAME,
135       VergenKey::SemverLightweight => SEMVER_TAGS_NAME,
136     }
137   }
138 }
139 
140 #[cfg(test)]
141 mod test {}
142