mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-17 13:17:55 +08:00
document build.rs
This commit is contained in:
@@ -1,76 +1,124 @@
|
||||
use std::{collections::HashMap, env};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
env::{self, VarError},
|
||||
};
|
||||
|
||||
use git2::{DescribeOptions, Repository};
|
||||
use serde::Deserialize;
|
||||
|
||||
fn main() {
|
||||
if let Ok(git) = Repository::open(".") {
|
||||
if let None = maybe_forward_env("GIT_DESCRIBE") {
|
||||
let mut opts = DescribeOptions::new();
|
||||
opts.describe_all();
|
||||
opts.show_commit_oid_as_fallback(true);
|
||||
features_env();
|
||||
target_envs();
|
||||
git_envs();
|
||||
}
|
||||
|
||||
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 let None = maybe_forward_env("GIT_REV") {
|
||||
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}");
|
||||
};
|
||||
/// 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_<name>` to finally collect
|
||||
/// them into a string.
|
||||
fn features_env() {
|
||||
#[derive(Deserialize)]
|
||||
struct Config {
|
||||
features: HashMap<String, Vec<String>>,
|
||||
}
|
||||
|
||||
let toml: CargoToml =
|
||||
toml::from_str(include_str!("./Cargo.toml")).expect("should read Cargo.toml");
|
||||
impl Config {
|
||||
fn enabled_features(self) -> impl Iterator<Item = String> {
|
||||
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 toml.features {
|
||||
if feature == "default" {
|
||||
continue;
|
||||
}
|
||||
|
||||
if feature_enabled(&feature) {
|
||||
for feature in config.enabled_features() {
|
||||
if !features.is_empty() {
|
||||
features.push(' ');
|
||||
features.push_str(&format!("+{feature}"));
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct CargoToml {
|
||||
features: HashMap<String, Vec<String>>,
|
||||
/// 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 {
|
||||
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}");
|
||||
};
|
||||
}
|
||||
|
||||
fn feature_enabled(feature: &str) -> bool {
|
||||
let feature = feature.replace('-', "_").to_uppercase();
|
||||
env::var(format!("CARGO_FEATURE_{feature}")).is_ok()
|
||||
}
|
||||
/// Tries to forward the given environment variable.
|
||||
///
|
||||
/// For a more strict version, see [`forward_env`].
|
||||
fn try_forward_env(key: &str) -> Result<String, VarError> {
|
||||
let env = env::var(key);
|
||||
|
||||
fn maybe_forward_env(key: &str) -> Option<String> {
|
||||
match env::var(key) {
|
||||
Err(_) => None,
|
||||
Ok(val) => {
|
||||
println!("cargo::rustc-env={key}={val}");
|
||||
Some(val)
|
||||
}
|
||||
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) {
|
||||
maybe_forward_env(key).expect(&format!("should get env {key}"));
|
||||
try_forward_env(key).expect(&format!("should get env {key}"));
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ impl Cli {
|
||||
pub const LONG_VERSION: &'static str = concat!(
|
||||
"v",
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
" ",
|
||||
env!("CARGO_FEATURES"),
|
||||
"\nbuild: ",
|
||||
env!("CARGO_CFG_TARGET_OS"),
|
||||
|
||||
Reference in New Issue
Block a user