aboutsummaryrefslogtreecommitdiff
path: root/dev/ci/src/res/crate_config.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-08-19 05:54:00 +0800
committer魏曹先生 <1992414357@qq.com>2026-08-19 06:15:20 +0800
commitec9edc294fd5e7e29977fc7b0e6fb953422bc0e2 (patch)
treebbf89ef4457b8de8a8a9bca5668045d612d27572 /dev/ci/src/res/crate_config.rs
parent06dfc27194c11e1d1033c292c759a1c5d82e780b (diff)
chore: reorganize dev tools into dev/ directory and consolidate configs
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.rs79
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 });
+}