filtertaskwarrior

Taskwarrior: How do I find the tasks that depend on a specific tasks?


How do I find out which task(s) depend on a specific task without reading the information of all tasks?

Reproduction

System

Version

$ task --version
2.5.1

.taskrc

# Taskwarrior program configuration file.

# Files
data.location=~/.task

alias.cal=calendar
rc.date.iso=Y-M-D

default.command=ready
journal.info=no
rc.regex=on

Here are the tasks that I created for testing purposes:

$ task list

ID Age  Description                           Urg 
 1 2min Something to do                          0
 2 1min first do this                            0
 3 1min do this whenever you feel like it        0

3 tasks

Create the dependency from task#1 to task#2:

$ task 1 modify depends:2
Modifying task 1 'something to do'.
Modified 1 task.

$ task list

ID Age  D Description                           Urg 
 2 4min   first do this                            8
 3 4min   do this whenever you feel like it        0
 1 4min D Something to do                         -5

3 tasks

Goal

Now I want to find the tasks that are dependent on task#2, which should be task#1.

Trials

Unfortunately, this does not result in any matches:

$ task list depends:2
No matches.
$ # I can filter by blocked tasks
$ task blocked

ID Deps Age   Description    
 1 2    18min Something to do

1 task

$ # But when I want to only have tasks \
    that are blocked by task#2 also task#3 is returned
$ task blocked:2
[task ready ( blocked:2 )]

ID Age   Description                       Urg 
 2 20min first do this                        8
 3 19min do this whenever you feel like it    0

2 tasks

Suggestions?

How would you approach this? Parsing the taskwarrior output through a script looks like a bit of an overkill.


Solution

  • You have the right command but have actually encountered a bug: the depends attribute does not work with "short id", it's a comma-delimited string of uuids.

    It will work if you use UUID instead. Use task <id> _uuid to resolve id to UUID.

    $ task --version
    2.5.1
    
    # Create tasks
    $ task rc.data.location: add -- Something to do
    $ task rc.data.location: add -- first do this
    $ task rc.data.location: add -- do this whenever you feel like it
    $ task rc.data.location: list
    
    ID Age Description                           Urg
     1 -   Something to do                        1.8
     2 -   first do this                          1.8
     3 -   do this whenever you feel like it      1.8
    3 tasks
    
    # Set up dependency
    $ task rc.data.location: 1 modify depends:2
    
    Modifying task 1 'Something to do'.
    Modified 1 task.
    
    # Query using depends:UUID
    $ task rc.data.location: list "depends.has:$(task rc.data.location: _get 2.uuid)"
    
    ID Age D Description         Urg
     1 -   D Something to do     -3.2
    
    1 task
    
    # Query using depends:SHORT ID
    # This does not work, despite documentation. Likely a bug
    $ task rc.data.location: list "depends.has:$(task rc.data.location: _get 2.id)"
    
    No matches.
    

    Small correction with your trial to find blocked tasks

    There is no blocked attribute and you're using the ready report.

    $ task blocked:2
    [task ready ( blocked:2 )]
    

    The ready report will filter out what we're looking for, the blocked report is what we need. To unmagickify this, these are simply useful default reports that have preset filters on top of task all.

    $ task show filter | grep -e 'blocked' -e 'ready'                                                                                                                                                                                                                                             
    report.blocked.filter   status:pending +BLOCKED
    report.ready.filter     +READY
    report.unblocked.filter status:pending -BLOCKED
    

    Blocked tasks will have the virtual tag +BLOCKED, which is mutually exclusive to +READY.

    The blocked attribute doesn't exist, use task _columns to show available attributes (e.g. depends). Unfortunately, the CLI parser is probably attempting to apply the filter blocked:2 and ends up ignoring it. For your workflow, the useful command to use is task blocked "depends.has:$(task _get 2.uuid)". Advisable to write a shell function to make it easier to use:

    #!/bin/bash
    # Untested but gets the point across
    function task_blocked {
      blocker=$1
      shift
      task blocked depends.has:$(task _get ${blocker}.uuid) "$@"
    }
    
    # Find tasks of project "foo" that are blocked on task 2
    task_blocked 2 project:foo
    # What about other project that is also impacted
    task_blocked 2 project:bar