diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-09-26 22:57:29 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-09-26 23:15:44 +0200 |
commit | 075e7c7fdc04c2173aac3d94127791a162d41bc1 (patch) | |
tree | e73fc27aab919d91396a42f3984926bd611d3d2d | |
parent | 82f2a406a0d9c3012c75197dc22e8c26a0187e87 (diff) | |
download | rebel-075e7c7fdc04c2173aac3d94127791a162d41bc1.tar rebel-075e7c7fdc04c2173aac3d94127791a162d41bc1.zip |
context: include dependencies from inherited tasks
In most cases, inheriting tasks want to use the same dependencies as
their ancestors. For special cases like gcc's header stubs, a noinherit
flag can be set on dependencies.
-rw-r--r-- | examples/gcc.yml | 2 | ||||
-rw-r--r-- | examples/libgcc-initial.yml | 2 | ||||
-rw-r--r-- | src/context.rs | 72 | ||||
-rw-r--r-- | src/task.rs | 2 |
4 files changed, 66 insertions, 12 deletions
diff --git a/examples/gcc.yml b/examples/gcc.yml index ac67a31..4bc19f4 100644 --- a/examples/gcc.yml +++ b/examples/gcc.yml @@ -30,6 +30,7 @@ tasks: target: 'target' depends: - task: 'header-stubs' + noinherit: true run: | mkdir gcc-build cd gcc-build @@ -85,6 +86,7 @@ tasks: target: 'target' depends: - task: 'header-stubs' + noinherit: true run: | cd gcc-build make -j8 all-host diff --git a/examples/libgcc-initial.yml b/examples/libgcc-initial.yml index 89a6734..046ff4f 100644 --- a/examples/libgcc-initial.yml +++ b/examples/libgcc-initial.yml @@ -14,6 +14,7 @@ tasks: depends: - recipe: 'gcc' task: 'header-stubs' + noinherit: true run: | cd gcc-build make configure-target-libgcc @@ -43,6 +44,7 @@ tasks: depends: - recipe: 'gcc' task: 'header-stubs' + noinherit: true run: | cd gcc-build make -j8 all-target-libgcc diff --git a/src/context.rs b/src/context.rs index 139b5d7..2fc4905 100644 --- a/src/context.rs +++ b/src/context.rs @@ -18,14 +18,14 @@ use crate::{ util::error, }; -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub enum ErrorKind<'ctx> { TaskNotFound, InvalidArgument(&'ctx str), InvalidArgRef(&'ctx str), } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub struct Error<'ctx> { pub task: &'ctx TaskID, pub kind: ErrorKind<'ctx>, @@ -231,26 +231,74 @@ impl Context { Some(self.inherit_ref(inherit, &task_ref.args)).transpose() } + fn inherit_iter<'ctx>( + &'ctx self, + task_ref: &TaskRef<'ctx>, + ) -> impl Iterator<Item = Result<TaskRef>> { + struct Iter<'ctx>(&'ctx Context, Option<Result<'ctx, TaskRef<'ctx>>>); + + impl<'ctx> Iterator for Iter<'ctx> { + type Item = Result<'ctx, TaskRef<'ctx>>; + + fn next(&mut self) -> Option<Self::Item> { + let task_ref = match self.1.take()? { + Ok(task_ref) => task_ref, + Err(err) => return Some(Err(err)), + }; + self.1 = self.0.get_inherit_depend(&task_ref).transpose(); + Some(Ok(task_ref)) + } + } + + Iter(self, Some(Ok(task_ref.clone()))) + } + pub fn get_build_depends<'ctx>( &'ctx self, task_ref: &TaskRef<'ctx>, ) -> Result<HashSet<OutputRef>> { - let task = self.get(task_ref.id)?; - task.build_depends - .iter() - .map(|dep| self.output_ref(dep, &task_ref.args, true)) - .collect() + let mut ret = HashSet::new(); + let mut allow_noinherit = true; + + for current in self.inherit_iter(task_ref) { + let task_ref = current?; + let task = self.get(task_ref.id)?; + let entries = task + .build_depends + .iter() + .filter(|dep| allow_noinherit || !dep.noinherit) + .map(|dep| self.output_ref(dep, &task_ref.args, true)) + .collect::<Result<Vec<_>>>()?; + ret.extend(entries); + + allow_noinherit = false; + } + + Ok(ret) } pub fn get_host_depends<'ctx>( &'ctx self, task_ref: &TaskRef<'ctx>, ) -> Result<HashSet<OutputRef>> { - let task = self.get(task_ref.id)?; - task.depends - .iter() - .map(|dep| self.output_ref(dep, &task_ref.args, false)) - .collect() + let mut ret = HashSet::new(); + let mut allow_noinherit = true; + + for current in self.inherit_iter(task_ref) { + let task_ref = current?; + let task = self.get(task_ref.id)?; + let entries = task + .depends + .iter() + .filter(|dep| allow_noinherit || !dep.noinherit) + .map(|dep| self.output_ref(dep, &task_ref.args, false)) + .collect::<Result<Vec<_>>>()?; + ret.extend(entries); + + allow_noinherit = false; + } + + Ok(ret) } pub fn in_rootfs<'ctx>(&'ctx self, output: &OutputRef<'ctx>) -> bool { diff --git a/src/task.rs b/src/task.rs index f921774..ca7f494 100644 --- a/src/task.rs +++ b/src/task.rs @@ -36,6 +36,8 @@ pub struct InheritDep { pub struct OutputDep { #[serde(flatten)] pub dep: TaskDep, + #[serde(default)] + pub noinherit: bool, #[serde(default = "default_output_name")] pub output: String, } |