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.
2017-07-03 21:20:58 -03:00
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
```
2017-04-24 09:56:14 -03:00
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
2017-03-07 12:35:45 +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-07-05 21:31:41 -03:00
If there are more than one dependency, they always run in parallel for better
performance.
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
2017-07-05 20:30:58 -03:00
to call other tasks serially. In this case, just use the following syntax:
2017-03-25 15:26:42 -03:00
```yml
2017-07-05 20:30:58 -03:00
main-task:
2017-03-25 15:26:42 -03:00
cmds:
2017-07-05 20:30:58 -03:00
- task: task-to-be-called
- task: another-task
2017-03-25 15:26:42 -03:00
- echo "Both done"
2017-07-05 20:30:58 -03:00
task-to-be-called:
cmds:
- echo "Task to be called"
2017-03-25 15:26:42 -03:00
another-task:
cmds:
2017-07-05 20:30:58 -03:00
- echo "Another task"
```
Overriding variables in the called task is as simple as informing `vars`
attribute:
```yml
main-task:
cmds:
- task: write-file
vars: {FILE: "hello.txt", CONTENT: "Hello!"}
- task: write-file
vars: {FILE: "world.txt", CONTENT: "World!"}
write-file:
cmds:
- echo "{{.CONTENT}}" > {{.FILE}}
```
The above syntax is also supported in `deps` .
> NOTE: It's also possible to call a task without any param prefixing it
with `^` , but this syntax is deprecaded:
```yml
a-task:
cmds:
- ^another-task
2017-03-25 15:26:42 -03:00
2017-07-05 20:30:58 -03:00
another-task:
2017-03-25 15:26:42 -03:00
cmds:
2017-07-05 20:30:58 -03:00
- echo "Another task"
2017-03-25 15:26:42 -03:00
```
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.
2017-03-05 17:12:57 -03:00
### Variables
2017-07-05 21:31:41 -03:00
When doing interpolation of variables, Task will look for the below.
They are listed below in order of importance (e.g. most important first):
2017-03-05 17:12:57 -03:00
2017-07-05 21:31:41 -03:00
- Variables given while calling a task from another.
(See [Calling another task ](#calling-another-task ) above)
- Environment variables
- Variables available in the `Taskvars.yml` file
- Variables declared locally in the task
2017-03-05 17:12:57 -03:00
2017-07-05 21:31:41 -03:00
Example of overriding with environment variables:
2017-03-05 17:12:57 -03:00
2017-07-05 21:31:41 -03:00
```bash
$ TASK_VARIABLE=a-value task do-something
```
2017-03-05 17:12:57 -03:00
2017-07-05 21:31:41 -03:00
Example of `Taskvars.yml` file:
```yml
PROJECT_NAME: My Project
DEV_MODE: production
GIT_COMMIT: $git log -n 1 --format=%h
```
2017-03-05 17:12:57 -03:00
2017-07-05 21:31:41 -03:00
Example of locally declared vars:
2017-03-05 17:12:57 -03:00
```yml
2017-07-05 21:31:41 -03:00
print-var:
2017-03-05 17:12:57 -03:00
cmds:
2017-07-05 21:31:41 -03:00
echo "{{.VAR}}"
2017-03-05 17:12:57 -03:00
vars:
2017-07-05 21:31:41 -03:00
VAR: Hello!
2017-03-05 17:12:57 -03:00
```
2017-07-05 21:31:41 -03:00
> NOTE: It's also possible setting a variable globally using `set` attribute
in task, but this is deprecated:
2017-03-05 17:12:57 -03:00
2017-07-05 21:31:41 -03:00
```yml
build:
deps: [set-message]
cmds:
- echo "Message: {{.MESSAGE}}"
set-message:
cmds:
- echo "This is an important message"
set: MESSAGE
2017-03-05 17:12:57 -03:00
```
2017-03-08 08:22:52 +01:00
#### Dynamic variables
2017-03-08 18:32:32 -03:00
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
```
2017-03-08 08:22:52 +01:00
2017-07-05 21:31:41 -03:00
This works for all types of variables.
2017-03-05 17:12:57 -03:00
### 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-03-05 17:12:57 -03:00
2017-04-24 10:46:42 -03:00
- `OS` : Returns operating system. Possible values are "windows", "linux",
2017-03-05 17:12:57 -03:00
"darwin" (macOS) and "freebsd".
- `ARCH` : return the architecture Task was compiled to: "386", "amd64", "arm"
or "s390x".
2017-04-24 09:56:14 -03:00
- `ToSlash` : Does nothing on Unix, but on Windows converts a string from `\`
2017-04-16 17:30:56 -03:00
path format to `/` .
2017-04-24 09:56:14 -03:00
- `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).
2017-03-05 17:12:57 -03:00
Example:
```yml
2017-06-28 21:20:52 -03:00
print-os:
2017-03-05 17:12:57 -03:00
cmds:
- echo '{{OS}} {{ARCH}}'
2017-06-28 21:20:52 -03:00
- echo '{{if eq OS "windows"}}windows-command{{else}}unix-command{{end}}'
2017-04-24 09:56:14 -03:00
# 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"}}'
2017-03-05 17:12:57 -03:00
```
2017-03-06 22:25:50 +01:00
### 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/
2017-03-05 17:05:44 -03:00
[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
2017-04-24 09:56:14 -03:00
[sh]: https://github.com/mvdan/sh