Help us shape the future of Go! Take the 2026 Go Developer Survey

taskwarrior

package
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package taskwarrior drives the task program: finds it, reads its tasks as the JSON its export writes, and changes them through its own commands.

Index

Constants

View Source
const (
	WithIssue = "linked"
	NoIssue   = "unlinked"
)

The two values of the issue facet.

View Source
const (
	// MinimumVersion is the oldest Taskwarrior workflow drives.
	MinimumVersion = "3.5.0"
	// LinkUDA holds the Jira issue key on a task; LinkURLUDA its page. bugwarrior
	// names them the same, so a task it made is recognized and one made here is
	// recognized by it.
	LinkUDA    = "jiraid"
	LinkURLUDA = "jiraurl"
	// LinkTag marks every task created from an issue.
	LinkTag = "jira"
)

What workflow asks of Taskwarrior, and the names it links a task to an issue by.

Variables

View Source
var (
	// ErrRelativeProgram reports a task program named by a path relative to
	// the working directory, which names a different program in each
	// directory workflow starts in, a working tree's own among them.
	ErrRelativeProgram = errors.New("the task program must be a name looked up on PATH or an absolute path")
	// ErrNotInstalled reports no task program to try, or none there to run.
	ErrNotInstalled = errors.New("taskwarrior is not installed")
	// ErrNotTaskwarrior reports task programs that did not answer _version as
	// Taskwarrior does; go-task, the Taskfile runner, is also called task.
	ErrNotTaskwarrior = errors.New("the task program is not Taskwarrior")
	// ErrTooOld reports a Taskwarrior older than MinimumVersion.
	ErrTooOld = errors.New("taskwarrior is older than workflow needs")
	// ErrNotConfigured reports a Taskwarrior with no taskrc, which it will not
	// create unless asked at a terminal.
	ErrNotConfigured = errors.New("taskwarrior has never been run: it has no configuration file")
	// ErrNothingChanged reports a write Taskwarrior declined: the task is not
	// pending, is already started, or is not there, or there is nothing to undo.
	ErrNothingChanged = errors.New("taskwarrior changed nothing")
	// ErrRefused reports a command Taskwarrior refused, in its own words, or
	// in fixed words when the taskrc has a line it cannot parse.
	ErrRefused = errors.New("taskwarrior refused the command")
	// ErrBadOutput reports an answer that is not what the command writes.
	ErrBadOutput = errors.New("taskwarrior answered with something other than its JSON")
	// ErrNoSync reports a sync asked of a Taskwarrior with nowhere to sync.
	ErrNoSync = errors.New("no sync backend is configured in taskrc")
	// ErrAnnotateFailed reports a task added whose annotation was not.
	ErrAnnotateFailed = errors.New("the task was created but could not be annotated")
)
View Source
var ErrKeyNotOneWord = errors.New("the issue key is not one word")

ErrKeyNotOneWord refuses an issue key Taskwarrior would read as more than one word.

Functions

func Candidates

func Candidates(pathList, goos string) []string

Candidates is every task on pathList, a PATH list in goos's syntax, in PATH order: on Windows task.exe beside task, elsewhere a regular file with an execute bit. It walks the entries in order, as exec.LookPath does, but keeps every hit rather than the first, since go-task, also called task, can come before Taskwarrior on PATH. It passes over an empty or relative entry, which is resolved against the working directory: LookPath refuses a program found through one with ErrDot, or on Windows skips an empty one, where Candidates goes on to the absolute entries.

func PriorityFor

func PriorityFor(jiraPriority string) string

PriorityFor maps a Jira priority name onto Taskwarrior's H, M, L, or "" for a name it does not know — bugwarrior's own map, matched without case.

func TrackLine

func TrackLine(issue IssueLink) (string, error)

TrackLine is the add line for an issue, in Taskwarrior's grammar:

jiraid:PROJ-42 jiraurl:https://… +jira priority:H -- PROJ-42: <summary>

(priority left out when PriorityFor gives ""). The summary is one line (sanitize.Line) and follows --, so a due:tomorrow in it stays words. The key stands before the --, so one that is not exactly one word is refused with ErrKeyNotOneWord: Taskwarrior would read a word after it as an attribute or an rc override of its own.

Types

type Annotation

type Annotation struct {
	Entry       time.Time
	Description string
}

Annotation is a note on a task, and when it was written.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client drives one Taskwarrior.

func New

func New(run Runner, install Install) Client

New builds a client for the Taskwarrior install describes, run through run.

func (Client) Add

func (c Client) Add(ctx context.Context, line string) (string, error)

Add creates a task from line, in Taskwarrior's own grammar, and returns the new task's uuid.

func (Client) Annotate

func (c Client) Annotate(ctx context.Context, uuid, text string) error

Annotate adds text to the task uuid names as an annotation, whatever the active context hides. The text follows --, so a word in it that looks like an attribute stays a word.

func (Client) Done

func (c Client) Done(ctx context.Context, uuid string) error

Done completes the task uuid names, whatever the active context hides.

func (Client) Linked

func (c Client) Linked(ctx context.Context) ([]Task, error)

Linked is every task that names a Jira issue and is not deleted, whatever the active context hides.

func (Client) Modify

func (c Client) Modify(ctx context.Context, uuid, line string) error

Modify changes the task uuid names by line, in Taskwarrior's own grammar, whatever the active context hides.

func (Client) Pending

func (c Client) Pending(ctx context.Context) (List, error)

Pending is the pending tasks the active context shows, waiting ones included, and its name. Export ignores the context, so Pending reads the context and its read filter from _show and puts the filter before the status filter, in parentheses as one word, so an or inside it stays inside it.

func (Client) Start

func (c Client) Start(ctx context.Context, uuid string) error

Start starts the task uuid names, whatever the active context hides.

func (Client) Stop

func (c Client) Stop(ctx context.Context, uuid string) error

Stop stops the task uuid names, whatever the active context hides.

func (Client) Sync

func (c Client) Sync(ctx context.Context) (string, error)

Sync syncs with the backend taskrc names and returns what Taskwarrior printed; ErrNoSync when it names none.

func (Client) Touched added in v0.6.0

func (c Client) Touched(ctx context.Context, since time.Time) ([]Task, error)

Touched is every task the active context shows that changed after since, whatever its status but deleted: a task completed is work done. Taskwarrior keeps a task's times to the second and reads after as strictly after, so the second before since is asked for.

func (Client) Undo

func (c Client) Undo(ctx context.Context) (string, error)

Undo reverts Taskwarrior's last change and says how many operations that was: "reverted 3 operations", "reverted 1 operation", or "" when Taskwarrior did not count them. ErrNothingChanged when there was nothing to undo, which Taskwarrior reports with exit 0.

type Facet added in v0.6.0

type Facet struct {
	Kind  FacetKind
	Value string
}

Facet is one value a task can hold in one kind: a state as the list words it, a priority, a project or a tag ("" for none), or whether it is linked to an issue.

func OfferedFacets added in v0.9.0

func OfferedFacets(tasks []Task, now time.Time) []Facet

OfferedFacets is every value the list offers to narrow to at now, in order: the states as ByState ranks them; priorities H, M, L, any other the tasks hold by name, then none; projects and tags the tasks hold by name, none last; with an issue, then without. A value only a waiting task holds is not offered but for its state, as Choices counts it.

func (Facet) Label added in v0.6.0

func (f Facet) Label() string

Label is the facet as the list words it.

type FacetChoice added in v0.6.0

type FacetChoice struct {
	Facet Facet
	Count int
}

FacetChoice is a value the list offers to narrow to, with how many listed tasks hold it.

func Choices added in v0.6.0

func Choices(tasks []Task, picked []Facet, now time.Time) []FacetChoice

Choices is every value the tasks hold, with how many hold each, in the order OfferedFacets offers them, and then every picked value it does not offer, at zero, in the order it was picked, so it can be unpicked. A count is over the tasks the list shows with nothing picked — the waiting tasks left out — but for the waiting state, which counts them.

type FacetKind added in v0.6.0

type FacetKind int

FacetKind is one of the ways the Tasks list can be narrowed. The rules are written here alone: the terminal's Tasks pane calls them, and the web server ships each task's facets and fields to match, and the order the values are offered in.

const (
	FacetState FacetKind = iota
	FacetPriority
	FacetProject
	FacetTag
	FacetIssue
)

The kinds, in the order the list offers them.

type Install

type Install struct {
	Program        string // the path or name that answered
	Version        string // "3.5.0"
	DataDir        string // rc.data.location, for doctor
	SyncConfigured bool   // any sync.* backend named in taskrc
	LinkUDADefined bool   // taskrc already defines uda.jiraid.type
}

Install is the Taskwarrior that answered, read once from _version and _show.

func Detect

func Detect(ctx context.Context, program string, candidates []string, run Runner) (Install, error)

Detect finds Taskwarrior. With program set only it is tried, and never when it is a path relative to the working directory, which is ErrRelativeProgram; otherwise each candidate in order, each asked from the filesystem root. The first that answers _version with MinimumVersion or newer wins; a candidate that fails _version is not Taskwarrior, one that answers with an older version is too old, one that is not there is neither, and once every candidate has been tried Detect reports the kindest: too old, then not Taskwarrior, then ErrNotInstalled when none was there. Three failures are Taskwarrior's own and end the walk at once. A Taskwarrior never run fails _version, or failing that _show, with "Cannot proceed without rc file": that is a NeverRunError, which is ErrNotConfigured. One whose taskrc has a line it cannot parse fails _version, or failing that _show, quoting the line: that is ErrRefused in fixed words, since the line may hold a secret, and is told apart first. One that cannot start for another reason — an include it cannot read, a database it cannot open — exits 2 with words not in go-task's "task: …" form: that is ErrRefused in Taskwarrior's words. An exit 2 with nothing on standard error is not Taskwarrior refusing, and the walk goes on past it. A context done stops the walk with an error that is the context's.

type IssueLink struct {
	Key, Summary, URL, Priority string
}

IssueLink is what a task created from an issue carries.

type List

type List struct {
	Tasks   []Task
	Context string
}

List is the pending tasks of the active context, most urgent first, and the context's name ("" for none). Pending applies the context itself, read from _show, since export ignores it.

type Narrowing added in v0.6.0

type Narrowing struct {
	Picked []Facet
	Text   string
}

Narrowing is what the Tasks list is narrowed to: values picked, which widen within a kind and narrow across kinds, and text typed, which a task matches when one of its fields holds it, ignoring case.

func (Narrowing) ListsWaiting added in v0.6.0

func (n Narrowing) ListsWaiting() bool

ListsWaiting reports a narrowing that asks for the waiting tasks, which the list otherwise only counts.

func (Narrowing) Matches added in v0.6.0

func (n Narrowing) Matches(task Task, now time.Time) bool

Matches reports a task the narrowing lets through at now: the typed text in one of its fields, and, in every kind with a value picked, one of them held.

func (Narrowing) Narrows added in v0.6.0

func (n Narrowing) Narrows() bool

Narrows reports a narrowing that leaves any task out: something picked or typed.

type NeverRunError

type NeverRunError struct {
	Program string
}

NeverRunError is ErrNotConfigured naming the Taskwarrior that answered so: the program to run once at a terminal, by its path, since go-task can come first on PATH and answer to task.

func (NeverRunError) Error

func (e NeverRunError) Error() string

Error says Taskwarrior has never been run, and which.

func (NeverRunError) Unwrap

func (NeverRunError) Unwrap() error

Unwrap is ErrNotConfigured, so errors.Is finds it.

type Ranks added in v0.9.0

type Ranks struct {
	Urgency  int
	State    int
	ID       int
	Tag      int
	Issue    int
	Priority int
}

Ranks is a task's place in each of the list's orders, 0 first.

func RanksOf added in v0.9.0

func RanksOf(tasks []Task, now time.Time) []Ranks

RanksOf is each task's place in every order among the tasks given, judged at now where the order is by state, in the order the tasks are given. Every order breaks each tie down to the uuid, so the places are those of one order however the tasks are later narrowed.

type Runner

type Runner func(ctx context.Context, timeout time.Duration, program proc.Command, input []byte) ([]byte, error)

Runner runs the task program with input on its standard input, bounded by timeout, and returns its standard output. A non-zero exit is an error that proc.Failure reads. In production it is proc.CaptureWithin.

type State added in v0.6.0

type State int

State is where a task stands, as the Tasks list words and orders it. It is not Taskwarrior's status alone: a pending task that has been started is started, and a pending one with a wait still ahead waits.

const (
	StateStarted State = iota
	StatePending
	StateWaiting
	StateRecurring
	StateCompleted
	StateDeleted
	StateUnknown
)

The states, in the order ByState lists them.

func (State) String added in v0.6.0

func (s State) String() string

String is the state as the list words it.

type Status

type Status string

Status is a task's state as Taskwarrior names it.

const (
	Pending   Status = "pending"
	Completed Status = "completed"
	Deleted   Status = "deleted"
	Waiting   Status = "waiting"
	Recurring Status = "recurring"
)

The states a task can be in.

type Task

type Task struct {
	UUID                        string
	ID                          int // 0 for a task not in the working set
	Description                 string
	Status                      Status
	Project                     string
	Priority                    string // "H", "M", "L" or ""
	Tags                        []string
	Due, Wait, Scheduled, Until time.Time
	Entry, Modified, Start, End time.Time
	Urgency                     float64
	Annotations                 []Annotation
	Depends                     []string
	IssueKey                    string // the jiraid UDA
	IssueURL                    string // the jiraurl UDA
}

Task is one task as export writes it. Every text field has been through sanitize.Line; a synced replica is as untrusted as a file on disk.

func ByID added in v0.6.0

func ByID(tasks []Task) []Task

ByID orders by working-set id, lowest first, with a task outside the working set, which has none, after every numbered one.

func ByIssue added in v0.6.0

func ByIssue(tasks []Task) []Task

ByIssue orders tasks linked to an issue first, by key in natural order, so PROJ-2 comes before PROJ-10, with unlinked tasks last.

func ByPriority added in v0.6.0

func ByPriority(tasks []Task) []Task

ByPriority orders high, medium and low, then any other value Taskwarrior was configured with, then tasks with no priority.

func ByState added in v0.6.0

func ByState(tasks []Task, now time.Time) []Task

ByState orders started tasks first, then pending, then waiting.

func ByTag added in v0.6.0

func ByTag(tasks []Task) []Task

ByTag orders by a task's tags taken in order, whatever order they were added in, so +ops comes before +ops +web, with untagged tasks last.

func ByUrgency

func ByUrgency(tasks []Task) []Task

ByUrgency orders most urgent first, then by id, then by uuid, so a refresh keeps a stable order.

func (Task) Active

func (t Task) Active() bool

Active reports a pending task that has been started.

func (Task) Facets added in v0.6.0

func (t Task) Facets(now time.Time) []Facet

Facets is every value the task holds at now, one or more in each kind.

func (Task) Linked

func (t Task) Linked() bool

Linked reports a task that names a Jira issue.

func (Task) Searchable added in v0.9.0

func (t Task) Searchable() []string

Searchable is every field typed text is matched against, lower-cased, as typed text is before it is matched: the task's description, project and issue key, each tag written +tag, and its id written #id when it has one.

func (Task) State added in v0.6.0

func (t Task) State(now time.Time) State

State is where the task stands at now.

func (Task) Waiting

func (t Task) Waiting(now time.Time) bool

Waiting reports a task hidden until a date still after now.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL