Skip to content

Commit 04df108

Browse files
authored
docs: package api docs (#2169)
* refactor: pass Node into Read method instead of Reader type * docs: add "key packages" and "Reading Taskfiles" sections to package doc
1 parent 8885d9e commit 04df108

File tree

3 files changed

+144
-13
lines changed

3 files changed

+144
-13
lines changed

setup.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ func (e *Executor) readTaskfile(node taskfile.Node) error {
7171
return e.Logger.Prompt(logger.Yellow, s, "n", "y", "yes")
7272
}
7373
reader := taskfile.NewReader(
74-
node,
7574
taskfile.WithInsecure(e.Insecure),
7675
taskfile.WithDownload(e.Download),
7776
taskfile.WithOffline(e.Offline),
@@ -80,7 +79,7 @@ func (e *Executor) readTaskfile(node taskfile.Node) error {
8079
taskfile.WithDebugFunc(debugFunc),
8180
taskfile.WithPromptFunc(promptFunc),
8281
)
83-
graph, err := reader.Read()
82+
graph, err := reader.Read(node)
8483
if err != nil {
8584
return err
8685
}

taskfile/reader.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ type (
4040
// [ast.TaskfileGraph] from them.
4141
Reader struct {
4242
graph *ast.TaskfileGraph
43-
node Node
4443
insecure bool
4544
download bool
4645
offline bool
@@ -54,13 +53,9 @@ type (
5453

5554
// NewReader constructs a new Taskfile [Reader] using the given Node and
5655
// options.
57-
func NewReader(
58-
node Node,
59-
opts ...ReaderOption,
60-
) *Reader {
56+
func NewReader(opts ...ReaderOption) *Reader {
6157
r := &Reader{
6258
graph: ast.NewTaskfileGraph(),
63-
node: node,
6459
insecure: false,
6560
download: false,
6661
offline: false,
@@ -191,8 +186,8 @@ func (o *promptFuncOption) ApplyToReader(r *Reader) {
191186
// through any [ast.Includes] it finds, reading each included Taskfile and
192187
// building an [ast.TaskfileGraph] as it goes. If any errors occur, they will be
193188
// returned immediately.
194-
func (r *Reader) Read() (*ast.TaskfileGraph, error) {
195-
if err := r.include(r.node); err != nil {
189+
func (r *Reader) Read(node Node) (*ast.TaskfileGraph, error) {
190+
if err := r.include(node); err != nil {
196191
return nil, err
197192
}
198193
return r.graph, nil

website/docs/reference/package.mdx

Lines changed: 140 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,144 @@ changelog entry for breaking changes to the package API.
2323
Task is primarily a CLI tool that is agnostic of any programming language.
2424
However, it is written in Go and therefore can also be used as a Go package too.
2525
This can be useful if you are already using Go in your project and you need to
26-
extend Task's functionality in some way.
26+
extend Task's functionality in some way. In this document, we describe the
27+
public API surface of Task and how to use it. This may also be useful if you
28+
want to contribute to Task or understand how it works in more detail.
2729

28-
The full generated documentation for the package API is available on
29-
[pkg.go.dev](https://pkg.go.dev/github.com/go-task/task/v3).
30+
## Key packages
31+
32+
The following packages make up the most important parts of Task's package API.
33+
Below we have listed what they are for and some of the key types available:
34+
35+
### [`github.com/go-task/task/v3`]
36+
37+
The core task package provides most of the main functionality for Task including
38+
fetching and executing tasks from a Taskfile. At this time, the vast majority of
39+
the this package's functionality is exposed via the [`task.Executor`] which
40+
allows the user to fetch and execute tasks from a Taskfile.
41+
42+
:::note
43+
This is the package which is most likely to be the subject of breaking changes
44+
as we refine the API.
45+
:::
46+
47+
### [`github.com/go-task/task/v3/taskfile`]
48+
49+
The `taskfile` package provides utilities for _reading_ Taskfiles from various
50+
sources. These sources can be local files, remote files, or even in-memory
51+
strings (via stdin).
52+
53+
- [`taskfile.Node`] - A reference to the location of a Taskfile. A `Node` is an
54+
interface that has several implementations:
55+
- [`taskfile.FileNode`] - Local files
56+
- [`taskfile.HTTPNode`] - Remote files via HTTP/HTTPS
57+
- [`taskfile.GitNode`] - Remote files via Git
58+
- [`taskfile.StdinNode`] - In-memory strings (via stdin)
59+
- [`taskfile.Reader`] - Accepts a `Node` and reads the Taskfile from it.
60+
- [`taskfile.Snippet`] - Mostly used for rendering Taskfile errors. A snippet
61+
stores a small part of a taskfile around a given line number and column. The
62+
output can be syntax highlighted for CLIs and include line/column indicators.
63+
64+
### [`github.com/go-task/task/v3/taskfile/ast`]
65+
66+
AST stands for ["Abstract Syntax Tree"][ast]. An AST allows us to easily
67+
represent the Taskfile syntax in Go. This package provides a way to parse
68+
Taskfile YAML into an AST and store them in memory.
69+
70+
- [`ast.TaskfileGraph`] - Represents a set of Taskfiles and their dependencies
71+
between one another.
72+
- [`ast.Taskfile`] - Represents a single Taskfile or a set of merged Taskfiles.
73+
The `Taskfile` type contains all of the subtypes for the Taskfile syntax, such
74+
as `tasks`, `includes`, `vars`, etc. These are not listed here for brevity.
75+
76+
### [`github.com/go-task/task/v3/errors`]
77+
78+
Contains all of the error types used in Task. All of these types implement the
79+
[`errors.TaskError`] interface which wraps Go's standard [`error`] interface.
80+
This allows you to call the `Code` method on the error to obtain the unique exit
81+
code for any error.
82+
83+
## Reading Taskfiles
84+
85+
Start by importing the `github.com/go-task/task/v3/taskfile` package. This
86+
provides all of the functions you need to read a Taskfile into memory:
87+
88+
```go
89+
import (
90+
"github.com/go-task/task/v3/taskfile"
91+
)
92+
```
93+
94+
Reading Taskfiles is done by using a [`taskfile.Reader`] and an implementation
95+
of [`taskfile.Node`]. In this example we will read a local file by using the
96+
[`taskfile.FileNode`] type. You can create this by calling the
97+
[`taskfile.NewFileNode`] function:
98+
99+
```go
100+
node := taskfile.NewFileNode("Taskfile.yml", "./path/to/dir")
101+
```
102+
103+
and then create a your reader by calling the [`taskfile.NewReader`] function and
104+
passing any functional options you want to use. For example, you could pass a
105+
debug function to the reader which will be called with debug messages:
106+
107+
```go
108+
reader := taskfile.NewReader(
109+
taskfile.WithDebugFunc(func(s string) {
110+
slog.Debug(s)
111+
}),
112+
)
113+
```
114+
115+
Now that everything is set up, you can read the Taskfile (and any included
116+
Taskfiles) by calling the `Read` method on the reader and pass the `Node` as an
117+
argument:
118+
119+
```go
120+
tfg, err := reader.Read(node)
121+
// handle error
122+
```
123+
124+
This returns an instance of [`ast.TaskfileGraph`] which is a "Directed Acyclic
125+
Graph" (DAG) of all the parsed Taskfiles. We use this graph to store and resolve
126+
the `includes` directives in Taskfiles. However most of the time, you will want
127+
a merged Taskfile. To do this, simply call the `Merge` method on the Taskfile
128+
graph:
129+
130+
```go
131+
tf, err := tfg.Merge()
132+
// handle error
133+
```
134+
135+
This compiles the DAG into a single [`ast.Taskfile`] containing all the
136+
namespaces and tasks from all the Taskfiles we read.
137+
138+
:::note
139+
We plan to remove AST merging in the future as it is unnecessarily complex and
140+
causes lots of issues with scoping.
141+
:::
142+
143+
{/* prettier-ignore-start */}
144+
[`github.com/go-task/task/v3`]: https://pkg.go.dev/github.com/go-task/task/v3
145+
[`github.com/go-task/task/v3/taskfile`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile
146+
[`github.com/go-task/task/v3/taskfile/ast`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile/ast
147+
[`github.com/go-task/task/v3/errors`]: https://pkg.go.dev/github.com/go-task/task/v3/errors
148+
149+
[`ast.TaskfileGraph`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile/ast#TaskfileGraph
150+
[`ast.Taskfile`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile/ast#Taskfile
151+
[`taskfile.Node`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Node
152+
[`taskfile.FileNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#FileNode
153+
[`taskfile.HTTPNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#HTTPNode
154+
[`taskfile.GitNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#GitNode
155+
[`taskfile.StdinNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#StdinNode
156+
[`taskfile.NewFileNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#NewFileNode
157+
[`taskfile.Reader`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader
158+
[`taskfile.NewReader`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#NewReader
159+
[`taskfile.Snippet`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet
160+
[`task.Executor`]: https://pkg.go.dev/github.com/go-task/task/v3#Executor
161+
[`task.Formatter`]: https://pkg.go.dev/github.com/go-task/task/v3#Formatter
162+
[`errors.TaskError`]: https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskError
163+
[`error`]: https://pkg.go.dev/builtin#error
164+
165+
[ast]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
166+
{/* prettier-ignore-end */}

0 commit comments

Comments
 (0)