summaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-04-04 20:04:30 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-04-04 20:04:30 +0200
commita4d7f4cad88472dbcf5b4dd433cfef5f9624d7e8 (patch)
treede25d6397f77dfc6638ae7e321e30fb168d34d12 /crates
parentb433fbf27b8d6ccf6e13d4b6a28de556012576d7 (diff)
downloadrebel-a4d7f4cad88472dbcf5b4dd433cfef5f9624d7e8.tar
rebel-a4d7f4cad88472dbcf5b4dd433cfef5f9624d7e8.zip
driver: resolve: limit number of reported errors
Reporting all dependency cycles may lead to a large number of errors in some cases, resulting in a long wait just for collecting the error data.
Diffstat (limited to 'crates')
-rw-r--r--crates/driver/src/resolve.rs59
1 files changed, 41 insertions, 18 deletions
diff --git a/crates/driver/src/resolve.rs b/crates/driver/src/resolve.rs
index d03f26d..c13fcd2 100644
--- a/crates/driver/src/resolve.rs
+++ b/crates/driver/src/resolve.rs
@@ -7,7 +7,7 @@ use common::types::TaskID;
use crate::args::TaskArgs;
use crate::context::{self, Context, OutputRef, TaskRef};
-#[derive(Debug)]
+#[derive(Debug, Default)]
pub struct DepChain<'ctx>(pub Vec<TaskRef<'ctx>>);
impl<'ctx> fmt::Display for DepChain<'ctx> {
@@ -48,11 +48,14 @@ impl<'ctx> From<&'ctx TaskID> for DepChain<'ctx> {
}
}
+const MAX_ERRORS: usize = 100;
+
#[derive(Debug)]
pub enum ErrorKind<'ctx> {
Context(context::Error<'ctx>),
OutputNotFound(&'ctx str),
DependencyCycle,
+ TooManyErrors,
}
#[derive(Debug)]
@@ -76,6 +79,13 @@ impl<'ctx> Error<'ctx> {
}
}
+ fn too_many_errors() -> Self {
+ Error {
+ dep_chain: DepChain::default(),
+ kind: ErrorKind::TooManyErrors,
+ }
+ }
+
fn extend(&mut self, task: &TaskRef<'ctx>) {
self.dep_chain.0.push(task.clone());
}
@@ -94,6 +104,9 @@ impl<'ctx> fmt::Display for Error<'ctx> {
ErrorKind::DependencyCycle => {
write!(f, "Dependency Cycle: ")?;
}
+ ErrorKind::TooManyErrors => {
+ write!(f, "Too many errors, stopping.")?;
+ }
}
dep_chain.fmt(f)
}
@@ -254,33 +267,43 @@ impl<'ctx> Resolver<'ctx> {
.insert(task.clone(), ResolveState::Resolving);
let mut ret = Vec::new();
- let mut handle_errors = |errors: Vec<Error<'ctx>>| {
+ let mut handle_errors = |errors: Vec<Error<'ctx>>| -> Result<(), ()> {
for mut error in errors {
error.extend(task);
ret.push(error);
+
+ if ret.len() > MAX_ERRORS {
+ ret.push(Error::too_many_errors());
+ return Err(());
+ }
}
+ Ok(())
};
- match self.ctx.get_inherit_depend(task) {
- Ok(Some(inherit)) => {
- handle_errors(self.add_task(&inherit, None));
- }
- Ok(None) => {}
- Err(err) => {
- handle_errors(vec![err.into()]);
+ let _ = (|| -> Result<(), ()> {
+ match self.ctx.get_inherit_depend(task) {
+ Ok(Some(inherit)) => {
+ handle_errors(self.add_task(&inherit, None))?;
+ }
+ Ok(None) => {}
+ Err(err) => {
+ handle_errors(vec![err.into()])?;
+ }
}
- }
- match get_dependent_outputs(self.ctx, task) {
- Ok(rdeps) => {
- for rdep in rdeps {
- handle_errors(self.add_task(&rdep.task, Some(rdep.output)));
+ match get_dependent_outputs(self.ctx, task) {
+ Ok(rdeps) => {
+ for rdep in rdeps {
+ handle_errors(self.add_task(&rdep.task, Some(rdep.output)))?;
+ }
+ }
+ Err(errors) => {
+ handle_errors(errors)?;
}
}
- Err(errors) => {
- handle_errors(errors);
- }
- }
+
+ Ok(())
+ })();
if ret.is_empty() {
*self