Package API
Task's package API is still experimental and subject to breaking changes.
This means that unlike our CLI, we may make breaking changes to the package API in minor (or even patch) releases. We try to avoid this when possible, but it may be necessary in order to improve the overall design of the package API.
In the future we may stabilize the package API. However, this is not currently
planned. For now, if you need to use Task as a Go package, we recommend pinning
the version in your go.mod
file. Where possible we will try to include a
changelog entry for breaking changes to the package API.
Task is primarily a CLI tool that is agnostic of any programming language. However, it is written in Go and therefore can also be used as a Go package too. This can be useful if you are already using Go in your project and you need to extend Task's functionality in some way. In this document, we describe the public API surface of Task and how to use it. This may also be useful if you want to contribute to Task or understand how it works in more detail.
Key packages​
The following packages make up the most important parts of Task's package API. Below we have listed what they are for and some of the key types available:
github.com/go-task/task/v3
​
The core task package provides most of the main functionality for Task including
fetching and executing tasks from a Taskfile. At this time, the vast majority of
the this package's functionality is exposed via the task.Executor
which
allows the user to fetch and execute tasks from a Taskfile.
This is the package which is most likely to be the subject of breaking changes as we refine the API.
github.com/go-task/task/v3/taskfile
​
The taskfile
package provides utilities for reading Taskfiles from various
sources. These sources can be local files, remote files, or even in-memory
strings (via stdin).
taskfile.Node
- A reference to the location of a Taskfile. ANode
is an interface that has several implementations:taskfile.FileNode
- Local filestaskfile.HTTPNode
- Remote files via HTTP/HTTPStaskfile.GitNode
- Remote files via Gittaskfile.StdinNode
- In-memory strings (via stdin)
taskfile.Reader
- Accepts aNode
and reads the Taskfile from it.taskfile.Snippet
- Mostly used for rendering Taskfile errors. A snippet stores a small part of a taskfile around a given line number and column. The output can be syntax highlighted for CLIs and include line/column indicators.
github.com/go-task/task/v3/taskfile/ast
​
AST stands for "Abstract Syntax Tree". An AST allows us to easily represent the Taskfile syntax in Go. This package provides a way to parse Taskfile YAML into an AST and store them in memory.
ast.TaskfileGraph
- Represents a set of Taskfiles and their dependencies between one another.ast.Taskfile
- Represents a single Taskfile or a set of merged Taskfiles. TheTaskfile
type contains all of the subtypes for the Taskfile syntax, such astasks
,includes
,vars
, etc. These are not listed here for brevity.
github.com/go-task/task/v3/errors
​
Contains all of the error types used in Task. All of these types implement the
errors.TaskError
interface which wraps Go's standard error
interface.
This allows you to call the Code
method on the error to obtain the unique exit
code for any error.
Reading Taskfiles​
Start by importing the github.com/go-task/task/v3/taskfile
package. This
provides all of the functions you need to read a Taskfile into memory:
import (
"github.com/go-task/task/v3/taskfile"
)
Reading Taskfiles is done by using a taskfile.Reader
and an implementation
of taskfile.Node
. In this example we will read a local file by using the
taskfile.FileNode
type. You can create this by calling the
taskfile.NewFileNode
function:
node := taskfile.NewFileNode("Taskfile.yml", "./path/to/dir")
and then create a your reader by calling the taskfile.NewReader
function and
passing any functional options you want to use. For example, you could pass a
debug function to the reader which will be called with debug messages:
reader := taskfile.NewReader(
taskfile.WithDebugFunc(func(s string) {
slog.Debug(s)
}),
)
Now that everything is set up, you can read the Taskfile (and any included
Taskfiles) by calling the Read
method on the reader and pass the Node
as an
argument:
ctx := context.Background()
tfg, err := reader.Read(ctx, node)
// handle error
This returns an instance of ast.TaskfileGraph
which is a "Directed Acyclic
Graph" (DAG) of all the parsed Taskfiles. We use this graph to store and resolve
the includes
directives in Taskfiles. However most of the time, you will want
a merged Taskfile. To do this, simply call the Merge
method on the Taskfile
graph:
tf, err := tfg.Merge()
// handle error
This compiles the DAG into a single ast.Taskfile
containing all the
namespaces and tasks from all the Taskfiles we read.
We plan to remove AST merging in the future as it is unnecessarily complex and causes lots of issues with scoping.