Files
task/README.md

402 lines
9.3 KiB
Markdown
Raw Normal View History

2017-06-04 17:05:01 -03:00
[![License](https://img.shields.io/github/license/go-task/task.svg)](https://github.com/go-task/task/blob/master/LICENSE)
[![Join the chat at https://gitter.im/go-task/task](https://img.shields.io/gitter/room/go-task/task.svg)](https://gitter.im/go-task/task?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Join Slack room](https://img.shields.io/badge/%23task%20on-gophers%20slack-blue.svg)](https://gophers.slack.com/messages/task)
2017-06-14 15:32:29 -03:00
[![Release Download Count](https://img.shields.io/github/downloads/go-task/task/total.svg)](http://www.somsubhra.com/github-release-stats/?username=go-task&repository=task)
2017-03-19 15:54:18 -03:00
[![Build Status](https://travis-ci.org/go-task/task.svg?branch=master)](https://travis-ci.org/go-task/task)
2017-03-01 20:07:21 -03:00
2017-03-15 20:55:53 -03:00
# Task - Simple task runner / "Make" alternative
2017-02-28 09:14:11 -03:00
Task is a simple tool that allows you to easily run development and build
2017-05-27 10:52:44 -03:00
tasks. Task is written in Golang, but can be used to develop any language.
2017-02-28 09:14:11 -03:00
It aims to be simpler and easier to use then [GNU Make][make].
2017-06-28 21:20:52 -03:00
- [Installation](#installation)
- [Usage](#usage)
- [Environment](#environment)
- [OS specific task](#os-specific-task)
- [Task directory](#task-directory)
- [Task dependencies](#task-dependencies)
- [Calling another task](#calling-another-task)
- [Prevent unnecessary work](#prevent-unnecessary-work)
- [Variables](#variables)
- [Dynamic variables](#dynamic-variables)
- [Go's template engine](#gos-template-engine)
- [Help](#help)
- [Watch tasks](#watch-tasks-experimental)
- [Alternative task runners](#alternative-task-runners)
2017-02-28 09:14:11 -03:00
## Installation
2017-04-24 10:46:42 -03:00
If you have a [Golang][golang] environment setup, you can simply run:
2017-02-28 09:14:11 -03:00
```bash
go get -u -v github.com/go-task/task/cmd/task
```
2017-06-19 20:55:21 -03:00
Or you can download the binary from the [releases][releases] page and add to
your `PATH`. DEB and RPM packages are also available.
2017-02-28 09:14:11 -03:00
## Usage
2017-02-28 18:57:56 -03:00
Create a file called `Taskfile.yml` in the root of the project.
(`Taskfile.toml` and `Taskfile.json` are also supported, but YAML is used in
2017-03-02 21:01:38 -03:00
the documentation). The `cmds` attribute should contains the commands of a
task:
2017-02-28 09:14:11 -03:00
```yml
build:
cmds:
- go build -v -i main.go
assets:
cmds:
- gulp
```
Running the tasks is as simple as running:
```bash
task assets build
```
Task uses [github.com/mvdan/sh](https://github.com/mvdan/sh), a native Go sh
interpreter. So you can write sh/bash commands and it will work even on
Windows, where `sh` or `bash` is usually not available. Just remember any
executable called must be available by the OS or in PATH.
2017-02-28 09:14:11 -03:00
2017-03-12 18:04:44 -03:00
If you ommit a task name, "default" will be assumed.
2017-03-06 13:55:03 +01:00
### Environment
2017-04-16 17:30:56 -03:00
2017-03-06 13:55:03 +01:00
You can specify environment variables that are added when running a command:
```yml
build:
cmds:
2017-06-28 21:20:52 -03:00
- echo $hallo
2017-03-06 13:55:03 +01:00
env:
hallo: welt
```
2017-06-28 21:20:52 -03:00
### OS specific task
2017-03-07 09:47:41 +01:00
2017-03-12 18:04:44 -03:00
If you add a `Taskfile_{{GOOS}}` you can override or amend your taskfile based
on the operating system.
2017-03-07 09:47:41 +01:00
Example:
Taskfile.yml:
```yml
build:
cmds:
2017-06-28 21:20:52 -03:00
- echo "default"
2017-03-07 09:47:41 +01:00
```
Taskfile_linux.yml:
```yml
build:
cmds:
2017-06-28 21:20:52 -03:00
- echo "linux"
2017-03-07 09:47:41 +01:00
```
Will print out `linux` and not default
2017-06-28 21:20:52 -03:00
### Task directory
2017-03-03 09:00:01 +01:00
By default, tasks will be executed in the directory where the Taskfile is
located. But you can easily make the task run in another folder informing
`dir`:
```yml
js:
dir: www/public/js
cmds:
- gulp
```
2017-02-28 09:14:11 -03:00
### Task dependencies
2017-02-28 18:57:56 -03:00
You may have tasks that depends on others. Just pointing them on `deps` will
2017-03-02 21:01:38 -03:00
make them run automatically before running the parent task:
2017-02-28 09:14:11 -03:00
```yml
build:
deps: [assets]
cmds:
- go build -v -i main.go
assets:
cmds:
- gulp
```
In the above example, `assets` will always run right before `build` if you run
`task build`.
A task can have only dependencies and no commands to group tasks together:
```yml
assets:
deps: [js, css]
js:
cmds:
- npm run buildjs
css:
cmds:
- npm run buildcss
```
2017-03-02 19:54:45 +01:00
Each task can only be run once. If it is included from another dependend task causing
a cyclomatic dependency, execution will be stopped.
```yml
task1:
deps: [task2]
task2:
deps: [task1]
```
2017-06-28 21:20:52 -03:00
The above will fail with the message: "cyclic dependency detected".
2017-03-02 19:54:45 +01:00
2017-06-28 21:20:52 -03:00
### Calling another task
2017-03-25 15:26:42 -03:00
When a task has many dependencies, they are executed concurrently. This will
often result in a faster build pipeline. But in some situations you may need
to call other tasks serially. For this just prefix a command with `^`:
```yml
a-task:
cmds:
- ^another-task
- ^even-another-task
- echo "Both done"
another-task:
cmds:
- ...
even-another-task:
cmds:
- ...
```
2017-06-28 21:20:52 -03:00
### Prevent unnecessary work
2017-02-28 09:14:11 -03:00
If a task generates something, you can inform Task the source and generated
2017-03-02 21:01:38 -03:00
files, so Task will prevent to run them if not necessary.
2017-02-28 09:14:11 -03:00
```yml
build:
deps: [js, css]
cmds:
- go build -v -i main.go
js:
cmds:
- npm run buildjs
sources:
- js/src/**/*.js
generates:
- public/bundle.js
css:
cmds:
- npm run buildcss
sources:
- css/src/*.css
generates:
- public/bundle.css
```
`sources` and `generates` should be file patterns. When both are given, Task
will compare the modification date/time of the files to determine if it's
necessary to run the task. If not, it will just print
`Task "js" is up to date`.
2017-05-17 14:42:23 -03:00
Alternatively, you can inform a sequence of tests as `status`. If no error
is returned (exit status 0), the task is considered up-to-date:
```yml
generate-files:
cmds:
- mkdir directory
- touch directory/file1.txt
- touch directory/file2.txt
# test existence of files
status:
- test -d directory
- test -f directory/file1.txt
- test -f directory/file2.txt
```
2017-03-01 20:46:45 -03:00
You can use `--force` or `-f` if you want to force a task to run even when
up-to-date.
### Variables
```yml
build:
deps: [setvar]
cmds:
2017-06-28 21:20:52 -03:00
- echo "{{.PREFIX}} {{.THEVAR}}"
vars:
PREFIX: "Path:"
setvar:
cmds:
2017-06-28 21:20:52 -03:00
- echo "{{.PATH}}"
set: THEVAR
```
The above sample saves the path into a new variable which is then again echoed.
You can use environment variables, task level variables and a file called
`Taskvars.yml` (or `Taskvars.toml` or `Taskvars.json`) as source of variables.
They are evaluated in the following order:
Task local variables are overwritten by variables found in `Taskvars` file.
Variables found in `Taskvars` file are overwritten with variables from the
environment. The output of the last command is stored in the environment. So
you can do something like this:
```yml
build:
deps: [setvar]
cmds:
2017-06-28 21:20:52 -03:00
- echo "{{.PREFIX}} '{{.THEVAR}}'"
vars:
PREFIX: "Result: "
setvar:
cmds:
2017-06-28 21:20:52 -03:00
- echo -n "a"
- echo -n "{{.THEVAR}}b"
- echo -n "{{.THEVAR}}c"
set: THEVAR
```
The result of a run of build would be:
```
a
ab
abc
Result: 'abc'
```
#### Dynamic variables
If you prefix a variable with `$`, then the variable is considered a dynamic
variable. The value after the $-symbol will be treated as a command and the
output assigned.
```yml
build:
cmds:
- go build -ldflags="-X main.Version={{.LAST_GIT_COMMIT}}" main.go
vars:
LAST_GIT_COMMIT: $git log -n 1 --format=%h
```
### Go's template engine
Task parse commands as [Go's template engine][gotemplate] before executing
2017-04-16 17:30:56 -03:00
them. Variables are acessible through dot syntax (`.VARNAME`).
All functions by the Go's [sprig lib](http://masterminds.github.io/sprig/)
are available. The following example gets the current date in a given format:
2017-06-28 21:20:52 -03:00
```yml
2017-04-16 17:30:56 -03:00
print-date:
cmds:
- echo {{now | date "2006-01-02"}}
```
Task also adds the following functions:
2017-04-24 10:46:42 -03:00
- `OS`: Returns operating system. Possible values are "windows", "linux",
"darwin" (macOS) and "freebsd".
- `ARCH`: return the architecture Task was compiled to: "386", "amd64", "arm"
or "s390x".
- `ToSlash`: Does nothing on Unix, but on Windows converts a string from `\`
2017-04-16 17:30:56 -03:00
path format to `/`.
- `FromSlash`: Oposite of `ToSlash`. Does nothing on Unix, but on Windows
2017-04-16 17:30:56 -03:00
converts a string from `\` path format to `/`.
2017-05-27 10:52:22 -03:00
- `ExeExt`: Returns the right executable extension for the current OS
(`".exe"` for Windows, `""` for others).
Example:
```yml
2017-06-28 21:20:52 -03:00
print-os:
cmds:
- echo '{{OS}} {{ARCH}}'
2017-06-28 21:20:52 -03:00
- echo '{{if eq OS "windows"}}windows-command{{else}}unix-command{{end}}'
# This will be path/to/file on Unix but path\to\file on Windows
2017-06-28 21:20:52 -03:00
- echo '{{FromSlash "path/to/file"}}'
```
### Help
Running `task help` lists all tasks with a description. The following taskfile:
```yml
build:
desc: Build the go binary.
cmds:
- go build -v -i main.go
test:
desc: Run all the go tests.
cmds:
- go test -race ./...
js:
cmds:
- npm run buildjs
css:
cmds:
- npm run buildcss
```
would print the following output:
```bash
build Build the go binary.
test Run all the go tests.
```
2017-04-01 16:12:10 -03:00
## Watch tasks (experimental)
If you give a `--watch` or `-w` argument, task will watch for files changes
and run the task again. This requires the `sources` attribute to be given,
so task know which files to watch.
2017-05-27 10:52:44 -03:00
## Alternative task runners
2017-03-05 17:31:30 -03:00
2017-05-27 10:52:44 -03:00
- YAML based:
- [tj/robo][robo]
- [dogtools/dog][dog]
2017-06-11 19:51:58 -03:00
- [goeuro/myke][myke]
2017-05-27 10:52:44 -03:00
- Go based:
- [go-godo][godo]
- [markbates/grift][grift]
2017-03-05 17:31:30 -03:00
2017-02-28 09:14:11 -03:00
[make]: https://www.gnu.org/software/make/
2017-02-28 09:37:07 -03:00
[releases]: https://github.com/go-task/task/releases
2017-03-02 21:01:38 -03:00
[golang]: https://golang.org/
[gotemplate]: https://golang.org/pkg/text/template/
2017-03-05 17:31:30 -03:00
[robo]: https://github.com/tj/robo
[dog]: https://github.com/dogtools/dog
2017-06-11 19:51:58 -03:00
[myke]: https://github.com/goeuro/myke
2017-05-27 10:52:44 -03:00
[godo]: https://github.com/go-godo/godo
[grift]: https://github.com/markbates/grift
[sh]: https://github.com/mvdan/sh