use std::env;
use std::fmt::Write;
use std::str::FromStr;
use chrono::Local;
use crate::cargo::Profile;
use crate::error::Result;
use crate::rust::{Channel, Toolchain};
pub fn setup(build_script: &BuildScript) -> anyhow::Result<()> {
build_script.setup()?;
Ok(())
}
#[allow(clippy::module_name_repetitions)]
#[derive(Clone, Copy, Debug, Default)]
pub struct BuildScript;
impl BuildScript {
pub fn setup(&self) -> Result<()> {
let mut stdout_buffer = String::new();
self.setup_build(&mut stdout_buffer)?;
self.setup_cargo(&mut stdout_buffer)?;
self.setup_rust(&mut stdout_buffer)?;
print!("{stdout_buffer}");
Ok(())
}
fn setup_build<T>(&self, stdout: &mut T) -> Result<()>
where
T: Write,
{
let datetime = Local::now().format("%Y-%m-%d %H:%M:%S");
writeln!(
stdout,
"cargo:rustc-env=CHKSUM_BUILD_INFO_BUILD_DATETIME=\"{datetime}\""
)?;
Ok(())
}
fn setup_cargo<T>(&self, stdout: &mut T) -> Result<()>
where
T: Write,
{
let profile = {
let profile = env::var("PROFILE")?;
Profile::from_str(&profile)?
};
writeln!(stdout, "cargo:rustc-cfg={profile}")?;
writeln!(stdout, "cargo:rustc-env=CHKSUM_BUILD_INFO_CARGO_PROFILE=\"{profile}\"")?;
Ok(())
}
fn setup_rust<T>(&self, stdout: &mut T) -> Result<()>
where
T: Write,
{
let toolchain = {
let toolchain = env::var("RUSTUP_TOOLCHAIN")?;
Toolchain::from_str(&toolchain)?
};
let channel = match toolchain.channel {
Channel::Version(_) => Channel::Stable,
channel => channel,
};
writeln!(stdout, "cargo:rustc-cfg={channel}")?;
writeln!(stdout, "cargo:rustc-env=CHKSUM_BUILD_INFO_RUST_CHANNEL=\"{channel}\"")?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_setup_build() {
let mut stdout = String::new();
assert!(BuildScript::default().setup_build(&mut stdout).is_ok());
assert_eq!(
stdout.to_string(),
format!(
"cargo:rustc-env=CHKSUM_BUILD_INFO_BUILD_DATETIME=\"{}\"\n",
Local::now().format("%Y-%m-%d %H:%M:%S")
)
);
}
#[test]
fn test_setup_cargo() {
env::set_var("PROFILE", "release");
let mut stdout = String::new();
assert!(BuildScript::default().setup_cargo(&mut stdout).is_ok());
assert_eq!(
stdout.to_string(),
"cargo:rustc-cfg=release\ncargo:rustc-env=CHKSUM_BUILD_INFO_CARGO_PROFILE=\"release\"\n"
);
}
#[test]
fn test_setup_rust() {
env::set_var("RUSTUP_TOOLCHAIN", "nightly-x86_64-unknown-linux-gnu");
let mut stdout = String::new();
assert!(BuildScript::default().setup_rust(&mut stdout).is_ok());
assert_eq!(
stdout.to_string(),
"cargo:rustc-cfg=nightly\ncargo:rustc-env=CHKSUM_BUILD_INFO_RUST_CHANNEL=\"nightly\"\n"
);
}
}