diff --git a/moz-webgpu-cts/src/file_spec.rs b/moz-webgpu-cts/src/file_spec.rs new file mode 100644 index 00000000..49eacb69 --- /dev/null +++ b/moz-webgpu-cts/src/file_spec.rs @@ -0,0 +1,126 @@ +use std::{fmt::Display, path::PathBuf}; + +use miette::Report; +use wax::Glob; + +use crate::AlreadyReportedToCommandline; + +pub(crate) struct FileSpec { + pub paths: Vec, + pub globs: Vec, +} + +impl FileSpec { + pub(crate) fn into_paths( + self, + what: impl Display, + ) -> Result, AlreadyReportedToCommandline> { + let Self { paths, globs } = self; + + let globs = { + let mut found_glob_parse_err = false; + let globs = globs + .into_iter() + .filter_map(|glob| match Glob::diagnosed(&glob) { + Ok((glob, _diagnostics)) => Some(glob.into_owned().partition()), + Err(diagnostics) => { + found_glob_parse_err = true; + let error_reports = diagnostics + .into_iter() + .filter(|diag| { + // N.B.: There should be at least one of these! + diag.severity() + .is_none_or(|sev| sev == miette::Severity::Error) + }) + .map(Report::new_boxed); + for report in error_reports { + eprintln!("{report:?}"); + } + None + } + }) + .collect::>(); + + if found_glob_parse_err { + log::error!("failed to parse one or more globs for {what}; bailing"); + return Err(AlreadyReportedToCommandline); + } + + globs + }; + + let paths_from_globs = { + let mut found_glob_walk_err = false; + let files = globs + .iter() + .flat_map(|(base_path, glob)| { + glob.walk(base_path) + .filter_map(|entry| match entry { + Ok(entry) => Some(entry.into_path()), + Err(e) => { + found_glob_walk_err = true; + let ctx_msg = if let Some(path) = e.path() { + format!( + "failed to enumerate {what} from glob `{}` at path {}", + glob, + path.display() + ) + } else { + format!("failed to enumerate {what} from glob `{glob}`") + }; + let e = Report::msg(e).wrap_err(ctx_msg); + eprintln!("{e:?}"); + None + } + }) + .collect::>() // OPT: Can we get rid of this somehow? + }) + .collect::>(); + + if found_glob_walk_err { + log::error!( + concat!( + "failed to enumerate {} from globs, ", + "see above for more details" + ), + what + ); + return Err(AlreadyReportedToCommandline); + } + + files + }; + + if paths_from_globs.is_empty() && !globs.is_empty() { + if paths.is_empty() { + log::error!( + concat!( + "{} were specified exclusively via glob search, ", + "but none were found; bailing" + ), + what + ); + return Err(AlreadyReportedToCommandline); + } else { + log::warn!( + concat!( + "{} were specified via path and glob search, ", + "but none were found via glob; ", + "continuing with direct paths" + ), + what + ) + } + } + + let exec_report_paths = paths + .into_iter() + .chain(paths_from_globs) + .collect::>(); + + log::trace!("working with the following {what}: {exec_report_paths:#?}"); + log::info!("working with {} {what}", exec_report_paths.len()); + + Ok(exec_report_paths) + } +} diff --git a/moz-webgpu-cts/src/main.rs b/moz-webgpu-cts/src/main.rs index 14649d56..08475218 100644 --- a/moz-webgpu-cts/src/main.rs +++ b/moz-webgpu-cts/src/main.rs @@ -1,15 +1,19 @@ +mod file_spec; mod process_reports; mod report; mod wpt; -use self::wpt::{ - metadata::{ - self, - properties::{ExpandedPropertyValue, Expected}, - File, ImplementationStatus, Platform, Subtest, SubtestOutcome, Test, TestOutcome, - TestProps, +use self::{ + file_spec::FileSpec, + wpt::{ + metadata::{ + self, + properties::{ExpandedPropertyValue, Expected}, + File, ImplementationStatus, Platform, Subtest, SubtestOutcome, Test, TestOutcome, + TestProps, + }, + path::TestEntryPath, }, - path::TestEntryPath, }; use std::{ @@ -161,102 +165,11 @@ impl ExecReportSpec { report_globs, } = self; - let report_globs = { - let mut found_glob_parse_err = false; - let globs = report_globs - .into_iter() - .filter_map(|glob| match Glob::diagnosed(&glob) { - Ok((glob, _diagnostics)) => Some(glob.into_owned().partition()), - Err(diagnostics) => { - found_glob_parse_err = true; - let error_reports = diagnostics - .into_iter() - .filter(|diag| { - // N.B.: There should be at least one of these! - diag.severity() - .is_none_or(|sev| sev == miette::Severity::Error) - }) - .map(Report::new_boxed); - for report in error_reports { - eprintln!("{report:?}"); - } - None - } - }) - .collect::>(); - - if found_glob_parse_err { - log::error!("failed to parse one or more WPT report globs; bailing"); - return Err(AlreadyReportedToCommandline); - } - - globs - }; - - let report_paths_from_glob = { - let mut found_glob_walk_err = false; - let files = report_globs - .iter() - .flat_map(|(base_path, glob)| { - glob.walk(base_path) - .filter_map(|entry| match entry { - Ok(entry) => Some(entry.into_path()), - Err(e) => { - found_glob_walk_err = true; - let ctx_msg = if let Some(path) = e.path() { - format!( - "failed to enumerate files for glob `{}` at path {}", - glob, - path.display() - ) - } else { - format!("failed to enumerate files for glob `{glob}`") - }; - let e = Report::msg(e).wrap_err(ctx_msg); - eprintln!("{e:?}"); - None - } - }) - .collect::>() // OPT: Can we get rid of this somehow? - }) - .collect::>(); - - if found_glob_walk_err { - log::error!(concat!( - "failed to enumerate files with WPT report globs, ", - "see above for more details" - )); - return Err(AlreadyReportedToCommandline); - } - - files - }; - - if report_paths_from_glob.is_empty() && !report_globs.is_empty() { - if report_paths.is_empty() { - log::error!(concat!( - "reports were specified exclusively via glob search, ", - "but none were found; bailing" - )); - return Err(AlreadyReportedToCommandline); - } else { - log::warn!(concat!( - "reports were specified via path and glob search, ", - "but none were found via glob; ", - "continuing with report paths" - )) - } + FileSpec { + paths: report_paths, + globs: report_globs, } - - let exec_report_paths = report_paths - .into_iter() - .chain(report_paths_from_glob) - .collect::>(); - - log::trace!("working with the following WPT report files: {exec_report_paths:#?}"); - log::info!("working with {} WPT report files", exec_report_paths.len()); - - Ok(exec_report_paths) + .into_paths("WPT report(s)") } }