Skip to main content

cdk_ansible_cli/
version.rs

1use core::fmt;
2use serde::Serialize;
3
4#[derive(Serialize)]
5/// Information about the git commit we may have been built from.
6pub struct CommitInfo {
7    /// The short commit hash.
8    short_commit_hash: String,
9    /// The commit hash.
10    commit_hash: String,
11    /// The commit date.
12    commit_date: String,
13    /// The last tag.
14    last_tag: Option<String>,
15    /// The number of commits since the last tag.
16    commits_since_last_tag: u32,
17    /// Whether the build time repo is dirty.
18    is_dirty: bool,
19}
20
21#[derive(Serialize)]
22pub struct VersionInfo {
23    /// version, such as "1.2.3".
24    version: String,
25    /// Information about the git commit we may have been built from.
26    ///
27    /// `None` if not built from a git repo or if retrieval failed.
28    commit_info: Option<CommitInfo>,
29}
30
31impl fmt::Display for VersionInfo {
32    /// Formatted version information: "<version>[+<commits>] (<commit> <date>)".
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        write!(f, "{}", self.version)?;
35
36        if let Some(ci) = self.commit_info.as_ref() {
37            if ci.commits_since_last_tag > 0 {
38                write!(f, "+{}", ci.commits_since_last_tag)?;
39            }
40            if ci.is_dirty {
41                write!(f, "-dirty")?;
42            }
43            write!(f, " ({} {})", ci.short_commit_hash, ci.commit_date)?;
44        }
45
46        Ok(())
47    }
48}
49
50/// Return the application version.
51///
52/// note: this function returns the version of `cdk-ansible-cli` crate
53///       and need to be the same as the version of `cdk-ansible` crate.
54const fn pkg_version() -> &'static str {
55    env!("CARGO_PKG_VERSION")
56}
57
58/// Returns version information.
59pub fn version() -> VersionInfo {
60    let version = pkg_version().to_owned();
61
62    // Commit info is pulled from git and set by `build.rs`
63    let commit_info = match (
64        option_env!("CDK_ANSIBLE_COMMIT_HASH"),
65        option_env!("CDK_ANSIBLE_COMMIT_SHORT_HASH"),
66        option_env!("CDK_ANSIBLE_COMMIT_DATE"),
67        option_env!("CDK_ANSIBLE_LAST_TAG"),
68        option_env!("CDK_ANSIBLE_LAST_TAG_DISTANCE"),
69        option_env!("CDK_ANSIBLE_LAST_TAG_DISTANCE_DIRTY"),
70    ) {
71        (
72            Some(commit_hash),
73            Some(short_commit_hash),
74            Some(commit_date),
75            Some(last_tag),
76            commits_since_last_tag,
77            is_dirty,
78        ) => Some(CommitInfo {
79            short_commit_hash: short_commit_hash.to_owned(),
80            commit_hash: commit_hash.to_owned(),
81            commit_date: commit_date.to_owned(),
82            last_tag: Some(last_tag.to_owned()),
83            commits_since_last_tag: commits_since_last_tag
84                .map_or(0, |distance| distance.parse::<u32>().unwrap_or(0)),
85            is_dirty: is_dirty == Some("1"),
86        }),
87        _ => None,
88    };
89
90    VersionInfo {
91        version,
92        commit_info,
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99
100    #[test]
101    fn get_version() {
102        let v_ = version();
103        assert_eq!(v_.version, env!("CARGO_PKG_VERSION").to_owned());
104    }
105}