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