aboutsummaryrefslogtreecommitdiff
path: root/mingling_ci/src/reporter.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 /mingling_ci/src/reporter.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 'mingling_ci/src/reporter.rs')
-rw-r--r--mingling_ci/src/reporter.rs208
1 files changed, 0 insertions, 208 deletions
diff --git a/mingling_ci/src/reporter.rs b/mingling_ci/src/reporter.rs
deleted file mode 100644
index 1a1ac08..0000000
--- a/mingling_ci/src/reporter.rs
+++ /dev/null
@@ -1,208 +0,0 @@
-//! Minimal log exporter for CI reports.
-//!
-//! Writes per-package results into `collect/{task}/{platform}/{package}.{ok|err}`
-//! so that the [`crate::cmd::collect_results`] command can assemble the final
-//! report. The task name is set once per CI phase via [`set_task`].
-
-use std::collections::HashMap;
-use std::fs;
-use std::path::Path;
-use std::sync::{LazyLock, Mutex};
-
-/// Root of the collected CI logs (relative to the repo root).
-pub const COLLECT_DIR: &str = "./.temp/reports/collect";
-
-/// Generated report output (relative to the repo root).
-pub const REPORT_PATH: &str = "./.temp/reports/result.md";
-
-/// The platform a package check ran on.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
-pub enum ReportPlatform {
- Windows,
- Linux,
- MacOS,
-}
-
-impl ReportPlatform {
- /// Directory name used under the task folder.
- const fn dir_name(self) -> &'static str {
- match self {
- Self::Windows => "Windows",
- Self::Linux => "Linux",
- Self::MacOS => "MacOS",
- }
- }
-}
-
-/// The outcome of a package check.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum ReportResult {
- /// Check passed.
- Ok,
- /// Check failed, with the captured output.
- Error(String),
-}
-
-/// Current task name (e.g. `Build-All`); set via [`set_task`].
-static CURRENT_TASK: Mutex<Option<String>> = Mutex::new(None);
-
-/// Pending success entries: `(item, location)`.
-type PendingOk = (String, String);
-
-/// Successful items pending a [`flush`], grouped by platform.
-static OK_BUFFER: LazyLock<Mutex<HashMap<ReportPlatform, Vec<PendingOk>>>> =
- LazyLock::new(|| Mutex::new(HashMap::new()));
-
-/// Sets the task that subsequent [`export`] calls write under.
-///
-/// # Panics
-///
-/// Panics if the internal mutex is poisoned.
-pub fn set_task(task: &str) {
- *CURRENT_TASK.lock().unwrap() = Some(task.to_string());
-}
-
-/// Exports one item result.
-///
-/// `item` and `location` are free-form strings chosen by the generator.
-/// Successes are buffered and written to the `ok` file by [`flush`]; failures
-/// write `{task}.{platform}.{item}.err` immediately (first line is the
-/// location). Errors are reported to stderr and otherwise ignored.
-///
-/// # Panics
-///
-/// Panics if the internal task mutex is poisoned.
-pub fn export(item: &str, location: &str, result: ReportResult) {
- export_on(item, location, current_platform(), result);
-}
-
-/// The `ReportPlatform` for the currently compiling target.
-fn current_platform() -> ReportPlatform {
- if cfg!(target_os = "windows") {
- ReportPlatform::Windows
- } else if cfg!(target_os = "macos") {
- ReportPlatform::MacOS
- } else {
- ReportPlatform::Linux
- }
-}
-
-/// Exports one item result for a specific platform.
-///
-/// `item` and `location` are free-form strings chosen by the generator.
-/// Successes are buffered and written to the `ok` file by [`flush`]; failures
-/// write `{task}.{platform}.{item}.err` immediately (first line is the
-/// location). Errors are reported to stderr and otherwise ignored.
-///
-/// # Panics
-///
-/// Panics if the internal task mutex is poisoned.
-pub fn export_on(item: &str, location: &str, platform: ReportPlatform, result: ReportResult) {
- match result {
- ReportResult::Ok => OK_BUFFER
- .lock()
- .unwrap()
- .entry(platform)
- .or_default()
- .push((item.to_string(), location.to_string())),
- ReportResult::Error(output) => write_err(item, location, platform, &output),
- }
-}
-
-/// Writes buffered successes to `collect/{task}.{platform}.ok`, one `item` (or
-/// `item = location`) per line.
-///
-/// # Panics
-///
-/// Panics if the internal task mutex is poisoned.
-pub fn flush() {
- let Some(task) = CURRENT_TASK.lock().unwrap().clone() else {
- eprintln!("reporter: no current task; call reporter::set_task first");
- return;
- };
-
- let buffered = std::mem::take(&mut *OK_BUFFER.lock().unwrap());
- if buffered.is_empty() {
- return;
- }
-
- if let Err(e) = fs::create_dir_all(COLLECT_DIR) {
- eprintln!("reporter: failed to create {COLLECT_DIR}: {e}");
- return;
- }
-
- for (platform, items) in buffered {
- let lines: Vec<String> = items
- .iter()
- .map(|(item, location)| {
- if location.is_empty() {
- item.clone()
- } else {
- format!("{item} = {location}")
- }
- })
- .collect();
- let content = if lines.is_empty() {
- String::new()
- } else {
- lines.join("\n") + "\n"
- };
- let platform_name = platform.dir_name();
- let path = Path::new(COLLECT_DIR).join(format!("{task}.{platform_name}.ok"));
- if let Err(e) = fs::write(&path, content) {
- eprintln!("reporter: failed to write {}: {e}", path.display());
- }
- }
-}
-
-/// Writes a failure entry to `collect/{task}.{platform}.{item}.err`, with the
-/// location as the first line (empty when unknown).
-fn write_err(item: &str, location: &str, platform: ReportPlatform, output: &str) {
- let Some(task) = CURRENT_TASK.lock().unwrap().clone() else {
- eprintln!("reporter: no current task; call reporter::set_task first");
- return;
- };
-
- if let Err(e) = fs::create_dir_all(COLLECT_DIR) {
- eprintln!("reporter: failed to create {COLLECT_DIR}: {e}");
- return;
- }
-
- let platform_name = platform.dir_name();
- let path = Path::new(COLLECT_DIR).join(format!("{task}.{platform_name}.{item}.err"));
- if let Err(e) = fs::write(&path, format!("{location}\n{output}")) {
- eprintln!("reporter: failed to write {}: {e}", path.display());
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn export_writes_ok_and_err_files() {
- set_task("reporter-test");
- let platform_name = current_platform().dir_name();
- let ok_path = Path::new(COLLECT_DIR).join(format!("reporter-test.{platform_name}.ok"));
- let err_path =
- Path::new(COLLECT_DIR).join(format!("reporter-test.{platform_name}.pkg-b.err"));
- fs::remove_file(&ok_path).ok();
- fs::remove_file(&err_path).ok();
-
- export("pkg-a", "./pkg-a", ReportResult::Ok);
- export("pkg-b", "./pkg-b", ReportResult::Error("boom".to_string()));
- export("pkg-c", "", ReportResult::Ok); // no location
- flush();
-
- assert!(ok_path.is_file());
- assert_eq!(
- fs::read_to_string(&ok_path).unwrap(),
- "pkg-a = ./pkg-a\npkg-c\n"
- );
- assert!(err_path.is_file());
- assert_eq!(fs::read_to_string(&err_path).unwrap(), "./pkg-b\nboom");
-
- fs::remove_file(ok_path).ok();
- fs::remove_file(err_path).ok();
- }
-}