// use std::{ // collections::HashMap, // env::{self, VarError}, // }; // use git2::{DescribeOptions, Repository}; // use serde::Deserialize; fn main() { // features_env(); // target_envs(); // git_envs(); } // /// Builds the `CARGO_FEATURES` environment variable. // /// // /// This function turns enabled cargo features into a simple string // /// `+feature1 +feature2 +featureN`, which then exposes it via the // /// `CARGO_FEATURES` environment variable. // /// // /// It first reads and parses the Cargo.toml in order to extract all // /// available features (omitting "default"). It then checks for // /// enabled features via `CARGO_FEATURE_` to finally collect // /// them into a string. // fn features_env() { // #[derive(Deserialize)] // struct Config { // features: HashMap>, // } // impl Config { // fn enabled_features(self) -> impl Iterator { // self.features // .into_keys() // .filter(|feature| feature != "default") // .filter(|feature| { // let feature = feature.replace('-', "_").to_uppercase(); // env::var(format!("CARGO_FEATURE_{feature}")).is_ok() // }) // } // } // let config: Config = // toml::from_str(include_str!("./Cargo.toml")).expect("should parse Cargo.toml"); // let mut features = String::new(); // for feature in config.enabled_features() { // if !features.is_empty() { // features.push(' '); // } // features.push_str(&format!("+{feature}")); // } // println!("cargo::rustc-env=CARGO_FEATURES={features}"); // } // /// Builds environment variables related to the target platform. // /// // /// This function basically forwards existing cargo environments // /// related to the target platform. // fn target_envs() { // forward_env("CARGO_CFG_TARGET_OS"); // forward_env("CARGO_CFG_TARGET_ENV"); // forward_env("CARGO_CFG_TARGET_ARCH"); // } // /// Builds environment variables related to git. // /// // /// This function basically tries to forward existing git environment // /// variables. In case of failure, it tries to build them using // /// [`git2`]. // fn git_envs() { // // skip the process if the current directory is not a git // // repository (for example, from a nix build root jail) // let Ok(git) = Repository::open(".") else { // println!("cargo::rustc-env=GIT_DESCRIBE=unknown"); // println!("cargo::rustc-env=GIT_REV=unknown"); // return; // }; // if try_forward_env("GIT_DESCRIBE").is_err() { // let mut opts = DescribeOptions::new(); // opts.describe_all(); // opts.show_commit_oid_as_fallback(true); // let description = git // .describe(&opts) // .expect("should describe git object") // .format(None) // .expect("should format git object description"); // println!("cargo::rustc-env=GIT_DESCRIBE={description}"); // }; // if try_forward_env("GIT_REV").is_err() { // let head = git.head().expect("should get git HEAD"); // let commit = head.peel_to_commit().expect("should get git HEAD commit"); // let rev = commit.id().to_string(); // println!("cargo::rustc-env=GIT_REV={rev}"); // }; // } // /// Tries to forward the given environment variable. // /// // /// For a more strict version, see [`forward_env`]. // fn try_forward_env(key: &str) -> Result { // let env = env::var(key); // if let Ok(val) = &env { // println!("cargo::rustc-env={key}={val}"); // } // env // } // /// Forwards the given environment variable. // /// // /// This function panics in case the forward fails (when the // /// environment variable does not exist for example). // /// // /// For a less strict version, see [`try_forward_env`]. // fn forward_env(key: &str) { // try_forward_env(key).expect(&format!("should get env {key}")); // }