diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-08-17 19:21:52 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-08-17 19:21:52 +0800 |
| commit | 89bf57f33a9f0f5a96fc50e272c83d926fa35c4a (patch) | |
| tree | cc5a72e850bdd9215b60dc1655f162e22ee97d12 /mingling_core/src | |
| parent | 40bb7ffd6954184fac718c8f99c9cdc3e054e4eb (diff) | |
refactor!: replace build.rs with compile-time macro build steps
BREAKING CHANGE: Replace the `build`/`builds` feature system with
compile-time macro-driven generation. `gen_program!()` now automatically
invokes `build_comp!()` and `build_pathf!()` when the `comp`/`pathf`
features are enabled, eliminating the need for `build.rs` and
`[build-dependencies]` blocks.
This removes the `build` feature, the `mingling::build` module, and all
related build-time API functions. Completion scripts are now written to
`{target_directory}/mingling/` instead of `target/release/`. The
`mingling_cli` uses `build_comp!("mling")` for its custom binary name.
Diffstat (limited to 'mingling_core/src')
| -rw-r--r-- | mingling_core/src/build.rs | 28 | ||||
| -rw-r--r-- | mingling_core/src/build/comp.rs | 183 | ||||
| -rw-r--r-- | mingling_core/src/build/pathf.rs | 98 | ||||
| -rw-r--r-- | mingling_core/src/docs/build.md | 57 | ||||
| -rw-r--r-- | mingling_core/src/lib.rs | 7 |
5 files changed, 0 insertions, 373 deletions
diff --git a/mingling_core/src/build.rs b/mingling_core/src/build.rs deleted file mode 100644 index 213d529..0000000 --- a/mingling_core/src/build.rs +++ /dev/null @@ -1,28 +0,0 @@ -#[doc(hidden)] -#[cfg(feature = "comp")] -mod comp; - -#[cfg(feature = "comp")] -mod comp_re_export { - pub use super::comp::build_comp_script; - pub use super::comp::build_comp_script_to; - pub use super::comp::build_comp_script_to_file; - pub use super::comp::build_comp_scripts; -} - -#[cfg(feature = "comp")] -pub use comp_re_export::*; - -#[doc(hidden)] -#[cfg(feature = "pathf")] -mod pathf; - -#[cfg(feature = "pathf")] -mod pathf_re_export { - pub use super::pathf::analyze; - pub use super::pathf::analyze_and_build_type_mapping; - pub use super::pathf::analyze_and_build_type_mapping_for; -} - -#[cfg(feature = "pathf")] -pub use pathf_re_export::*; diff --git a/mingling_core/src/build/comp.rs b/mingling_core/src/build/comp.rs deleted file mode 100644 index d6bb34f..0000000 --- a/mingling_core/src/build/comp.rs +++ /dev/null @@ -1,183 +0,0 @@ -use std::path::PathBuf; - -use just_template::tmpl; - -use crate::ShellFlag; - -const TMPL_COMP_BASH: &str = include_str!("../../tmpls/comps/bash.sh"); -const TMPL_COMP_ZSH: &str = include_str!("../../tmpls/comps/zsh.zsh"); -const TMPL_COMP_FISH: &str = include_str!("../../tmpls/comps/fish.fish"); -const TMPL_COMP_PWSH: &str = include_str!("../../tmpls/comps/pwsh.ps1"); - -/// Generate shell completion scripts for a given binary name. -/// -/// On Windows, generates `PowerShell` completion. -/// On Linux, generates Zsh, Bash, and Fish completions. -/// Scripts are written to the `OUT_DIR` (or `target/` if `OUT_DIR` is not set). -/// -/// # Example -/// ``` -/// # #[cfg(all(feature = "build", feature = "comp"))] { -/// # temp_env::with_var("OUT_DIR", Some(".temp/target/test/out/"), || { -/// # use mingling_core::ShellFlag; -/// # use mingling_core::build::build_comp_scripts; -/// // Generate completion scripts for "myapp" -/// build_comp_scripts("myapp").unwrap(); -/// -/// // Generate completion scripts for current package -/// build_comp_scripts(env!("CARGO_PKG_NAME")).unwrap(); -/// # }); -/// # } -/// ``` -pub fn build_comp_scripts(name: &str) -> Result<(), std::io::Error> { - #[cfg(target_os = "windows")] - { - build_comp_script(&ShellFlag::Powershell, name)?; - Ok(()) - } - - #[cfg(target_os = "linux")] - { - build_comp_script(&ShellFlag::Zsh, name)?; - build_comp_script(&ShellFlag::Bash, name)?; - build_comp_script(&ShellFlag::Fish, name)?; - Ok(()) - } - - #[cfg(target_os = "macos")] - { - build_comp_script(&ShellFlag::Zsh, name)?; - build_comp_script(&ShellFlag::Bash, name)?; - build_comp_script(&ShellFlag::Fish, name)?; - Ok(()) - } -} - -/// Generate a shell completion script for a specific shell. -/// -/// This function takes a shell flag and a binary name, selects the appropriate -/// template, substitutes the binary name into the template, and writes the -/// resulting completion script to the target directory (typically `target/`). -/// -/// # Example -/// ``` -/// # #[cfg(all(feature = "build", feature = "comp"))] { -/// # temp_env::with_var("OUT_DIR", Some(".temp/target/test/out/"), || { -/// # use mingling_core::ShellFlag; -/// # use mingling_core::build::build_comp_script; -/// build_comp_script(&ShellFlag::Bash, "myapp").unwrap(); -/// # }); -/// # } -/// ``` -pub fn build_comp_script(shell_flag: &ShellFlag, bin_name: &str) -> Result<(), std::io::Error> { - let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()); - let target_dir = out_dir.join("../../../"); - build_comp_script_to(shell_flag, bin_name, &target_dir.to_string_lossy()) -} - -/// Generate a shell completion script to a specified directory. -/// -/// This function takes a shell flag, a binary name, and a target directory path, -/// selects the appropriate template, substitutes the binary name into the template, -/// and writes the resulting completion script to the specified directory. -/// -/// # Example -/// ``` -/// # #[cfg(all(feature = "build", feature = "comp"))] { -/// # temp_env::with_var("OUT_DIR", Some(".temp/target/test/out/"), || { -/// # use mingling_core::ShellFlag; -/// # use mingling_core::build::build_comp_script_to; -/// build_comp_script_to(&ShellFlag::Bash, "myapp", ".temp/target/test/out/").unwrap(); -/// # }); -/// # } -/// ``` -pub fn build_comp_script_to( - shell_flag: &ShellFlag, - bin_name: &str, - target_dir: &str, -) -> Result<(), std::io::Error> { - let (tmpl_str, ext) = get_tmpl(shell_flag); - let mut tmpl = just_template::Template::from(tmpl_str); - tmpl!(bin_name = bin_name); - let target_path = std::path::PathBuf::from(target_dir); - std::fs::create_dir_all(&target_path)?; - let output_path = target_path.join(format!("{bin_name}_comp{ext}")); - std::fs::write(&output_path, tmpl.to_string()) -} - -/// Generate a shell completion script and write it to a specified file path. -/// -/// This function takes a shell flag, a binary name, and an output file path, -/// selects the appropriate template, substitutes the binary name into the template, -/// and writes the resulting completion script directly to the specified file path. -/// -/// # Example -/// ``` -/// # #[cfg(all(feature = "build", feature = "comp"))] { -/// # temp_env::with_var("OUT_DIR", Some(".temp/target/test/out/"), || { -/// # use mingling_core::ShellFlag; -/// # use mingling_core::build::build_comp_script_to_file; -/// build_comp_script_to_file(&ShellFlag::Bash, "myapp", ".temp/target/test/out/myapp.comp.sh").unwrap(); -/// # }); -/// # } -/// ``` -pub fn build_comp_script_to_file( - shell_flag: &ShellFlag, - bin_name: &str, - output_path: impl Into<PathBuf>, -) -> Result<(), std::io::Error> { - let (tmpl_str, _ext) = get_tmpl(shell_flag); - let mut tmpl = just_template::Template::from(tmpl_str); - tmpl!(bin_name = bin_name); - std::fs::write(output_path.into(), tmpl.to_string()) -} - -const fn get_tmpl(shell_flag: &ShellFlag) -> (&'static str, &'static str) { - match shell_flag { - ShellFlag::Bash | ShellFlag::Other(_) => (TMPL_COMP_BASH, ".sh"), - ShellFlag::Zsh => (TMPL_COMP_ZSH, ".zsh"), - ShellFlag::Fish => (TMPL_COMP_FISH, ".fish"), - ShellFlag::Powershell => (TMPL_COMP_PWSH, ".ps1"), - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::ShellFlag; - - #[test] - fn get_tmpl_bash() { - let (tmpl, ext) = get_tmpl(&ShellFlag::Bash); - assert_eq!(ext, ".sh"); - assert!(!tmpl.is_empty(), "bash template should not be empty"); - } - - #[test] - fn get_tmpl_zsh() { - let (tmpl, ext) = get_tmpl(&ShellFlag::Zsh); - assert_eq!(ext, ".zsh"); - assert!(!tmpl.is_empty(), "zsh template should not be empty"); - } - - #[test] - fn get_tmpl_fish() { - let (tmpl, ext) = get_tmpl(&ShellFlag::Fish); - assert_eq!(ext, ".fish"); - assert!(!tmpl.is_empty(), "fish template should not be empty"); - } - - #[test] - fn get_tmpl_powershell() { - let (tmpl, ext) = get_tmpl(&ShellFlag::Powershell); - assert_eq!(ext, ".ps1"); - assert!(!tmpl.is_empty(), "powershell template should not be empty"); - } - - #[test] - fn get_tmpl_other() { - let (tmpl, ext) = get_tmpl(&ShellFlag::Other("custom".to_string())); - assert_eq!(ext, ".sh"); - assert!(!tmpl.is_empty(), "fallback template should not be empty"); - } -} diff --git a/mingling_core/src/build/pathf.rs b/mingling_core/src/build/pathf.rs deleted file mode 100644 index 4b8af1b..0000000 --- a/mingling_core/src/build/pathf.rs +++ /dev/null @@ -1,98 +0,0 @@ -#![allow(unused_imports)] - -pub use mingling_pathf::module_pathf::*; -pub use mingling_pathf::pattern_analyzer::*; -pub use mingling_pathf::patterns::*; - -use std::path::Path; - -/// Analyzes and builds a type mapping for a specific crate. -/// -/// Accepts `crate_dir` and `output_dir`, and invokes `pathf` to build the type mapping. -/// -/// # Arguments -/// -/// - `crate_dir`: Root directory of the crate's source code to analyze (usually `CARGO_MANIFEST_DIR`). -/// - `output_dir`: Output directory for generated artifacts (type mapping data). -/// -/// # Returns -/// -/// - On success: returns `Ok(())`; -/// - On failure: returns the corresponding `MinglingPathfinderError`. -/// -/// # Example -/// -/// ``` -/// # #[cfg(all(feature = "build", feature = "pathf"))] { -/// use mingling_core::build::analyze_and_build_type_mapping_for; -/// use std::path::Path; -/// -/// let crate_dir = Path::new("."); -/// let output_dir = Path::new(".temp/target/out"); -/// analyze_and_build_type_mapping_for(crate_dir, output_dir).expect("analysis failed"); -/// # } -/// ``` -pub fn analyze_and_build_type_mapping_for( - crate_dir: &Path, - output_dir: &Path, -) -> Result<(), crate::error::MinglingPathfinderError> { - mingling_pathf::analyze_and_build_type_mapping_for(crate_dir, output_dir) -} - -/// # Analyzes and builds a type mapping -/// -/// This function reads the current crate directory (`CARGO_PKG_NAME`) and output directory (`OUT_DIR`) -/// from environment variables, automatically combines them into the target output path, and invokes -/// the underlying analysis logic. Suitable for use in `build.rs`. -/// -/// It also sends the `cargo:rerun-if-changed=src/` directive to Cargo so that a rebuild is -/// automatically triggered when source code changes. -/// -/// # Prerequisites -/// -/// This function depends on the following environment variables, which are typically set -/// automatically during a Cargo build: -/// -/// - `CARGO_PKG_NAME`: Name of the current crate. -/// - `OUT_DIR`: Build output directory provided by Cargo. -/// -/// If these variables are missing, a corresponding [`MinglingPathfinderError`](crate::error::MinglingPathfinderError) -/// is returned. -/// -/// # Returns -/// -/// Returns `Ok(())` on success; returns a corresponding -/// [`MinglingPathfinderError`](crate::error::MinglingPathfinderError) on failure. -/// -/// # Example -/// -/// ``` -/// # #[cfg(all(feature = "build", feature = "pathf"))] { -/// use mingling_core::build::analyze_and_build_type_mapping; -/// -/// fn main() { -/// analyze_and_build_type_mapping().expect("failed to build type mapping"); -/// } -/// # } -/// ``` - -pub fn analyze_and_build_type_mapping() -> Result<(), crate::error::MinglingPathfinderError> { - let crate_dir = - std::env::current_dir().map_err(crate::error::MinglingPathfinderError::IoError)?; - let crate_name = std::env::var("CARGO_PKG_NAME").map_err(|_| { - crate::error::MinglingPathfinderError::IoError(std::io::Error::new( - std::io::ErrorKind::NotFound, - "CARGO_PKG_NAME not set", - )) - })?; - let out_dir = std::env::var("OUT_DIR").map_err(|_| { - crate::error::MinglingPathfinderError::IoError(std::io::Error::new( - std::io::ErrorKind::NotFound, - "OUT_DIR not set", - )) - })?; - let output_dir = Path::new(&out_dir).join(&crate_name); - mingling_pathf::analyze_and_build_type_mapping_for(&crate_dir, &output_dir)?; - println!("cargo:rerun-if-changed=src/"); - Ok(()) -} diff --git a/mingling_core/src/docs/build.md b/mingling_core/src/docs/build.md deleted file mode 100644 index 6f9285a..0000000 --- a/mingling_core/src/docs/build.md +++ /dev/null @@ -1,57 +0,0 @@ -Provide Mingling's build script module for build-time behavior of specific features in `build.rs`. - -To use it, add a dependency on mingling under `[build-dependencies]` in `Cargo.toml`, and enable the relevant features: - -## Build-Time Related Features - -| Name | Purpose | -| ---------------- | ------------------------------------------------------------------------------------------------- | -| `build` | Master switch for build-time features | -| `build_advanced` | Master switch for build-time features, paired with the `advanced` feature | -| `build_full` | Master switch for build-time features, paired with the `full` feature | -| `comp` | Completion script builder; both sides must enable it, generates cross-platform completion scripts | -| `pathf` | Type path analyzer; both sides must enable it, generates type mapping tables | -| `dispatch_tree` | Compile-time dispatch tree; when `pathf` is a build-time dependency, | -| | and `dispatch_tree` (included in `advanced` or `full`) is enabled, both sides should enable it | - -```toml -# Cargo.toml -[dependencies.mingling] -features = [ - "advanced", # Enable `advanced` if using it -] - -[build-dependencies.mingling] -features = [ - "build_advanced" # This side should enable `build_advanced` -] -``` - -## `build.rs` Templates - -You can use the following template to write `build.rs` to quickly gain the build-time capabilities of `comp` and `pathf`: - -```rust,ignore -// build.rs -fn main() { - build_scripts(); - build_pathf_mapping(); -} - -/// Generate completion scripts -fn build_scripts() { - // `env!("CARGO_PKG_NAME")` equals the crate name, which matches the binary name. - // If your binary name differs from the crate name, specify it explicitly. - mingling::build::build_comp_scripts( - // Your binary name: - env!("CARGO_PKG_NAME"), - ) - .unwrap(); -} - -fn build_pathf_mapping() { - // Build pathf type mapping to ensure that the enabled `pathf` feature - // can correctly scan macros in the project - mingling::build::analyze_and_build_type_mapping().unwrap(); -} -``` diff --git a/mingling_core/src/lib.rs b/mingling_core/src/lib.rs index 2aa2ce1..1d26ebb 100644 --- a/mingling_core/src/lib.rs +++ b/mingling_core/src/lib.rs @@ -46,10 +46,6 @@ pub mod core_res { #[cfg(feature = "comp")] pub(crate) mod comp; -#[cfg(feature = "build")] -#[doc = include_str!("docs/build.md")] -pub mod build; - // Public Modules /// Provides a toolkit for `Mingling` testing capabilities. @@ -90,9 +86,6 @@ pub mod error { #[cfg(feature = "structural_renderer")] pub use crate::renderer::structural::error::*; - - #[cfg(feature = "pathf")] - pub use mingling_pathf::error::*; } #[doc(hidden)] |
