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 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}