1#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct BuildInfo {
18 pub version: &'static str,
20 pub sha: &'static str,
22}
23
24pub const DUMMY_BUILD_INFO: BuildInfo = BuildInfo {
29 version: "0.0.0+dummy",
30 sha: "0000000000000000000000000000000000000000",
31};
32
33pub const TARGET_TRIPLE: &str = env!("TARGET_TRIPLE");
35
36impl BuildInfo {
37 pub fn human_version(&self, helm_chart_version: Option<String>) -> String {
39 if let Some(ref helm_chart_version) = helm_chart_version {
40 if helm_chart_version != &self.version {
41 return format!(
42 "v{} ({}, helm chart: {})",
43 self.version,
44 &self.sha[..9],
45 helm_chart_version
46 );
47 }
48 }
49 format!("v{} ({})", self.version, &self.sha[..9])
50 }
51
52 #[cfg(feature = "semver")]
62 pub fn semver_version(&self) -> semver::Version {
63 self.version
64 .parse()
65 .expect("build version is not valid semver")
66 }
67
68 #[cfg(feature = "semver")]
71 pub fn semver_version_build(&self) -> Option<semver::Version> {
72 let build_id = buildid::build_id()?;
73 let build_id = hex::encode(build_id);
74 let version = format!("{}+{}", self.version, build_id)
75 .parse()
76 .expect("build version is not valid semver");
77 Some(version)
78 }
79
80 #[cfg(feature = "semver")]
82 pub fn version_num(&self) -> i32 {
83 let semver: semver::Version = self
84 .version
85 .parse()
86 .expect("build version is not a valid semver");
87 let ver_string = format!(
88 "{:0>2}{:0>3}{:0>2}",
89 semver.major, semver.minor, semver.patch
90 );
91 ver_string.parse::<i32>().unwrap()
92 }
93
94 pub fn is_dev(&self) -> bool {
96 self.version.contains("dev")
97 }
98}
99
100#[macro_export]
107macro_rules! build_info {
108 () => {
109 $crate::BuildInfo {
110 version: env!("CARGO_PKG_VERSION"),
111 sha: $crate::__git_sha_internal!(),
112 }
113 };
114}
115
116#[macro_export]
117macro_rules! __git_sha_internal {
118 () => {
119 $crate::private::run_command_str!(
120 "sh",
121 "-c",
122 r#"if [ -n "$MZ_DEV_BUILD_SHA" ]; then
123 echo "$MZ_DEV_BUILD_SHA"
124 else
125 # Unfortunately we need to suppress error messages from `git`, as
126 # run_command_str will display no error message at all if we print
127 # more than one line of output to stderr.
128 git rev-parse --verify HEAD 2>/dev/null || {
129 printf "error: unable to determine Git SHA; " >&2
130 printf "either build from working Git clone " >&2
131 printf "(see https://materialize.com/docs/install/#build-from-source), " >&2
132 printf "or specify SHA manually by setting MZ_DEV_BUILD_SHA environment variable" >&2
133 printf "If you are using git worktrees, you must be in the primary worktree" >&2
134 printf "for automatic detection to work." >&2
135 exit 1
136 }
137 fi"#
138 )
139 }
140}
141
142#[doc(hidden)]
143pub mod private {
144 pub use compile_time_run::run_command_str;
145}
146
147#[cfg(test)]
148mod test {
149 #[test] fn smoketest_build_info() {
151 let build_info = crate::build_info!();
152
153 assert_eq!(build_info.sha.len(), 40);
154 }
155}