diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-08-19 05:54:00 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-08-19 06:15:20 +0800 |
| commit | ec9edc294fd5e7e29977fc7b0e6fb953422bc0e2 (patch) | |
| tree | bbf89ef4457b8de8a8a9bca5668045d612d27572 /dev/ci/src/res/crate_config.rs | |
| parent | 06dfc27194c11e1d1033c292c759a1c5d82e780b (diff) | |
Move CI, dev tools, and configs from root-level scattered locations into
a
unified `dev/` directory structure. Update all references across build
scripts, documentation, and editor configurations.
Also consolidate editor config generation into build.rs for automated
synchronization of rust-analyzer settings across VS Code and Zed.
Diffstat (limited to 'dev/ci/src/res/crate_config.rs')
| -rw-r--r-- | dev/ci/src/res/crate_config.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/dev/ci/src/res/crate_config.rs b/dev/ci/src/res/crate_config.rs new file mode 100644 index 0000000..b20e83d --- /dev/null +++ b/dev/ci/src/res/crate_config.rs @@ -0,0 +1,79 @@ +use std::collections::HashMap; +use std::path::Path; + +use mingling::{Program, macros::program_setup}; + +use crate::ThisProgram; +use crate::res::{Manifests, ResFeatureList}; + +/// Per-crate CI overrides from `mingling-ci.toml` (optional, crate root). +/// +/// Currently only `[test] command` is read; `clippy.command` / `build.command` +/// will follow the same shape. +#[derive(Default, Clone)] +pub struct ResCrateConfig { + /// Package name -> test command argv (with `<<<features>>>` expanded). + test_commands: HashMap<String, Vec<String>>, +} + +impl ResCrateConfig { + /// The configured `[test] command` for a package, if any. + #[must_use] + pub fn test_command(&self, package: &str) -> Option<&[String]> { + self.test_commands.get(package).map(Vec::as_slice) + } +} + +#[program_setup] +pub fn crate_config_setup(p: &mut Program<ThisProgram>) { + let features = p + .res::<ResFeatureList>() + .map(|f| f.list.clone()) + .unwrap_or_default(); + let joined_features = features.join(","); + + let Some(manifests) = p.res::<Manifests>() else { + return; + }; + + let mut test_commands = HashMap::new(); + for (name, manifest_path) in &manifests.package_dirs { + let config_path = manifest_path + .parent() + .unwrap_or_else(|| Path::new(".")) + .join("mingling-ci.toml"); + + let Ok(content) = std::fs::read_to_string(&config_path) else { + continue; + }; + + let Ok(table) = content.parse::<toml::Value>() else { + continue; + }; + + let Some(command) = table + .get("test") + .and_then(|t| t.get("command")) + .and_then(|c| c.as_array()) + else { + continue; + }; + + let argv: Vec<String> = command + .iter() + .filter_map(|v| v.as_str().map(str::to_string)) + .collect(); + + if argv.is_empty() { + continue; + } + + let argv = argv + .into_iter() + .map(|arg| arg.replace("<<<features>>>", &joined_features)) + .collect(); + test_commands.insert(name.clone(), argv); + } + + p.with_resource(ResCrateConfig { test_commands }); +} |
