1use std::env;
4use std::fmt::Write;
5use std::str::FromStr;
6
7use chrono::Local;
8
9use crate::cargo::Profile;
10use crate::error::Result;
11use crate::rust::{Channel, Toolchain};
12
13pub fn setup(build_script: &BuildScript) -> anyhow::Result<()> {
30 build_script.setup()?;
31 Ok(())
32}
33
34#[allow(clippy::module_name_repetitions)]
36#[derive(Clone, Copy, Debug, Default)]
37pub struct BuildScript;
38
39impl BuildScript {
40 pub fn setup(&self) -> Result<()> {
60 let mut stdout_buffer = String::new();
61
62 self.setup_build(&mut stdout_buffer)?;
63
64 self.setup_cargo(&mut stdout_buffer)?;
65
66 self.setup_rust(&mut stdout_buffer)?;
67
68 print!("{stdout_buffer}");
69
70 Ok(())
71 }
72
73 fn setup_build<T>(&self, stdout: &mut T) -> Result<()>
74 where
75 T: Write,
76 {
77 let datetime = Local::now().format("%Y-%m-%d %H:%M:%S");
78
79 writeln!(
80 stdout,
81 "cargo:rustc-env=CHKSUM_BUILD_INFO_BUILD_DATETIME=\"{datetime}\""
82 )?;
83
84 Ok(())
85 }
86
87 fn setup_cargo<T>(&self, stdout: &mut T) -> Result<()>
88 where
89 T: Write,
90 {
91 let profile = {
92 let profile = env::var("PROFILE")?;
93 Profile::from_str(&profile)?
94 };
95
96 writeln!(stdout, "cargo:rustc-cfg={profile}")?;
97 writeln!(stdout, "cargo:rustc-env=CHKSUM_BUILD_INFO_CARGO_PROFILE=\"{profile}\"")?;
98
99 Ok(())
100 }
101
102 fn setup_rust<T>(&self, stdout: &mut T) -> Result<()>
103 where
104 T: Write,
105 {
106 let toolchain = {
107 let toolchain = env::var("RUSTUP_TOOLCHAIN")?;
108 Toolchain::from_str(&toolchain)?
109 };
110 let channel = match toolchain.channel {
111 Channel::Version(_) => Channel::Stable,
112 channel => channel,
113 };
114
115 writeln!(stdout, "cargo:rustc-cfg={channel}")?;
116 writeln!(stdout, "cargo:rustc-env=CHKSUM_BUILD_INFO_RUST_CHANNEL=\"{channel}\"")?;
117
118 Ok(())
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_setup_build() {
128 let mut stdout = String::new();
129 assert!(BuildScript::default().setup_build(&mut stdout).is_ok());
130 assert_eq!(
131 stdout.to_string(),
132 format!(
133 "cargo:rustc-env=CHKSUM_BUILD_INFO_BUILD_DATETIME=\"{}\"\n",
134 Local::now().format("%Y-%m-%d %H:%M:%S")
135 )
136 );
137 }
138
139 #[test]
140 fn test_setup_cargo() {
141 env::set_var("PROFILE", "release");
142
143 let mut stdout = String::new();
144 assert!(BuildScript::default().setup_cargo(&mut stdout).is_ok());
145 assert_eq!(
146 stdout.to_string(),
147 "cargo:rustc-cfg=release\ncargo:rustc-env=CHKSUM_BUILD_INFO_CARGO_PROFILE=\"release\"\n"
148 );
149 }
150
151 #[test]
152 fn test_setup_rust() {
153 env::set_var("RUSTUP_TOOLCHAIN", "nightly-x86_64-unknown-linux-gnu");
154
155 let mut stdout = String::new();
156 assert!(BuildScript::default().setup_rust(&mut stdout).is_ok());
157 assert_eq!(
158 stdout.to_string(),
159 "cargo:rustc-cfg=nightly\ncargo:rustc-env=CHKSUM_BUILD_INFO_RUST_CHANNEL=\"nightly\"\n"
160 );
161 }
162}