summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2021-09-26 22:57:29 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2021-09-26 23:15:44 +0200
commit075e7c7fdc04c2173aac3d94127791a162d41bc1 (patch)
treee73fc27aab919d91396a42f3984926bd611d3d2d
parent82f2a406a0d9c3012c75197dc22e8c26a0187e87 (diff)
downloadrebel-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.yml2
-rw-r--r--examples/libgcc-initial.yml2
-rw-r--r--src/context.rs72
-rw-r--r--src/task.rs2
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,
}