aboutsummaryrefslogtreecommitdiff
path: root/dev/ci/src/task/cmd_example_check.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/task/cmd_example_check.rs
parent06dfc27194c11e1d1033c292c759a1c5d82e780b (diff)
chore: reorganize dev tools into dev/ directory and consolidate configsHEADmain
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/task/cmd_example_check.rs')
-rw-r--r--dev/ci/src/task/cmd_example_check.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/dev/ci/src/task/cmd_example_check.rs b/dev/ci/src/task/cmd_example_check.rs
new file mode 100644
index 0000000..1b9f440
--- /dev/null
+++ b/dev/ci/src/task/cmd_example_check.rs
@@ -0,0 +1,69 @@
+use colored::Colorize;
+use mingling::{
+ Grouped, Routable,
+ macros::{buffer, command, renderer},
+ res::ResExitCode,
+};
+
+use crate::Next;
+use crate::examples::{check_example, load_test_configs};
+use crate::progress::task_progress_bar;
+use crate::reporter::{self, ReportResult};
+
+#[command(node = "example-check")]
+pub async fn example_check() -> Next {
+ reporter::set_task("Example-Check");
+
+ let configs = load_test_configs();
+ let total = configs.len();
+ let pb = task_progress_bar(total, "Testing");
+ pb.set_message("examples");
+
+ // One blocking task per example: build + run its test cases.
+ let mut handles = Vec::new();
+ for example in configs {
+ handles.push(tokio::task::spawn_blocking(move || check_example(example)));
+ }
+
+ let mut fail_count = 0;
+ for handle in handles {
+ let Ok(outcome) = handle.await else {
+ continue;
+ };
+ pb.set_message(outcome.name.clone());
+ pb.inc(1);
+
+ if outcome.ok {
+ reporter::export(&outcome.name, &outcome.location, ReportResult::Ok);
+ } else {
+ fail_count += 1;
+ // Plain stderr: `pb.println` is swallowed on non-TTY (CI).
+ eprintln!(" {} {}", "failed".bright_red(), outcome.name);
+ eprintln!(" {}", outcome.output);
+ reporter::export(
+ &outcome.name,
+ &outcome.location,
+ ReportResult::Error(outcome.output),
+ );
+ }
+ }
+
+ pb.finish_and_clear();
+ reporter::flush();
+
+ ResultExampleCheck { fail_count }.to_chain()
+}
+
+/// Number of examples that failed to build or pass their tests.
+#[derive(Grouped)]
+pub struct ResultExampleCheck {
+ pub fail_count: usize,
+}
+
+/// Silently sets a non-zero exit code when any example failed.
+#[renderer(buffer)]
+pub fn render_example_check(r: ResultExampleCheck, exit_code: &mut ResExitCode) {
+ if r.fail_count > 0 {
+ exit_code.exit_code = 1;
+ }
+}