mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
Only consider tasks dependent if both are pending
More specifically, consider them dependent if a task in the working set (regardless of status) depends on a task with status "pending" (regardless of presence in the working set). This has the desired user-visible effect of making a task no longer +BLOCKED when the task it depends on is marked as done, without requiring a working-set rebuild in the intervening time.
This commit is contained in:
parent
05c7f36b17
commit
7b0104e177
1 changed files with 46 additions and 3 deletions
|
@ -106,6 +106,9 @@ impl Replica {
|
||||||
|
|
||||||
/// Get the dependency map for all pending tasks.
|
/// Get the dependency map for all pending tasks.
|
||||||
///
|
///
|
||||||
|
/// A task dependency is recognized when a task in the working set depends on a task with
|
||||||
|
/// status equal to Pending.
|
||||||
|
///
|
||||||
/// The data in this map is cached when it is first requested and may not contain modifications
|
/// The data in this map is cached when it is first requested and may not contain modifications
|
||||||
/// made locally in this Replica instance. The result is reference-counted and may
|
/// made locally in this Replica instance. The result is reference-counted and may
|
||||||
/// outlive the Replica.
|
/// outlive the Replica.
|
||||||
|
@ -114,17 +117,40 @@ impl Replica {
|
||||||
/// although previously-returned dependency maps are not updated.
|
/// although previously-returned dependency maps are not updated.
|
||||||
pub fn dependency_map(&mut self, force: bool) -> Result<Rc<DependencyMap>> {
|
pub fn dependency_map(&mut self, force: bool) -> Result<Rc<DependencyMap>> {
|
||||||
if force || self.depmap.is_none() {
|
if force || self.depmap.is_none() {
|
||||||
|
// note: we can't use self.get_task here, as that depends on a
|
||||||
|
// DependencyMap
|
||||||
|
|
||||||
let mut dm = DependencyMap::new();
|
let mut dm = DependencyMap::new();
|
||||||
|
// temporary cache tracking whether tasks are considered Pending or not.
|
||||||
|
let mut is_pending = HashMap::new();
|
||||||
let ws = self.working_set()?;
|
let ws = self.working_set()?;
|
||||||
for i in 1..=ws.largest_index() {
|
for i in 1..=ws.largest_index() {
|
||||||
if let Some(u) = ws.by_index(i) {
|
if let Some(u) = ws.by_index(i) {
|
||||||
// note: we can't use self.get_task here, as that depends on a
|
|
||||||
// DependencyMap
|
|
||||||
if let Some(taskmap) = self.taskdb.get_task(u)? {
|
if let Some(taskmap) = self.taskdb.get_task(u)? {
|
||||||
for p in taskmap.keys() {
|
for p in taskmap.keys() {
|
||||||
if let Some(dep_str) = p.strip_prefix("dep_") {
|
if let Some(dep_str) = p.strip_prefix("dep_") {
|
||||||
if let Ok(dep) = Uuid::parse_str(dep_str) {
|
if let Ok(dep) = Uuid::parse_str(dep_str) {
|
||||||
dm.add_dependency(u, dep);
|
let dep_pending = {
|
||||||
|
if let Some(dep_pending) = is_pending.get(&dep) {
|
||||||
|
*dep_pending
|
||||||
|
} else if let Some(dep_taskmap) =
|
||||||
|
self.taskdb.get_task(dep)?
|
||||||
|
{
|
||||||
|
let dep_pending = matches!(
|
||||||
|
dep_taskmap
|
||||||
|
.get("status")
|
||||||
|
.map(|tm| Status::from_taskmap(tm)),
|
||||||
|
Some(Status::Pending)
|
||||||
|
);
|
||||||
|
is_pending.insert(dep, dep_pending);
|
||||||
|
dep_pending
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if dep_pending {
|
||||||
|
dm.add_dependency(u, dep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -615,5 +641,22 @@ mod tests {
|
||||||
dm.dependents(uuids[0]).collect::<HashSet<_>>(),
|
dm.dependents(uuids[0]).collect::<HashSet<_>>(),
|
||||||
set![uuids[1], uuids[2]]
|
set![uuids[1], uuids[2]]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// mark t[0] as done, removing it from the working set
|
||||||
|
rep.get_task(uuids[0])
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.into_mut(&mut rep)
|
||||||
|
.done()
|
||||||
|
.unwrap();
|
||||||
|
let dm = rep.dependency_map(true).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
dm.dependencies(uuids[3]).collect::<HashSet<_>>(),
|
||||||
|
set![uuids[1], uuids[2]]
|
||||||
|
);
|
||||||
|
assert_eq!(dm.dependencies(uuids[2]).collect::<HashSet<_>>(), set![]);
|
||||||
|
assert_eq!(dm.dependencies(uuids[1]).collect::<HashSet<_>>(), set![]);
|
||||||
|
assert_eq!(dm.dependents(uuids[0]).collect::<HashSet<_>>(), set![]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue