Skip to main content

nym_bin_common/build_information/
mod.rs

1// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4// TODO: at a later date this crate should probably also expose `ContractBuildInformation`
5// and be used by our smart contracts
6
7use serde::{Deserialize, Serialize};
8use std::fmt::{Display, Formatter};
9
10#[derive(Debug)]
11pub struct BinaryBuildInformation {
12    /// Provides the name of the binary, i.e. the content of `CARGO_PKG_NAME` environmental variable.
13    pub binary_name: &'static str,
14
15    // VERGEN_BUILD_TIMESTAMP
16    /// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
17    pub build_timestamp: &'static str,
18
19    // VERGEN_BUILD_SEMVER
20    /// Provides the build version, for example `0.1.0-9-g46f83e1`.
21    pub build_version: &'static str,
22
23    // VERGEN_GIT_SHA
24    /// Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.
25    pub commit_sha: &'static str,
26
27    // VERGEN_GIT_COMMIT_TIMESTAMP
28    /// Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.
29    pub commit_timestamp: &'static str,
30
31    // VERGEN_GIT_BRANCH
32    /// Provides the name of the git branch that was used for the build, for example `master`.
33    pub commit_branch: &'static str,
34
35    // VERGEN_RUSTC_SEMVER
36    /// Provides the rustc version that was used for the build, for example `1.52.0-nightly`.
37    pub rustc_version: &'static str,
38
39    // VERGEN_RUSTC_CHANNEL
40    /// Provides the rustc channel that was used for the build, for example `nightly`.
41    pub rustc_channel: &'static str,
42
43    // VERGEN_CARGO_DEBUG
44    /// Provides the cargo debug mode that was used for the build.
45    // NOTE: keep the old name cargo_profile instead of cargo_debug for backwards compatibility
46    pub cargo_profile: &'static str,
47
48    // VERGEN_CARGO_TARGET_TRIPLE
49    /// Provides the cargo target triple that was used for the build.
50    pub cargo_triple: &'static str,
51}
52
53impl BinaryBuildInformation {
54    // explicitly require the build_version to be passed as it's binary specific
55    pub const fn new(binary_name: &'static str, build_version: &'static str) -> Self {
56        let cargo_debug = env!("VERGEN_CARGO_DEBUG");
57        let cargo_profile = if const_str::equal!(cargo_debug, "true") {
58            "debug"
59        } else {
60            "release"
61        };
62
63        BinaryBuildInformation {
64            binary_name,
65            build_timestamp: env!("VERGEN_BUILD_TIMESTAMP"),
66            build_version,
67            commit_sha: env!("VERGEN_GIT_SHA"),
68            commit_timestamp: env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
69            commit_branch: env!("VERGEN_GIT_BRANCH"),
70            rustc_version: env!("VERGEN_RUSTC_SEMVER"),
71            rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
72            cargo_profile,
73            cargo_triple: env!("VERGEN_CARGO_TARGET_TRIPLE"),
74        }
75    }
76
77    // Varient where we want to use the metadata generated by vergen in the consuming crate.
78    pub const fn new_with_local_vergen(
79        binary_name: &'static str,
80        build_timestamp: &'static str,
81        build_version: &'static str,
82        commit_sha: &'static str,
83        commit_timestamp: &'static str,
84        commit_branch: &'static str,
85    ) -> Self {
86        let cargo_debug = env!("VERGEN_CARGO_DEBUG");
87        let cargo_profile = if const_str::equal!(cargo_debug, "true") {
88            "debug"
89        } else {
90            "release"
91        };
92
93        BinaryBuildInformation {
94            binary_name,
95            build_timestamp,
96            build_version,
97            commit_sha,
98            commit_timestamp,
99            commit_branch,
100            rustc_version: env!("VERGEN_RUSTC_SEMVER"),
101            rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
102            cargo_profile,
103            cargo_triple: env!("VERGEN_CARGO_TARGET_TRIPLE"),
104        }
105    }
106
107    pub fn to_owned(&self) -> BinaryBuildInformationOwned {
108        BinaryBuildInformationOwned {
109            binary_name: self.binary_name.to_owned(),
110            build_timestamp: self.build_timestamp.to_owned(),
111            build_version: self.build_version.to_owned(),
112            commit_sha: self.commit_sha.to_owned(),
113            commit_timestamp: self.commit_timestamp.to_owned(),
114            commit_branch: self.commit_branch.to_owned(),
115            rustc_version: self.rustc_version.to_owned(),
116            rustc_channel: self.rustc_channel.to_owned(),
117            cargo_profile: self.cargo_profile.to_owned(),
118            cargo_triple: self.cargo_triple.to_owned(),
119        }
120    }
121
122    pub fn pretty_print(&self) -> String {
123        self.to_owned().to_string()
124    }
125}
126
127// to whoever is thinking of modifying this struct.
128// you MUST NOT change its structure in any way - adding, removing or changing fields
129// otherwise, it will break old clients as bincode serialisation is not backwards compatible
130// even if you put `#[serde(default)]` all over the place
131#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
132#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
133#[cfg_attr(feature = "bin_info_schema", derive(schemars::JsonSchema))]
134pub struct BinaryBuildInformationOwned {
135    /// Provides the name of the binary, i.e. the content of `CARGO_PKG_NAME` environmental variable.
136    pub binary_name: String,
137
138    // VERGEN_BUILD_TIMESTAMP
139    /// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
140    pub build_timestamp: String,
141
142    // VERGEN_BUILD_SEMVER
143    /// Provides the build version, for example `0.1.0-9-g46f83e1`.
144    pub build_version: String,
145
146    // VERGEN_GIT_SHA
147    /// Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.
148    pub commit_sha: String,
149
150    // VERGEN_GIT_COMMIT_TIMESTAMP
151    /// Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.
152    pub commit_timestamp: String,
153
154    // VERGEN_GIT_BRANCH
155    /// Provides the name of the git branch that was used for the build, for example `master`.
156    pub commit_branch: String,
157
158    // VERGEN_RUSTC_SEMVER
159    /// Provides the rustc version that was used for the build, for example `1.52.0-nightly`.
160    pub rustc_version: String,
161
162    // VERGEN_RUSTC_CHANNEL
163    /// Provides the rustc channel that was used for the build, for example `nightly`.
164    pub rustc_channel: String,
165
166    // VERGEN_CARGO_DEBUG
167    /// Provides the cargo debug mode that was used for the build.
168    // NOTE: keep the old name cargo_profile instead of cargo_debug for backwards compatibility
169    pub cargo_profile: String,
170
171    // VERGEN_CARGO_TARGET_TRIPLE
172    /// Provides the cargo target triple that was used for the build.
173    #[serde(default = "unknown")]
174    pub cargo_triple: String,
175}
176
177fn unknown() -> String {
178    "unknown".to_string()
179}
180
181impl Display for BinaryBuildInformationOwned {
182    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
183        write!(
184            f,
185            r#"
186{:<20}{}
187{:<20}{}
188{:<20}{}
189{:<20}{}
190{:<20}{}
191{:<20}{}
192{:<20}{}
193{:<20}{}
194{:<20}{}
195"#,
196            "Binary Name:",
197            self.binary_name,
198            "Build Timestamp:",
199            self.build_timestamp,
200            "Build Version:",
201            self.build_version,
202            "Commit SHA:",
203            self.commit_sha,
204            "Commit Date:",
205            self.commit_timestamp,
206            "Commit Branch:",
207            self.commit_branch,
208            "rustc Version:",
209            self.rustc_version,
210            "rustc Channel:",
211            self.rustc_channel,
212            "cargo Profile:",
213            self.cargo_profile,
214        )
215    }
216}
217
218// since this macro will get expanded at the callsite, it will pull in correct binary version
219#[macro_export]
220macro_rules! bin_info {
221    () => {
222        $crate::build_information::BinaryBuildInformation::new(
223            env!("CARGO_PKG_NAME"),
224            env!("CARGO_PKG_VERSION"),
225        )
226    };
227}
228
229#[macro_export]
230macro_rules! bin_info_owned {
231    () => {
232        $crate::build_information::BinaryBuildInformation::new(
233            env!("CARGO_PKG_NAME"),
234            env!("CARGO_PKG_VERSION"),
235        )
236        .to_owned()
237    };
238}
239
240// variant that picks up the vergen build information generated by the build.rs in the consumer
241// crate.
242#[macro_export]
243macro_rules! bin_info_local_vergen {
244    () => {
245        $crate::build_information::BinaryBuildInformation::new_with_local_vergen(
246            env!("CARGO_PKG_NAME"),
247            env!("VERGEN_BUILD_TIMESTAMP"),
248            env!("CARGO_PKG_VERSION"),
249            env!("VERGEN_GIT_SHA"),
250            env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
251            env!("VERGEN_GIT_BRANCH"),
252        )
253    };
254}
255
256#[macro_export]
257macro_rules! bin_info_local_vergen_owned {
258    () => {
259        $crate::build_information::BinaryBuildInformation::new_with_local_vergen(
260            env!("CARGO_PKG_NAME"),
261            env!("VERGEN_BUILD_TIMESTAMP"),
262            env!("CARGO_PKG_VERSION"),
263            env!("VERGEN_GIT_SHA"),
264            env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
265            env!("VERGEN_GIT_BRANCH"),
266        )
267    };
268}