gitversion_build/
lib.rs

1use serde::{Deserialize, Serialize};
2use std::process::Command;
3
4pub fn get_version() -> Result<GitVersion, String> {
5    let version = get_git_version();
6    println!("version: {}", version);
7    let v: GitVersion = serde_json::from_str(version.as_str())
8        .map_err(|e| format!("Get gitversion failed! {e}"))?;
9    Ok(v)
10}
11
12pub fn inject_version() -> Result<(), String> {
13    let v = get_version()?;
14
15    println!(
16        "cargo::rustc-env=CARGO_PKG_VERSION={}{}",
17        v.major_minor_patch,
18        match v.pre_release_label_with_dash.as_str() {
19            "" => format!("-{}", v.full_build_meta_data),
20            _ => format!(
21                "{}.{}",
22                v.pre_release_label_with_dash, v.full_build_meta_data
23            ),
24        }
25    );
26    println!("cargo::rustc-env=CARGO_PKG_VERSION_MAJOR={}", v.major);
27    println!("cargo::rustc-env=CARGO_PKG_VERSION_MINOR={}", v.minor);
28    println!("cargo::rustc-env=CARGO_PKG_VERSION_PATCH={}", v.patch);
29    println!(
30        "cargo::rustc-env=CARGO_PKG_VERSION_PRE={}",
31        v.informational_version
32    );
33
34    // add all version fileds to env
35    println!(
36        "cargo::rustc-env=GITVERSION_ASSEMBLY_SEM_FILE_VER={}",
37        v.assembly_sem_file_ver
38    );
39    println!(
40        "cargo::rustc-env=GITVERSION_ASSEMBLY_SEM_VER={}",
41        v.assembly_sem_ver
42    );
43    println!("cargo::rustc-env=GITVERSION_BRANCH_NAME={}", v.branch_name);
44    println!(
45        "cargo::rustc-env=GITVERSION_BUILD_META_DATA={}",
46        v.build_meta_data.unwrap_or("".into())
47    );
48    println!("cargo::rustc-env=GITVERSION_COMMIT_DATE={}", v.commit_date);
49    println!(
50        "cargo::rustc-env=GITVERSION_COMMITS_SINCE_VERSION_SOURCE={}",
51        v.commits_since_version_source
52    );
53    println!(
54        "cargo::rustc-env=GITVERSION_ESCAPED_BRANCH_NAME={}",
55        v.escaped_branch_name
56    );
57    println!(
58        "cargo::rustc-env=GITVERSION_FULL_BUILD_META_DATA={}",
59        v.full_build_meta_data
60    );
61    println!(
62        "cargo::rustc-env=GITVERSION_FULL_SEM_VER={}",
63        v.full_sem_ver
64    );
65    println!(
66        "cargo::rustc-env=GITVERSION_INFORMATIONAL_VERSION={}",
67        v.informational_version
68    );
69    println!("cargo::rustc-env=GITVERSION_MAJOR={}", v.major);
70    println!(
71        "cargo::rustc-env=GITVERSION_MAJOR_MINOR_PATCH={}",
72        v.major_minor_patch
73    );
74    println!("cargo::rustc-env=GITVERSION_MINOR={}", v.minor);
75    println!("cargo::rustc-env=GITVERSION_PATCH={}", v.patch);
76    println!(
77        "cargo::rustc-env=GITVERSION_PRE_RELEASE_LABEL={}",
78        v.pre_release_label
79    );
80    println!(
81        "cargo::rustc-env=GITVERSION_PRE_RELEASE_LABEL_WITH_DASH={}",
82        v.pre_release_label_with_dash
83    );
84    println!(
85        "cargo::rustc-env=GITVERSION_PRE_RELEASE_NUMBER={}",
86        v.pre_release_number.map_or("".into(), |x| x.to_string())
87    );
88    println!(
89        "cargo::rustc-env=GITVERSION_PRE_RELEASE_TAG={}",
90        v.pre_release_tag
91    );
92    println!(
93        "cargo::rustc-env=GITVERSION_PRE_RELEASE_TAG_WITH_DASH={}",
94        v.pre_release_tag_with_dash
95    );
96    println!("cargo::rustc-env=GITVERSION_SEM_VER={}", v.sem_ver);
97    println!("cargo::rustc-env=GITVERSION_SHA={}", v.sha);
98    println!("cargo::rustc-env=GITVERSION_SHORT_SHA={}", v.short_sha);
99    println!(
100        "cargo::rustc-env=GITVERSION_UNCOMMITTED_CHANGES={}",
101        v.uncommitted_changes
102    );
103    println!(
104        "cargo::rustc-env=GITVERSION_VERSION_SOURCE_SHA={}",
105        v.version_source_sha
106    );
107    println!(
108        "cargo::rustc-env=GITVERSION_WEIGHTED_PRE_RELEASE_NUMBER={}",
109        v.weighted_pre_release_number
110    );
111
112    Ok(())
113}
114
115#[derive(Debug, Serialize, Deserialize)]
116#[serde(rename_all = "PascalCase")]
117pub struct GitVersion {
118    pub assembly_sem_file_ver: String,
119    pub assembly_sem_ver: String,
120    pub branch_name: String,
121    pub build_meta_data: Option<serde_json::Value>,
122    pub commit_date: String,
123    pub commits_since_version_source: i64,
124    pub escaped_branch_name: String,
125    pub full_build_meta_data: String,
126    pub full_sem_ver: String,
127    pub informational_version: String,
128    pub major: i64,
129    pub major_minor_patch: String,
130    pub minor: i64,
131    pub patch: i64,
132    pub pre_release_label: String,
133    pub pre_release_label_with_dash: String,
134    pub pre_release_number: Option<i64>,
135    pub pre_release_tag: String,
136    pub pre_release_tag_with_dash: String,
137    pub sem_ver: String,
138    pub sha: String,
139    pub short_sha: String,
140    pub uncommitted_changes: i64,
141    pub version_source_sha: String,
142    pub weighted_pre_release_number: i64,
143}
144
145fn get_git_version() -> String {
146    let child = Command::new("dotnet")
147        .arg("gitversion")
148        .args(["/output", "json"])
149        .output();
150
151    let child = if let Ok(child) = child {
152        if child.status.success() {
153            Ok(String::from_utf8(child.stdout).expect("failed to read stdout"))
154        } else {
155            Err(format!(
156                "Execte `dotnet gitversion` failed! {}",
157                String::from_utf8(child.stderr).expect("failed to read stdout")
158            ))
159        }
160    } else {
161        Err(format!(
162            "Execte `dotnet gitversion` failed! {}",
163            child.unwrap_err()
164        ))
165    };
166
167    child.unwrap_or_else(|e| {
168        println!("{}", e);
169        println!("Try to execte `gitversion`");
170        let child = Command::new("gitversion")
171            .args(["/output", "json"])
172            .output();
173
174        let child = if let Ok(child) = child {
175            if child.status.success() {
176                Ok(String::from_utf8(child.stdout).expect("failed to read stdout"))
177            } else {
178                Err(format!(
179                    "Execte `gitversion` failed! {}",
180                    String::from_utf8(child.stdout).expect("failed to read stdout")
181                ))
182            }
183        } else {
184            Err(format!(
185                "Execte `gitversion` failed! {}",
186                child.unwrap_err()
187            ))
188        };
189
190        child.unwrap()
191    })
192}
193
194#[cfg(test)]
195mod tests {
196    use super::*;
197
198    #[test]
199    fn it_works() {
200        get_version().unwrap();
201    }
202}