From 062c31c256adfa23382cfa26fd0e5cc203c2ebd4 Mon Sep 17 00:00:00 2001 From: baoyachi Date: Sun, 15 Dec 2024 11:39:54 +0800 Subject: [PATCH] Add ShadowBuilder build shadow --- src/build.rs | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ src/gen_const.rs | 2 +- src/lib.rs | 51 +++++++++++++++++++++------ 3 files changed, 134 insertions(+), 11 deletions(-) diff --git a/src/build.rs b/src/build.rs index c943a36..61adadc 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,3 +1,6 @@ +use crate::hook::HookExt; +use crate::{default_deny, SdResult, Shadow}; +use std::collections::BTreeSet; use std::fmt::{Display, Formatter}; /// `shadow-rs` build constant identifiers. @@ -60,3 +63,92 @@ impl Display for ConstType { } } } + +pub struct ShadowBuilder<'a> { + hook: Option>, + build_pattern: BuildPattern, + deny_const: BTreeSet, + src_path: Option, + out_path: Option, +} + +#[derive(Debug, Default, Clone)] +pub enum BuildPattern { + //TODO handle pattern + #[default] + Lazy, + RealTime, + Custom(CBuildPattern), +} + +#[derive(Debug, Default, Clone)] +pub struct CBuildPattern { + // https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed + if_path_changed: Vec, + // https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-env-changed + if_env_changed: Vec, +} + +impl<'a> ShadowBuilder<'a> { + pub fn builder() -> Self { + let default_src_path = std::env::var("CARGO_MANIFEST_DIR").ok(); + let default_out_path = std::env::var("OUT_DIR").ok(); + Self { + hook: None, + build_pattern: BuildPattern::default(), + deny_const: default_deny(), + src_path: default_src_path, + out_path: default_out_path, + } + } + + pub fn hook(mut self, hook: impl HookExt + 'a) -> Self { + self.hook = Some(Box::new(hook)); + self + } + + pub fn src_path>(mut self, src_path: P) -> Self { + self.src_path = Some(src_path.as_ref().to_owned()); + self + } + + pub fn out_path>(mut self, out_path: P) -> Self { + self.out_path = Some(out_path.as_ref().to_owned()); + self + } + + pub fn build_pattern(mut self, pattern: BuildPattern) -> Self { + self.build_pattern = pattern; + self + } + + pub fn deny_const(mut self, deny_const: BTreeSet) -> Self { + self.deny_const = deny_const; + self + } + + pub fn build(self) -> SdResult { + Shadow::build_inner(self) + } + + pub fn get_src_path(&self) -> SdResult<&String> { + let src_path = self.src_path.as_ref().ok_or("missing `src_path`")?; + Ok(src_path) + } + pub fn get_out_path(&self) -> SdResult<&String> { + let out_path = self.out_path.as_ref().ok_or("missing `out_path`")?; + Ok(out_path) + } + + pub fn get_build_pattern(&self) -> &BuildPattern { + &self.build_pattern + } + + pub fn get_deny_const(&self) -> &BTreeSet { + &self.deny_const + } + + pub fn get_hook(&'a self) -> Option<&Box> { + self.hook.as_ref() + } +} diff --git a/src/gen_const.rs b/src/gen_const.rs index d433da4..ddb7207 100644 --- a/src/gen_const.rs +++ b/src/gen_const.rs @@ -81,7 +81,7 @@ const CLAP_LONG_VERSION_TAG_CONST: (&str, &str) = ( tag:{} commit_hash:{} build_time:{} -build_env:{},{}"#,PKG_VERSION, TAG, SHORT_COMMIT, BUILD_TIME, RUST_VERSION, RUST_CHANNEL +build_env:{},{}"#,PKG_VERSION, TAG, SHORT_COMMIT, BUILD_TIME_2822, RUST_VERSION, RUST_CHANNEL );"##, ); diff --git a/src/lib.rs b/src/lib.rs index 7dc6c70..c8dab7e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -179,6 +179,7 @@ use crate::gen_const::{ }; pub use err::{SdResult, ShadowError}; +use crate::build::{BuildPattern, ShadowBuilder}; use crate::hook::HookExt; pub use {build::ShadowConst, env::*, git::*}; @@ -188,7 +189,7 @@ pub trait Format { const SHADOW_RS: &str = "shadow.rs"; -pub(crate) const CARGO_CLIPPY_ALLOW_ALL: &str = +pub const CARGO_CLIPPY_ALLOW_ALL: &str = "#[allow(clippy::all, clippy::pedantic, clippy::restriction, clippy::nursery)]"; /// Add a module with the provided name which contains the build information generated by `shadow-rs`. @@ -229,7 +230,8 @@ macro_rules! shadow { /// } /// ``` pub fn new() -> SdResult<()> { - Shadow::build(default_deny())?; + // Shadow::build(default_deny())?; + ShadowBuilder::builder().build()?; Ok(()) } @@ -265,7 +267,8 @@ pub fn default_deny() -> BTreeSet { /// } /// ``` pub fn new_deny(deny_const: BTreeSet) -> SdResult<()> { - Shadow::build(deny_const)?; + // Shadow::build(deny_const)?; + ShadowBuilder::builder().deny_const(deny_const).build()?; Ok(()) } @@ -296,8 +299,13 @@ pub fn new_hook(f: F) -> SdResult<()> where F: HookExt, { - let shadow = Shadow::build(f.default_deny())?; - shadow.hook(f.hook_inner()) + // let shadow = Shadow::build(f.default_deny())?; + // shadow.hook(f.hook_inner()) + ShadowBuilder::builder() + .deny_const(f.default_deny()) + .hook(f.hook_inner()) + .build()?; + Ok(()) } /// Returns the contents of [`std::env::vars`] as an ordered map. @@ -323,6 +331,8 @@ pub struct Shadow { pub std_env: BTreeMap, /// Constants in the deny list, passed through [`new_deny`] or [`Shadow::build`]. pub deny_const: BTreeSet, + + pub build_pattern: BuildPattern, } impl Shadow { @@ -371,9 +381,11 @@ impl Shadow { /// Create a new [`Shadow`] configuration with a provided denylist. /// The project source path and output file are automatically derived from Cargo build environment variables. pub fn build(deny_const: BTreeSet) -> SdResult { - let src_path = std::env::var("CARGO_MANIFEST_DIR")?; - let out_path = std::env::var("OUT_DIR")?; - Self::build_with(src_path, out_path, deny_const) + // let src_path = std::env::var("CARGO_MANIFEST_DIR")?; + // let out_path = std::env::var("OUT_DIR")?; + // Self::build_with(src_path, out_path, deny_const) + + ShadowBuilder::builder().deny_const(deny_const).build() } pub fn build_with( @@ -381,8 +393,21 @@ impl Shadow { out_path: String, deny_const: BTreeSet, ) -> SdResult { + ShadowBuilder::builder() + .deny_const(deny_const) + .src_path(src_path) + .out_path(out_path) + .build() + } + + fn build_inner(builder: ShadowBuilder) -> SdResult { + let out_path = builder.get_out_path()?; + let src_path = builder.get_src_path()?; + let build_pattern = builder.get_build_pattern().clone(); + let deny_const = builder.get_deny_const().clone(); + let out = { - let path = Path::new(out_path.as_str()); + let path = Path::new(out_path); if !out_path.ends_with('/') { path.join(format!("{out_path}/{SHADOW_RS}")) } else { @@ -395,6 +420,7 @@ impl Shadow { map: Default::default(), std_env: Default::default(), deny_const, + build_pattern, }; shadow.std_env = get_std_env(); @@ -415,6 +441,11 @@ impl Shadow { shadow.write_all()?; + // handle hook + if let Some(h) = builder.get_hook() { + shadow.hook(h.hook_inner())? + } + Ok(shadow) } @@ -466,7 +497,7 @@ impl Shadow { // Author: https://www.github.com/baoyachi // Generation time: {} "#, - DateTime::now().human_format() + DateTime::now().to_rfc2822() ); writeln!(&self.f, "{desc}\n\n")?; Ok(())