Taskwarrior

From wikinotes


task warrior is the answer you've been looking for for task management. It syncs between PCs (but is tolerant of connectivity issues), it can export data to just about anything you could possibly want. CLI interface is simple, and supports aliases for your most common workflow tasks. Has it's own builtin calendar for displaying tasks. Tracks the time you spend performing tasks.

Because of taskwarrior's very accessible/flexible dataset, there are many front-ends to taskwarrior that facilitate one workflow or another. Some notable examples:

  • taskwiki (define tasks/subtasks by indentation in vim)
  • vit (ncurses interface to taskwarrior)


Install

Linux

task

sudo pacman -S task
cower -s vit

cd $HOME
mkdir .task_pers .task_work	## create the taskdirs

FreeBSD

taskd

## Note I am only installing the task-server on FreeBSD
##

sudo pkg install taskd

#### /etc/rc.conf
taskd_enable="YES"
####

## (taskd does not come with an rc-script, but I wrote one)
## (and it lives in configsync repo                       )

useradd taskd
chown taskd:taskd /usr/local/share/taskd
su taskd

sudo pw usermod will -G taskd    ## add user 'will' to existing group 'taskd'
											#  (you'll need to reboot for this to take effect)



Usage

CLI Structure

Task is the core command of taskwarrior. Each command is composed of 4 sections, all of which are entirely optional.

#task <filter> <command> <modifications> <miscellaneous>
 task +home     list      proj:test      editor


Main Commands

task   add   <desc>		## new task
task 1 del					## delete task entirely
task   log   <desc>		## add task, and mark complete

task 1 start				## start recording time on task
task 1 stop					## stop  recording time on task
task 1 done					## mark task complete

Personal Workflow

Taskwarrior is pretty flexible, but not quite flexible enough to suit my needs with a single task-server. Instead, I'll have separate task-servers for separate projects.



Commands

Task Server

/tmp/taskd.log
default log-location for taskd
/home/taskd/.taskdata
personal location for taskdata dir



Task Client

Task Heirarchy

Without extensions, taskwarrior is built with each task as it's own independent unit, no centralized datastore is used to maintain a master collections of tasks, each task is self-contained.

These tasks are categorized into files based on their level of completion.

pending.data
uncompleted tasks
completed.data
all completed tasks
backlog.data
???
undo.data
total undo history. (stores task old and new)
## example of a single task
[description:"time in report timesheet" entry:"1457748143" modified:"1457800384" project:"dev.taskwarrior" status:"pending" uuid:"8c36f574-7165-4316-bb19-5ba6fde8a0dc"]


Tasks can then have metadata attached to them, which is used to categorize them, and makes it easier to search for them.

projects
task add proj:dev "my task"
subprojects
task add proj:dev.subproj "my task"
tags
task add +mytag "my task"

Task LifeCycle

task add <desc>	## add new tasks
task					## list current tasks

task 1				## list info about task1
task 1 start		## start working on task1

task 1   done		## mark task 1 as complete
task 1-3 done		## mark a range of tasks as done

task 4   del		## delete a task
task log <desc>	## log a task that you have already done.
						#  you want to track everything.


Displaying Tasks

## Filters
task entry.after:today-4days		## list all tasks entered in last 4x days
task entry:yesterday					## list tasks entered yesterday
task project:<project>				## list tasks associated with project


## Virtual Tags
task 1 info								## get virtual-tags associated with task
task +DUETODAY							## tasks due today
task +DUE -DUETODAY					## tasks that are due _NOT_ today
task +OVERDUE list					## tasks that are overdue
task +WEEK    list					## tasks due this week


Adding Task Metadata

## Adding Metadata
task   add   project:<project> <desc>	## Create a task with metadata
task 1 mod   project:<project>			## modify existing task

## Types of MetaData

## Heirarchy
task    project:<project>	             <desc>	## Move a task to a different project
task    project:<project>.<subproject>  <desc>
task    depends:2				             <desc>	## task dependencies (task1 cannot be copleted until task2 finished)


## Dates
task    due:10th				              <desc>		## modify due date
task    scheduled:10th                   <desc>  	## task is dormant until it's scheduled date 
																	#  (then receives status 'ready')
task    wait:november                    <desc>		## hide task until nobember
task    until:december                   <desc>  	## if you miss a deadline, task stays alive until december
																	#  when it deletes itself

## Filtering
task    priority:(H|L|M)	               <desc>	## priority high/low/medium
task    +problem -house		               <desc>	## Add/Remove Task Tags
task    status:pending		               <desc>	## moddify status of task

Searching

task /cat/        list					## list any tasks containing the word 'cat'
task "/c[a-z]+/"  list					## searches are regex by default

Reports/Graphs

## Most Used
task summary										## overview of projects
task timesheet										## short-term report of tasks finished
task calendar										## displays a calendar of tasks/duedates


## All reorts
task reports										## list of all available reports


## long-term graphs/reports
task burndown.(daily|weekly|monthly)		## graph of daily started/pending/completed
task ghistory.(monthly|annual)				## graph of history report
task  history.(monthly|annual)				## report of history




Config

~/.taskrc
config file
~/.task/*
task info storage
~/.taskdata/config
task-daemon config (points to --data location)


taskserver

https://taskwarrior.org/docs/taskserver/setup.html
official taskserver docs


base config

su taskd

## Edit 'vars' file with your cert values
##

mkdir ~/.taskdata
#### /usr/local/share/taskd/vars
CN = 192.168.1.211
####
/usr/local/share/taskd/generate								## documentation warns that this does not use sensible defaults.
																		#  need to configure manually (creates self-signed CA)


## create base config file
##
taskd init --data /home/taskd/.taskdata					## create base-config
taskd config server 192.168.1.211:53589					## set addr/port to bind


## Generate certificates
setenv TASKDDATA /home/taskd/.taskdata 					## set root
cp /usr/local/share/*.pem $TASKDDATA/						## copy certs to TASKDATA dir


## make config use the certificates we just generated
taskd config --force client.cert $TASKDDATA/client.cert.pem
taskd config --force client.key  $TASKDDATA/client.key.pem
taskd config --force server.cert $TASKDDATA/server.cert.pem
taskd config --force server.key  $TASKDDATA/server.key.pem
taskd config --force server.crl  $TASKDDATA/server.crl.pem
taskd config --force ca.cert     $TASKDDATA/ca.cert.pem

taskd config --force log         $PWD/taskd.log
taskd config --force pid.file    $PWD/taskd.pid



## run taskd (make sure it works)
##
taskd server


create user

taskd add org  'Personal' --data /home/taskd/.taskdata							## create organization 'Personal'
taskd add user 'Personal' 'Will Pittman'	--data /home/taskd/.taskdata 		## add user 'Will Pittman' to organization 'Personal'

## Save the unique-key
# f5cd9571-e723-11e5-a73d-001d09ab5523

cd /usr/local/share/taskd 
./generate.client will_pittman.pem
cp will* ~/.taskdata/

## Copy Certificcates to your taskwarrior client.
scp client*      will@miranda:/home/will/.task/				## copy client certificates to task-client
scp ca.cert.pem  will@miranda:/home/will/.task/				## copy server's ca-cert to client


Router

forward port 53589 to taskwarrior locally.



task

add user from taskd

## Make sure you have the keys
/home/will/.task/ca.cert.pem
/home/will/.task/task.cert.pem
/home/will/.task/task.key.pem

## configure task to use the taskd server
task config taskd.server      -- 192.168.1.211:53589
task config taskd.credentials -- Personal/Will Pittman/f5cd9571-e723-11e5-a73d-001d09ab5523

## synchronize with the server
task sync init



Custom Hooks

~/.task/hooks/*
location of hooks.
https://taskwarrior.org/docs/hooks_guide.html taskwarrior's excellent API/hook guide.

Hook Types

on-add
task creation
on-modify
modifying/annotating tasks (not on creation)
on-launch
once the 'task' command has been initialized (run), but before it does anything.
on-exit
after processing, but immediately before tasks are displayed onscreen

Input/Output

Taskwarrior has a hook model that is inspired by git. TaskWarrior is built with events at key points. Hooks can subscribe to these events, and be run with specific information.

Hooks are subscribed to events based on their names <event_name>-description. The order of execution is alphabetical. Hooks can written in any language that can process CLI commands, and parse json. Hooks must have executable permissions.


WARNING:

Watch out! Different types of hooks provide a different number of lines, and expect different kinds of output. See https://taskwarrior.org/docs/hooks.html#interfaces

## see 'Interfaces' at the following link for more detailed
## information about input/output.
https://taskwarrior.org/docs/hooks.html


#### Input
# the input sent to hook scripts consists of a single-line json object representing the
# task. MUST BE A SINGLE LINE.

{
	"description" : "test",
	"entry"       : "20161105T202606Z",
	"modified"    : "20161213T005507Z",
	"project"     : "pers",
	"status"      : "pending",
	"uuid"        : "58fb9ddd-1ee4-4446-9e92-4f4be9d039e2"
}


#### Output
# output consists of two lines:
# - the single-line json object representing a task (presumably modified)
# - a single line of text.

Other than that, as a safeguard against silently corrupting your data, if json is not a task, or is malformed, it is ignored/discarded.

Example Script

The following is an example of a python script, used as a taskwarrior hook. All this script does is receive the JSON task sent to it, and spits it back out unmodified, with an exit code of 0 (not fail).

This is the base of all hook-scripts.

#!/usr/bin/env python

import sys
import json

stdin = sys.stdin.readline()
if stdin:
	task = json.loads(sys.stdin.readline())
	task['desc'] = 'abcdefg'
	print(json.dumps(task))
	print('updated task successfully')
sys.exit(0)
## Test-Run hook (outside of taskwarrior)
chmod +x hook.py
echo '{"name":"value"}' | ./hook.py
>> {"name": "value"}

## Test that the hook exited correctly
echo $?
0



Plugins/Hooks

https://github.com/kostajh/taskwarrior-time-tracking-hook taskwarrior time-tracking-hook (taskwarrior does not record total times spent on tasks by default, only what is accomplished.)
https://github.com/blindFS/vim-taskwarrior allows you to toggle annotations on/off, switch out tags, etc. Looks more powerful than vit, the default taskwarrior interface.

Time Tracking Hook

WARNING:

I no longer use the time-tracking hook, I have replaced it with the official timewarrior program.

sudo pip install taskwarrior-time-tracking-hook

mkdir -p ~/.task/hooks
ln -s /usr/bin/taskwarrior_time_tracking_hook $HOME/.task/hooks/on-modify.timetracking		## install the hook

#### ~/.taskrc
task config uda.totalactivetime.type duration
task config uda.totalactivetime.label Total active time
task config uda.totalactivetime.values ''

####