mirror of
https://github.com/go-task/task.git
synced 2026-06-23 12:45:52 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36317f8ddd | ||
|
|
115b4a308f | ||
|
|
62ba8dbabf |
@@ -9,6 +9,6 @@ trim_trailing_whitespace = true
|
|||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = 8
|
indent_size = 8
|
||||||
|
|
||||||
[*.{md,yml,yaml,json,toml,htm,html}]
|
[*.{md,yml,yaml,json,toml}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|||||||
8
.github/CONTRIBUTING.md
vendored
8
.github/CONTRIBUTING.md
vendored
@@ -1,6 +1,12 @@
|
|||||||
* Bug reports and feature requests are welcome in [the issues][issues]
|
* Bug reports and feature requests are welcome in [the issues][issues]
|
||||||
|
* For questions and discussion there's the [Slack room][slack] ([invititation here][slackinvite])
|
||||||
* Pull Requests are welcome. For more complex changes and features it's
|
* Pull Requests are welcome. For more complex changes and features it's
|
||||||
recommended to open an issue with the feature request first
|
recommended to open an issue first
|
||||||
|
* About 3 or 4 pull requests accepted one gets write access to the repo.
|
||||||
|
Even then, possible backward incompatible changes should be discussed first
|
||||||
|
in an issue or pull request
|
||||||
* Documentation contributions are as important as code contributions
|
* Documentation contributions are as important as code contributions
|
||||||
|
|
||||||
[issues]: https://github.com/go-task/task/issues
|
[issues]: https://github.com/go-task/task/issues
|
||||||
|
[slack]: https://gophers.slack.com/messages/task
|
||||||
|
[slackinvite]: https://invite.slack.golangbridge.org/
|
||||||
|
|||||||
3
.github/ISSUE_TEMPLATE.md
vendored
3
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,4 +1,7 @@
|
|||||||
<!--
|
<!--
|
||||||
|
For questions and general talk there's the Slack room: https://gophers.slack.com/messages/task
|
||||||
|
Invite to the Slack is available in this link: https://invite.slack.golangbridge.org/
|
||||||
|
|
||||||
If relevant, include the following information:
|
If relevant, include the following information:
|
||||||
- Task version
|
- Task version
|
||||||
- OS
|
- OS
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,7 +14,6 @@
|
|||||||
.glide/
|
.glide/
|
||||||
|
|
||||||
./task
|
./task
|
||||||
.task
|
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ build:
|
|||||||
ignore:
|
ignore:
|
||||||
- goos: darwin
|
- goos: darwin
|
||||||
goarch: 386
|
goarch: 386
|
||||||
env:
|
|
||||||
- CGO_ENABLED=0
|
|
||||||
|
|
||||||
archive:
|
archive:
|
||||||
name_template: "{{.Binary}}_{{.Os}}_{{.Arch}}"
|
name_template: "{{.Binary}}_{{.Os}}_{{.Arch}}"
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.10.x
|
- '1.8'
|
||||||
- 1.11.x
|
- '1.9'
|
||||||
|
- '1.10'
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
|||||||
136
Gopkg.lock
generated
Normal file
136
Gopkg.lock
generated
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/Masterminds/semver"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "15d8430ab86497c5c0da827b748823945e1cf1e1"
|
||||||
|
version = "v1.4.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/Masterminds/sprig"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "9d9aa1f74c86fd9d36ecfe3f2a44a3093c3d4c15"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/aokoli/goutils"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "3391d3790d23d03408670993e957e8f408993c34"
|
||||||
|
version = "v1.0.1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/davecgh/go-spew"
|
||||||
|
packages = ["spew"]
|
||||||
|
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||||
|
version = "v1.1.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/huandu/xstrings"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "2bf18b218c51864a87384c06996e40ff9dcff8e1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/imdario/mergo"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "0d4b488675fdec1dde48751b05ab530cf0b630e1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/mattn/go-zglob"
|
||||||
|
packages = [
|
||||||
|
".",
|
||||||
|
"fastwalk"
|
||||||
|
]
|
||||||
|
revision = "4959821b481786922ac53e7ef25c61ae19fb7c36"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/mitchellh/go-homedir"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "b8bc1bf767474819792c23f32d8286a45736f1c6"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/pmezard/go-difflib"
|
||||||
|
packages = ["difflib"]
|
||||||
|
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
||||||
|
version = "v1.0.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/radovskyb/watcher"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "6145e1439b9de93806925353403f91d2abbad8a5"
|
||||||
|
version = "v1.0.2"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/satori/go.uuid"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3"
|
||||||
|
version = "v1.2.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/spf13/pflag"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "ee5fd03fd6acfd43e44aea0b4135958546ed8e73"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/stretchr/testify"
|
||||||
|
packages = ["assert"]
|
||||||
|
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
|
||||||
|
version = "v1.2.1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/crypto"
|
||||||
|
packages = [
|
||||||
|
"pbkdf2",
|
||||||
|
"scrypt",
|
||||||
|
"ssh/terminal"
|
||||||
|
]
|
||||||
|
revision = "91a49db82a88618983a78a06c1cbd4e00ab749ab"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/net"
|
||||||
|
packages = ["context"]
|
||||||
|
revision = "22ae77b79946ea320088417e4d50825671d82d57"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/sync"
|
||||||
|
packages = ["errgroup"]
|
||||||
|
revision = "fd80eb99c8f653c847d294a001bdf2a3a6f768f5"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/sys"
|
||||||
|
packages = [
|
||||||
|
"unix",
|
||||||
|
"windows"
|
||||||
|
]
|
||||||
|
revision = "dd2ff4accc098aceecb86b36eaa7829b2a17b1c9"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "gopkg.in/yaml.v2"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "7f97868eec74b32b0982dd158a51a446d1da7eb5"
|
||||||
|
version = "v2.1.1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "mvdan.cc/sh"
|
||||||
|
packages = [
|
||||||
|
"interp",
|
||||||
|
"syntax"
|
||||||
|
]
|
||||||
|
revision = "fb0bad77f8fa7a57e6f249f53074ec52b21558d1"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "976972e7291789a9d4904805cc7f49d733476868bf80f120309078b02a095a65"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
||||||
44
Gopkg.toml
Normal file
44
Gopkg.toml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
[prune]
|
||||||
|
unused-packages = true
|
||||||
|
non-go = true
|
||||||
|
go-tests = true
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/Masterminds/sprig"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/imdario/mergo"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/mattn/go-zglob"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "mvdan.cc/sh"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/spf13/pflag"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/sync"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "v2"
|
||||||
|
name = "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/radovskyb/watcher"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/mitchellh/go-homedir"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/Masterminds/semver"
|
||||||
663
README.md
663
README.md
@@ -1,12 +1,665 @@
|
|||||||
|
[](https://gophers.slack.com/messages/task)
|
||||||
[](https://travis-ci.org/go-task/task)
|
[](https://travis-ci.org/go-task/task)
|
||||||
|
|
||||||
# Task
|
# Task - A task runner / simpler Make alternative written in Go
|
||||||
|
|
||||||
Task is a task runner / build tool that aims to be simpler and easier to use
|
> We recently released version 2.0.0 of Task. The Taskfile changed a bit.
|
||||||
than, for example, [GNU Make][make].
|
Please, check the [Taskfile versions](TASKFILE_VERSIONS.md) document to see
|
||||||
|
what changed and how to upgrade.
|
||||||
|
|
||||||
---
|
Task is a simple tool that allows you to easily run development and build
|
||||||
|
tasks. Task is written in Golang, but can be used to develop any language.
|
||||||
|
It aims to be simpler and easier to use then [GNU Make][make].
|
||||||
|
|
||||||
See [taskfile.org](https://taskfile.org) for documentation.
|
- [Installation](#installation)
|
||||||
|
- [Go](#go)
|
||||||
|
- [Homebrew](#homebrew)
|
||||||
|
- [Snap](#snap)
|
||||||
|
- [Binary](#binary)
|
||||||
|
- [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)
|
||||||
|
- [Silent mode](#silent-mode)
|
||||||
|
- [Watch tasks](#watch-tasks-experimental)
|
||||||
|
- [Examples](#examples)
|
||||||
|
- [Alternative task runners](#alternative-task-runners)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Go
|
||||||
|
|
||||||
|
If you have a [Golang][golang] environment setup, you can simply run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get -u -v github.com/go-task/task/cmd/task
|
||||||
|
```
|
||||||
|
|
||||||
|
### Homebrew
|
||||||
|
|
||||||
|
If you're on macOS and have [Homebrew][homebrew] installed, getting Task is
|
||||||
|
as simple as running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
brew update
|
||||||
|
brew tap go-task/tap
|
||||||
|
brew install go-task
|
||||||
|
```
|
||||||
|
|
||||||
|
### Snap
|
||||||
|
|
||||||
|
Task is available for [Snapcraft][snapcraft], but keep in mind that your
|
||||||
|
Linux distribution should allow classic confinement for Snaps to Task work
|
||||||
|
right:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo snap install task
|
||||||
|
```
|
||||||
|
|
||||||
|
### Binary
|
||||||
|
|
||||||
|
Or you can download the binary from the [releases][releases] page and add to
|
||||||
|
your `PATH`. DEB and RPM packages are also available.
|
||||||
|
The `task_checksums.txt` file contains the sha256 checksum for each file.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Create a file called `Taskfile.yml` in the root of the project.
|
||||||
|
The `cmds` attribute should contains the commands of a task.
|
||||||
|
The example below allows compile a Go app and uses [Minify][minify] to concat
|
||||||
|
and minify multiple CSS files into a single one.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
cmds:
|
||||||
|
- go build -v -i main.go
|
||||||
|
|
||||||
|
assets:
|
||||||
|
cmds:
|
||||||
|
- minify -o public/style.css src/css
|
||||||
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
If you ommit a task name, "default" will be assumed.
|
||||||
|
|
||||||
|
### Environment
|
||||||
|
|
||||||
|
You can specify environment variables that are added when running a command:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
cmds:
|
||||||
|
- echo $hallo
|
||||||
|
env:
|
||||||
|
hallo: welt
|
||||||
|
```
|
||||||
|
|
||||||
|
### OS specific task
|
||||||
|
|
||||||
|
If you add a `Taskfile_{{GOOS}}.yml` you can override or amend your taskfile
|
||||||
|
based on the operating system.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
Taskfile.yml:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
cmds:
|
||||||
|
- echo "default"
|
||||||
|
```
|
||||||
|
|
||||||
|
Taskfile_linux.yml:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
cmds:
|
||||||
|
- echo "linux"
|
||||||
|
```
|
||||||
|
|
||||||
|
Will print out `linux` and not default.
|
||||||
|
|
||||||
|
It's also possible to have OS specific `Taskvars.yml` file, like
|
||||||
|
`Taskvars_windows.yml`, `Taskfile_linux.yml` or `Taskvars_darwin.yml`. See the
|
||||||
|
[variables section](#variables) below.
|
||||||
|
|
||||||
|
### Task directory
|
||||||
|
|
||||||
|
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
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
serve:
|
||||||
|
dir: public/www
|
||||||
|
cmds:
|
||||||
|
# run http server
|
||||||
|
- caddy
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task dependencies
|
||||||
|
|
||||||
|
You may have tasks that depends on others. Just pointing them on `deps` will
|
||||||
|
make them run automatically before running the parent task:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
deps: [assets]
|
||||||
|
cmds:
|
||||||
|
- go build -v -i main.go
|
||||||
|
|
||||||
|
assets:
|
||||||
|
cmds:
|
||||||
|
- minify -o public/style.css src/css
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
assets:
|
||||||
|
deps: [js, css]
|
||||||
|
|
||||||
|
js:
|
||||||
|
cmds:
|
||||||
|
- minify -o public/script.js src/js
|
||||||
|
|
||||||
|
css:
|
||||||
|
cmds:
|
||||||
|
- minify -o public/style.css src/css
|
||||||
|
```
|
||||||
|
|
||||||
|
If there are more than one dependency, they always run in parallel for better
|
||||||
|
performance.
|
||||||
|
|
||||||
|
If you want to pass information to dependencies, you can do that the same
|
||||||
|
manner as you would to [call another task](#calling-another-task):
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
deps:
|
||||||
|
- task: echo_sth
|
||||||
|
vars: {TEXT: "before 1"}
|
||||||
|
- task: echo_sth
|
||||||
|
vars: {TEXT: "before 2"}
|
||||||
|
cmds:
|
||||||
|
- echo "after"
|
||||||
|
|
||||||
|
echo_sth:
|
||||||
|
cmds:
|
||||||
|
- echo {{.TEXT}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Calling another task
|
||||||
|
|
||||||
|
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. In this case, just use the following syntax:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
main-task:
|
||||||
|
cmds:
|
||||||
|
- task: task-to-be-called
|
||||||
|
- task: another-task
|
||||||
|
- echo "Both done"
|
||||||
|
|
||||||
|
task-to-be-called:
|
||||||
|
cmds:
|
||||||
|
- echo "Task to be called"
|
||||||
|
|
||||||
|
another-task:
|
||||||
|
cmds:
|
||||||
|
- echo "Another task"
|
||||||
|
```
|
||||||
|
|
||||||
|
Overriding variables in the called task is as simple as informing `vars`
|
||||||
|
attribute:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
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`.
|
||||||
|
|
||||||
|
### Prevent unnecessary work
|
||||||
|
|
||||||
|
If a task generates something, you can inform Task the source and generated
|
||||||
|
files, so Task will prevent to run them if not necessary.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
deps: [js, css]
|
||||||
|
cmds:
|
||||||
|
- go build -v -i main.go
|
||||||
|
|
||||||
|
js:
|
||||||
|
cmds:
|
||||||
|
- minify -o public/script.js src/js
|
||||||
|
sources:
|
||||||
|
- src/js/**/*.js
|
||||||
|
generates:
|
||||||
|
- public/script.js
|
||||||
|
|
||||||
|
css:
|
||||||
|
cmds:
|
||||||
|
- minify -o public/style.css src/css
|
||||||
|
sources:
|
||||||
|
- src/css/**/*.css
|
||||||
|
generates:
|
||||||
|
- public/style.css
|
||||||
|
```
|
||||||
|
|
||||||
|
`sources` and `generates` can be files or 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 a message like
|
||||||
|
`Task "js" is up to date`.
|
||||||
|
|
||||||
|
If you prefer this check to be made by the content of the files, instead of
|
||||||
|
its timestamp, just set the `method` property to `checksum`.
|
||||||
|
You will probably want to ignore the `.task` folder in your `.gitignore` file
|
||||||
|
(It's there that Task stores the last checksum).
|
||||||
|
This feature is still experimental and can change until it's stable.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
cmds:
|
||||||
|
- go build .
|
||||||
|
sources:
|
||||||
|
- ./*.go
|
||||||
|
generates:
|
||||||
|
- app{{exeExt}}
|
||||||
|
method: checksum
|
||||||
|
```
|
||||||
|
|
||||||
|
> TIP: method `none` skips any validation and always run the task.
|
||||||
|
|
||||||
|
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
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use `--force` or `-f` if you want to force a task to run even when
|
||||||
|
up-to-date.
|
||||||
|
|
||||||
|
Also, `task --status [tasks]...` will exit with non-zero exit code if any of
|
||||||
|
the tasks is not up-to-date.
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
|
||||||
|
When doing interpolation of variables, Task will look for the below.
|
||||||
|
They are listed below in order of importance (e.g. most important first):
|
||||||
|
|
||||||
|
- Variables declared locally in the task
|
||||||
|
- Variables given while calling a task from another.
|
||||||
|
(See [Calling another task](#calling-another-task) above)
|
||||||
|
- Variables declared in the `vars:` option in the `Taskfile`
|
||||||
|
- Variables available in the `Taskvars.yml` file
|
||||||
|
- Environment variables
|
||||||
|
|
||||||
|
Example of sending parameters with environment variables:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ TASK_VARIABLE=a-value task do-something
|
||||||
|
```
|
||||||
|
|
||||||
|
Since some shells don't support above syntax to set environment variables
|
||||||
|
(Windows) tasks also accepts a similar style when not in the beginning of
|
||||||
|
the command. Variables given in this form are only visible to the task called
|
||||||
|
right before.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example of locally declared vars:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
print-var:
|
||||||
|
cmds:
|
||||||
|
echo "{{.VAR}}"
|
||||||
|
vars:
|
||||||
|
VAR: Hello!
|
||||||
|
```
|
||||||
|
|
||||||
|
Example of global vars in a `Taskfile.yml`:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
vars:
|
||||||
|
GREETING: Hello from Taskfile!
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
greet:
|
||||||
|
cmds:
|
||||||
|
- echo "{{.GREETING}}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example of `Taskvars.yml` file:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
PROJECT_NAME: My Project
|
||||||
|
DEV_MODE: production
|
||||||
|
GIT_COMMIT: {sh: git log -n 1 --format=%h}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Variables expansion
|
||||||
|
|
||||||
|
Variables are expanded 2 times by default. You can change that by setting the
|
||||||
|
`expansions:` option. Change that will be necessary if you compose many
|
||||||
|
variables together:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
expansions: 3
|
||||||
|
|
||||||
|
vars:
|
||||||
|
FOO: foo
|
||||||
|
BAR: bar
|
||||||
|
BAZ: baz
|
||||||
|
FOOBAR: "{{.FOO}}{{.BAR}}"
|
||||||
|
FOOBARBAZ: "{{.FOOBAR}}{{.BAZ}}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
cmds:
|
||||||
|
- echo "{{.FOOBARBAZ}}"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Dynamic variables
|
||||||
|
|
||||||
|
The below syntax (`sh:` prop in a variable) is considered a dynamic variable.
|
||||||
|
The value will be treated as a command and the output assigned. If there is one
|
||||||
|
or more trailing newlines, the last newline will be trimmed.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
cmds:
|
||||||
|
- go build -ldflags="-X main.Version={{.GIT_COMMIT}}" main.go
|
||||||
|
vars:
|
||||||
|
GIT_COMMIT:
|
||||||
|
sh: git log -n 1 --format=%h
|
||||||
|
```
|
||||||
|
|
||||||
|
This works for all types of variables.
|
||||||
|
|
||||||
|
### Go's template engine
|
||||||
|
|
||||||
|
Task parse commands as [Go's template engine][gotemplate] before executing
|
||||||
|
them. Variables are accessible 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:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
print-date:
|
||||||
|
cmds:
|
||||||
|
- echo {{now | date "2006-01-02"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Task also adds the following functions:
|
||||||
|
|
||||||
|
- `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".
|
||||||
|
- `splitLines`: Splits Unix (\n) and Windows (\r\n) styled newlines.
|
||||||
|
- `catLines`: Replaces Unix (\n) and Windows (\r\n) styled newlines with a space.
|
||||||
|
- `toSlash`: Does nothing on Unix, but on Windows converts a string from `\`
|
||||||
|
path format to `/`.
|
||||||
|
- `fromSlash`: Oposite of `toSlash`. Does nothing on Unix, but on Windows
|
||||||
|
converts a string from `\` path format to `/`.
|
||||||
|
- `exeExt`: Returns the right executable extension for the current OS
|
||||||
|
(`".exe"` for Windows, `""` for others).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
print-os:
|
||||||
|
cmds:
|
||||||
|
- echo '{{OS}} {{ARCH}}'
|
||||||
|
- 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
|
||||||
|
- echo '{{fromSlash "path/to/file"}}'
|
||||||
|
enumerated-file:
|
||||||
|
vars:
|
||||||
|
CONTENT: |
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
cmds:
|
||||||
|
- |
|
||||||
|
cat << EOF > output.txt
|
||||||
|
{{range $i, $line := .CONTENT | splitLines -}}
|
||||||
|
{{printf "%3d" $i}}: {{$line}}
|
||||||
|
{{end}}EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Help
|
||||||
|
|
||||||
|
Running `task --list` (or `task -l`) lists all tasks with a description.
|
||||||
|
The following taskfile:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
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:
|
||||||
|
- minify -o public/script.js src/js
|
||||||
|
|
||||||
|
css:
|
||||||
|
cmds:
|
||||||
|
- minify -o public/style.css src/css
|
||||||
|
```
|
||||||
|
|
||||||
|
would print the following output:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
* build: Build the go binary.
|
||||||
|
* test: Run all the go tests.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Silent mode
|
||||||
|
|
||||||
|
Silent mode disables echoing of commands before Task runs it.
|
||||||
|
For the following Taskfile:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
echo:
|
||||||
|
cmds:
|
||||||
|
- echo "Print something"
|
||||||
|
```
|
||||||
|
|
||||||
|
Normally this will be print:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
echo "Print something"
|
||||||
|
Print something
|
||||||
|
```
|
||||||
|
|
||||||
|
With silent mode on, the below will be print instead:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
Print something
|
||||||
|
```
|
||||||
|
|
||||||
|
There's three ways to enable silent mode:
|
||||||
|
|
||||||
|
* At command level:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
echo:
|
||||||
|
cmds:
|
||||||
|
- cmd: echo "Print something"
|
||||||
|
silent: true
|
||||||
|
```
|
||||||
|
|
||||||
|
* At task level:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
echo:
|
||||||
|
cmds:
|
||||||
|
- echo "Print something"
|
||||||
|
silent: true
|
||||||
|
```
|
||||||
|
|
||||||
|
* Or globally with `--silent` or `-s` flag
|
||||||
|
|
||||||
|
If you want to suppress stdout instead, just redirect a command to `/dev/null`:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
echo:
|
||||||
|
cmds:
|
||||||
|
- echo "This will print nothing" > /dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
The [go-task/examples][examples] intends to be a collection of Taskfiles for
|
||||||
|
various use cases.
|
||||||
|
(It still lacks many examples, though. Contributions are welcome).
|
||||||
|
|
||||||
|
## Alternative task runners
|
||||||
|
|
||||||
|
- YAML based:
|
||||||
|
- [goeuro/myke][myke]
|
||||||
|
- [dreadl0ck/zeus][zeus]
|
||||||
|
- [rliebz/tusk][tusk]
|
||||||
|
- Go based:
|
||||||
|
- [markbates/grift][grift]
|
||||||
|
- [magefile/mage][mage]
|
||||||
|
- Make based:
|
||||||
|
- [tj/mmake][mmake]
|
||||||
|
|
||||||
[make]: https://www.gnu.org/software/make/
|
[make]: https://www.gnu.org/software/make/
|
||||||
|
[releases]: https://github.com/go-task/task/releases
|
||||||
|
[golang]: https://golang.org/
|
||||||
|
[gotemplate]: https://golang.org/pkg/text/template/
|
||||||
|
[myke]: https://github.com/goeuro/myke
|
||||||
|
[zeus]: https://github.com/dreadl0ck/zeus
|
||||||
|
[tusk]: https://github.com/rliebz/tusk
|
||||||
|
[grift]: https://github.com/markbates/grift
|
||||||
|
[mage]: https://github.com/magefile/mage
|
||||||
|
[mmake]: https://github.com/tj/mmake
|
||||||
|
[sh]: https://github.com/mvdan/sh
|
||||||
|
[minify]: https://github.com/tdewolff/minify/tree/master/cmd/minify
|
||||||
|
[examples]: https://github.com/go-task/examples
|
||||||
|
[snapcraft]: https://snapcraft.io/
|
||||||
|
[homebrew]: https://brew.sh/
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ The exception is the publishing of a new version of the
|
|||||||
the binaries:
|
the binaries:
|
||||||
|
|
||||||
* Updating the current version on [snapcraft.yaml][snapcraftyaml];
|
* Updating the current version on [snapcraft.yaml][snapcraftyaml];
|
||||||
* Moving both `i386` and `amd64` new artifacts to the stable channel on
|
* Moving either the `i386` and `amd64` new artifacts to the stable channel on
|
||||||
the [Snapscraft dashboard][snapcraftdashboard]
|
the [Snapscraft dashboard][snapcraftdashboard]
|
||||||
|
|
||||||
[goreleaser]: https://goreleaser.com/#continuous_integration
|
[goreleaser]: https://goreleaser.com/#continuous_integration
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
# Taskfile Versions
|
# Taskfile version
|
||||||
|
|
||||||
The Taskfile syntax and features changed with time. This document explains what
|
The Taskfile syntax and features changed with time. This document explains what
|
||||||
changed on each version and how to upgrade your Taskfile.
|
changed on each version and how to upgrade your Taskfile.
|
||||||
|
|
||||||
## What the Taskfile version mean
|
# What the Taskfile version mean
|
||||||
|
|
||||||
The Taskfile version follows the Task version. E.g. the change to Taskfile
|
The Taskfile version follows the Task version. E.g. the change to Taskfile
|
||||||
version `2` means that Task `v2.0.0` should be release to support it.
|
version `2` means that Task `v2.0.0` should be release to support it.
|
||||||
@@ -18,7 +18,7 @@ available, but not `3.0.0+`.
|
|||||||
In the first version of the `Taskfile`, the `version:` key was not available,
|
In the first version of the `Taskfile`, the `version:` key was not available,
|
||||||
because the tasks was in the root of the YAML document. Like this:
|
because the tasks was in the root of the YAML document. Like this:
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
echo:
|
echo:
|
||||||
cmds:
|
cmds:
|
||||||
- echo "Hello, World!"
|
- echo "Hello, World!"
|
||||||
@@ -37,7 +37,7 @@ At version 2, we introduced the `version:` key, to allow us to envolve Task
|
|||||||
with new features without breaking existing Taskfiles. The new syntax is as
|
with new features without breaking existing Taskfiles. The new syntax is as
|
||||||
follows:
|
follows:
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
version: '2'
|
version: '2'
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
@@ -49,7 +49,7 @@ tasks:
|
|||||||
Version 2 allows you to write global variables directly in the Taskfile,
|
Version 2 allows you to write global variables directly in the Taskfile,
|
||||||
if you don't want to create a `Taskvars.yml`:
|
if you don't want to create a `Taskvars.yml`:
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
version: '2'
|
version: '2'
|
||||||
|
|
||||||
vars:
|
vars:
|
||||||
@@ -72,7 +72,7 @@ The variable priority order changed to the following:
|
|||||||
A new global option was added to configure the number of variables expansions
|
A new global option was added to configure the number of variables expansions
|
||||||
(which default to 2):
|
(which default to 2):
|
||||||
|
|
||||||
```yaml
|
```yml
|
||||||
version: '2'
|
version: '2'
|
||||||
|
|
||||||
expansions: 3
|
expansions: 3
|
||||||
@@ -89,60 +89,3 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- echo "{{.FOOBARBAZ}}"
|
- echo "{{.FOOBARBAZ}}"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Version 2.1
|
|
||||||
|
|
||||||
Version 2.1 includes a global `output` option, to allow having more control
|
|
||||||
over how commands output are printed to the console
|
|
||||||
(see [documentation][output] for more info):
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
output: prefixed
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
server:
|
|
||||||
cmds:
|
|
||||||
- go run main.go
|
|
||||||
prefix: server
|
|
||||||
```
|
|
||||||
|
|
||||||
From this version it's not also possible to ignore errors of a command or task
|
|
||||||
(check documentation [here][ignore_errors]):
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
example-1:
|
|
||||||
cmds:
|
|
||||||
- cmd: exit 1
|
|
||||||
ignore_error: true
|
|
||||||
- echo "This will be print"
|
|
||||||
|
|
||||||
example-2:
|
|
||||||
cmds:
|
|
||||||
- exit 1
|
|
||||||
- echo "This will be print"
|
|
||||||
ignore_error: true
|
|
||||||
```
|
|
||||||
|
|
||||||
## Version 2.2
|
|
||||||
|
|
||||||
Version 2.2 comes with a global `includes` options to include other
|
|
||||||
Taskfiles:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
includes:
|
|
||||||
docs: ./documentation # will look for ./documentation/Taskfile.yml
|
|
||||||
docker: ./DockerTasks.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
Please check the [documentation][includes]
|
|
||||||
|
|
||||||
[output]: usage.md#output-syntax
|
|
||||||
[ignore_errors]: usage.md#ignore-errors
|
|
||||||
[includes]: usage.md#including-other-taskfiles
|
|
||||||
55
Taskfile.yml
55
Taskfile.yml
@@ -1,39 +1,27 @@
|
|||||||
version: '2'
|
version: '2'
|
||||||
|
|
||||||
vars:
|
|
||||||
GIT_COMMIT:
|
|
||||||
sh: git log -n 1 --format=%h
|
|
||||||
|
|
||||||
GO_PACKAGES:
|
|
||||||
sh: go list ./...
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
default:
|
# compiles current source code and make "task" executable available on
|
||||||
cmds:
|
# $GOPATH/bin/task{.exe}
|
||||||
- task: test
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
desc: Installs Task
|
desc: Installs Task
|
||||||
cmds:
|
cmds:
|
||||||
- go install -v -ldflags="-w -s -X main.version={{.GIT_COMMIT}}" ./cmd/task
|
- go install -v -ldflags="-w -s -X main.version={{.GIT_COMMIT}}" ./cmd/task
|
||||||
env:
|
|
||||||
CGO_ENABLED: '0'
|
|
||||||
|
|
||||||
dl-deps:
|
dl-deps:
|
||||||
desc: Downloads cli dependencies
|
desc: Downloads cli dependencies
|
||||||
cmds:
|
cmds:
|
||||||
- task: go-get
|
- task: go-get
|
||||||
vars: {REPO: golang.org/x/lint/golint}
|
vars: {REPO: github.com/golang/lint/golint}
|
||||||
|
- task: go-get
|
||||||
|
vars: {REPO: github.com/asticode/go-astitodo/astitodo}
|
||||||
|
- task: go-get
|
||||||
|
vars: {REPO: github.com/golang/dep/cmd/dep}
|
||||||
- task: go-get
|
- task: go-get
|
||||||
vars: {REPO: github.com/goreleaser/goreleaser}
|
vars: {REPO: github.com/goreleaser/goreleaser}
|
||||||
- task: go-get
|
- task: go-get
|
||||||
vars: {REPO: github.com/goreleaser/godownloader}
|
vars: {REPO: github.com/goreleaser/godownloader}
|
||||||
|
|
||||||
vendor:
|
|
||||||
desc: Sync vendor/ directory according to go.mod file
|
|
||||||
cmds:
|
|
||||||
- go mod vendor
|
|
||||||
|
|
||||||
update-deps:
|
update-deps:
|
||||||
desc: Updates dependencies
|
desc: Updates dependencies
|
||||||
cmds:
|
cmds:
|
||||||
@@ -48,48 +36,33 @@ tasks:
|
|||||||
lint:
|
lint:
|
||||||
desc: Runs golint
|
desc: Runs golint
|
||||||
cmds:
|
cmds:
|
||||||
- golint {{catLines .GO_PACKAGES}}
|
- golint {{.GO_PACKAGES}}
|
||||||
silent: true
|
silent: true
|
||||||
|
|
||||||
test:
|
test:
|
||||||
desc: Runs test suite
|
desc: Runs test suite
|
||||||
deps: [install]
|
deps: [install]
|
||||||
cmds:
|
cmds:
|
||||||
- go test {{catLines .GO_PACKAGES}}
|
- go test {{.GO_PACKAGES}}
|
||||||
|
|
||||||
test-release:
|
test-release:
|
||||||
desc: Tests release process without publishing
|
desc: Tests release process without publishing
|
||||||
cmds:
|
cmds:
|
||||||
- goreleaser --snapshot --rm-dist
|
- goreleaser --snapshot --rm-dist
|
||||||
|
|
||||||
generate-install-script:
|
todo:
|
||||||
desc: Generate install script using https://github.com/goreleaser/godownloader
|
desc: Prints TODO comments present in the code
|
||||||
cmds:
|
cmds:
|
||||||
- godownloader --repo go-task/task -o install-task.sh
|
- astitodo {{.GO_PACKAGES}}
|
||||||
- cp ./install-task.sh ./docs/install.sh
|
silent: true
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
cmds:
|
cmds:
|
||||||
- task: go-get
|
- task: go-get
|
||||||
vars: {REPO: golang.org/x/lint/golint}
|
vars: {REPO: github.com/golang/lint/golint}
|
||||||
- task: lint
|
- task: lint
|
||||||
- task: test
|
- task: test
|
||||||
|
|
||||||
go-get:
|
go-get:
|
||||||
cmds:
|
cmds:
|
||||||
- go get -u {{.REPO}}
|
- go get -u {{.REPO}}
|
||||||
|
|
||||||
packages:
|
|
||||||
cmds:
|
|
||||||
- echo '{{.GO_PACKAGES}}'
|
|
||||||
silent: true
|
|
||||||
|
|
||||||
docs:install:
|
|
||||||
desc: Installs docsify to work the on the documentation site
|
|
||||||
cmds:
|
|
||||||
- npm install docsify-cli -g
|
|
||||||
|
|
||||||
docs:serve:
|
|
||||||
desc: Serves the documentation site locally
|
|
||||||
cmds:
|
|
||||||
- docsify serve docs
|
|
||||||
|
|||||||
15
Taskvars.yml
Normal file
15
Taskvars.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
GIT_COMMIT:
|
||||||
|
sh: git log -n 1 --format=%h
|
||||||
|
|
||||||
|
GO_PACKAGES:
|
||||||
|
.
|
||||||
|
./cmd/task
|
||||||
|
./internal/args
|
||||||
|
./internal/compiler
|
||||||
|
./internal/compiler/v1
|
||||||
|
./internal/compiler/v2
|
||||||
|
./internal/execext
|
||||||
|
./internal/logger
|
||||||
|
./internal/status
|
||||||
|
./internal/taskfile
|
||||||
|
./internal/templater
|
||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/go-task/task/v2"
|
"github.com/go-task/task"
|
||||||
"github.com/go-task/task/v2/internal/args"
|
"github.com/go-task/task/internal/args"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
@@ -17,7 +17,7 @@ var (
|
|||||||
version = "master"
|
version = "master"
|
||||||
)
|
)
|
||||||
|
|
||||||
const usage = `Usage: task [-ilfwvsd] [--init] [--list] [--force] [--watch] [--verbose] [--silent] [--dir] [--dry] [task...]
|
const usage = `Usage: task [-ilfwvsd] [--init] [--list] [--force] [--watch] [--verbose] [--silent] [--dir] [task...]
|
||||||
|
|
||||||
Runs the specified task(s). Falls back to the "default" task if no task name
|
Runs the specified task(s). Falls back to the "default" task if no task name
|
||||||
was specified, or lists all tasks if an unknown task name was specified.
|
was specified, or lists all tasks if an unknown task name was specified.
|
||||||
@@ -55,7 +55,6 @@ func main() {
|
|||||||
watch bool
|
watch bool
|
||||||
verbose bool
|
verbose bool
|
||||||
silent bool
|
silent bool
|
||||||
dry bool
|
|
||||||
dir string
|
dir string
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -67,7 +66,6 @@ func main() {
|
|||||||
pflag.BoolVarP(&watch, "watch", "w", false, "enables watch of the given task")
|
pflag.BoolVarP(&watch, "watch", "w", false, "enables watch of the given task")
|
||||||
pflag.BoolVarP(&verbose, "verbose", "v", false, "enables verbose mode")
|
pflag.BoolVarP(&verbose, "verbose", "v", false, "enables verbose mode")
|
||||||
pflag.BoolVarP(&silent, "silent", "s", false, "disables echoing")
|
pflag.BoolVarP(&silent, "silent", "s", false, "disables echoing")
|
||||||
pflag.BoolVar(&dry, "dry", false, "compiles and prints tasks in the order that they would be run, without executing them")
|
|
||||||
pflag.StringVarP(&dir, "dir", "d", "", "sets directory of execution")
|
pflag.StringVarP(&dir, "dir", "d", "", "sets directory of execution")
|
||||||
pflag.Parse()
|
pflag.Parse()
|
||||||
|
|
||||||
@@ -87,20 +85,14 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
if !watch {
|
|
||||||
ctx = getSignalContext()
|
|
||||||
}
|
|
||||||
|
|
||||||
e := task.Executor{
|
e := task.Executor{
|
||||||
Force: force,
|
Force: force,
|
||||||
Watch: watch,
|
Watch: watch,
|
||||||
Verbose: verbose,
|
Verbose: verbose,
|
||||||
Silent: silent,
|
Silent: silent,
|
||||||
Dir: dir,
|
Dir: dir,
|
||||||
Dry: dry,
|
|
||||||
|
|
||||||
Context: ctx,
|
Context: getSignalContext(),
|
||||||
|
|
||||||
Stdin: os.Stdin,
|
Stdin: os.Stdin,
|
||||||
Stdout: os.Stdout,
|
Stdout: os.Stdout,
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
#compdef task
|
|
||||||
|
|
||||||
# Listing commands from Taskfile.yml
|
|
||||||
function __list() {
|
|
||||||
local -a scripts
|
|
||||||
|
|
||||||
if [ -f Taskfile.yml ]; then
|
|
||||||
scripts=($(task -l | sed '1d' | sed 's/://' | awk '{ print $2 }'))
|
|
||||||
_describe 'script' scripts
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_arguments \
|
|
||||||
'(-d --dir)'{-d,--dir}': :_files' \
|
|
||||||
'(--dry)'--dry \
|
|
||||||
'(-f --force)'{-f,--force} \
|
|
||||||
'(-i --init)'{-i,--init} \
|
|
||||||
'(-l --list)'{-l,--list} \
|
|
||||||
'(-s --silent)'{-s,--silent} \
|
|
||||||
'(--status)'--status \
|
|
||||||
'(-v --verbose)'{-v,--verbose} \
|
|
||||||
'(--version)'--version \
|
|
||||||
'(-w --watch)'{-w,--watch} \
|
|
||||||
'(- *)'{-h,--help} \
|
|
||||||
'*: :__list' \
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
taskfile.org
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# Task
|
|
||||||
|
|
||||||
Task is a task runner / build tool that aims to be simpler and easier to use
|
|
||||||
than, for example, [GNU Make][make].
|
|
||||||
|
|
||||||
Since it's written in [Go][go], Task is just a single binary and has no other
|
|
||||||
dependencies, which means you don't need to mess with any complicated install
|
|
||||||
setups just to use a build tool.
|
|
||||||
|
|
||||||
Once [installed](installation.md), you just need to describe your build tasks
|
|
||||||
using a simple [YAML][yaml] schema in a file called `Taskfile.yml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
hello:
|
|
||||||
cmds:
|
|
||||||
- echo 'Hello World from Task!'
|
|
||||||
silent: true
|
|
||||||
```
|
|
||||||
|
|
||||||
And call it by running `task hello` from you terminal.
|
|
||||||
|
|
||||||
The above example is just the start, you can take a look at the [usage](usage.md)
|
|
||||||
guide to check the full schema documentation and Task features.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- [Easy installation](installation.md): just download a single binary, add to
|
|
||||||
$PATH and you're done! Or you can also install using [Homebrew][homebrew] or
|
|
||||||
[Snapcraft][snapcraft] if you want;
|
|
||||||
- Available on CIs: by adding [this simple command](installation.md#install-script)
|
|
||||||
to install on your CI script and you're done to use Task as part of your CI pipeline;
|
|
||||||
- Truly cross-platform: while most build tools only work well on Linux or macOS,
|
|
||||||
Task also supports Windows thanks to [this awesome shell interpreter for Go][sh];
|
|
||||||
- Great for code generation: you can easily [prevent a task from running](usage.md#prevent-unnecessary-work)
|
|
||||||
if a given set of files haven't changed since last run (based either on its
|
|
||||||
timestamp or content).
|
|
||||||
|
|
||||||
[make]: https://www.gnu.org/software/make/
|
|
||||||
[go]: https://golang.org/
|
|
||||||
[yaml]: http://yaml.org/
|
|
||||||
[homebrew]: https://brew.sh/
|
|
||||||
[snapcraft]: https://snapcraft.io/
|
|
||||||
[sh]: https://mvdan.cc/sh
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
- [Installation](installation.md)
|
|
||||||
- [Usage](usage.md)
|
|
||||||
- [Taskfile Versions](taskfile_versions.md)
|
|
||||||
- [Examples](examples.md)
|
|
||||||
- [Releasing Task](releasing_task.md)
|
|
||||||
- [Alternative Task Runners](alternative_task_runners.md)
|
|
||||||
- [Sponsors and Backers](sponsors_and_backers.md)
|
|
||||||
- [Github](https://github.com/go-task/task)
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
# Alternative task runners
|
|
||||||
|
|
||||||
## YAML based
|
|
||||||
|
|
||||||
- [rliebz/tusk][tusk]
|
|
||||||
|
|
||||||
## Go based
|
|
||||||
|
|
||||||
- [magefile/mage][mage]
|
|
||||||
|
|
||||||
## Make similar
|
|
||||||
|
|
||||||
- [casey/just][just]
|
|
||||||
|
|
||||||
[tusk]: https://github.com/rliebz/tusk
|
|
||||||
[mage]: https://github.com/magefile/mage
|
|
||||||
[just]: https://github.com/casey/just
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# Examples
|
|
||||||
|
|
||||||
The [go-task/examples][examples] intends to be a collection of Taskfiles for
|
|
||||||
various use cases.
|
|
||||||
(It still lacks many examples, though. Contributions are welcome).
|
|
||||||
|
|
||||||
[examples]: https://github.com/go-task/examples
|
|
||||||
BIN
docs/favicon.ico
BIN
docs/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 136 KiB |
@@ -1,49 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Task</title>
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
|
||||||
<meta name="description" content="A task runner / simpler Make alternative written in Go">
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<link rel="stylesheet" href="//unpkg.com/docsify-themeable/dist/css/theme-simple.css">
|
|
||||||
<meta name="google-site-verification" content="VGAYkbdmuaciIDGkBe-eAg9yfZg0C6ostgonbGxxOa0" />
|
|
||||||
<script>
|
|
||||||
var SeedAndDewConfig = {};
|
|
||||||
(function() {
|
|
||||||
SeedAndDewConfig['adClass'] = "snd-ad";
|
|
||||||
/* * * DON'T EDIT BELOW THIS LINE * * */
|
|
||||||
SeedAndDewConfig['projectId'] = '16e0aed0-b265-48c9-9eae-0aad56147553';
|
|
||||||
SeedAndDewConfig['loadStartTime'] = performance.now();
|
|
||||||
SeedAndDewConfig['apiVersion'] = '2018-05-28'
|
|
||||||
SeedAndDewConfig['sessionId'] = Math.random().toString(36).substring(2, 15);
|
|
||||||
var snd = document.createElement('script');
|
|
||||||
snd.type = 'text/javascript';
|
|
||||||
snd.async = true;
|
|
||||||
snd.src = 'https://www.seedanddew.com/static/embed.min.js';
|
|
||||||
(document.getElementsByTagName('head')[0] ||
|
|
||||||
document.getElementsByTagName('body')[0]).appendChild(snd);
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script>
|
|
||||||
window.$docsify = {
|
|
||||||
name: 'Task',
|
|
||||||
repo: 'go-task/task',
|
|
||||||
ga: 'UA-126286662-1',
|
|
||||||
themeColor: '#83d0f2',
|
|
||||||
loadSidebar: true,
|
|
||||||
auto2top: true,
|
|
||||||
maxLevel: 3,
|
|
||||||
subMaxLevel: 3
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
|
||||||
<script src="//unpkg.com/docsify/lib/plugins/ga.min.js"></script>
|
|
||||||
<script src="//unpkg.com/docsify-themeable"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-yaml.min.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
390
docs/install.sh
390
docs/install.sh
@@ -1,390 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
# Code generated by godownloader on 2018-04-07T17:47:38Z. DO NOT EDIT.
|
|
||||||
#
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
this=$1
|
|
||||||
cat <<EOF
|
|
||||||
$this: download go binaries for go-task/task
|
|
||||||
|
|
||||||
Usage: $this [-b] bindir [-d] [tag]
|
|
||||||
-b sets bindir or installation directory, Defaults to ./bin
|
|
||||||
-d turns on debug logging
|
|
||||||
[tag] is a tag from
|
|
||||||
https://github.com/go-task/task/releases
|
|
||||||
If tag is missing, then the latest will be used.
|
|
||||||
|
|
||||||
Generated by godownloader
|
|
||||||
https://github.com/goreleaser/godownloader
|
|
||||||
|
|
||||||
EOF
|
|
||||||
exit 2
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_args() {
|
|
||||||
#BINDIR is ./bin unless set be ENV
|
|
||||||
# over-ridden by flag below
|
|
||||||
|
|
||||||
BINDIR=${BINDIR:-./bin}
|
|
||||||
while getopts "b:dh?" arg; do
|
|
||||||
case "$arg" in
|
|
||||||
b) BINDIR="$OPTARG" ;;
|
|
||||||
d) log_set_priority 10 ;;
|
|
||||||
h | \?) usage "$0" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift $((OPTIND - 1))
|
|
||||||
TAG=$1
|
|
||||||
}
|
|
||||||
# this function wraps all the destructive operations
|
|
||||||
# if a curl|bash cuts off the end of the script due to
|
|
||||||
# network, either nothing will happen or will syntax error
|
|
||||||
# out preventing half-done work
|
|
||||||
execute() {
|
|
||||||
tmpdir=$(mktmpdir)
|
|
||||||
log_debug "downloading files into ${tmpdir}"
|
|
||||||
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
|
|
||||||
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
|
|
||||||
hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
|
|
||||||
srcdir="${tmpdir}"
|
|
||||||
(cd "${tmpdir}" && untar "${TARBALL}")
|
|
||||||
install -d "${BINDIR}"
|
|
||||||
for binexe in "task" ; do
|
|
||||||
if [ "$OS" = "windows" ]; then
|
|
||||||
binexe="${binexe}.exe"
|
|
||||||
fi
|
|
||||||
install "${srcdir}/${binexe}" "${BINDIR}/"
|
|
||||||
log_info "installed ${BINDIR}/${binexe}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
is_supported_platform() {
|
|
||||||
platform=$1
|
|
||||||
found=1
|
|
||||||
case "$platform" in
|
|
||||||
windows/386) found=0 ;;
|
|
||||||
windows/amd64) found=0 ;;
|
|
||||||
darwin/386) found=0 ;;
|
|
||||||
darwin/amd64) found=0 ;;
|
|
||||||
linux/386) found=0 ;;
|
|
||||||
linux/amd64) found=0 ;;
|
|
||||||
esac
|
|
||||||
case "$platform" in
|
|
||||||
darwin/386) found=1 ;;
|
|
||||||
esac
|
|
||||||
return $found
|
|
||||||
}
|
|
||||||
check_platform() {
|
|
||||||
if is_supported_platform "$PLATFORM"; then
|
|
||||||
# optional logging goes here
|
|
||||||
true
|
|
||||||
else
|
|
||||||
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
tag_to_version() {
|
|
||||||
if [ -z "${TAG}" ]; then
|
|
||||||
log_info "checking GitHub for latest tag"
|
|
||||||
else
|
|
||||||
log_info "checking GitHub for tag '${TAG}'"
|
|
||||||
fi
|
|
||||||
REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
|
|
||||||
if test -z "$REALTAG"; then
|
|
||||||
log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# if version starts with 'v', remove it
|
|
||||||
TAG="$REALTAG"
|
|
||||||
VERSION=${TAG#v}
|
|
||||||
}
|
|
||||||
adjust_format() {
|
|
||||||
# change format (tar.gz or zip) based on ARCH
|
|
||||||
case ${ARCH} in
|
|
||||||
windows) FORMAT=zip ;;
|
|
||||||
esac
|
|
||||||
true
|
|
||||||
}
|
|
||||||
adjust_os() {
|
|
||||||
# adjust archive name based on OS
|
|
||||||
true
|
|
||||||
}
|
|
||||||
adjust_arch() {
|
|
||||||
# adjust archive name based on ARCH
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
cat /dev/null <<EOF
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
https://github.com/client9/shlib - portable posix shell functions
|
|
||||||
Public domain - http://unlicense.org
|
|
||||||
https://github.com/client9/shlib/blob/master/LICENSE.md
|
|
||||||
but credit (and pull requests) appreciated.
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
EOF
|
|
||||||
is_command() {
|
|
||||||
command -v "$1" >/dev/null
|
|
||||||
}
|
|
||||||
echoerr() {
|
|
||||||
echo "$@" 1>&2
|
|
||||||
}
|
|
||||||
log_prefix() {
|
|
||||||
echo "$0"
|
|
||||||
}
|
|
||||||
_logp=6
|
|
||||||
log_set_priority() {
|
|
||||||
_logp="$1"
|
|
||||||
}
|
|
||||||
log_priority() {
|
|
||||||
if test -z "$1"; then
|
|
||||||
echo "$_logp"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
[ "$1" -le "$_logp" ]
|
|
||||||
}
|
|
||||||
log_tag() {
|
|
||||||
case $1 in
|
|
||||||
0) echo "emerg" ;;
|
|
||||||
1) echo "alert" ;;
|
|
||||||
2) echo "crit" ;;
|
|
||||||
3) echo "err" ;;
|
|
||||||
4) echo "warning" ;;
|
|
||||||
5) echo "notice" ;;
|
|
||||||
6) echo "info" ;;
|
|
||||||
7) echo "debug" ;;
|
|
||||||
*) echo "$1" ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
log_debug() {
|
|
||||||
log_priority 7 || return 0
|
|
||||||
echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
|
|
||||||
}
|
|
||||||
log_info() {
|
|
||||||
log_priority 6 || return 0
|
|
||||||
echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
|
|
||||||
}
|
|
||||||
log_err() {
|
|
||||||
log_priority 3 || return 0
|
|
||||||
echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
|
|
||||||
}
|
|
||||||
log_crit() {
|
|
||||||
log_priority 2 || return 0
|
|
||||||
echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
|
|
||||||
}
|
|
||||||
uname_os() {
|
|
||||||
os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
||||||
case "$os" in
|
|
||||||
msys_nt) os="windows" ;;
|
|
||||||
esac
|
|
||||||
echo "$os"
|
|
||||||
}
|
|
||||||
uname_arch() {
|
|
||||||
arch=$(uname -m)
|
|
||||||
case $arch in
|
|
||||||
x86_64) arch="amd64" ;;
|
|
||||||
x86) arch="386" ;;
|
|
||||||
i686) arch="386" ;;
|
|
||||||
i386) arch="386" ;;
|
|
||||||
aarch64) arch="arm64" ;;
|
|
||||||
armv5*) arch="arm5" ;;
|
|
||||||
armv6*) arch="arm6" ;;
|
|
||||||
armv7*) arch="arm7" ;;
|
|
||||||
esac
|
|
||||||
echo ${arch}
|
|
||||||
}
|
|
||||||
uname_os_check() {
|
|
||||||
os=$(uname_os)
|
|
||||||
case "$os" in
|
|
||||||
darwin) return 0 ;;
|
|
||||||
dragonfly) return 0 ;;
|
|
||||||
freebsd) return 0 ;;
|
|
||||||
linux) return 0 ;;
|
|
||||||
android) return 0 ;;
|
|
||||||
nacl) return 0 ;;
|
|
||||||
netbsd) return 0 ;;
|
|
||||||
openbsd) return 0 ;;
|
|
||||||
plan9) return 0 ;;
|
|
||||||
solaris) return 0 ;;
|
|
||||||
windows) return 0 ;;
|
|
||||||
esac
|
|
||||||
log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
uname_arch_check() {
|
|
||||||
arch=$(uname_arch)
|
|
||||||
case "$arch" in
|
|
||||||
386) return 0 ;;
|
|
||||||
amd64) return 0 ;;
|
|
||||||
arm64) return 0 ;;
|
|
||||||
armv5) return 0 ;;
|
|
||||||
armv6) return 0 ;;
|
|
||||||
armv7) return 0 ;;
|
|
||||||
ppc64) return 0 ;;
|
|
||||||
ppc64le) return 0 ;;
|
|
||||||
mips) return 0 ;;
|
|
||||||
mipsle) return 0 ;;
|
|
||||||
mips64) return 0 ;;
|
|
||||||
mips64le) return 0 ;;
|
|
||||||
s390x) return 0 ;;
|
|
||||||
amd64p32) return 0 ;;
|
|
||||||
esac
|
|
||||||
log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
untar() {
|
|
||||||
tarball=$1
|
|
||||||
case "${tarball}" in
|
|
||||||
*.tar.gz | *.tgz) tar -xzf "${tarball}" ;;
|
|
||||||
*.tar) tar -xf "${tarball}" ;;
|
|
||||||
*.zip) unzip "${tarball}" ;;
|
|
||||||
*)
|
|
||||||
log_err "untar unknown archive format for ${tarball}"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
mktmpdir() {
|
|
||||||
test -z "$TMPDIR" && TMPDIR="$(mktemp -d)"
|
|
||||||
mkdir -p "${TMPDIR}"
|
|
||||||
echo "${TMPDIR}"
|
|
||||||
}
|
|
||||||
http_download_curl() {
|
|
||||||
local_file=$1
|
|
||||||
source_url=$2
|
|
||||||
header=$3
|
|
||||||
if [ -z "$header" ]; then
|
|
||||||
code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
|
|
||||||
else
|
|
||||||
code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
|
|
||||||
fi
|
|
||||||
if [ "$code" != "200" ]; then
|
|
||||||
log_debug "http_download_curl received HTTP status $code"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
http_download_wget() {
|
|
||||||
local_file=$1
|
|
||||||
source_url=$2
|
|
||||||
header=$3
|
|
||||||
if [ -z "$header" ]; then
|
|
||||||
wget -q -O "$local_file" "$source_url"
|
|
||||||
else
|
|
||||||
wget -q --header "$header" -O "$local_file" "$source_url"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
http_download() {
|
|
||||||
log_debug "http_download $2"
|
|
||||||
if is_command curl; then
|
|
||||||
http_download_curl "$@"
|
|
||||||
return
|
|
||||||
elif is_command wget; then
|
|
||||||
http_download_wget "$@"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
log_crit "http_download unable to find wget or curl"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
http_copy() {
|
|
||||||
tmp=$(mktemp)
|
|
||||||
http_download "${tmp}" "$1" "$2" || return 1
|
|
||||||
body=$(cat "$tmp")
|
|
||||||
rm -f "${tmp}"
|
|
||||||
echo "$body"
|
|
||||||
}
|
|
||||||
github_release() {
|
|
||||||
owner_repo=$1
|
|
||||||
version=$2
|
|
||||||
test -z "$version" && version="latest"
|
|
||||||
giturl="https://github.com/${owner_repo}/releases/${version}"
|
|
||||||
json=$(http_copy "$giturl" "Accept:application/json")
|
|
||||||
test -z "$json" && return 1
|
|
||||||
version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
|
|
||||||
test -z "$version" && return 1
|
|
||||||
echo "$version"
|
|
||||||
}
|
|
||||||
hash_sha256() {
|
|
||||||
TARGET=${1:-/dev/stdin}
|
|
||||||
if is_command gsha256sum; then
|
|
||||||
hash=$(gsha256sum "$TARGET") || return 1
|
|
||||||
echo "$hash" | cut -d ' ' -f 1
|
|
||||||
elif is_command sha256sum; then
|
|
||||||
hash=$(sha256sum "$TARGET") || return 1
|
|
||||||
echo "$hash" | cut -d ' ' -f 1
|
|
||||||
elif is_command shasum; then
|
|
||||||
hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1
|
|
||||||
echo "$hash" | cut -d ' ' -f 1
|
|
||||||
elif is_command openssl; then
|
|
||||||
hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
|
|
||||||
echo "$hash" | cut -d ' ' -f a
|
|
||||||
else
|
|
||||||
log_crit "hash_sha256 unable to find command to compute sha-256 hash"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
hash_sha256_verify() {
|
|
||||||
TARGET=$1
|
|
||||||
checksums=$2
|
|
||||||
if [ -z "$checksums" ]; then
|
|
||||||
log_err "hash_sha256_verify checksum file not specified in arg2"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
BASENAME=${TARGET##*/}
|
|
||||||
want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)
|
|
||||||
if [ -z "$want" ]; then
|
|
||||||
log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
got=$(hash_sha256 "$TARGET")
|
|
||||||
if [ "$want" != "$got" ]; then
|
|
||||||
log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
cat /dev/null <<EOF
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
End of functions from https://github.com/client9/shlib
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
EOF
|
|
||||||
|
|
||||||
PROJECT_NAME="task"
|
|
||||||
OWNER=go-task
|
|
||||||
REPO="task"
|
|
||||||
BINARY=task
|
|
||||||
FORMAT=tar.gz
|
|
||||||
OS=$(uname_os)
|
|
||||||
ARCH=$(uname_arch)
|
|
||||||
PREFIX="$OWNER/$REPO"
|
|
||||||
|
|
||||||
# use in logging routines
|
|
||||||
log_prefix() {
|
|
||||||
echo "$PREFIX"
|
|
||||||
}
|
|
||||||
PLATFORM="${OS}/${ARCH}"
|
|
||||||
GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download
|
|
||||||
|
|
||||||
uname_os_check "$OS"
|
|
||||||
uname_arch_check "$ARCH"
|
|
||||||
|
|
||||||
parse_args "$@"
|
|
||||||
|
|
||||||
check_platform
|
|
||||||
|
|
||||||
tag_to_version
|
|
||||||
|
|
||||||
adjust_format
|
|
||||||
|
|
||||||
adjust_os
|
|
||||||
|
|
||||||
adjust_arch
|
|
||||||
|
|
||||||
log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}"
|
|
||||||
|
|
||||||
NAME=${BINARY}_${OS}_${ARCH}
|
|
||||||
TARBALL=${NAME}.${FORMAT}
|
|
||||||
TARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}
|
|
||||||
CHECKSUM=task_checksums.txt
|
|
||||||
CHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}
|
|
||||||
|
|
||||||
|
|
||||||
execute
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
# Installation
|
|
||||||
|
|
||||||
## Binary
|
|
||||||
|
|
||||||
Or you can download the binary from the [releases][releases] page and add to
|
|
||||||
your $PATH. DEB and RPM packages are also available.
|
|
||||||
The `task_checksums.txt` file contains the sha256 checksum for each file.
|
|
||||||
|
|
||||||
## Homebrew
|
|
||||||
|
|
||||||
If you're on macOS and have [Homebrew][homebrew] installed, getting Task is
|
|
||||||
as simple as running:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew install go-task/tap/go-task
|
|
||||||
```
|
|
||||||
|
|
||||||
## Snap
|
|
||||||
|
|
||||||
Task is available for [Snapcraft][snapcraft], but keep in mind that your
|
|
||||||
Linux distribution should allow classic confinement for Snaps to Task work
|
|
||||||
right:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo snap install task
|
|
||||||
```
|
|
||||||
|
|
||||||
## Go
|
|
||||||
|
|
||||||
Task now uses [Go Modules](https://github.com/golang/go/wiki/Modules), which
|
|
||||||
means you may have trouble compiling it on older Go versions.
|
|
||||||
|
|
||||||
For CI environments we recommend using the [Install Script](#install-script)
|
|
||||||
instead, which is faster and more stable, since it'll just download the latest
|
|
||||||
released binary, instead of compiling the edge (master branch) version.
|
|
||||||
|
|
||||||
Installing in your `$GOPATH`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go get -u -v github.com/go-task/task/cmd/task
|
|
||||||
```
|
|
||||||
|
|
||||||
Installing in another directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/go-task/task
|
|
||||||
cd task
|
|
||||||
|
|
||||||
# compiling binary to $GOPATH/bin
|
|
||||||
go install -v
|
|
||||||
|
|
||||||
# compiling it to another location
|
|
||||||
# use -o ./task.exe on Windows
|
|
||||||
go build -v -o ./task ./cmd/task
|
|
||||||
```
|
|
||||||
|
|
||||||
Both methods requires having the [Go][go] environment properly setup locally.
|
|
||||||
|
|
||||||
## Install script
|
|
||||||
|
|
||||||
We also have a [install script][installscript], which is very useful on
|
|
||||||
scanarios like CIs. Many thanks to [godownloader][godownloader] for allowing
|
|
||||||
easily generating this script.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -s https://taskfile.org/install.sh | sh
|
|
||||||
```
|
|
||||||
|
|
||||||
> This method will download the binary on the local `./bin` directory by default.
|
|
||||||
|
|
||||||
[go]: https://golang.org/
|
|
||||||
[snapcraft]: https://snapcraft.io/
|
|
||||||
[homebrew]: https://brew.sh/
|
|
||||||
[installscript]: https://github.com/go-task/task/blob/master/install-task.sh
|
|
||||||
[releases]: https://github.com/go-task/task/releases
|
|
||||||
[godownloader]: https://github.com/goreleaser/godownloader
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# Sponsors and Backers
|
|
||||||
|
|
||||||
## Sponsors
|
|
||||||
|
|
||||||
[][opencollective]
|
|
||||||
|
|
||||||
## Backers
|
|
||||||
|
|
||||||
[][opencollective]
|
|
||||||
|
|
||||||
## Contributors
|
|
||||||
|
|
||||||
[][contributors]
|
|
||||||
|
|
||||||
[opencollective]: https://opencollective.com/task
|
|
||||||
[contributors]: https://github.com/go-task/task/graphs/contributors
|
|
||||||
696
docs/usage.md
696
docs/usage.md
@@ -1,696 +0,0 @@
|
|||||||
# Usage
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
Create a file called `Taskfile.yml` in the root of your project.
|
|
||||||
The `cmds` attribute should contain the commands of a task.
|
|
||||||
The example below allows compiling a Go app and uses [Minify][minify] to concat
|
|
||||||
and minify multiple CSS files into a single one.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
build:
|
|
||||||
cmds:
|
|
||||||
- go build -v -i main.go
|
|
||||||
|
|
||||||
assets:
|
|
||||||
cmds:
|
|
||||||
- minify -o public/style.css src/css
|
|
||||||
```
|
|
||||||
|
|
||||||
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` are usually not available. Just remember any
|
|
||||||
executable called must be available by the OS or in PATH.
|
|
||||||
|
|
||||||
If you ommit a task name, "default" will be assumed.
|
|
||||||
|
|
||||||
## Environment
|
|
||||||
|
|
||||||
You can specify environment variables that are added when running a command:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
build:
|
|
||||||
cmds:
|
|
||||||
- echo $hallo
|
|
||||||
env:
|
|
||||||
hallo: welt
|
|
||||||
```
|
|
||||||
|
|
||||||
## Operating System specific tasks
|
|
||||||
|
|
||||||
If you add a `Taskfile_{{GOOS}}.yml` you can override or amend your Taskfile
|
|
||||||
based on the operating system.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
Taskfile.yml:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
build:
|
|
||||||
cmds:
|
|
||||||
- echo "default"
|
|
||||||
```
|
|
||||||
|
|
||||||
Taskfile_linux.yml:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
build:
|
|
||||||
cmds:
|
|
||||||
- echo "linux"
|
|
||||||
```
|
|
||||||
|
|
||||||
Will print out `linux` and not `default`.
|
|
||||||
|
|
||||||
Keep in mind that the version of the files should match. Also, when redefining
|
|
||||||
a task the whole task is replaced, properties of the task are not merged.
|
|
||||||
|
|
||||||
It's also possible to have an OS specific `Taskvars.yml` file, like
|
|
||||||
`Taskvars_windows.yml`, `Taskfile_linux.yml`, or `Taskvars_darwin.yml`. See the
|
|
||||||
[variables section](#variables) below.
|
|
||||||
|
|
||||||
## Including other Taskfiles
|
|
||||||
|
|
||||||
> This feature is still experimental and may have bugs.
|
|
||||||
|
|
||||||
If you want to share tasks between different projects (Taskfiles), you can use
|
|
||||||
the importing mechanism to include other Taskfiles using the `includes` keyword:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
includes:
|
|
||||||
docs: ./documentation # will look for ./documentation/Taskfile.yml
|
|
||||||
docker: ./DockerTasks.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
The tasks described in the given Taskfiles will be available with the informed
|
|
||||||
namespace. So, you'd call `task docs:serve` to run the `serve` task from
|
|
||||||
`documentation/Taskfile.yml` or `task docker:build` to run the `build` task
|
|
||||||
from the `DockerTasks.yml` file.
|
|
||||||
|
|
||||||
> The included Taskfiles must be using the same schema version the main
|
|
||||||
> Taskfile uses.
|
|
||||||
|
|
||||||
> Also, for now included Taskfiles can't include other Taskfiles.
|
|
||||||
> This was a deliberate decision to keep use and implementation simple.
|
|
||||||
> If you disagree, open an GitHub issue and explain your use case. =)
|
|
||||||
|
|
||||||
## Task directory
|
|
||||||
|
|
||||||
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`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
serve:
|
|
||||||
dir: public/www
|
|
||||||
cmds:
|
|
||||||
# run http server
|
|
||||||
- caddy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Task dependencies
|
|
||||||
|
|
||||||
You may have tasks that depend on others. Just pointing them on `deps` will
|
|
||||||
make them run automatically before running the parent task:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
build:
|
|
||||||
deps: [assets]
|
|
||||||
cmds:
|
|
||||||
- go build -v -i main.go
|
|
||||||
|
|
||||||
assets:
|
|
||||||
cmds:
|
|
||||||
- minify -o public/style.css src/css
|
|
||||||
```
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
assets:
|
|
||||||
deps: [js, css]
|
|
||||||
|
|
||||||
js:
|
|
||||||
cmds:
|
|
||||||
- minify -o public/script.js src/js
|
|
||||||
|
|
||||||
css:
|
|
||||||
cmds:
|
|
||||||
- minify -o public/style.css src/css
|
|
||||||
```
|
|
||||||
|
|
||||||
If there is more than one dependency, they always run in parallel for better
|
|
||||||
performance.
|
|
||||||
|
|
||||||
If you want to pass information to dependencies, you can do that the same
|
|
||||||
manner as you would to [call another task](#calling-another-task):
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
default:
|
|
||||||
deps:
|
|
||||||
- task: echo_sth
|
|
||||||
vars: {TEXT: "before 1"}
|
|
||||||
- task: echo_sth
|
|
||||||
vars: {TEXT: "before 2"}
|
|
||||||
cmds:
|
|
||||||
- echo "after"
|
|
||||||
|
|
||||||
echo_sth:
|
|
||||||
cmds:
|
|
||||||
- echo {{.TEXT}}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Calling another task
|
|
||||||
|
|
||||||
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. In this case, just use the following syntax:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
main-task:
|
|
||||||
cmds:
|
|
||||||
- task: task-to-be-called
|
|
||||||
- task: another-task
|
|
||||||
- echo "Both done"
|
|
||||||
|
|
||||||
task-to-be-called:
|
|
||||||
cmds:
|
|
||||||
- echo "Task to be called"
|
|
||||||
|
|
||||||
another-task:
|
|
||||||
cmds:
|
|
||||||
- echo "Another task"
|
|
||||||
```
|
|
||||||
|
|
||||||
Overriding variables in the called task is as simple as informing `vars`
|
|
||||||
attribute:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
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`.
|
|
||||||
|
|
||||||
## Prevent unnecessary work
|
|
||||||
|
|
||||||
If a task generates something, you can inform Task the source and generated
|
|
||||||
files, so Task will prevent to run them if not necessary.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
build:
|
|
||||||
deps: [js, css]
|
|
||||||
cmds:
|
|
||||||
- go build -v -i main.go
|
|
||||||
|
|
||||||
js:
|
|
||||||
cmds:
|
|
||||||
- minify -o public/script.js src/js
|
|
||||||
sources:
|
|
||||||
- src/js/**/*.js
|
|
||||||
generates:
|
|
||||||
- public/script.js
|
|
||||||
|
|
||||||
css:
|
|
||||||
cmds:
|
|
||||||
- minify -o public/style.css src/css
|
|
||||||
sources:
|
|
||||||
- src/css/**/*.css
|
|
||||||
generates:
|
|
||||||
- public/style.css
|
|
||||||
```
|
|
||||||
|
|
||||||
`sources` and `generates` can be files or 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 a message like
|
|
||||||
`Task "js" is up to date`.
|
|
||||||
|
|
||||||
If you prefer this check to be made by the content of the files, instead of
|
|
||||||
its timestamp, just set the `method` property to `checksum`.
|
|
||||||
You will probably want to ignore the `.task` folder in your `.gitignore` file
|
|
||||||
(It's there that Task stores the last checksum).
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
build:
|
|
||||||
cmds:
|
|
||||||
- go build .
|
|
||||||
sources:
|
|
||||||
- ./*.go
|
|
||||||
generates:
|
|
||||||
- app{{exeExt}}
|
|
||||||
method: checksum
|
|
||||||
```
|
|
||||||
|
|
||||||
> TIP: method `none` skips any validation and always run the task.
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
You can use `--force` or `-f` if you want to force a task to run even when
|
|
||||||
up-to-date.
|
|
||||||
|
|
||||||
Also, `task --status [tasks]...` will exit with a non-zero exit code if any of
|
|
||||||
the tasks are not up-to-date.
|
|
||||||
|
|
||||||
## Variables
|
|
||||||
|
|
||||||
When doing interpolation of variables, Task will look for the below.
|
|
||||||
They are listed below in order of importance (e.g. most important first):
|
|
||||||
|
|
||||||
- Variables declared locally in the task
|
|
||||||
- Variables given while calling a task from another.
|
|
||||||
(See [Calling another task](#calling-another-task) above)
|
|
||||||
- Variables declared in the `vars:` option in the `Taskfile`
|
|
||||||
- Variables available in the `Taskvars.yml` file
|
|
||||||
- Environment variables
|
|
||||||
|
|
||||||
Example of sending parameters with environment variables:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ TASK_VARIABLE=a-value task do-something
|
|
||||||
```
|
|
||||||
|
|
||||||
Since some shells don't support above syntax to set environment variables
|
|
||||||
(Windows) tasks also accepts a similar style when not in the beginning of
|
|
||||||
the command. Variables given in this form are only visible to the task called
|
|
||||||
right before.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example of locally declared vars:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
print-var:
|
|
||||||
cmds:
|
|
||||||
echo "{{.VAR}}"
|
|
||||||
vars:
|
|
||||||
VAR: Hello!
|
|
||||||
```
|
|
||||||
|
|
||||||
Example of global vars in a `Taskfile.yml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
vars:
|
|
||||||
GREETING: Hello from Taskfile!
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
greet:
|
|
||||||
cmds:
|
|
||||||
- echo "{{.GREETING}}"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example of `Taskvars.yml` file:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
PROJECT_NAME: My Project
|
|
||||||
DEV_MODE: production
|
|
||||||
GIT_COMMIT: {sh: git log -n 1 --format=%h}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Variables expansion
|
|
||||||
|
|
||||||
Variables are expanded 2 times by default. You can change that by setting the
|
|
||||||
`expansions:` option. Change that will be necessary if you compose many
|
|
||||||
variables together:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
expansions: 3
|
|
||||||
|
|
||||||
vars:
|
|
||||||
FOO: foo
|
|
||||||
BAR: bar
|
|
||||||
BAZ: baz
|
|
||||||
FOOBAR: "{{.FOO}}{{.BAR}}"
|
|
||||||
FOOBARBAZ: "{{.FOOBAR}}{{.BAZ}}"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
default:
|
|
||||||
cmds:
|
|
||||||
- echo "{{.FOOBARBAZ}}"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Dynamic variables
|
|
||||||
|
|
||||||
The below syntax (`sh:` prop in a variable) is considered a dynamic variable.
|
|
||||||
The value will be treated as a command and the output assigned. If there is one
|
|
||||||
or more trailing newlines, the last newline will be trimmed.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
build:
|
|
||||||
cmds:
|
|
||||||
- go build -ldflags="-X main.Version={{.GIT_COMMIT}}" main.go
|
|
||||||
vars:
|
|
||||||
GIT_COMMIT:
|
|
||||||
sh: git log -n 1 --format=%h
|
|
||||||
```
|
|
||||||
|
|
||||||
This works for all types of variables.
|
|
||||||
|
|
||||||
## Go's template engine
|
|
||||||
|
|
||||||
Task parse commands as [Go's template engine][gotemplate] before executing
|
|
||||||
them. Variables are accessible 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:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
print-date:
|
|
||||||
cmds:
|
|
||||||
- echo {{now | date "2006-01-02"}}
|
|
||||||
```
|
|
||||||
|
|
||||||
Task also adds the following functions:
|
|
||||||
|
|
||||||
- `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".
|
|
||||||
- `splitLines`: Splits Unix (\n) and Windows (\r\n) styled newlines.
|
|
||||||
- `catLines`: Replaces Unix (\n) and Windows (\r\n) styled newlines with a space.
|
|
||||||
- `toSlash`: Does nothing on Unix, but on Windows converts a string from `\`
|
|
||||||
path format to `/`.
|
|
||||||
- `fromSlash`: Oposite of `toSlash`. Does nothing on Unix, but on Windows
|
|
||||||
converts a string from `\` path format to `/`.
|
|
||||||
- `exeExt`: Returns the right executable extension for the current OS
|
|
||||||
(`".exe"` for Windows, `""` for others).
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
print-os:
|
|
||||||
cmds:
|
|
||||||
- echo '{{OS}} {{ARCH}}'
|
|
||||||
- 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
|
|
||||||
- echo '{{fromSlash "path/to/file"}}'
|
|
||||||
enumerated-file:
|
|
||||||
vars:
|
|
||||||
CONTENT: |
|
|
||||||
foo
|
|
||||||
bar
|
|
||||||
cmds:
|
|
||||||
- |
|
|
||||||
cat << EOF > output.txt
|
|
||||||
{{range $i, $line := .CONTENT | splitLines -}}
|
|
||||||
{{printf "%3d" $i}}: {{$line}}
|
|
||||||
{{end}}EOF
|
|
||||||
```
|
|
||||||
|
|
||||||
## Help
|
|
||||||
|
|
||||||
Running `task --list` (or `task -l`) lists all tasks with a description.
|
|
||||||
The following taskfile:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
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:
|
|
||||||
- minify -o public/script.js src/js
|
|
||||||
|
|
||||||
css:
|
|
||||||
cmds:
|
|
||||||
- minify -o public/style.css src/css
|
|
||||||
```
|
|
||||||
|
|
||||||
would print the following output:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
* build: Build the go binary.
|
|
||||||
* test: Run all the go tests.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Silent mode
|
|
||||||
|
|
||||||
Silent mode disables echoing of commands before Task runs it.
|
|
||||||
For the following Taskfile:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
echo:
|
|
||||||
cmds:
|
|
||||||
- echo "Print something"
|
|
||||||
```
|
|
||||||
|
|
||||||
Normally this will be print:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
echo "Print something"
|
|
||||||
Print something
|
|
||||||
```
|
|
||||||
|
|
||||||
With silent mode on, the below will be print instead:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
Print something
|
|
||||||
```
|
|
||||||
|
|
||||||
There's three ways to enable silent mode:
|
|
||||||
|
|
||||||
* At command level:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
echo:
|
|
||||||
cmds:
|
|
||||||
- cmd: echo "Print something"
|
|
||||||
silent: true
|
|
||||||
```
|
|
||||||
|
|
||||||
* At task level:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
echo:
|
|
||||||
cmds:
|
|
||||||
- echo "Print something"
|
|
||||||
silent: true
|
|
||||||
```
|
|
||||||
|
|
||||||
* Or globally with `--silent` or `-s` flag
|
|
||||||
|
|
||||||
If you want to suppress stdout instead, just redirect a command to `/dev/null`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
echo:
|
|
||||||
cmds:
|
|
||||||
- echo "This will print nothing" > /dev/null
|
|
||||||
```
|
|
||||||
|
|
||||||
## Dry run mode
|
|
||||||
|
|
||||||
Dry run mode (`--dry`) compiles and steps through each task, printing the commands
|
|
||||||
that would be run without executing them. This is useful for debugging your Taskfiles.
|
|
||||||
|
|
||||||
## Ignore errors
|
|
||||||
|
|
||||||
You have the option to ignore errors during command execution.
|
|
||||||
Given the following Taskfile:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
echo:
|
|
||||||
cmds:
|
|
||||||
- exit 1
|
|
||||||
- echo "Hello World"
|
|
||||||
```
|
|
||||||
|
|
||||||
Task will abort the execution after running `exit 1` because the status code `1` stands for `EXIT_FAILURE`.
|
|
||||||
However it is possible to continue with execution using `ignore_error`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
echo:
|
|
||||||
cmds:
|
|
||||||
- cmd: exit 1
|
|
||||||
ignore_error: true
|
|
||||||
- echo "Hello World"
|
|
||||||
```
|
|
||||||
|
|
||||||
`ignore_error` can also be set for a task, which mean errors will be supressed
|
|
||||||
for all commands. But keep in mind this option won't propagate to other tasks
|
|
||||||
called either by `deps` or `cmds`!
|
|
||||||
|
|
||||||
## Output syntax
|
|
||||||
|
|
||||||
By default, Task just redirect the STDOUT and STDERR of the running commands
|
|
||||||
to the shell in real time. This is good for having live feedback for log
|
|
||||||
printed by commands, but the output can become messy if you have multiple
|
|
||||||
commands running at the same time and printing lots of stuff.
|
|
||||||
|
|
||||||
To make this more customizable, there are currently three different output
|
|
||||||
options you can choose:
|
|
||||||
|
|
||||||
- `interleaved` (default)
|
|
||||||
- `group`
|
|
||||||
- `prefixed`
|
|
||||||
|
|
||||||
To choose another one, just set it to root in the Taskfile:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
output: 'group'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
# ...
|
|
||||||
```
|
|
||||||
|
|
||||||
The `group` output will print the entire output of a command once, after it
|
|
||||||
finishes, so you won't have live feedback for commands that take a long time
|
|
||||||
to run.
|
|
||||||
|
|
||||||
The `prefix` output will prefix every line printed by a command with
|
|
||||||
`[task-name] ` as the prefix, but you can customize the prefix for a command
|
|
||||||
with the `prefix:` attribute:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '2'
|
|
||||||
|
|
||||||
output: prefixed
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
default:
|
|
||||||
deps:
|
|
||||||
- task: print
|
|
||||||
vars: {TEXT: foo}
|
|
||||||
- task: print
|
|
||||||
vars: {TEXT: bar}
|
|
||||||
- task: print
|
|
||||||
vars: {TEXT: baz}
|
|
||||||
|
|
||||||
print:
|
|
||||||
cmds:
|
|
||||||
- echo "{{.TEXT}}"
|
|
||||||
prefix: "print-{{.TEXT}}"
|
|
||||||
silent: true
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ task default
|
|
||||||
[print-foo] foo
|
|
||||||
[print-bar] bar
|
|
||||||
[print-baz] baz
|
|
||||||
```
|
|
||||||
|
|
||||||
## Watch tasks
|
|
||||||
|
|
||||||
If you give a `--watch` or `-w` argument, task will watch for file changes
|
|
||||||
and run the task again. This requires the `sources` attribute to be given,
|
|
||||||
so task know which files to watch.
|
|
||||||
|
|
||||||
[gotemplate]: https://golang.org/pkg/text/template/
|
|
||||||
[minify]: https://github.com/tdewolff/minify/tree/master/cmd/minify
|
|
||||||
24
errors.go
24
errors.go
@@ -10,6 +10,14 @@ var (
|
|||||||
ErrTaskfileAlreadyExists = errors.New("task: A Taskfile already exists")
|
ErrTaskfileAlreadyExists = errors.New("task: A Taskfile already exists")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type taskFileNotFound struct {
|
||||||
|
taskFile string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err taskFileNotFound) Error() string {
|
||||||
|
return fmt.Sprintf(`task: No task file found (is it named "%s"?). Use "task --init" to create a new one`, err.taskFile)
|
||||||
|
}
|
||||||
|
|
||||||
type taskNotFoundError struct {
|
type taskNotFoundError struct {
|
||||||
taskName string
|
taskName string
|
||||||
}
|
}
|
||||||
@@ -27,6 +35,22 @@ func (err *taskRunError) Error() string {
|
|||||||
return fmt.Sprintf(`task: Failed to run task "%s": %v`, err.taskName, err.err)
|
return fmt.Sprintf(`task: Failed to run task "%s": %v`, err.taskName, err.err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type cyclicDepError struct {
|
||||||
|
taskName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err *cyclicDepError) Error() string {
|
||||||
|
return fmt.Sprintf(`task: Cyclic dependency of task "%s" detected`, err.taskName)
|
||||||
|
}
|
||||||
|
|
||||||
|
type cantWatchNoSourcesError struct {
|
||||||
|
taskName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err *cantWatchNoSourcesError) Error() string {
|
||||||
|
return fmt.Sprintf(`task: Can't watch task "%s" because it has no specified sources`, err.taskName)
|
||||||
|
}
|
||||||
|
|
||||||
// MaximumTaskCallExceededError is returned when a task is called too
|
// MaximumTaskCallExceededError is returned when a task is called too
|
||||||
// many times. In this case you probably have a cyclic dependendy or
|
// many times. In this case you probably have a cyclic dependendy or
|
||||||
// infinite loop
|
// infinite loop
|
||||||
|
|||||||
24
go.mod
24
go.mod
@@ -1,24 +0,0 @@
|
|||||||
module github.com/go-task/task/v2
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/Masterminds/semver v1.4.2
|
|
||||||
github.com/Masterminds/sprig v2.16.0+incompatible
|
|
||||||
github.com/aokoli/goutils v1.0.1 // indirect
|
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
||||||
github.com/google/uuid v1.0.0 // indirect
|
|
||||||
github.com/huandu/xstrings v1.1.0 // indirect
|
|
||||||
github.com/imdario/mergo v0.3.6 // indirect
|
|
||||||
github.com/kr/pretty v0.1.0 // indirect
|
|
||||||
github.com/mattn/go-zglob v0.0.0-20180803001819-2ea3427bfa53
|
|
||||||
github.com/mitchellh/go-homedir v1.0.0
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
||||||
github.com/radovskyb/watcher v1.0.2
|
|
||||||
github.com/spf13/pflag v1.0.3
|
|
||||||
github.com/stretchr/testify v1.2.2
|
|
||||||
golang.org/x/crypto v0.0.0-20180830192347-182538f80094 // indirect
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d // indirect
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f
|
|
||||||
golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.2.1
|
|
||||||
mvdan.cc/sh v0.0.0-20180829163519-3a244a89e2e5
|
|
||||||
)
|
|
||||||
45
go.sum
45
go.sum
@@ -1,45 +0,0 @@
|
|||||||
github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
|
|
||||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
|
||||||
github.com/Masterminds/sprig v2.16.0+incompatible h1:QZbMUPxRQ50EKAq3LFMnxddMu88/EUUG3qmxwtDmPsY=
|
|
||||||
github.com/Masterminds/sprig v2.16.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
|
||||||
github.com/aokoli/goutils v1.0.1 h1:7fpzNGoJ3VA8qcrm++XEE1QUe0mIwNeLa02Nwq7RDkg=
|
|
||||||
github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
|
|
||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/huandu/xstrings v1.1.0 h1:9oZY6Z/H3A1gytJxzuicbmV5QoR8M1TAPcn9WTg7vqg=
|
|
||||||
github.com/huandu/xstrings v1.1.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
|
|
||||||
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
|
||||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/mattn/go-zglob v0.0.0-20180803001819-2ea3427bfa53 h1:tGfIHhDghvEnneeRhODvGYOt305TPwingKt6p90F4MU=
|
|
||||||
github.com/mattn/go-zglob v0.0.0-20180803001819-2ea3427bfa53/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
|
||||||
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
|
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/radovskyb/watcher v1.0.2 h1:9L5TsZUbo1nKhQEQPtICVc+x9UZQ6VPdBepLHyGw/bQ=
|
|
||||||
github.com/radovskyb/watcher v1.0.2/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
|
|
||||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
golang.org/x/crypto v0.0.0-20180830192347-182538f80094 h1:rVTAlhYa4+lCfNxmAIEOGQRoD23UqP72M3+rSWVGDTg=
|
|
||||||
golang.org/x/crypto v0.0.0-20180830192347-182538f80094/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I=
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789 h1:T8D7l6WB3tLu+VpKvw06ieD/OhBi1XpJmG1U/FtttZg=
|
|
||||||
golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
mvdan.cc/sh v0.0.0-20180829163519-3a244a89e2e5 h1:FKi9XtQO5aNipfQ/qnnLCoM6gdFwPQY702RRbNRxjK8=
|
|
||||||
mvdan.cc/sh v0.0.0-20180829163519-3a244a89e2e5/go.mod h1:IeeQbZq+x2SUGBensq/jge5lLQbS3XT2ktyp3wrt4x8=
|
|
||||||
2
help.go
2
help.go
@@ -5,7 +5,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrintTasksHelp prints help os tasks that have a description
|
// PrintTasksHelp prints help os tasks that have a description
|
||||||
|
|||||||
2
init.go
2
init.go
@@ -8,7 +8,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultTaskfile = `# https://taskfile.org
|
const defaultTaskfile = `# github.com/go-task/task
|
||||||
|
|
||||||
version: '2'
|
version: '2'
|
||||||
|
|
||||||
|
|||||||
390
install-task.sh
390
install-task.sh
@@ -1,390 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
# Code generated by godownloader on 2018-04-07T17:47:38Z. DO NOT EDIT.
|
|
||||||
#
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
this=$1
|
|
||||||
cat <<EOF
|
|
||||||
$this: download go binaries for go-task/task
|
|
||||||
|
|
||||||
Usage: $this [-b] bindir [-d] [tag]
|
|
||||||
-b sets bindir or installation directory, Defaults to ./bin
|
|
||||||
-d turns on debug logging
|
|
||||||
[tag] is a tag from
|
|
||||||
https://github.com/go-task/task/releases
|
|
||||||
If tag is missing, then the latest will be used.
|
|
||||||
|
|
||||||
Generated by godownloader
|
|
||||||
https://github.com/goreleaser/godownloader
|
|
||||||
|
|
||||||
EOF
|
|
||||||
exit 2
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_args() {
|
|
||||||
#BINDIR is ./bin unless set be ENV
|
|
||||||
# over-ridden by flag below
|
|
||||||
|
|
||||||
BINDIR=${BINDIR:-./bin}
|
|
||||||
while getopts "b:dh?" arg; do
|
|
||||||
case "$arg" in
|
|
||||||
b) BINDIR="$OPTARG" ;;
|
|
||||||
d) log_set_priority 10 ;;
|
|
||||||
h | \?) usage "$0" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift $((OPTIND - 1))
|
|
||||||
TAG=$1
|
|
||||||
}
|
|
||||||
# this function wraps all the destructive operations
|
|
||||||
# if a curl|bash cuts off the end of the script due to
|
|
||||||
# network, either nothing will happen or will syntax error
|
|
||||||
# out preventing half-done work
|
|
||||||
execute() {
|
|
||||||
tmpdir=$(mktmpdir)
|
|
||||||
log_debug "downloading files into ${tmpdir}"
|
|
||||||
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
|
|
||||||
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
|
|
||||||
hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
|
|
||||||
srcdir="${tmpdir}"
|
|
||||||
(cd "${tmpdir}" && untar "${TARBALL}")
|
|
||||||
install -d "${BINDIR}"
|
|
||||||
for binexe in "task" ; do
|
|
||||||
if [ "$OS" = "windows" ]; then
|
|
||||||
binexe="${binexe}.exe"
|
|
||||||
fi
|
|
||||||
install "${srcdir}/${binexe}" "${BINDIR}/"
|
|
||||||
log_info "installed ${BINDIR}/${binexe}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
is_supported_platform() {
|
|
||||||
platform=$1
|
|
||||||
found=1
|
|
||||||
case "$platform" in
|
|
||||||
windows/386) found=0 ;;
|
|
||||||
windows/amd64) found=0 ;;
|
|
||||||
darwin/386) found=0 ;;
|
|
||||||
darwin/amd64) found=0 ;;
|
|
||||||
linux/386) found=0 ;;
|
|
||||||
linux/amd64) found=0 ;;
|
|
||||||
esac
|
|
||||||
case "$platform" in
|
|
||||||
darwin/386) found=1 ;;
|
|
||||||
esac
|
|
||||||
return $found
|
|
||||||
}
|
|
||||||
check_platform() {
|
|
||||||
if is_supported_platform "$PLATFORM"; then
|
|
||||||
# optional logging goes here
|
|
||||||
true
|
|
||||||
else
|
|
||||||
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
tag_to_version() {
|
|
||||||
if [ -z "${TAG}" ]; then
|
|
||||||
log_info "checking GitHub for latest tag"
|
|
||||||
else
|
|
||||||
log_info "checking GitHub for tag '${TAG}'"
|
|
||||||
fi
|
|
||||||
REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
|
|
||||||
if test -z "$REALTAG"; then
|
|
||||||
log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# if version starts with 'v', remove it
|
|
||||||
TAG="$REALTAG"
|
|
||||||
VERSION=${TAG#v}
|
|
||||||
}
|
|
||||||
adjust_format() {
|
|
||||||
# change format (tar.gz or zip) based on ARCH
|
|
||||||
case ${ARCH} in
|
|
||||||
windows) FORMAT=zip ;;
|
|
||||||
esac
|
|
||||||
true
|
|
||||||
}
|
|
||||||
adjust_os() {
|
|
||||||
# adjust archive name based on OS
|
|
||||||
true
|
|
||||||
}
|
|
||||||
adjust_arch() {
|
|
||||||
# adjust archive name based on ARCH
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
cat /dev/null <<EOF
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
https://github.com/client9/shlib - portable posix shell functions
|
|
||||||
Public domain - http://unlicense.org
|
|
||||||
https://github.com/client9/shlib/blob/master/LICENSE.md
|
|
||||||
but credit (and pull requests) appreciated.
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
EOF
|
|
||||||
is_command() {
|
|
||||||
command -v "$1" >/dev/null
|
|
||||||
}
|
|
||||||
echoerr() {
|
|
||||||
echo "$@" 1>&2
|
|
||||||
}
|
|
||||||
log_prefix() {
|
|
||||||
echo "$0"
|
|
||||||
}
|
|
||||||
_logp=6
|
|
||||||
log_set_priority() {
|
|
||||||
_logp="$1"
|
|
||||||
}
|
|
||||||
log_priority() {
|
|
||||||
if test -z "$1"; then
|
|
||||||
echo "$_logp"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
[ "$1" -le "$_logp" ]
|
|
||||||
}
|
|
||||||
log_tag() {
|
|
||||||
case $1 in
|
|
||||||
0) echo "emerg" ;;
|
|
||||||
1) echo "alert" ;;
|
|
||||||
2) echo "crit" ;;
|
|
||||||
3) echo "err" ;;
|
|
||||||
4) echo "warning" ;;
|
|
||||||
5) echo "notice" ;;
|
|
||||||
6) echo "info" ;;
|
|
||||||
7) echo "debug" ;;
|
|
||||||
*) echo "$1" ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
log_debug() {
|
|
||||||
log_priority 7 || return 0
|
|
||||||
echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
|
|
||||||
}
|
|
||||||
log_info() {
|
|
||||||
log_priority 6 || return 0
|
|
||||||
echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
|
|
||||||
}
|
|
||||||
log_err() {
|
|
||||||
log_priority 3 || return 0
|
|
||||||
echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
|
|
||||||
}
|
|
||||||
log_crit() {
|
|
||||||
log_priority 2 || return 0
|
|
||||||
echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
|
|
||||||
}
|
|
||||||
uname_os() {
|
|
||||||
os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
||||||
case "$os" in
|
|
||||||
msys_nt) os="windows" ;;
|
|
||||||
esac
|
|
||||||
echo "$os"
|
|
||||||
}
|
|
||||||
uname_arch() {
|
|
||||||
arch=$(uname -m)
|
|
||||||
case $arch in
|
|
||||||
x86_64) arch="amd64" ;;
|
|
||||||
x86) arch="386" ;;
|
|
||||||
i686) arch="386" ;;
|
|
||||||
i386) arch="386" ;;
|
|
||||||
aarch64) arch="arm64" ;;
|
|
||||||
armv5*) arch="arm5" ;;
|
|
||||||
armv6*) arch="arm6" ;;
|
|
||||||
armv7*) arch="arm7" ;;
|
|
||||||
esac
|
|
||||||
echo ${arch}
|
|
||||||
}
|
|
||||||
uname_os_check() {
|
|
||||||
os=$(uname_os)
|
|
||||||
case "$os" in
|
|
||||||
darwin) return 0 ;;
|
|
||||||
dragonfly) return 0 ;;
|
|
||||||
freebsd) return 0 ;;
|
|
||||||
linux) return 0 ;;
|
|
||||||
android) return 0 ;;
|
|
||||||
nacl) return 0 ;;
|
|
||||||
netbsd) return 0 ;;
|
|
||||||
openbsd) return 0 ;;
|
|
||||||
plan9) return 0 ;;
|
|
||||||
solaris) return 0 ;;
|
|
||||||
windows) return 0 ;;
|
|
||||||
esac
|
|
||||||
log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
uname_arch_check() {
|
|
||||||
arch=$(uname_arch)
|
|
||||||
case "$arch" in
|
|
||||||
386) return 0 ;;
|
|
||||||
amd64) return 0 ;;
|
|
||||||
arm64) return 0 ;;
|
|
||||||
armv5) return 0 ;;
|
|
||||||
armv6) return 0 ;;
|
|
||||||
armv7) return 0 ;;
|
|
||||||
ppc64) return 0 ;;
|
|
||||||
ppc64le) return 0 ;;
|
|
||||||
mips) return 0 ;;
|
|
||||||
mipsle) return 0 ;;
|
|
||||||
mips64) return 0 ;;
|
|
||||||
mips64le) return 0 ;;
|
|
||||||
s390x) return 0 ;;
|
|
||||||
amd64p32) return 0 ;;
|
|
||||||
esac
|
|
||||||
log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
untar() {
|
|
||||||
tarball=$1
|
|
||||||
case "${tarball}" in
|
|
||||||
*.tar.gz | *.tgz) tar -xzf "${tarball}" ;;
|
|
||||||
*.tar) tar -xf "${tarball}" ;;
|
|
||||||
*.zip) unzip "${tarball}" ;;
|
|
||||||
*)
|
|
||||||
log_err "untar unknown archive format for ${tarball}"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
mktmpdir() {
|
|
||||||
test -z "$TMPDIR" && TMPDIR="$(mktemp -d)"
|
|
||||||
mkdir -p "${TMPDIR}"
|
|
||||||
echo "${TMPDIR}"
|
|
||||||
}
|
|
||||||
http_download_curl() {
|
|
||||||
local_file=$1
|
|
||||||
source_url=$2
|
|
||||||
header=$3
|
|
||||||
if [ -z "$header" ]; then
|
|
||||||
code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
|
|
||||||
else
|
|
||||||
code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
|
|
||||||
fi
|
|
||||||
if [ "$code" != "200" ]; then
|
|
||||||
log_debug "http_download_curl received HTTP status $code"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
http_download_wget() {
|
|
||||||
local_file=$1
|
|
||||||
source_url=$2
|
|
||||||
header=$3
|
|
||||||
if [ -z "$header" ]; then
|
|
||||||
wget -q -O "$local_file" "$source_url"
|
|
||||||
else
|
|
||||||
wget -q --header "$header" -O "$local_file" "$source_url"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
http_download() {
|
|
||||||
log_debug "http_download $2"
|
|
||||||
if is_command curl; then
|
|
||||||
http_download_curl "$@"
|
|
||||||
return
|
|
||||||
elif is_command wget; then
|
|
||||||
http_download_wget "$@"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
log_crit "http_download unable to find wget or curl"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
http_copy() {
|
|
||||||
tmp=$(mktemp)
|
|
||||||
http_download "${tmp}" "$1" "$2" || return 1
|
|
||||||
body=$(cat "$tmp")
|
|
||||||
rm -f "${tmp}"
|
|
||||||
echo "$body"
|
|
||||||
}
|
|
||||||
github_release() {
|
|
||||||
owner_repo=$1
|
|
||||||
version=$2
|
|
||||||
test -z "$version" && version="latest"
|
|
||||||
giturl="https://github.com/${owner_repo}/releases/${version}"
|
|
||||||
json=$(http_copy "$giturl" "Accept:application/json")
|
|
||||||
test -z "$json" && return 1
|
|
||||||
version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
|
|
||||||
test -z "$version" && return 1
|
|
||||||
echo "$version"
|
|
||||||
}
|
|
||||||
hash_sha256() {
|
|
||||||
TARGET=${1:-/dev/stdin}
|
|
||||||
if is_command gsha256sum; then
|
|
||||||
hash=$(gsha256sum "$TARGET") || return 1
|
|
||||||
echo "$hash" | cut -d ' ' -f 1
|
|
||||||
elif is_command sha256sum; then
|
|
||||||
hash=$(sha256sum "$TARGET") || return 1
|
|
||||||
echo "$hash" | cut -d ' ' -f 1
|
|
||||||
elif is_command shasum; then
|
|
||||||
hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1
|
|
||||||
echo "$hash" | cut -d ' ' -f 1
|
|
||||||
elif is_command openssl; then
|
|
||||||
hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
|
|
||||||
echo "$hash" | cut -d ' ' -f a
|
|
||||||
else
|
|
||||||
log_crit "hash_sha256 unable to find command to compute sha-256 hash"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
hash_sha256_verify() {
|
|
||||||
TARGET=$1
|
|
||||||
checksums=$2
|
|
||||||
if [ -z "$checksums" ]; then
|
|
||||||
log_err "hash_sha256_verify checksum file not specified in arg2"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
BASENAME=${TARGET##*/}
|
|
||||||
want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)
|
|
||||||
if [ -z "$want" ]; then
|
|
||||||
log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
got=$(hash_sha256 "$TARGET")
|
|
||||||
if [ "$want" != "$got" ]; then
|
|
||||||
log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
cat /dev/null <<EOF
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
End of functions from https://github.com/client9/shlib
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
EOF
|
|
||||||
|
|
||||||
PROJECT_NAME="task"
|
|
||||||
OWNER=go-task
|
|
||||||
REPO="task"
|
|
||||||
BINARY=task
|
|
||||||
FORMAT=tar.gz
|
|
||||||
OS=$(uname_os)
|
|
||||||
ARCH=$(uname_arch)
|
|
||||||
PREFIX="$OWNER/$REPO"
|
|
||||||
|
|
||||||
# use in logging routines
|
|
||||||
log_prefix() {
|
|
||||||
echo "$PREFIX"
|
|
||||||
}
|
|
||||||
PLATFORM="${OS}/${ARCH}"
|
|
||||||
GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download
|
|
||||||
|
|
||||||
uname_os_check "$OS"
|
|
||||||
uname_arch_check "$ARCH"
|
|
||||||
|
|
||||||
parse_args "$@"
|
|
||||||
|
|
||||||
check_platform
|
|
||||||
|
|
||||||
tag_to_version
|
|
||||||
|
|
||||||
adjust_format
|
|
||||||
|
|
||||||
adjust_os
|
|
||||||
|
|
||||||
adjust_arch
|
|
||||||
|
|
||||||
log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}"
|
|
||||||
|
|
||||||
NAME=${BINARY}_${OS}_${ARCH}
|
|
||||||
TARBALL=${NAME}.${FORMAT}
|
|
||||||
TARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}
|
|
||||||
CHECKSUM=task_checksums.txt
|
|
||||||
CHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}
|
|
||||||
|
|
||||||
|
|
||||||
execute
|
|
||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/args"
|
"github.com/go-task/task/internal/args"
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package compiler
|
package compiler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Compiler handles compilation of a task before its execution.
|
// Compiler handles compilation of a task before its execution.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetEnviron the all return all environment variables encapsulated on a
|
// GetEnviron the all return all environment variables encapsulated on a
|
||||||
|
|||||||
@@ -2,16 +2,15 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/compiler"
|
"github.com/go-task/task/internal/compiler"
|
||||||
"github.com/go-task/task/v2/internal/execext"
|
"github.com/go-task/task/internal/execext"
|
||||||
"github.com/go-task/task/v2/internal/logger"
|
"github.com/go-task/task/internal/logger"
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
"github.com/go-task/task/v2/internal/templater"
|
"github.com/go-task/task/internal/templater"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ compiler.Compiler = &CompilerV1{}
|
var _ compiler.Compiler = &CompilerV1{}
|
||||||
@@ -122,7 +121,7 @@ func (c *CompilerV1) HandleDynamicVar(v taskfile.Var) (string, error) {
|
|||||||
Stdout: &stdout,
|
Stdout: &stdout,
|
||||||
Stderr: c.Logger.Stderr,
|
Stderr: c.Logger.Stderr,
|
||||||
}
|
}
|
||||||
if err := execext.RunCommand(context.Background(), opts); err != nil {
|
if err := execext.RunCommand(opts); err != nil {
|
||||||
return "", fmt.Errorf(`task: Command "%s" in taskvars file failed: %s`, opts.Command, err)
|
return "", fmt.Errorf(`task: Command "%s" in taskvars file failed: %s`, opts.Command, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,15 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/compiler"
|
"github.com/go-task/task/internal/compiler"
|
||||||
"github.com/go-task/task/v2/internal/execext"
|
"github.com/go-task/task/internal/execext"
|
||||||
"github.com/go-task/task/v2/internal/logger"
|
"github.com/go-task/task/internal/logger"
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
"github.com/go-task/task/v2/internal/templater"
|
"github.com/go-task/task/internal/templater"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ compiler.Compiler = &CompilerV2{}
|
var _ compiler.Compiler = &CompilerV2{}
|
||||||
@@ -94,7 +93,7 @@ func (c *CompilerV2) HandleDynamicVar(v taskfile.Var) (string, error) {
|
|||||||
Stdout: &stdout,
|
Stdout: &stdout,
|
||||||
Stderr: c.Logger.Stderr,
|
Stderr: c.Logger.Stderr,
|
||||||
}
|
}
|
||||||
if err := execext.RunCommand(context.Background(), opts); err != nil {
|
if err := execext.RunCommand(opts); err != nil {
|
||||||
return "", fmt.Errorf(`task: Command "%s" in taskvars file failed: %s`, opts.Command, err)
|
return "", fmt.Errorf(`task: Command "%s" in taskvars file failed: %s`, opts.Command, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"mvdan.cc/sh/interp"
|
"mvdan.cc/sh/interp"
|
||||||
@@ -13,6 +12,7 @@ import (
|
|||||||
|
|
||||||
// RunCommandOptions is the options for the RunCommand func
|
// RunCommandOptions is the options for the RunCommand func
|
||||||
type RunCommandOptions struct {
|
type RunCommandOptions struct {
|
||||||
|
Context context.Context
|
||||||
Command string
|
Command string
|
||||||
Dir string
|
Dir string
|
||||||
Env []string
|
Env []string
|
||||||
@@ -27,7 +27,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// RunCommand runs a shell command
|
// RunCommand runs a shell command
|
||||||
func RunCommand(ctx context.Context, opts *RunCommandOptions) error {
|
func RunCommand(opts *RunCommandOptions) error {
|
||||||
if opts == nil {
|
if opts == nil {
|
||||||
return ErrNilOptions
|
return ErrNilOptions
|
||||||
}
|
}
|
||||||
@@ -37,36 +37,20 @@ func RunCommand(ctx context.Context, opts *RunCommandOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
environ := opts.Env
|
r := interp.Runner{
|
||||||
if len(environ) == 0 {
|
Context: opts.Context,
|
||||||
environ = os.Environ()
|
Dir: opts.Dir,
|
||||||
|
Env: opts.Env,
|
||||||
|
|
||||||
|
Exec: interp.DefaultExec,
|
||||||
|
Open: interp.OpenDevImpls(interp.DefaultOpen),
|
||||||
|
|
||||||
|
Stdin: opts.Stdin,
|
||||||
|
Stdout: opts.Stdout,
|
||||||
|
Stderr: opts.Stderr,
|
||||||
}
|
}
|
||||||
env, err := interp.EnvFromList(environ)
|
if err = r.Reset(); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return r.Run(p)
|
||||||
r, err := interp.New(
|
|
||||||
interp.Dir(opts.Dir),
|
|
||||||
interp.Env(env),
|
|
||||||
|
|
||||||
interp.Module(interp.DefaultExec),
|
|
||||||
interp.Module(interp.OpenDevImpls(interp.DefaultOpen)),
|
|
||||||
|
|
||||||
interp.StdIO(opts.Stdin, opts.Stdout, opts.Stderr),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return r.Run(ctx, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExitError returns true the given error is an exis status error
|
|
||||||
func IsExitError(err error) bool {
|
|
||||||
switch err.(type) {
|
|
||||||
case interp.ExitStatus, interp.ShellExitStatus:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
package output
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Group struct{}
|
|
||||||
|
|
||||||
func (Group) WrapWriter(w io.Writer, _ string) io.WriteCloser {
|
|
||||||
return &groupWriter{writer: w}
|
|
||||||
}
|
|
||||||
|
|
||||||
type groupWriter struct {
|
|
||||||
writer io.Writer
|
|
||||||
buff bytes.Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gw *groupWriter) Write(p []byte) (int, error) {
|
|
||||||
return gw.buff.Write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gw *groupWriter) Close() error {
|
|
||||||
_, err := io.Copy(gw.writer, &gw.buff)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package output
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Interleaved struct{}
|
|
||||||
|
|
||||||
func (Interleaved) WrapWriter(w io.Writer, _ string) io.WriteCloser {
|
|
||||||
return nopWriterCloser{w: w}
|
|
||||||
}
|
|
||||||
|
|
||||||
type nopWriterCloser struct {
|
|
||||||
w io.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wc nopWriterCloser) Write(p []byte) (int, error) {
|
|
||||||
return wc.w.Write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wc nopWriterCloser) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package output
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Output interface {
|
|
||||||
WrapWriter(w io.Writer, prefix string) io.WriteCloser
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package output_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/output"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestInterleaved(t *testing.T) {
|
|
||||||
var b bytes.Buffer
|
|
||||||
var o output.Output = output.Interleaved{}
|
|
||||||
var w = o.WrapWriter(&b, "")
|
|
||||||
|
|
||||||
fmt.Fprintln(w, "foo\nbar")
|
|
||||||
assert.Equal(t, "foo\nbar\n", b.String())
|
|
||||||
fmt.Fprintln(w, "baz")
|
|
||||||
assert.Equal(t, "foo\nbar\nbaz\n", b.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGroup(t *testing.T) {
|
|
||||||
var b bytes.Buffer
|
|
||||||
var o output.Output = output.Group{}
|
|
||||||
var w = o.WrapWriter(&b, "")
|
|
||||||
|
|
||||||
fmt.Fprintln(w, "foo\nbar")
|
|
||||||
assert.Equal(t, "", b.String())
|
|
||||||
fmt.Fprintln(w, "baz")
|
|
||||||
assert.Equal(t, "", b.String())
|
|
||||||
assert.NoError(t, w.Close())
|
|
||||||
assert.Equal(t, "foo\nbar\nbaz\n", b.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPrefixed(t *testing.T) {
|
|
||||||
var b bytes.Buffer
|
|
||||||
var o output.Output = output.Prefixed{}
|
|
||||||
var w = o.WrapWriter(&b, "prefix")
|
|
||||||
|
|
||||||
t.Run("simple use cases", func(t *testing.T) {
|
|
||||||
b.Reset()
|
|
||||||
|
|
||||||
fmt.Fprintln(w, "foo\nbar")
|
|
||||||
assert.Equal(t, "[prefix] foo\n[prefix] bar\n", b.String())
|
|
||||||
fmt.Fprintln(w, "baz")
|
|
||||||
assert.Equal(t, "[prefix] foo\n[prefix] bar\n[prefix] baz\n", b.String())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("multiple writes for a single line", func(t *testing.T) {
|
|
||||||
b.Reset()
|
|
||||||
|
|
||||||
for _, char := range []string{"T", "e", "s", "t", "!"} {
|
|
||||||
fmt.Fprint(w, char)
|
|
||||||
assert.Equal(t, "", b.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(t, w.Close())
|
|
||||||
assert.Equal(t, "[prefix] Test!\n", b.String())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package output
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Prefixed struct{}
|
|
||||||
|
|
||||||
func (Prefixed) WrapWriter(w io.Writer, prefix string) io.WriteCloser {
|
|
||||||
return &prefixWriter{writer: w, prefix: prefix}
|
|
||||||
}
|
|
||||||
|
|
||||||
type prefixWriter struct {
|
|
||||||
writer io.Writer
|
|
||||||
prefix string
|
|
||||||
buff bytes.Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pw *prefixWriter) Write(p []byte) (int, error) {
|
|
||||||
n, err := pw.buff.Write(p)
|
|
||||||
if err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, pw.writeOutputLines(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pw *prefixWriter) Close() error {
|
|
||||||
return pw.writeOutputLines(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pw *prefixWriter) writeOutputLines(force bool) error {
|
|
||||||
for {
|
|
||||||
line, err := pw.buff.ReadString('\n')
|
|
||||||
if err == nil {
|
|
||||||
if err = pw.writeLine(line); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else if err == io.EOF {
|
|
||||||
// if this line was not a complete line, re-add to the buffer
|
|
||||||
if !force && !strings.HasSuffix(line, "\n") {
|
|
||||||
_, err = pw.buff.WriteString(line)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return pw.writeLine(line)
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pw *prefixWriter) writeLine(line string) error {
|
|
||||||
if line == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if !strings.HasSuffix(line, "\n") {
|
|
||||||
line += "\n"
|
|
||||||
}
|
|
||||||
_, err := fmt.Fprintf(pw.writer, "[%s] %s", pw.prefix, line)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/mattn/go-zglob"
|
"github.com/mattn/go-zglob"
|
||||||
"mvdan.cc/sh/shell"
|
"github.com/mitchellh/go-homedir"
|
||||||
)
|
)
|
||||||
|
|
||||||
func glob(dir string, globs []string) (files []string, err error) {
|
func glob(dir string, globs []string) (files []string, err error) {
|
||||||
@@ -13,13 +13,13 @@ func glob(dir string, globs []string) (files []string, err error) {
|
|||||||
if !filepath.IsAbs(g) {
|
if !filepath.IsAbs(g) {
|
||||||
g = filepath.Join(dir, g)
|
g = filepath.Join(dir, g)
|
||||||
}
|
}
|
||||||
g, err = shell.Expand(g, nil)
|
g, err = homedir.Expand(g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
f, err := zglob.Glob(g)
|
f, err := zglob.Glob(g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
return nil, err
|
||||||
}
|
}
|
||||||
files = append(files, f...)
|
files = append(files, f...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,10 @@ import (
|
|||||||
|
|
||||||
// Cmd is a task command
|
// Cmd is a task command
|
||||||
type Cmd struct {
|
type Cmd struct {
|
||||||
Cmd string
|
Cmd string
|
||||||
Silent bool
|
Silent bool
|
||||||
Task string
|
Task string
|
||||||
Vars Vars
|
Vars Vars
|
||||||
IgnoreError bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dep is a task dependency
|
// Dep is a task dependency
|
||||||
@@ -39,14 +38,12 @@ func (c *Cmd) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var cmdStruct struct {
|
var cmdStruct struct {
|
||||||
Cmd string
|
Cmd string
|
||||||
Silent bool
|
Silent bool
|
||||||
IgnoreError bool `yaml:"ignore_error"`
|
|
||||||
}
|
}
|
||||||
if err := unmarshal(&cmdStruct); err == nil && cmdStruct.Cmd != "" {
|
if err := unmarshal(&cmdStruct); err == nil && cmdStruct.Cmd != "" {
|
||||||
c.Cmd = cmdStruct.Cmd
|
c.Cmd = cmdStruct.Cmd
|
||||||
c.Silent = cmdStruct.Silent
|
c.Silent = cmdStruct.Silent
|
||||||
c.IgnoreError = cmdStruct.IgnoreError
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var taskCall struct {
|
var taskCall struct {
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
package taskfile
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NamespaceSeparator contains the character that separates namescapes
|
|
||||||
const NamespaceSeparator = ":"
|
|
||||||
|
|
||||||
// Merge merges the second Taskfile into the first
|
|
||||||
func Merge(t1, t2 *Taskfile, namespaces ...string) error {
|
|
||||||
if t1.Version != t2.Version {
|
|
||||||
return fmt.Errorf(`Taskfiles versions should match. First is "%s" but second is "%s"`, t1.Version, t2.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
if t2.Expansions != 0 && t2.Expansions != 2 {
|
|
||||||
t1.Expansions = t2.Expansions
|
|
||||||
}
|
|
||||||
if t2.Output != "" {
|
|
||||||
t1.Output = t2.Output
|
|
||||||
}
|
|
||||||
|
|
||||||
if t1.Includes == nil {
|
|
||||||
t1.Includes = make(map[string]string)
|
|
||||||
}
|
|
||||||
for k, v := range t2.Includes {
|
|
||||||
t1.Includes[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if t1.Vars == nil {
|
|
||||||
t1.Vars = make(Vars)
|
|
||||||
}
|
|
||||||
for k, v := range t2.Vars {
|
|
||||||
t1.Vars[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if t1.Tasks == nil {
|
|
||||||
t1.Tasks = make(Tasks)
|
|
||||||
}
|
|
||||||
for k, v := range t2.Tasks {
|
|
||||||
// FIXME(@andreynering): Refactor this block, otherwise we can
|
|
||||||
// have serious side-effects in the future, since we're editing
|
|
||||||
// the original references instead of deep copying them.
|
|
||||||
|
|
||||||
t1.Tasks[taskNameWithNamespace(k, namespaces...)] = v
|
|
||||||
|
|
||||||
for _, dep := range v.Deps {
|
|
||||||
dep.Task = taskNameWithNamespace(dep.Task, namespaces...)
|
|
||||||
}
|
|
||||||
for _, cmd := range v.Cmds {
|
|
||||||
if cmd.Task != "" {
|
|
||||||
cmd.Task = taskNameWithNamespace(cmd.Task, namespaces...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func taskNameWithNamespace(taskName string, namespaces ...string) string {
|
|
||||||
return strings.Join(append(namespaces, taskName), NamespaceSeparator)
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
package read
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrIncludedTaskfilesCantHaveIncludes is returned when a included Taskfile contains includes
|
|
||||||
var ErrIncludedTaskfilesCantHaveIncludes = errors.New("task: Included Taskfiles can't have includes. Please, move the include to the main Taskfile")
|
|
||||||
|
|
||||||
// Taskfile reads a Taskfile for a given directory
|
|
||||||
func Taskfile(dir string) (*taskfile.Taskfile, error) {
|
|
||||||
path := filepath.Join(dir, "Taskfile.yml")
|
|
||||||
if _, err := os.Stat(path); err != nil {
|
|
||||||
return nil, fmt.Errorf(`No Taskfile.yml found. Use "task --init" to create a new one`)
|
|
||||||
}
|
|
||||||
t, err := readTaskfile(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for namespace, path := range t.Includes {
|
|
||||||
path = filepath.Join(dir, path)
|
|
||||||
info, err := os.Stat(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if info.IsDir() {
|
|
||||||
path = filepath.Join(path, "Taskfile.yml")
|
|
||||||
}
|
|
||||||
includedTaskfile, err := readTaskfile(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(includedTaskfile.Includes) > 0 {
|
|
||||||
return nil, ErrIncludedTaskfilesCantHaveIncludes
|
|
||||||
}
|
|
||||||
if err = taskfile.Merge(t, includedTaskfile, namespace); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
path = filepath.Join(dir, fmt.Sprintf("Taskfile_%s.yml", runtime.GOOS))
|
|
||||||
if _, err = os.Stat(path); err == nil {
|
|
||||||
osTaskfile, err := readTaskfile(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err = taskfile.Merge(t, osTaskfile); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for name, task := range t.Tasks {
|
|
||||||
task.Task = name
|
|
||||||
}
|
|
||||||
|
|
||||||
return t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readTaskfile(file string) (*taskfile.Taskfile, error) {
|
|
||||||
f, err := os.Open(file)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var t taskfile.Taskfile
|
|
||||||
return &t, yaml.NewDecoder(f).Decode(&t)
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
package read
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Taskvars reads a Taskvars for a given directory
|
|
||||||
func Taskvars(dir string) (taskfile.Vars, error) {
|
|
||||||
vars := make(taskfile.Vars)
|
|
||||||
|
|
||||||
path := filepath.Join(dir, "Taskvars.yml")
|
|
||||||
if _, err := os.Stat(path); err == nil {
|
|
||||||
vars, err = readTaskvars(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
path = filepath.Join(dir, fmt.Sprintf("Taskvars_%s.yml", runtime.GOOS))
|
|
||||||
if _, err := os.Stat(path); err == nil {
|
|
||||||
osVars, err := readTaskvars(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if vars == nil {
|
|
||||||
vars = osVars
|
|
||||||
} else {
|
|
||||||
for k, v := range osVars {
|
|
||||||
vars[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vars, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readTaskvars(file string) (taskfile.Vars, error) {
|
|
||||||
f, err := os.Open(file)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var vars taskfile.Vars
|
|
||||||
return vars, yaml.NewDecoder(f).Decode(&vars)
|
|
||||||
}
|
|
||||||
@@ -5,18 +5,16 @@ type Tasks map[string]*Task
|
|||||||
|
|
||||||
// Task represents a task
|
// Task represents a task
|
||||||
type Task struct {
|
type Task struct {
|
||||||
Task string
|
Task string
|
||||||
Cmds []*Cmd
|
Cmds []*Cmd
|
||||||
Deps []*Dep
|
Deps []*Dep
|
||||||
Desc string
|
Desc string
|
||||||
Sources []string
|
Sources []string
|
||||||
Generates []string
|
Generates []string
|
||||||
Status []string
|
Status []string
|
||||||
Dir string
|
Dir string
|
||||||
Vars Vars
|
Vars Vars
|
||||||
Env Vars
|
Env Vars
|
||||||
Silent bool
|
Silent bool
|
||||||
Method string
|
Method string
|
||||||
Prefix string
|
|
||||||
IgnoreError bool `yaml:"ignore_error"`
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ package taskfile
|
|||||||
type Taskfile struct {
|
type Taskfile struct {
|
||||||
Version string
|
Version string
|
||||||
Expansions int
|
Expansions int
|
||||||
Output string
|
|
||||||
Includes map[string]string
|
|
||||||
Vars Vars
|
Vars Vars
|
||||||
Tasks Tasks
|
Tasks Tasks
|
||||||
}
|
}
|
||||||
@@ -20,8 +18,6 @@ func (tf *Taskfile) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
var taskfile struct {
|
var taskfile struct {
|
||||||
Version string
|
Version string
|
||||||
Expansions int
|
Expansions int
|
||||||
Output string
|
|
||||||
Includes map[string]string
|
|
||||||
Vars Vars
|
Vars Vars
|
||||||
Tasks Tasks
|
Tasks Tasks
|
||||||
}
|
}
|
||||||
@@ -30,8 +26,6 @@ func (tf *Taskfile) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
}
|
}
|
||||||
tf.Version = taskfile.Version
|
tf.Version = taskfile.Version
|
||||||
tf.Expansions = taskfile.Expansions
|
tf.Expansions = taskfile.Expansions
|
||||||
tf.Output = taskfile.Output
|
|
||||||
tf.Includes = taskfile.Includes
|
|
||||||
tf.Vars = taskfile.Vars
|
tf.Vars = taskfile.Vars
|
||||||
tf.Tasks = taskfile.Tasks
|
tf.Tasks = taskfile.Tasks
|
||||||
if tf.Expansions <= 0 {
|
if tf.Expansions <= 0 {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package taskfile_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|||||||
@@ -5,36 +5,27 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
v1 = mustVersion("1")
|
v1 = mustVersion("1")
|
||||||
v2 = mustVersion("2")
|
v2 = mustVersion("2")
|
||||||
v21 = mustVersion("2.1")
|
|
||||||
v22 = mustVersion("2.2")
|
isV1 = mustConstraint("= 1")
|
||||||
v23 = mustVersion("2.3")
|
isV2 = mustConstraint(">= 2")
|
||||||
|
isV21 = mustConstraint(">= 2.1")
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsV1 returns if is a given Taskfile version is version 1
|
// IsV1 returns if is a given Taskfile version is version 1
|
||||||
func IsV1(v *semver.Constraints) bool {
|
func IsV1(v *semver.Version) bool {
|
||||||
return v.Check(v1)
|
return isV1.Check(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsV2 returns if is a given Taskfile version is at least version 2
|
// IsV2 returns if is a given Taskfile version is at least version 2
|
||||||
func IsV2(v *semver.Constraints) bool {
|
func IsV2(v *semver.Version) bool {
|
||||||
return v.Check(v2)
|
return isV2.Check(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsV21 returns if is a given Taskfile version is at least version 2.1
|
// IsV21 returns if is a given Taskfile version is at least version 2
|
||||||
func IsV21(v *semver.Constraints) bool {
|
func IsV21(v *semver.Version) bool {
|
||||||
return v.Check(v21)
|
return isV21.Check(v)
|
||||||
}
|
|
||||||
|
|
||||||
// IsV22 returns if is a given Taskfile version is at least version 2.2
|
|
||||||
func IsV22(v *semver.Constraints) bool {
|
|
||||||
return v.Check(v22)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsV23 returns if is a given Taskfile version is at least version 2.3
|
|
||||||
func IsV23(v *semver.Constraints) bool {
|
|
||||||
return v.Check(v23)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustVersion(s string) *semver.Version {
|
func mustVersion(s string) *semver.Version {
|
||||||
@@ -44,3 +35,11 @@ func mustVersion(s string) *semver.Version {
|
|||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mustConstraint(s string) *semver.Constraints {
|
||||||
|
c, err := semver.NewConstraint(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Templater is a help struct that allow us to call "replaceX" funcs multiple
|
// Templater is a help struct that allow us to call "replaceX" funcs multiple
|
||||||
|
|||||||
15
status.go
15
status.go
@@ -4,17 +4,17 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/execext"
|
"github.com/go-task/task/internal/execext"
|
||||||
"github.com/go-task/task/v2/internal/status"
|
"github.com/go-task/task/internal/status"
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Status returns an error if any the of given tasks is not up-to-date
|
// Status returns an error if any the of given tasks is not up-to-date
|
||||||
func (e *Executor) Status(calls ...taskfile.Call) error {
|
func (e *Executor) Status(calls ...taskfile.Call) error {
|
||||||
for _, call := range calls {
|
for _, call := range calls {
|
||||||
t, err := e.CompiledTask(call)
|
t, ok := e.Taskfile.Tasks[call.Task]
|
||||||
if err != nil {
|
if !ok {
|
||||||
return err
|
return &taskNotFoundError{taskName: call.Task}
|
||||||
}
|
}
|
||||||
isUpToDate, err := isTaskUpToDate(e.Context, t)
|
isUpToDate, err := isTaskUpToDate(e.Context, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -71,7 +71,8 @@ func getStatusChecker(t *taskfile.Task) (status.Checker, error) {
|
|||||||
|
|
||||||
func isTaskUpToDateStatus(ctx context.Context, t *taskfile.Task) (bool, error) {
|
func isTaskUpToDateStatus(ctx context.Context, t *taskfile.Task) (bool, error) {
|
||||||
for _, s := range t.Status {
|
for _, s := range t.Status {
|
||||||
err := execext.RunCommand(ctx, &execext.RunCommandOptions{
|
err := execext.RunCommand(&execext.RunCommandOptions{
|
||||||
|
Context: ctx,
|
||||||
Command: s,
|
Command: s,
|
||||||
Dir: t.Dir,
|
Dir: t.Dir,
|
||||||
Env: getEnviron(t),
|
Env: getEnviron(t),
|
||||||
|
|||||||
120
task.go
120
task.go
@@ -7,21 +7,21 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/compiler"
|
"github.com/go-task/task/internal/compiler"
|
||||||
compilerv1 "github.com/go-task/task/v2/internal/compiler/v1"
|
compilerv1 "github.com/go-task/task/internal/compiler/v1"
|
||||||
compilerv2 "github.com/go-task/task/v2/internal/compiler/v2"
|
compilerv2 "github.com/go-task/task/internal/compiler/v2"
|
||||||
"github.com/go-task/task/v2/internal/execext"
|
"github.com/go-task/task/internal/execext"
|
||||||
"github.com/go-task/task/v2/internal/logger"
|
"github.com/go-task/task/internal/logger"
|
||||||
"github.com/go-task/task/v2/internal/output"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile/version"
|
||||||
"github.com/go-task/task/v2/internal/taskfile/read"
|
|
||||||
"github.com/go-task/task/v2/internal/taskfile/version"
|
|
||||||
|
|
||||||
"github.com/Masterminds/semver"
|
"github.com/Masterminds/semver"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// TaskFilePath is the default Taskfile
|
||||||
|
TaskFilePath = "Taskfile"
|
||||||
// MaximumTaskCall is the max number of times a task can be called.
|
// MaximumTaskCall is the max number of times a task can be called.
|
||||||
// This exists to prevent infinite loops on cyclic dependencies
|
// This exists to prevent infinite loops on cyclic dependencies
|
||||||
MaximumTaskCall = 100
|
MaximumTaskCall = 100
|
||||||
@@ -35,7 +35,6 @@ type Executor struct {
|
|||||||
Watch bool
|
Watch bool
|
||||||
Verbose bool
|
Verbose bool
|
||||||
Silent bool
|
Silent bool
|
||||||
Dry bool
|
|
||||||
|
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
|
||||||
@@ -45,7 +44,6 @@ type Executor struct {
|
|||||||
|
|
||||||
Logger *logger.Logger
|
Logger *logger.Logger
|
||||||
Compiler compiler.Compiler
|
Compiler compiler.Compiler
|
||||||
Output output.Output
|
|
||||||
|
|
||||||
taskvars taskfile.Vars
|
taskvars taskfile.Vars
|
||||||
|
|
||||||
@@ -77,17 +75,11 @@ func (e *Executor) Run(calls ...taskfile.Call) error {
|
|||||||
|
|
||||||
// Setup setups Executor's internal state
|
// Setup setups Executor's internal state
|
||||||
func (e *Executor) Setup() error {
|
func (e *Executor) Setup() error {
|
||||||
var err error
|
if err := e.readTaskfile(); err != nil {
|
||||||
e.Taskfile, err = read.Taskfile(e.Dir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
e.taskvars, err = read.Taskvars(e.Dir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err := semver.NewConstraint(e.Taskfile.Version)
|
v, err := semver.NewVersion(e.Taskfile.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(`task: could not parse taskfile version "%s": %v`, e.Taskfile.Version, err)
|
return fmt.Errorf(`task: could not parse taskfile version "%s": %v`, e.Taskfile.Version, err)
|
||||||
}
|
}
|
||||||
@@ -116,7 +108,7 @@ func (e *Executor) Setup() error {
|
|||||||
Vars: e.taskvars,
|
Vars: e.taskvars,
|
||||||
Logger: e.Logger,
|
Logger: e.Logger,
|
||||||
}
|
}
|
||||||
case version.IsV2(v), version.IsV21(v), version.IsV22(v):
|
case version.IsV2(v):
|
||||||
e.Compiler = &compilerv2.CompilerV2{
|
e.Compiler = &compilerv2.CompilerV2{
|
||||||
Dir: e.Dir,
|
Dir: e.Dir,
|
||||||
Taskvars: e.taskvars,
|
Taskvars: e.taskvars,
|
||||||
@@ -124,40 +116,8 @@ func (e *Executor) Setup() error {
|
|||||||
Expansions: e.Taskfile.Expansions,
|
Expansions: e.Taskfile.Expansions,
|
||||||
Logger: e.Logger,
|
Logger: e.Logger,
|
||||||
}
|
}
|
||||||
case version.IsV23(v):
|
case version.IsV21(v):
|
||||||
return fmt.Errorf(`task: Taskfile versions greater than v2.3 not implemented in the version of Task`)
|
return fmt.Errorf(`task: Taskfile versions greater than v2 not implemented in the version of Task`)
|
||||||
}
|
|
||||||
|
|
||||||
if !version.IsV21(v) && e.Taskfile.Output != "" {
|
|
||||||
return fmt.Errorf(`task: Taskfile option "output" is only available starting on Taskfile version v2.1`)
|
|
||||||
}
|
|
||||||
if !version.IsV22(v) && len(e.Taskfile.Includes) > 0 {
|
|
||||||
return fmt.Errorf(`task: Including Taskfiles is only available starting on Taskfile version v2.2`)
|
|
||||||
}
|
|
||||||
switch e.Taskfile.Output {
|
|
||||||
case "", "interleaved":
|
|
||||||
e.Output = output.Interleaved{}
|
|
||||||
case "group":
|
|
||||||
e.Output = output.Group{}
|
|
||||||
case "prefixed":
|
|
||||||
e.Output = output.Prefixed{}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf(`task: output option "%s" not recognized`, e.Taskfile.Output)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !version.IsV21(v) {
|
|
||||||
err := fmt.Errorf(`task: Taskfile option "ignore_error" is only available starting on Taskfile version v2.1`)
|
|
||||||
|
|
||||||
for _, task := range e.Taskfile.Tasks {
|
|
||||||
if task.IgnoreError {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, cmd := range task.Cmds {
|
|
||||||
if cmd.IgnoreError {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e.taskCallCount = make(map[string]*int32, len(e.Taskfile.Tasks))
|
e.taskCallCount = make(map[string]*int32, len(e.Taskfile.Tasks))
|
||||||
@@ -199,12 +159,6 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error {
|
|||||||
if err2 := statusOnError(t); err2 != nil {
|
if err2 := statusOnError(t); err2 != nil {
|
||||||
e.Logger.VerboseErrf("task: error cleaning status on error: %v", err2)
|
e.Logger.VerboseErrf("task: error cleaning status on error: %v", err2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if execext.IsExitError(err) && t.IgnoreError {
|
|
||||||
e.Logger.VerboseErrf("task: task error ignored: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return &taskRunError{t.Task, err}
|
return &taskRunError{t.Task, err}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,39 +182,23 @@ func (e *Executor) runDeps(ctx context.Context, t *taskfile.Task) error {
|
|||||||
func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfile.Call, i int) error {
|
func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfile.Call, i int) error {
|
||||||
cmd := t.Cmds[i]
|
cmd := t.Cmds[i]
|
||||||
|
|
||||||
switch {
|
if cmd.Cmd == "" {
|
||||||
case cmd.Task != "":
|
|
||||||
return e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars})
|
return e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars})
|
||||||
case cmd.Cmd != "":
|
|
||||||
if e.Verbose || (!cmd.Silent && !t.Silent && !e.Silent) {
|
|
||||||
e.Logger.Errf(cmd.Cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
if e.Dry {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
stdOut := e.Output.WrapWriter(e.Stdout, t.Prefix)
|
|
||||||
stdErr := e.Output.WrapWriter(e.Stderr, t.Prefix)
|
|
||||||
defer stdOut.Close()
|
|
||||||
defer stdErr.Close()
|
|
||||||
|
|
||||||
err := execext.RunCommand(ctx, &execext.RunCommandOptions{
|
|
||||||
Command: cmd.Cmd,
|
|
||||||
Dir: t.Dir,
|
|
||||||
Env: getEnviron(t),
|
|
||||||
Stdin: e.Stdin,
|
|
||||||
Stdout: stdOut,
|
|
||||||
Stderr: stdErr,
|
|
||||||
})
|
|
||||||
if execext.IsExitError(err) && cmd.IgnoreError {
|
|
||||||
e.Logger.VerboseErrf("task: command error ignored: %v", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if e.Verbose || (!cmd.Silent && !t.Silent && !e.Silent) {
|
||||||
|
e.Logger.Errf(cmd.Cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
return execext.RunCommand(&execext.RunCommandOptions{
|
||||||
|
Context: ctx,
|
||||||
|
Command: cmd.Cmd,
|
||||||
|
Dir: t.Dir,
|
||||||
|
Env: getEnviron(t),
|
||||||
|
Stdin: e.Stdin,
|
||||||
|
Stdout: e.Stdout,
|
||||||
|
Stderr: e.Stderr,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEnviron(t *taskfile.Task) []string {
|
func getEnviron(t *taskfile.Task) []string {
|
||||||
|
|||||||
104
task_test.go
104
task_test.go
@@ -9,10 +9,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-task/task/v2"
|
"github.com/go-task/task"
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
"github.com/mitchellh/go-homedir"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,6 +52,7 @@ func (fct fileContentTest) Run(t *testing.T) {
|
|||||||
assert.Equal(t, expectContent, s, "unexpected file content")
|
assert.Equal(t, expectContent, s, "unexpected file content")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnv(t *testing.T) {
|
func TestEnv(t *testing.T) {
|
||||||
@@ -412,101 +412,3 @@ func TestTaskVersion(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTaskIgnoreErrors(t *testing.T) {
|
|
||||||
const dir = "testdata/ignore_errors"
|
|
||||||
|
|
||||||
e := task.Executor{
|
|
||||||
Dir: dir,
|
|
||||||
Stdout: ioutil.Discard,
|
|
||||||
Stderr: ioutil.Discard,
|
|
||||||
}
|
|
||||||
assert.NoError(t, e.Setup())
|
|
||||||
|
|
||||||
assert.NoError(t, e.Run(taskfile.Call{Task: "task-should-pass"}))
|
|
||||||
assert.Error(t, e.Run(taskfile.Call{Task: "task-should-fail"}))
|
|
||||||
assert.NoError(t, e.Run(taskfile.Call{Task: "cmd-should-pass"}))
|
|
||||||
assert.Error(t, e.Run(taskfile.Call{Task: "cmd-should-fail"}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExpand(t *testing.T) {
|
|
||||||
const dir = "testdata/expand"
|
|
||||||
|
|
||||||
home, err := homedir.Dir()
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Couldn't get $HOME: %v", err)
|
|
||||||
}
|
|
||||||
var buff bytes.Buffer
|
|
||||||
|
|
||||||
e := task.Executor{
|
|
||||||
Dir: dir,
|
|
||||||
Stdout: &buff,
|
|
||||||
Stderr: &buff,
|
|
||||||
}
|
|
||||||
assert.NoError(t, e.Setup())
|
|
||||||
assert.NoError(t, e.Run(taskfile.Call{Task: "pwd"}))
|
|
||||||
assert.Equal(t, home, strings.TrimSpace(buff.String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDry(t *testing.T) {
|
|
||||||
const dir = "testdata/dry"
|
|
||||||
|
|
||||||
file := filepath.Join(dir, "file.txt")
|
|
||||||
_ = os.Remove(file)
|
|
||||||
|
|
||||||
var buff bytes.Buffer
|
|
||||||
|
|
||||||
e := task.Executor{
|
|
||||||
Dir: dir,
|
|
||||||
Stdout: &buff,
|
|
||||||
Stderr: &buff,
|
|
||||||
Dry: true,
|
|
||||||
}
|
|
||||||
assert.NoError(t, e.Setup())
|
|
||||||
assert.NoError(t, e.Run(taskfile.Call{Task: "build"}))
|
|
||||||
|
|
||||||
assert.Equal(t, "touch file.txt", strings.TrimSpace(buff.String()))
|
|
||||||
if _, err := os.Stat(file); err == nil {
|
|
||||||
t.Errorf("File should not exist %s", file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIncludes(t *testing.T) {
|
|
||||||
tt := fileContentTest{
|
|
||||||
Dir: "testdata/includes",
|
|
||||||
Target: "default",
|
|
||||||
TrimSpace: true,
|
|
||||||
Files: map[string]string{
|
|
||||||
"main.txt": "main",
|
|
||||||
"included_directory.txt": "included_directory",
|
|
||||||
"included_taskfile.txt": "included_taskfile",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
tt.Run(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIncludesEmptyMain(t *testing.T) {
|
|
||||||
tt := fileContentTest{
|
|
||||||
Dir: "testdata/includes_empty",
|
|
||||||
Target: "included:default",
|
|
||||||
TrimSpace: true,
|
|
||||||
Files: map[string]string{
|
|
||||||
"file.txt": "default",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
tt.Run(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIncludesDependencies(t *testing.T) {
|
|
||||||
tt := fileContentTest{
|
|
||||||
Dir: "testdata/includes_deps",
|
|
||||||
Target: "default",
|
|
||||||
TrimSpace: true,
|
|
||||||
Files: map[string]string{
|
|
||||||
"default.txt": "default",
|
|
||||||
"called_dep.txt": "called_dep",
|
|
||||||
"called_task.txt": "called_task",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
tt.Run(t)
|
|
||||||
}
|
|
||||||
|
|||||||
74
taskfile.go
Normal file
74
taskfile.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
|
"github.com/imdario/mergo"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// readTaskfile parses Taskfile from the disk
|
||||||
|
func (e *Executor) readTaskfile() error {
|
||||||
|
path := filepath.Join(e.Dir, TaskFilePath)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
e.Taskfile, err = e.readTaskfileData(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
osTasks, err := e.readTaskfileData(fmt.Sprintf("%s_%s", path, runtime.GOOS))
|
||||||
|
if err != nil {
|
||||||
|
switch err.(type) {
|
||||||
|
case taskFileNotFound:
|
||||||
|
default:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := mergo.MapWithOverwrite(&e.Taskfile.Tasks, osTasks.Tasks); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for name, task := range e.Taskfile.Tasks {
|
||||||
|
task.Task = name
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.readTaskvars()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Executor) readTaskfileData(path string) (*taskfile.Taskfile, error) {
|
||||||
|
if b, err := ioutil.ReadFile(path + ".yml"); err == nil {
|
||||||
|
var taskfile taskfile.Taskfile
|
||||||
|
return &taskfile, yaml.Unmarshal(b, &taskfile)
|
||||||
|
}
|
||||||
|
return nil, taskFileNotFound{path}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Executor) readTaskvars() error {
|
||||||
|
var (
|
||||||
|
file = filepath.Join(e.Dir, TaskvarsFilePath)
|
||||||
|
osSpecificFile = fmt.Sprintf("%s_%s", file, runtime.GOOS)
|
||||||
|
)
|
||||||
|
|
||||||
|
if b, err := ioutil.ReadFile(file + ".yml"); err == nil {
|
||||||
|
if err := yaml.Unmarshal(b, &e.taskvars); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if b, err := ioutil.ReadFile(osSpecificFile + ".yml"); err == nil {
|
||||||
|
osTaskvars := make(taskfile.Vars, 10)
|
||||||
|
if err := yaml.Unmarshal(b, &osTaskvars); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for k, v := range osTaskvars {
|
||||||
|
e.taskvars[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
1
testdata/checksum/Taskfile.yml
vendored
1
testdata/checksum/Taskfile.yml
vendored
@@ -2,7 +2,6 @@ build:
|
|||||||
cmds:
|
cmds:
|
||||||
- cp ./source.txt ./generated.txt
|
- cp ./source.txt ./generated.txt
|
||||||
sources:
|
sources:
|
||||||
- ./**/glob-with-inexistent-file.txt
|
|
||||||
- ./source.txt
|
- ./source.txt
|
||||||
generates:
|
generates:
|
||||||
- ./generated.txt
|
- ./generated.txt
|
||||||
|
|||||||
6
testdata/dry/Taskfile.yml
vendored
6
testdata/dry/Taskfile.yml
vendored
@@ -1,6 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
build:
|
|
||||||
cmds:
|
|
||||||
- touch file.txt
|
|
||||||
8
testdata/expand/Taskfile.yml
vendored
8
testdata/expand/Taskfile.yml
vendored
@@ -1,8 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
pwd:
|
|
||||||
cmds:
|
|
||||||
- pwd
|
|
||||||
dir: '~'
|
|
||||||
silent: true
|
|
||||||
20
testdata/ignore_errors/Taskfile.yml
vendored
20
testdata/ignore_errors/Taskfile.yml
vendored
@@ -1,20 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
task-should-pass:
|
|
||||||
cmds:
|
|
||||||
- exit 1
|
|
||||||
ignore_error: true
|
|
||||||
|
|
||||||
task-should-fail:
|
|
||||||
cmds:
|
|
||||||
- exit 1
|
|
||||||
|
|
||||||
cmd-should-pass:
|
|
||||||
cmds:
|
|
||||||
- cmd: exit 1
|
|
||||||
ignore_error: true
|
|
||||||
|
|
||||||
cmd-should-fail:
|
|
||||||
cmds:
|
|
||||||
- cmd: exit 1
|
|
||||||
1
testdata/includes/.gitignore
vendored
1
testdata/includes/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
*.txt
|
|
||||||
16
testdata/includes/Taskfile.yml
vendored
16
testdata/includes/Taskfile.yml
vendored
@@ -1,16 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
includes:
|
|
||||||
included: ./included
|
|
||||||
included_taskfile: ./Taskfile2.yml
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
default:
|
|
||||||
cmds:
|
|
||||||
- task: gen
|
|
||||||
- task: included:gen
|
|
||||||
- task: included_taskfile:gen
|
|
||||||
|
|
||||||
gen:
|
|
||||||
cmds:
|
|
||||||
- echo main > main.txt
|
|
||||||
6
testdata/includes/Taskfile2.yml
vendored
6
testdata/includes/Taskfile2.yml
vendored
@@ -1,6 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
gen:
|
|
||||||
cmds:
|
|
||||||
- echo included_taskfile > included_taskfile.txt
|
|
||||||
6
testdata/includes/included/Taskfile.yml
vendored
6
testdata/includes/included/Taskfile.yml
vendored
@@ -1,6 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
gen:
|
|
||||||
cmds:
|
|
||||||
- echo included_directory > included_directory.txt
|
|
||||||
1
testdata/includes_deps/.gitignore
vendored
1
testdata/includes_deps/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
*.txt
|
|
||||||
9
testdata/includes_deps/Taskfile.yml
vendored
9
testdata/includes_deps/Taskfile.yml
vendored
@@ -1,9 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
includes:
|
|
||||||
included: Taskfile2.yml
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
default:
|
|
||||||
cmds:
|
|
||||||
- task: included:default
|
|
||||||
16
testdata/includes_deps/Taskfile2.yml
vendored
16
testdata/includes_deps/Taskfile2.yml
vendored
@@ -1,16 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
default:
|
|
||||||
deps: [called_dep]
|
|
||||||
cmds:
|
|
||||||
- echo "default" > default.txt
|
|
||||||
- task: called_task
|
|
||||||
|
|
||||||
called_dep:
|
|
||||||
cmds:
|
|
||||||
- echo "called_dep" > called_dep.txt
|
|
||||||
|
|
||||||
called_task:
|
|
||||||
cmds:
|
|
||||||
- echo "called_task" > called_task.txt
|
|
||||||
1
testdata/includes_empty/.gitignore
vendored
1
testdata/includes_empty/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
file.txt
|
|
||||||
4
testdata/includes_empty/Taskfile.yml
vendored
4
testdata/includes_empty/Taskfile.yml
vendored
@@ -1,4 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
includes:
|
|
||||||
included: Taskfile2.yml
|
|
||||||
10
testdata/includes_empty/Taskfile2.yml
vendored
10
testdata/includes_empty/Taskfile2.yml
vendored
@@ -1,10 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
|
|
||||||
vars:
|
|
||||||
FILE: file.txt
|
|
||||||
CONTENT: default
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
default:
|
|
||||||
cmds:
|
|
||||||
- echo "{{.CONTENT}}" > {{.FILE}}
|
|
||||||
48
variables.go
48
variables.go
@@ -3,10 +3,15 @@ package task
|
|||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/go-task/task/v2/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
"github.com/go-task/task/v2/internal/templater"
|
"github.com/go-task/task/internal/templater"
|
||||||
|
|
||||||
"mvdan.cc/sh/shell"
|
"github.com/mitchellh/go-homedir"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// TaskvarsFilePath file containing additional variables.
|
||||||
|
TaskvarsFilePath = "Taskvars"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompiledTask returns a copy of a task, but replacing variables in almost all
|
// CompiledTask returns a copy of a task, but replacing variables in almost all
|
||||||
@@ -24,29 +29,24 @@ func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) {
|
|||||||
r := templater.Templater{Vars: vars}
|
r := templater.Templater{Vars: vars}
|
||||||
|
|
||||||
new := taskfile.Task{
|
new := taskfile.Task{
|
||||||
Task: origTask.Task,
|
Task: origTask.Task,
|
||||||
Desc: r.Replace(origTask.Desc),
|
Desc: r.Replace(origTask.Desc),
|
||||||
Sources: r.ReplaceSlice(origTask.Sources),
|
Sources: r.ReplaceSlice(origTask.Sources),
|
||||||
Generates: r.ReplaceSlice(origTask.Generates),
|
Generates: r.ReplaceSlice(origTask.Generates),
|
||||||
Status: r.ReplaceSlice(origTask.Status),
|
Status: r.ReplaceSlice(origTask.Status),
|
||||||
Dir: r.Replace(origTask.Dir),
|
Dir: r.Replace(origTask.Dir),
|
||||||
Vars: nil,
|
Vars: nil,
|
||||||
Env: r.ReplaceVars(origTask.Env),
|
Env: r.ReplaceVars(origTask.Env),
|
||||||
Silent: origTask.Silent,
|
Silent: origTask.Silent,
|
||||||
Method: r.Replace(origTask.Method),
|
Method: r.Replace(origTask.Method),
|
||||||
Prefix: r.Replace(origTask.Prefix),
|
|
||||||
IgnoreError: origTask.IgnoreError,
|
|
||||||
}
|
}
|
||||||
new.Dir, err = shell.Expand(new.Dir, nil)
|
new.Dir, err = homedir.Expand(new.Dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if e.Dir != "" && !filepath.IsAbs(new.Dir) {
|
if e.Dir != "" && !filepath.IsAbs(new.Dir) {
|
||||||
new.Dir = filepath.Join(e.Dir, new.Dir)
|
new.Dir = filepath.Join(e.Dir, new.Dir)
|
||||||
}
|
}
|
||||||
if new.Prefix == "" {
|
|
||||||
new.Prefix = new.Task
|
|
||||||
}
|
|
||||||
for k, v := range new.Env {
|
for k, v := range new.Env {
|
||||||
static, err := e.Compiler.HandleDynamicVar(v)
|
static, err := e.Compiler.HandleDynamicVar(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -59,12 +59,12 @@ func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) {
|
|||||||
new.Cmds = make([]*taskfile.Cmd, len(origTask.Cmds))
|
new.Cmds = make([]*taskfile.Cmd, len(origTask.Cmds))
|
||||||
for i, cmd := range origTask.Cmds {
|
for i, cmd := range origTask.Cmds {
|
||||||
new.Cmds[i] = &taskfile.Cmd{
|
new.Cmds[i] = &taskfile.Cmd{
|
||||||
Task: r.Replace(cmd.Task),
|
Task: r.Replace(cmd.Task),
|
||||||
Silent: cmd.Silent,
|
Silent: cmd.Silent,
|
||||||
Cmd: r.Replace(cmd.Cmd),
|
Cmd: r.Replace(cmd.Cmd),
|
||||||
Vars: r.ReplaceVars(cmd.Vars),
|
Vars: r.ReplaceVars(cmd.Vars),
|
||||||
IgnoreError: cmd.IgnoreError,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(origTask.Deps) > 0 {
|
if len(origTask.Deps) > 0 {
|
||||||
|
|||||||
27
vendor/github.com/Masterminds/semver/.travis.yml
generated
vendored
27
vendor/github.com/Masterminds/semver/.travis.yml
generated
vendored
@@ -1,27 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.6.x
|
|
||||||
- 1.7.x
|
|
||||||
- 1.8.x
|
|
||||||
- 1.9.x
|
|
||||||
- 1.10.x
|
|
||||||
- tip
|
|
||||||
|
|
||||||
# Setting sudo access to false will let Travis CI use containers rather than
|
|
||||||
# VMs to run the tests. For more details see:
|
|
||||||
# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
|
||||||
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
script:
|
|
||||||
- make setup
|
|
||||||
- make test
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
webhooks:
|
|
||||||
urls:
|
|
||||||
- https://webhooks.gitter.im/e/06e3328629952dabe3e0
|
|
||||||
on_success: change # options: [always|never|change] default: always
|
|
||||||
on_failure: always # options: [always|never|change] default: always
|
|
||||||
on_start: never # options: [always|never|change] default: always
|
|
||||||
86
vendor/github.com/Masterminds/semver/CHANGELOG.md
generated
vendored
86
vendor/github.com/Masterminds/semver/CHANGELOG.md
generated
vendored
@@ -1,86 +0,0 @@
|
|||||||
# 1.4.2 (2018-04-10)
|
|
||||||
|
|
||||||
## Changed
|
|
||||||
- #72: Updated the docs to point to vert for a console appliaction
|
|
||||||
- #71: Update the docs on pre-release comparator handling
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
|
|
||||||
|
|
||||||
# 1.4.1 (2018-04-02)
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
- Fixed #64: Fix pre-release precedence issue (thanks @uudashr)
|
|
||||||
|
|
||||||
# 1.4.0 (2017-10-04)
|
|
||||||
|
|
||||||
## Changed
|
|
||||||
- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill)
|
|
||||||
|
|
||||||
# 1.3.1 (2017-07-10)
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
- Fixed #57: number comparisons in prerelease sometimes inaccurate
|
|
||||||
|
|
||||||
# 1.3.0 (2017-05-02)
|
|
||||||
|
|
||||||
## Added
|
|
||||||
- #45: Added json (un)marshaling support (thanks @mh-cbon)
|
|
||||||
- Stability marker. See https://masterminds.github.io/stability/
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
- #51: Fix handling of single digit tilde constraint (thanks @dgodd)
|
|
||||||
|
|
||||||
## Changed
|
|
||||||
- #55: The godoc icon moved from png to svg
|
|
||||||
|
|
||||||
# 1.2.3 (2017-04-03)
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
- #46: Fixed 0.x.x and 0.0.x in constraints being treated as *
|
|
||||||
|
|
||||||
# Release 1.2.2 (2016-12-13)
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
- #34: Fixed issue where hyphen range was not working with pre-release parsing.
|
|
||||||
|
|
||||||
# Release 1.2.1 (2016-11-28)
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha"
|
|
||||||
properly.
|
|
||||||
|
|
||||||
# Release 1.2.0 (2016-11-04)
|
|
||||||
|
|
||||||
## Added
|
|
||||||
- #20: Added MustParse function for versions (thanks @adamreese)
|
|
||||||
- #15: Added increment methods on versions (thanks @mh-cbon)
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and
|
|
||||||
might not satisfy the intended compatibility. The change here ignores pre-releases
|
|
||||||
on constraint checks (e.g., ~ or ^) when a pre-release is not part of the
|
|
||||||
constraint. For example, `^1.2.3` will ignore pre-releases while
|
|
||||||
`^1.2.3-alpha` will include them.
|
|
||||||
|
|
||||||
# Release 1.1.1 (2016-06-30)
|
|
||||||
|
|
||||||
## Changed
|
|
||||||
- Issue #9: Speed up version comparison performance (thanks @sdboyer)
|
|
||||||
- Issue #8: Added benchmarks (thanks @sdboyer)
|
|
||||||
- Updated Go Report Card URL to new location
|
|
||||||
- Updated Readme to add code snippet formatting (thanks @mh-cbon)
|
|
||||||
- Updating tagging to v[SemVer] structure for compatibility with other tools.
|
|
||||||
|
|
||||||
# Release 1.1.0 (2016-03-11)
|
|
||||||
|
|
||||||
- Issue #2: Implemented validation to provide reasons a versions failed a
|
|
||||||
constraint.
|
|
||||||
|
|
||||||
# Release 1.0.1 (2015-12-31)
|
|
||||||
|
|
||||||
- Fixed #1: * constraint failing on valid versions.
|
|
||||||
|
|
||||||
# Release 1.0.0 (2015-10-20)
|
|
||||||
|
|
||||||
- Initial release
|
|
||||||
36
vendor/github.com/Masterminds/semver/Makefile
generated
vendored
36
vendor/github.com/Masterminds/semver/Makefile
generated
vendored
@@ -1,36 +0,0 @@
|
|||||||
.PHONY: setup
|
|
||||||
setup:
|
|
||||||
go get -u gopkg.in/alecthomas/gometalinter.v1
|
|
||||||
gometalinter.v1 --install
|
|
||||||
|
|
||||||
.PHONY: test
|
|
||||||
test: validate lint
|
|
||||||
@echo "==> Running tests"
|
|
||||||
go test -v
|
|
||||||
|
|
||||||
.PHONY: validate
|
|
||||||
validate:
|
|
||||||
@echo "==> Running static validations"
|
|
||||||
@gometalinter.v1 \
|
|
||||||
--disable-all \
|
|
||||||
--enable deadcode \
|
|
||||||
--severity deadcode:error \
|
|
||||||
--enable gofmt \
|
|
||||||
--enable gosimple \
|
|
||||||
--enable ineffassign \
|
|
||||||
--enable misspell \
|
|
||||||
--enable vet \
|
|
||||||
--tests \
|
|
||||||
--vendor \
|
|
||||||
--deadline 60s \
|
|
||||||
./... || exit_code=1
|
|
||||||
|
|
||||||
.PHONY: lint
|
|
||||||
lint:
|
|
||||||
@echo "==> Running linters"
|
|
||||||
@gometalinter.v1 \
|
|
||||||
--disable-all \
|
|
||||||
--enable golint \
|
|
||||||
--vendor \
|
|
||||||
--deadline 60s \
|
|
||||||
./... || :
|
|
||||||
165
vendor/github.com/Masterminds/semver/README.md
generated
vendored
165
vendor/github.com/Masterminds/semver/README.md
generated
vendored
@@ -1,165 +0,0 @@
|
|||||||
# SemVer
|
|
||||||
|
|
||||||
The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to:
|
|
||||||
|
|
||||||
* Parse semantic versions
|
|
||||||
* Sort semantic versions
|
|
||||||
* Check if a semantic version fits within a set of constraints
|
|
||||||
* Optionally work with a `v` prefix
|
|
||||||
|
|
||||||
[](https://masterminds.github.io/stability/active.html)
|
|
||||||
[](https://travis-ci.org/Masterminds/semver) [](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [](https://godoc.org/github.com/Masterminds/semver) [](https://goreportcard.com/report/github.com/Masterminds/semver)
|
|
||||||
|
|
||||||
## Parsing Semantic Versions
|
|
||||||
|
|
||||||
To parse a semantic version use the `NewVersion` function. For example,
|
|
||||||
|
|
||||||
```go
|
|
||||||
v, err := semver.NewVersion("1.2.3-beta.1+build345")
|
|
||||||
```
|
|
||||||
|
|
||||||
If there is an error the version wasn't parseable. The version object has methods
|
|
||||||
to get the parts of the version, compare it to other versions, convert the
|
|
||||||
version back into a string, and get the original string. For more details
|
|
||||||
please see the [documentation](https://godoc.org/github.com/Masterminds/semver).
|
|
||||||
|
|
||||||
## Sorting Semantic Versions
|
|
||||||
|
|
||||||
A set of versions can be sorted using the [`sort`](https://golang.org/pkg/sort/)
|
|
||||||
package from the standard library. For example,
|
|
||||||
|
|
||||||
```go
|
|
||||||
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
|
|
||||||
vs := make([]*semver.Version, len(raw))
|
|
||||||
for i, r := range raw {
|
|
||||||
v, err := semver.NewVersion(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Error parsing version: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
vs[i] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(semver.Collection(vs))
|
|
||||||
```
|
|
||||||
|
|
||||||
## Checking Version Constraints
|
|
||||||
|
|
||||||
Checking a version against version constraints is one of the most featureful
|
|
||||||
parts of the package.
|
|
||||||
|
|
||||||
```go
|
|
||||||
c, err := semver.NewConstraint(">= 1.2.3")
|
|
||||||
if err != nil {
|
|
||||||
// Handle constraint not being parseable.
|
|
||||||
}
|
|
||||||
|
|
||||||
v, _ := semver.NewVersion("1.3")
|
|
||||||
if err != nil {
|
|
||||||
// Handle version not being parseable.
|
|
||||||
}
|
|
||||||
// Check if the version meets the constraints. The a variable will be true.
|
|
||||||
a := c.Check(v)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Basic Comparisons
|
|
||||||
|
|
||||||
There are two elements to the comparisons. First, a comparison string is a list
|
|
||||||
of comma separated and comparisons. These are then separated by || separated or
|
|
||||||
comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
|
|
||||||
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
|
|
||||||
greater than or equal to 4.2.3.
|
|
||||||
|
|
||||||
The basic comparisons are:
|
|
||||||
|
|
||||||
* `=`: equal (aliased to no operator)
|
|
||||||
* `!=`: not equal
|
|
||||||
* `>`: greater than
|
|
||||||
* `<`: less than
|
|
||||||
* `>=`: greater than or equal to
|
|
||||||
* `<=`: less than or equal to
|
|
||||||
|
|
||||||
_Note, according to the Semantic Version specification pre-releases may not be
|
|
||||||
API compliant with their release counterpart. It says,_
|
|
||||||
|
|
||||||
> _A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version._
|
|
||||||
|
|
||||||
_SemVer comparisons without a pre-release value will skip pre-release versions.
|
|
||||||
For example, `>1.2.3` will skip pre-releases when looking at a list of values
|
|
||||||
while `>1.2.3-alpha.1` will evaluate pre-releases._
|
|
||||||
|
|
||||||
## Hyphen Range Comparisons
|
|
||||||
|
|
||||||
There are multiple methods to handle ranges and the first is hyphens ranges.
|
|
||||||
These look like:
|
|
||||||
|
|
||||||
* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
|
|
||||||
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
|
|
||||||
|
|
||||||
## Wildcards In Comparisons
|
|
||||||
|
|
||||||
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
|
|
||||||
for all comparison operators. When used on the `=` operator it falls
|
|
||||||
back to the pack level comparison (see tilde below). For example,
|
|
||||||
|
|
||||||
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
|
||||||
* `>= 1.2.x` is equivalent to `>= 1.2.0`
|
|
||||||
* `<= 2.x` is equivalent to `<= 3`
|
|
||||||
* `*` is equivalent to `>= 0.0.0`
|
|
||||||
|
|
||||||
## Tilde Range Comparisons (Patch)
|
|
||||||
|
|
||||||
The tilde (`~`) comparison operator is for patch level ranges when a minor
|
|
||||||
version is specified and major level changes when the minor number is missing.
|
|
||||||
For example,
|
|
||||||
|
|
||||||
* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
|
|
||||||
* `~1` is equivalent to `>= 1, < 2`
|
|
||||||
* `~2.3` is equivalent to `>= 2.3, < 2.4`
|
|
||||||
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
|
||||||
* `~1.x` is equivalent to `>= 1, < 2`
|
|
||||||
|
|
||||||
## Caret Range Comparisons (Major)
|
|
||||||
|
|
||||||
The caret (`^`) comparison operator is for major level changes. This is useful
|
|
||||||
when comparisons of API versions as a major change is API breaking. For example,
|
|
||||||
|
|
||||||
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
|
|
||||||
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
|
|
||||||
* `^2.3` is equivalent to `>= 2.3, < 3`
|
|
||||||
* `^2.x` is equivalent to `>= 2.0.0, < 3`
|
|
||||||
|
|
||||||
# Validation
|
|
||||||
|
|
||||||
In addition to testing a version against a constraint, a version can be validated
|
|
||||||
against a constraint. When validation fails a slice of errors containing why a
|
|
||||||
version didn't meet the constraint is returned. For example,
|
|
||||||
|
|
||||||
```go
|
|
||||||
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
|
|
||||||
if err != nil {
|
|
||||||
// Handle constraint not being parseable.
|
|
||||||
}
|
|
||||||
|
|
||||||
v, _ := semver.NewVersion("1.3")
|
|
||||||
if err != nil {
|
|
||||||
// Handle version not being parseable.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate a version against a constraint.
|
|
||||||
a, msgs := c.Validate(v)
|
|
||||||
// a is false
|
|
||||||
for _, m := range msgs {
|
|
||||||
fmt.Println(m)
|
|
||||||
|
|
||||||
// Loops over the errors which would read
|
|
||||||
// "1.3 is greater than 1.2.3"
|
|
||||||
// "1.3 is less than 1.4"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# Contribute
|
|
||||||
|
|
||||||
If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
|
|
||||||
or [create a pull request](https://github.com/Masterminds/semver/pulls).
|
|
||||||
44
vendor/github.com/Masterminds/semver/appveyor.yml
generated
vendored
44
vendor/github.com/Masterminds/semver/appveyor.yml
generated
vendored
@@ -1,44 +0,0 @@
|
|||||||
version: build-{build}.{branch}
|
|
||||||
|
|
||||||
clone_folder: C:\gopath\src\github.com\Masterminds\semver
|
|
||||||
shallow_clone: true
|
|
||||||
|
|
||||||
environment:
|
|
||||||
GOPATH: C:\gopath
|
|
||||||
|
|
||||||
platform:
|
|
||||||
- x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- go version
|
|
||||||
- go env
|
|
||||||
- go get -u gopkg.in/alecthomas/gometalinter.v1
|
|
||||||
- set PATH=%PATH%;%GOPATH%\bin
|
|
||||||
- gometalinter.v1.exe --install
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- go install -v ./...
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- "gometalinter.v1 \
|
|
||||||
--disable-all \
|
|
||||||
--enable deadcode \
|
|
||||||
--severity deadcode:error \
|
|
||||||
--enable gofmt \
|
|
||||||
--enable gosimple \
|
|
||||||
--enable ineffassign \
|
|
||||||
--enable misspell \
|
|
||||||
--enable vet \
|
|
||||||
--tests \
|
|
||||||
--vendor \
|
|
||||||
--deadline 60s \
|
|
||||||
./... || exit_code=1"
|
|
||||||
- "gometalinter.v1 \
|
|
||||||
--disable-all \
|
|
||||||
--enable golint \
|
|
||||||
--vendor \
|
|
||||||
--deadline 60s \
|
|
||||||
./... || :"
|
|
||||||
- go test -v
|
|
||||||
|
|
||||||
deploy: off
|
|
||||||
11
vendor/github.com/Masterminds/semver/version.go
generated
vendored
11
vendor/github.com/Masterminds/semver/version.go
generated
vendored
@@ -379,15 +379,16 @@ func comparePrePart(s, o string) int {
|
|||||||
|
|
||||||
// When s or o are empty we can use the other in an attempt to determine
|
// When s or o are empty we can use the other in an attempt to determine
|
||||||
// the response.
|
// the response.
|
||||||
if s == "" {
|
if o == "" {
|
||||||
if o != "" {
|
_, n := strconv.ParseInt(s, 10, 64)
|
||||||
|
if n != nil {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
if s == "" {
|
||||||
if o == "" {
|
_, n := strconv.ParseInt(o, 10, 64)
|
||||||
if s != "" {
|
if n != nil {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
|
|||||||
2
vendor/github.com/Masterminds/sprig/.gitignore
generated
vendored
2
vendor/github.com/Masterminds/sprig/.gitignore
generated
vendored
@@ -1,2 +0,0 @@
|
|||||||
vendor/
|
|
||||||
/.glide
|
|
||||||
24
vendor/github.com/Masterminds/sprig/.travis.yml
generated
vendored
24
vendor/github.com/Masterminds/sprig/.travis.yml
generated
vendored
@@ -1,24 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.9.x
|
|
||||||
- 1.10.x
|
|
||||||
- 1.11.x
|
|
||||||
- tip
|
|
||||||
|
|
||||||
# Setting sudo access to false will let Travis CI use containers rather than
|
|
||||||
# VMs to run the tests. For more details see:
|
|
||||||
# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
|
||||||
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
script:
|
|
||||||
- make setup test
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
webhooks:
|
|
||||||
urls:
|
|
||||||
- https://webhooks.gitter.im/e/06e3328629952dabe3e0
|
|
||||||
on_success: change # options: [always|never|change] default: always
|
|
||||||
on_failure: always # options: [always|never|change] default: always
|
|
||||||
on_start: never # options: [always|never|change] default: always
|
|
||||||
153
vendor/github.com/Masterminds/sprig/CHANGELOG.md
generated
vendored
153
vendor/github.com/Masterminds/sprig/CHANGELOG.md
generated
vendored
@@ -1,153 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
## Release 2.15.0 (2018-04-02)
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- #68 and #69: Add json helpers to docs (thanks @arunvelsriram)
|
|
||||||
- #66: Add ternary function (thanks @binoculars)
|
|
||||||
- #67: Allow keys function to take multiple dicts (thanks @binoculars)
|
|
||||||
- #89: Added sha1sum to crypto function (thanks @benkeil)
|
|
||||||
- #81: Allow customizing Root CA that used by genSignedCert (thanks @chenzhiwei)
|
|
||||||
- #92: Add travis testing for go 1.10
|
|
||||||
- #93: Adding appveyor config for windows testing
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- #90: Updating to more recent dependencies
|
|
||||||
- #73: replace satori/go.uuid with google/uuid (thanks @petterw)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- #76: Fixed documentation typos (thanks @Thiht)
|
|
||||||
- Fixed rounding issue on the `ago` function. Note, the removes support for Go 1.8 and older
|
|
||||||
|
|
||||||
## Release 2.14.1 (2017-12-01)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- #60: Fix typo in function name documentation (thanks @neil-ca-moore)
|
|
||||||
- #61: Removing line with {{ due to blocking github pages genertion
|
|
||||||
- #64: Update the list functions to handle int, string, and other slices for compatibility
|
|
||||||
|
|
||||||
## Release 2.14.0 (2017-10-06)
|
|
||||||
|
|
||||||
This new version of Sprig adds a set of functions for generating and working with SSL certificates.
|
|
||||||
|
|
||||||
- `genCA` generates an SSL Certificate Authority
|
|
||||||
- `genSelfSignedCert` generates an SSL self-signed certificate
|
|
||||||
- `genSignedCert` generates an SSL certificate and key based on a given CA
|
|
||||||
|
|
||||||
## Release 2.13.0 (2017-09-18)
|
|
||||||
|
|
||||||
This release adds new functions, including:
|
|
||||||
|
|
||||||
- `regexMatch`, `regexFindAll`, `regexFind`, `regexReplaceAll`, `regexReplaceAllLiteral`, and `regexSplit` to work with regular expressions
|
|
||||||
- `floor`, `ceil`, and `round` math functions
|
|
||||||
- `toDate` converts a string to a date
|
|
||||||
- `nindent` is just like `indent` but also prepends a new line
|
|
||||||
- `ago` returns the time from `time.Now`
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- #40: Added basic regex functionality (thanks @alanquillin)
|
|
||||||
- #41: Added ceil floor and round functions (thanks @alanquillin)
|
|
||||||
- #48: Added toDate function (thanks @andreynering)
|
|
||||||
- #50: Added nindent function (thanks @binoculars)
|
|
||||||
- #46: Added ago function (thanks @slayer)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- #51: Updated godocs to include new string functions (thanks @curtisallen)
|
|
||||||
- #49: Added ability to merge multiple dicts (thanks @binoculars)
|
|
||||||
|
|
||||||
## Release 2.12.0 (2017-05-17)
|
|
||||||
|
|
||||||
- `snakecase`, `camelcase`, and `shuffle` are three new string functions
|
|
||||||
- `fail` allows you to bail out of a template render when conditions are not met
|
|
||||||
|
|
||||||
## Release 2.11.0 (2017-05-02)
|
|
||||||
|
|
||||||
- Added `toJson` and `toPrettyJson`
|
|
||||||
- Added `merge`
|
|
||||||
- Refactored documentation
|
|
||||||
|
|
||||||
## Release 2.10.0 (2017-03-15)
|
|
||||||
|
|
||||||
- Added `semver` and `semverCompare` for Semantic Versions
|
|
||||||
- `list` replaces `tuple`
|
|
||||||
- Fixed issue with `join`
|
|
||||||
- Added `first`, `last`, `intial`, `rest`, `prepend`, `append`, `toString`, `toStrings`, `sortAlpha`, `reverse`, `coalesce`, `pluck`, `pick`, `compact`, `keys`, `omit`, `uniq`, `has`, `without`
|
|
||||||
|
|
||||||
## Release 2.9.0 (2017-02-23)
|
|
||||||
|
|
||||||
- Added `splitList` to split a list
|
|
||||||
- Added crypto functions of `genPrivateKey` and `derivePassword`
|
|
||||||
|
|
||||||
## Release 2.8.0 (2016-12-21)
|
|
||||||
|
|
||||||
- Added access to several path functions (`base`, `dir`, `clean`, `ext`, and `abs`)
|
|
||||||
- Added functions for _mutating_ dictionaries (`set`, `unset`, `hasKey`)
|
|
||||||
|
|
||||||
## Release 2.7.0 (2016-12-01)
|
|
||||||
|
|
||||||
- Added `sha256sum` to generate a hash of an input
|
|
||||||
- Added functions to convert a numeric or string to `int`, `int64`, `float64`
|
|
||||||
|
|
||||||
## Release 2.6.0 (2016-10-03)
|
|
||||||
|
|
||||||
- Added a `uuidv4` template function for generating UUIDs inside of a template.
|
|
||||||
|
|
||||||
## Release 2.5.0 (2016-08-19)
|
|
||||||
|
|
||||||
- New `trimSuffix`, `trimPrefix`, `hasSuffix`, and `hasPrefix` functions
|
|
||||||
- New aliases have been added for a few functions that didn't follow the naming conventions (`trimAll` and `abbrevBoth`)
|
|
||||||
- `trimall` and `abbrevboth` (notice the case) are deprecated and will be removed in 3.0.0
|
|
||||||
|
|
||||||
## Release 2.4.0 (2016-08-16)
|
|
||||||
|
|
||||||
- Adds two functions: `until` and `untilStep`
|
|
||||||
|
|
||||||
## Release 2.3.0 (2016-06-21)
|
|
||||||
|
|
||||||
- cat: Concatenate strings with whitespace separators.
|
|
||||||
- replace: Replace parts of a string: `replace " " "-" "Me First"` renders "Me-First"
|
|
||||||
- plural: Format plurals: `len "foo" | plural "one foo" "many foos"` renders "many foos"
|
|
||||||
- indent: Indent blocks of text in a way that is sensitive to "\n" characters.
|
|
||||||
|
|
||||||
## Release 2.2.0 (2016-04-21)
|
|
||||||
|
|
||||||
- Added a `genPrivateKey` function (Thanks @bacongobbler)
|
|
||||||
|
|
||||||
## Release 2.1.0 (2016-03-30)
|
|
||||||
|
|
||||||
- `default` now prints the default value when it does not receive a value down the pipeline. It is much safer now to do `{{.Foo | default "bar"}}`.
|
|
||||||
- Added accessors for "hermetic" functions. These return only functions that, when given the same input, produce the same output.
|
|
||||||
|
|
||||||
## Release 2.0.0 (2016-03-29)
|
|
||||||
|
|
||||||
Because we switched from `int` to `int64` as the return value for all integer math functions, the library's major version number has been incremented.
|
|
||||||
|
|
||||||
- `min` complements `max` (formerly `biggest`)
|
|
||||||
- `empty` indicates that a value is the empty value for its type
|
|
||||||
- `tuple` creates a tuple inside of a template: `{{$t := tuple "a", "b" "c"}}`
|
|
||||||
- `dict` creates a dictionary inside of a template `{{$d := dict "key1" "val1" "key2" "val2"}}`
|
|
||||||
- Date formatters have been added for HTML dates (as used in `date` input fields)
|
|
||||||
- Integer math functions can convert from a number of types, including `string` (via `strconv.ParseInt`).
|
|
||||||
|
|
||||||
## Release 1.2.0 (2016-02-01)
|
|
||||||
|
|
||||||
- Added quote and squote
|
|
||||||
- Added b32enc and b32dec
|
|
||||||
- add now takes varargs
|
|
||||||
- biggest now takes varargs
|
|
||||||
|
|
||||||
## Release 1.1.0 (2015-12-29)
|
|
||||||
|
|
||||||
- Added #4: Added contains function. strings.Contains, but with the arguments
|
|
||||||
switched to simplify common pipelines. (thanks krancour)
|
|
||||||
- Added Travis-CI testing support
|
|
||||||
|
|
||||||
## Release 1.0.0 (2015-12-23)
|
|
||||||
|
|
||||||
- Initial release
|
|
||||||
13
vendor/github.com/Masterminds/sprig/Makefile
generated
vendored
13
vendor/github.com/Masterminds/sprig/Makefile
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
HAS_GLIDE := $(shell command -v glide;)
|
|
||||||
|
|
||||||
.PHONY: test
|
|
||||||
test:
|
|
||||||
go test -v .
|
|
||||||
|
|
||||||
.PHONY: setup
|
|
||||||
setup:
|
|
||||||
ifndef HAS_GLIDE
|
|
||||||
go get -u github.com/Masterminds/glide
|
|
||||||
endif
|
|
||||||
glide install
|
|
||||||
81
vendor/github.com/Masterminds/sprig/README.md
generated
vendored
81
vendor/github.com/Masterminds/sprig/README.md
generated
vendored
@@ -1,81 +0,0 @@
|
|||||||
# Sprig: Template functions for Go templates
|
|
||||||
[](https://masterminds.github.io/stability/sustained.html)
|
|
||||||
[](https://travis-ci.org/Masterminds/sprig)
|
|
||||||
|
|
||||||
The Go language comes with a [built-in template
|
|
||||||
language](http://golang.org/pkg/text/template/), but not
|
|
||||||
very many template functions. This library provides a group of commonly
|
|
||||||
used template functions.
|
|
||||||
|
|
||||||
It is inspired by the template functions found in
|
|
||||||
[Twig](http://twig.sensiolabs.org/documentation) and also in various
|
|
||||||
JavaScript libraries, such as [underscore.js](http://underscorejs.org/).
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Template developers can read the [Sprig function documentation](http://masterminds.github.io/sprig/) to
|
|
||||||
learn about the >100 template functions available.
|
|
||||||
|
|
||||||
For Go developers wishing to include Sprig as a library in their programs,
|
|
||||||
API documentation is available [at GoDoc.org](http://godoc.org/github.com/Masterminds/sprig), but
|
|
||||||
read on for standard usage.
|
|
||||||
|
|
||||||
### Load the Sprig library
|
|
||||||
|
|
||||||
To load the Sprig `FuncMap`:
|
|
||||||
|
|
||||||
```go
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/Masterminds/sprig"
|
|
||||||
"html/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This example illustrates that the FuncMap *must* be set before the
|
|
||||||
// templates themselves are loaded.
|
|
||||||
tpl := template.Must(
|
|
||||||
template.New("base").Funcs(sprig.FuncMap()).ParseGlob("*.html")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### Call the functions inside of templates
|
|
||||||
|
|
||||||
By convention, all functions are lowercase. This seems to follow the Go
|
|
||||||
idiom for template functions (as opposed to template methods, which are
|
|
||||||
TitleCase).
|
|
||||||
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
{{ "hello!" | upper | repeat 5 }}
|
|
||||||
```
|
|
||||||
|
|
||||||
Produces:
|
|
||||||
|
|
||||||
```
|
|
||||||
HELLO!HELLO!HELLO!HELLO!HELLO!
|
|
||||||
```
|
|
||||||
|
|
||||||
## Principles:
|
|
||||||
|
|
||||||
The following principles were used in deciding on which functions to add, and
|
|
||||||
determining how to implement them.
|
|
||||||
|
|
||||||
- Template functions should be used to build layout. Therefore, the following
|
|
||||||
types of operations are within the domain of template functions:
|
|
||||||
- Formatting
|
|
||||||
- Layout
|
|
||||||
- Simple type conversions
|
|
||||||
- Utilities that assist in handling common formatting and layout needs (e.g. arithmetic)
|
|
||||||
- Template functions should not return errors unless there is no way to print
|
|
||||||
a sensible value. For example, converting a string to an integer should not
|
|
||||||
produce an error if conversion fails. Instead, it should display a default
|
|
||||||
value that can be displayed.
|
|
||||||
- Simple math is necessary for grid layouts, pagers, and so on. Complex math
|
|
||||||
(anything other than arithmetic) should be done outside of templates.
|
|
||||||
- Template functions only deal with the data passed into them. They never retrieve
|
|
||||||
data from a source.
|
|
||||||
- Finally, do not override core Go template functions.
|
|
||||||
26
vendor/github.com/Masterminds/sprig/appveyor.yml
generated
vendored
26
vendor/github.com/Masterminds/sprig/appveyor.yml
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
version: build-{build}.{branch}
|
|
||||||
|
|
||||||
clone_folder: C:\gopath\src\github.com\Masterminds\sprig
|
|
||||||
shallow_clone: true
|
|
||||||
|
|
||||||
environment:
|
|
||||||
GOPATH: C:\gopath
|
|
||||||
|
|
||||||
platform:
|
|
||||||
- x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- go get -u github.com/Masterminds/glide
|
|
||||||
- set PATH=%GOPATH%\bin;%PATH%
|
|
||||||
- go version
|
|
||||||
- go env
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- glide install
|
|
||||||
- go install ./...
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- go test -v
|
|
||||||
|
|
||||||
deploy: off
|
|
||||||
61
vendor/github.com/Masterminds/sprig/crypto.go
generated
vendored
61
vendor/github.com/Masterminds/sprig/crypto.go
generated
vendored
@@ -8,12 +8,10 @@ import (
|
|||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/sha1"
|
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
"encoding/base64"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
@@ -23,7 +21,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
uuid "github.com/satori/go.uuid"
|
||||||
"golang.org/x/crypto/scrypt"
|
"golang.org/x/crypto/scrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,14 +30,9 @@ func sha256sum(input string) string {
|
|||||||
return hex.EncodeToString(hash[:])
|
return hex.EncodeToString(hash[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func sha1sum(input string) string {
|
|
||||||
hash := sha1.Sum([]byte(input))
|
|
||||||
return hex.EncodeToString(hash[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// uuidv4 provides a safe and secure UUID v4 implementation
|
// uuidv4 provides a safe and secure UUID v4 implementation
|
||||||
func uuidv4() string {
|
func uuidv4() string {
|
||||||
return fmt.Sprintf("%s", uuid.New())
|
return fmt.Sprintf("%s", uuid.NewV4())
|
||||||
}
|
}
|
||||||
|
|
||||||
var master_password_seed = "com.lyndir.masterpassword"
|
var master_password_seed = "com.lyndir.masterpassword"
|
||||||
@@ -163,49 +156,6 @@ type certificate struct {
|
|||||||
Key string
|
Key string
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildCustomCertificate(b64cert string, b64key string) (certificate, error) {
|
|
||||||
crt := certificate{}
|
|
||||||
|
|
||||||
cert, err := base64.StdEncoding.DecodeString(b64cert)
|
|
||||||
if err != nil {
|
|
||||||
return crt, errors.New("unable to decode base64 certificate")
|
|
||||||
}
|
|
||||||
|
|
||||||
key, err := base64.StdEncoding.DecodeString(b64key)
|
|
||||||
if err != nil {
|
|
||||||
return crt, errors.New("unable to decode base64 private key")
|
|
||||||
}
|
|
||||||
|
|
||||||
decodedCert, _ := pem.Decode(cert)
|
|
||||||
if decodedCert == nil {
|
|
||||||
return crt, errors.New("unable to decode certificate")
|
|
||||||
}
|
|
||||||
_, err = x509.ParseCertificate(decodedCert.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return crt, fmt.Errorf(
|
|
||||||
"error parsing certificate: decodedCert.Bytes: %s",
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
decodedKey, _ := pem.Decode(key)
|
|
||||||
if decodedKey == nil {
|
|
||||||
return crt, errors.New("unable to decode key")
|
|
||||||
}
|
|
||||||
_, err = x509.ParsePKCS1PrivateKey(decodedKey.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return crt, fmt.Errorf(
|
|
||||||
"error parsing prive key: decodedKey.Bytes: %s",
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
crt.Cert = string(cert)
|
|
||||||
crt.Key = string(key)
|
|
||||||
|
|
||||||
return crt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateCertificateAuthority(
|
func generateCertificateAuthority(
|
||||||
cn string,
|
cn string,
|
||||||
daysValid int,
|
daysValid int,
|
||||||
@@ -369,13 +319,8 @@ func getBaseCertTemplate(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
serialNumberUpperBound := new(big.Int).Lsh(big.NewInt(1), 128)
|
|
||||||
serialNumber, err := rand.Int(rand.Reader, serialNumberUpperBound)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &x509.Certificate{
|
return &x509.Certificate{
|
||||||
SerialNumber: serialNumber,
|
SerialNumber: big.NewInt(1),
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
CommonName: cn,
|
CommonName: cn,
|
||||||
},
|
},
|
||||||
|
|||||||
2
vendor/github.com/Masterminds/sprig/date.go
generated
vendored
2
vendor/github.com/Masterminds/sprig/date.go
generated
vendored
@@ -66,7 +66,7 @@ func dateAgo(date interface{}) string {
|
|||||||
t = time.Unix(int64(date), 0)
|
t = time.Unix(int64(date), 0)
|
||||||
}
|
}
|
||||||
// Drop resolution to seconds
|
// Drop resolution to seconds
|
||||||
duration := time.Since(t).Round(time.Second)
|
duration := time.Since(t) / time.Second * time.Second
|
||||||
return duration.String()
|
return duration.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
vendor/github.com/Masterminds/sprig/defaults.go
generated
vendored
10
vendor/github.com/Masterminds/sprig/defaults.go
generated
vendored
@@ -49,6 +49,7 @@ func empty(given interface{}) bool {
|
|||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// coalesce returns the first non-empty value.
|
// coalesce returns the first non-empty value.
|
||||||
@@ -72,12 +73,3 @@ func toPrettyJson(v interface{}) string {
|
|||||||
output, _ := json.MarshalIndent(v, "", " ")
|
output, _ := json.MarshalIndent(v, "", " ")
|
||||||
return string(output)
|
return string(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ternary returns the first value if the last value is true, otherwise returns the second value.
|
|
||||||
func ternary(vt interface{}, vf interface{}, v bool) interface{} {
|
|
||||||
if v {
|
|
||||||
return vt
|
|
||||||
}
|
|
||||||
|
|
||||||
return vf
|
|
||||||
}
|
|
||||||
|
|||||||
17
vendor/github.com/Masterminds/sprig/dict.go
generated
vendored
17
vendor/github.com/Masterminds/sprig/dict.go
generated
vendored
@@ -27,12 +27,10 @@ func pluck(key string, d ...map[string]interface{}) []interface{} {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func keys(dicts ...map[string]interface{}) []string {
|
func keys(dict map[string]interface{}) []string {
|
||||||
k := []string{}
|
k := []string{}
|
||||||
for _, dict := range dicts {
|
for key := range dict {
|
||||||
for key := range dict {
|
k = append(k, key)
|
||||||
k = append(k, key)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
@@ -86,12 +84,3 @@ func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface
|
|||||||
}
|
}
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
func values(dict map[string]interface{}) []interface{} {
|
|
||||||
values := []interface{}{}
|
|
||||||
for _, value := range dict {
|
|
||||||
values = append(values, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return values
|
|
||||||
}
|
|
||||||
|
|||||||
213
vendor/github.com/Masterminds/sprig/doc.go
generated
vendored
213
vendor/github.com/Masterminds/sprig/doc.go
generated
vendored
@@ -14,6 +14,217 @@ Note that you should add the function map before you parse any template files.
|
|||||||
appear in the standard library. This is to make it easier to pipe
|
appear in the standard library. This is to make it easier to pipe
|
||||||
arguments into functions.
|
arguments into functions.
|
||||||
|
|
||||||
See http://masterminds.github.io/sprig/ for more detailed documentation on each of the available functions.
|
Date Functions
|
||||||
|
|
||||||
|
- date FORMAT TIME: Format a date, where a date is an integer type or a time.Time type, and
|
||||||
|
format is a time.Format formatting string.
|
||||||
|
- dateModify: Given a date, modify it with a duration: `date_modify "-1.5h" now`. If the duration doesn't
|
||||||
|
parse, it returns the time unaltered. See `time.ParseDuration` for info on duration strings.
|
||||||
|
- now: Current time.Time, for feeding into date-related functions.
|
||||||
|
- htmlDate TIME: Format a date for use in the value field of an HTML "date" form element.
|
||||||
|
- dateInZone FORMAT TIME TZ: Like date, but takes three arguments: format, timestamp,
|
||||||
|
timezone.
|
||||||
|
- htmlDateInZone TIME TZ: Like htmlDate, but takes two arguments: timestamp,
|
||||||
|
timezone.
|
||||||
|
|
||||||
|
String Functions
|
||||||
|
|
||||||
|
- abbrev: Truncate a string with ellipses. `abbrev 5 "hello world"` yields "he..."
|
||||||
|
- abbrevboth: Abbreviate from both sides, yielding "...lo wo..."
|
||||||
|
- trunc: Truncate a string (no suffix). `trunc 5 "Hello World"` yields "hello".
|
||||||
|
- trim: strings.TrimSpace
|
||||||
|
- trimAll: strings.Trim, but with the argument order reversed `trimAll "$" "$5.00"` or `"$5.00 | trimAll "$"`
|
||||||
|
- trimSuffix: strings.TrimSuffix, but with the argument order reversed: `trimSuffix "-" "ends-with-"`
|
||||||
|
- trimPrefix: strings.TrimPrefix, but with the argument order reversed `trimPrefix "$" "$5"`
|
||||||
|
- upper: strings.ToUpper
|
||||||
|
- lower: strings.ToLower
|
||||||
|
- nospace: Remove all space characters from a string. `nospace "h e l l o"` becomes "hello"
|
||||||
|
- title: strings.Title
|
||||||
|
- untitle: Remove title casing
|
||||||
|
- repeat: strings.Repeat, but with the arguments switched: `repeat count str`. (This simplifies common pipelines)
|
||||||
|
- substr: Given string, start, and length, return a substr.
|
||||||
|
- initials: Given a multi-word string, return the initials. `initials "Matt Butcher"` returns "MB"
|
||||||
|
- randAlphaNum: Given a length, generate a random alphanumeric sequence
|
||||||
|
- randAlpha: Given a length, generate an alphabetic string
|
||||||
|
- randAscii: Given a length, generate a random ASCII string (symbols included)
|
||||||
|
- randNumeric: Given a length, generate a string of digits.
|
||||||
|
- swapcase: SwapCase swaps the case of a string using a word based algorithm. see https://godoc.org/github.com/Masterminds/goutils#SwapCase
|
||||||
|
- shuffle: Shuffle randomizes runes in a string and returns the result. It uses default random source in `math/rand`
|
||||||
|
- snakecase: convert all upper case characters in a string to underscore format.
|
||||||
|
- camelcase: convert all lower case characters behind underscores to upper case character
|
||||||
|
- wrap: Force a line wrap at the given width. `wrap 80 "imagine a longer string"`
|
||||||
|
- wrapWith: Wrap a line at the given length, but using 'sep' instead of a newline. `wrapWith 50, "<br>", $html`
|
||||||
|
- contains: strings.Contains, but with the arguments switched: `contains substr str`. (This simplifies common pipelines)
|
||||||
|
- hasPrefix: strings.hasPrefix, but with the arguments switched
|
||||||
|
- hasSuffix: strings.hasSuffix, but with the arguments switched
|
||||||
|
- quote: Wrap string(s) in double quotation marks, escape the contents by adding '\' before '"'.
|
||||||
|
- squote: Wrap string(s) in double quotation marks, does not escape content.
|
||||||
|
- cat: Concatenate strings, separating them by spaces. `cat $a $b $c`.
|
||||||
|
- indent: Indent a string using space characters. `indent 4 "foo\nbar"` produces " foo\n bar"
|
||||||
|
- nindent: Indent a string using space characters and prepend a new line. `indent 4 "foo\nbar"` produces "\n foo\n bar"
|
||||||
|
- replace: Replace an old with a new in a string: `$name | replace " " "-"`
|
||||||
|
- plural: Choose singular or plural based on length: `len $fish | plural "one anchovy" "many anchovies"`
|
||||||
|
- sha256sum: Generate a hex encoded sha256 hash of the input
|
||||||
|
- toString: Convert something to a string
|
||||||
|
|
||||||
|
String Slice Functions:
|
||||||
|
|
||||||
|
- join: strings.Join, but as `join SEP SLICE`
|
||||||
|
- split: strings.Split, but as `split SEP STRING`. The results are returned
|
||||||
|
as a map with the indexes set to _N, where N is an integer starting from 0.
|
||||||
|
Use it like this: `{{$v := "foo/bar/baz" | split "/"}}{{$v._0}}` (Prints `foo`)
|
||||||
|
- splitList: strings.Split, but as `split SEP STRING`. The results are returned
|
||||||
|
as an array.
|
||||||
|
- toStrings: convert a list to a list of strings. 'list 1 2 3 | toStrings' produces '["1" "2" "3"]'
|
||||||
|
- sortAlpha: sort a list lexicographically.
|
||||||
|
|
||||||
|
Integer Slice Functions:
|
||||||
|
|
||||||
|
- until: Given an integer, returns a slice of counting integers from 0 to one
|
||||||
|
less than the given integer: `range $i, $e := until 5`
|
||||||
|
- untilStep: Given start, stop, and step, return an integer slice starting at
|
||||||
|
'start', stopping at `stop`, and incrementing by 'step. This is the same
|
||||||
|
as Python's long-form of 'range'.
|
||||||
|
|
||||||
|
Conversions:
|
||||||
|
|
||||||
|
- atoi: Convert a string to an integer. 0 if the integer could not be parsed.
|
||||||
|
- int64: Convert a string or another numeric type to an int64.
|
||||||
|
- int: Convert a string or another numeric type to an int.
|
||||||
|
- float64: Convert a string or another numeric type to a float64.
|
||||||
|
|
||||||
|
Defaults:
|
||||||
|
|
||||||
|
- default: Give a default value. Used like this: trim " "| default "empty".
|
||||||
|
Since trim produces an empty string, the default value is returned. For
|
||||||
|
things with a length (strings, slices, maps), len(0) will trigger the default.
|
||||||
|
For numbers, the value 0 will trigger the default. For booleans, false will
|
||||||
|
trigger the default. For structs, the default is never returned (there is
|
||||||
|
no clear empty condition). For everything else, nil value triggers a default.
|
||||||
|
- empty: Return true if the given value is the zero value for its type.
|
||||||
|
Caveats: structs are always non-empty. This should match the behavior of
|
||||||
|
{{if pipeline}}, but can be used inside of a pipeline.
|
||||||
|
- coalesce: Given a list of items, return the first non-empty one.
|
||||||
|
This follows the same rules as 'empty'. '{{ coalesce .someVal 0 "hello" }}`
|
||||||
|
will return `.someVal` if set, or else return "hello". The 0 is skipped
|
||||||
|
because it is an empty value.
|
||||||
|
- compact: Return a copy of a list with all of the empty values removed.
|
||||||
|
'list 0 1 2 "" | compact' will return '[1 2]'
|
||||||
|
|
||||||
|
OS:
|
||||||
|
- env: Resolve an environment variable
|
||||||
|
- expandenv: Expand a string through the environment
|
||||||
|
|
||||||
|
File Paths:
|
||||||
|
- base: Return the last element of a path. https://golang.org/pkg/path#Base
|
||||||
|
- dir: Remove the last element of a path. https://golang.org/pkg/path#Dir
|
||||||
|
- clean: Clean a path to the shortest equivalent name. (e.g. remove "foo/.."
|
||||||
|
from "foo/../bar.html") https://golang.org/pkg/path#Clean
|
||||||
|
- ext: https://golang.org/pkg/path#Ext
|
||||||
|
- isAbs: https://golang.org/pkg/path#IsAbs
|
||||||
|
|
||||||
|
Encoding:
|
||||||
|
- b64enc: Base 64 encode a string.
|
||||||
|
- b64dec: Base 64 decode a string.
|
||||||
|
|
||||||
|
Reflection:
|
||||||
|
|
||||||
|
- typeOf: Takes an interface and returns a string representation of the type.
|
||||||
|
For pointers, this will return a type prefixed with an asterisk(`*`). So
|
||||||
|
a pointer to type `Foo` will be `*Foo`.
|
||||||
|
- typeIs: Compares an interface with a string name, and returns true if they match.
|
||||||
|
Note that a pointer will not match a reference. For example `*Foo` will not
|
||||||
|
match `Foo`.
|
||||||
|
- typeIsLike: Compares an interface with a string name and returns true if
|
||||||
|
the interface is that `name` or that `*name`. In other words, if the given
|
||||||
|
value matches the given type or is a pointer to the given type, this returns
|
||||||
|
true.
|
||||||
|
- kindOf: Takes an interface and returns a string representation of its kind.
|
||||||
|
- kindIs: Returns true if the given string matches the kind of the given interface.
|
||||||
|
|
||||||
|
Note: None of these can test whether or not something implements a given
|
||||||
|
interface, since doing so would require compiling the interface in ahead of
|
||||||
|
time.
|
||||||
|
|
||||||
|
Data Structures:
|
||||||
|
|
||||||
|
- tuple: Takes an arbitrary list of items and returns a slice of items. Its
|
||||||
|
tuple-ish properties are mainly gained through the template idiom, and not
|
||||||
|
through an API provided here. WARNING: The implementation of tuple will
|
||||||
|
change in the future.
|
||||||
|
- list: An arbitrary ordered list of items. (This is prefered over tuple.)
|
||||||
|
- dict: Takes a list of name/values and returns a map[string]interface{}.
|
||||||
|
The first parameter is converted to a string and stored as a key, the
|
||||||
|
second parameter is treated as the value. And so on, with odds as keys and
|
||||||
|
evens as values. If the function call ends with an odd, the last key will
|
||||||
|
be assigned the empty string. Non-string keys are converted to strings as
|
||||||
|
follows: []byte are converted, fmt.Stringers will have String() called.
|
||||||
|
errors will have Error() called. All others will be passed through
|
||||||
|
fmt.Sprtinf("%v").
|
||||||
|
|
||||||
|
Lists Functions:
|
||||||
|
|
||||||
|
These are used to manipulate lists: '{{ list 1 2 3 | reverse | first }}'
|
||||||
|
|
||||||
|
- first: Get the first item in a 'list'. 'list 1 2 3 | first' prints '1'
|
||||||
|
- last: Get the last item in a 'list': 'list 1 2 3 | last ' prints '3'
|
||||||
|
- rest: Get all but the first item in a list: 'list 1 2 3 | rest' returns '[2 3]'
|
||||||
|
- initial: Get all but the last item in a list: 'list 1 2 3 | initial' returns '[1 2]'
|
||||||
|
- append: Add an item to the end of a list: 'append $list 4' adds '4' to the end of '$list'
|
||||||
|
- prepend: Add an item to the beginning of a list: 'prepend $list 4' puts 4 at the beginning of the list.
|
||||||
|
- reverse: Reverse the items in a list.
|
||||||
|
- uniq: Remove duplicates from a list.
|
||||||
|
- without: Return a list with the given values removed: 'without (list 1 2 3) 1' would return '[2 3]'
|
||||||
|
- has: Return 'true' if the item is found in the list: 'has "foo" $list' will return 'true' if the list contains "foo"
|
||||||
|
|
||||||
|
Dict Functions:
|
||||||
|
|
||||||
|
These are used to manipulate dicts.
|
||||||
|
|
||||||
|
- set: Takes a dict, a key, and a value, and sets that key/value pair in
|
||||||
|
the dict. `set $dict $key $value`. For convenience, it returns the dict,
|
||||||
|
even though the dict was modified in place.
|
||||||
|
- unset: Takes a dict and a key, and deletes that key/value pair from the
|
||||||
|
dict. `unset $dict $key`. This returns the dict for convenience.
|
||||||
|
- hasKey: Takes a dict and a key, and returns boolean true if the key is in
|
||||||
|
the dict.
|
||||||
|
- pluck: Given a key and one or more maps, get all of the values for that key.
|
||||||
|
- keys: Get an array of all of the keys in a dict.
|
||||||
|
- pick: Select just the given keys out of the dict, and return a new dict.
|
||||||
|
- omit: Return a dict without the given keys.
|
||||||
|
|
||||||
|
Math Functions:
|
||||||
|
|
||||||
|
Integer functions will convert integers of any width to `int64`. If a
|
||||||
|
string is passed in, functions will attempt to convert with
|
||||||
|
`strconv.ParseInt(s, 1064)`. If this fails, the value will be treated as 0.
|
||||||
|
|
||||||
|
- add1: Increment an integer by 1
|
||||||
|
- add: Sum an arbitrary number of integers
|
||||||
|
- sub: Subtract the second integer from the first
|
||||||
|
- div: Divide the first integer by the second
|
||||||
|
- mod: Module of first integer divided by second
|
||||||
|
- mul: Multiply integers
|
||||||
|
- max: Return the biggest of a series of one or more integers
|
||||||
|
- min: Return the smallest of a series of one or more integers
|
||||||
|
- biggest: DEPRECATED. Return the biggest of a series of one or more integers
|
||||||
|
|
||||||
|
Crypto Functions:
|
||||||
|
|
||||||
|
- genPrivateKey: Generate a private key for the given cryptosystem. If no
|
||||||
|
argument is supplied, by default it will generate a private key using
|
||||||
|
the RSA algorithm. Accepted values are `rsa`, `dsa`, and `ecdsa`.
|
||||||
|
- derivePassword: Derive a password from the given parameters according to the ["Master Password" algorithm](http://masterpasswordapp.com/algorithm.html)
|
||||||
|
Given parameters (in order) are:
|
||||||
|
`counter` (starting with 1), `password_type` (maximum, long, medium, short, basic, or pin), `password`,
|
||||||
|
`user`, and `site`
|
||||||
|
|
||||||
|
SemVer Functions:
|
||||||
|
|
||||||
|
These functions provide version parsing and comparisons for SemVer 2 version
|
||||||
|
strings.
|
||||||
|
|
||||||
|
- semver: Parse a semantic version and return a Version object.
|
||||||
|
- semverCompare: Compare a SemVer range to a particular version.
|
||||||
*/
|
*/
|
||||||
package sprig
|
package sprig
|
||||||
|
|||||||
7
vendor/github.com/Masterminds/sprig/functions.go
generated
vendored
7
vendor/github.com/Masterminds/sprig/functions.go
generated
vendored
@@ -142,7 +142,6 @@ var genericMap = map[string]interface{}{
|
|||||||
"nindent": nindent,
|
"nindent": nindent,
|
||||||
"replace": replace,
|
"replace": replace,
|
||||||
"plural": plural,
|
"plural": plural,
|
||||||
"sha1sum": sha1sum,
|
|
||||||
"sha256sum": sha256sum,
|
"sha256sum": sha256sum,
|
||||||
"toString": strval,
|
"toString": strval,
|
||||||
|
|
||||||
@@ -160,8 +159,6 @@ var genericMap = map[string]interface{}{
|
|||||||
// split "/" foo/bar returns map[int]string{0: foo, 1: bar}
|
// split "/" foo/bar returns map[int]string{0: foo, 1: bar}
|
||||||
"split": split,
|
"split": split,
|
||||||
"splitList": func(sep, orig string) []string { return strings.Split(orig, sep) },
|
"splitList": func(sep, orig string) []string { return strings.Split(orig, sep) },
|
||||||
// splitn "/" foo/bar/fuu returns map[int]string{0: foo, 1: bar/fuu}
|
|
||||||
"splitn": splitn,
|
|
||||||
"toStrings": strslice,
|
"toStrings": strslice,
|
||||||
|
|
||||||
"until": until,
|
"until": until,
|
||||||
@@ -205,7 +202,6 @@ var genericMap = map[string]interface{}{
|
|||||||
"compact": compact,
|
"compact": compact,
|
||||||
"toJson": toJson,
|
"toJson": toJson,
|
||||||
"toPrettyJson": toPrettyJson,
|
"toPrettyJson": toPrettyJson,
|
||||||
"ternary": ternary,
|
|
||||||
|
|
||||||
// Reflection
|
// Reflection
|
||||||
"typeOf": typeOf,
|
"typeOf": typeOf,
|
||||||
@@ -243,7 +239,6 @@ var genericMap = map[string]interface{}{
|
|||||||
"pick": pick,
|
"pick": pick,
|
||||||
"omit": omit,
|
"omit": omit,
|
||||||
"merge": merge,
|
"merge": merge,
|
||||||
"values": values,
|
|
||||||
|
|
||||||
"append": push, "push": push,
|
"append": push, "push": push,
|
||||||
"prepend": prepend,
|
"prepend": prepend,
|
||||||
@@ -255,12 +250,10 @@ var genericMap = map[string]interface{}{
|
|||||||
"uniq": uniq,
|
"uniq": uniq,
|
||||||
"without": without,
|
"without": without,
|
||||||
"has": has,
|
"has": has,
|
||||||
"slice": slice,
|
|
||||||
|
|
||||||
// Crypto:
|
// Crypto:
|
||||||
"genPrivateKey": generatePrivateKey,
|
"genPrivateKey": generatePrivateKey,
|
||||||
"derivePassword": derivePassword,
|
"derivePassword": derivePassword,
|
||||||
"buildCustomCert": buildCustomCertificate,
|
|
||||||
"genCA": generateCertificateAuthority,
|
"genCA": generateCertificateAuthority,
|
||||||
"genSelfSignedCert": generateSelfSignedCertificate,
|
"genSelfSignedCert": generateSelfSignedCertificate,
|
||||||
"genSignedCert": generateSignedCertificate,
|
"genSignedCert": generateSignedCertificate,
|
||||||
|
|||||||
33
vendor/github.com/Masterminds/sprig/glide.lock
generated
vendored
33
vendor/github.com/Masterminds/sprig/glide.lock
generated
vendored
@@ -1,33 +0,0 @@
|
|||||||
hash: 770b6a1132b743dadf6a0bb5fb8bf7083b1a5209f6d6c07826234ab2a97aade9
|
|
||||||
updated: 2018-04-02T23:08:56.947456531+02:00
|
|
||||||
imports:
|
|
||||||
- name: github.com/aokoli/goutils
|
|
||||||
version: 9c37978a95bd5c709a15883b6242714ea6709e64
|
|
||||||
- name: github.com/google/uuid
|
|
||||||
version: 064e2069ce9c359c118179501254f67d7d37ba24
|
|
||||||
- name: github.com/huandu/xstrings
|
|
||||||
version: 3959339b333561bf62a38b424fd41517c2c90f40
|
|
||||||
- name: github.com/imdario/mergo
|
|
||||||
version: 7fe0c75c13abdee74b09fcacef5ea1c6bba6a874
|
|
||||||
- name: github.com/Masterminds/goutils
|
|
||||||
version: 3391d3790d23d03408670993e957e8f408993c34
|
|
||||||
- name: github.com/Masterminds/semver
|
|
||||||
version: 59c29afe1a994eacb71c833025ca7acf874bb1da
|
|
||||||
- name: github.com/stretchr/testify
|
|
||||||
version: e3a8ff8ce36581f87a15341206f205b1da467059
|
|
||||||
subpackages:
|
|
||||||
- assert
|
|
||||||
- name: golang.org/x/crypto
|
|
||||||
version: d172538b2cfce0c13cee31e647d0367aa8cd2486
|
|
||||||
subpackages:
|
|
||||||
- pbkdf2
|
|
||||||
- scrypt
|
|
||||||
testImports:
|
|
||||||
- name: github.com/davecgh/go-spew
|
|
||||||
version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
|
|
||||||
subpackages:
|
|
||||||
- spew
|
|
||||||
- name: github.com/pmezard/go-difflib
|
|
||||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
|
||||||
subpackages:
|
|
||||||
- difflib
|
|
||||||
15
vendor/github.com/Masterminds/sprig/glide.yaml
generated
vendored
15
vendor/github.com/Masterminds/sprig/glide.yaml
generated
vendored
@@ -1,15 +0,0 @@
|
|||||||
package: github.com/Masterminds/sprig
|
|
||||||
import:
|
|
||||||
- package: github.com/Masterminds/goutils
|
|
||||||
version: ^1.0.0
|
|
||||||
- package: github.com/google/uuid
|
|
||||||
version: ^0.2
|
|
||||||
- package: golang.org/x/crypto
|
|
||||||
subpackages:
|
|
||||||
- scrypt
|
|
||||||
- package: github.com/Masterminds/semver
|
|
||||||
version: v1.2.2
|
|
||||||
- package: github.com/stretchr/testify
|
|
||||||
- package: github.com/imdario/mergo
|
|
||||||
version: ~0.2.2
|
|
||||||
- package: github.com/huandu/xstrings
|
|
||||||
32
vendor/github.com/Masterminds/sprig/list.go
generated
vendored
32
vendor/github.com/Masterminds/sprig/list.go
generated
vendored
@@ -257,35 +257,3 @@ func has(needle interface{}, haystack interface{}) bool {
|
|||||||
panic(fmt.Sprintf("Cannot find has on type %s", tp))
|
panic(fmt.Sprintf("Cannot find has on type %s", tp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// $list := [1, 2, 3, 4, 5]
|
|
||||||
// slice $list -> list[0:5] = list[:]
|
|
||||||
// slice $list 0 3 -> list[0:3] = list[:3]
|
|
||||||
// slice $list 3 5 -> list[3:5]
|
|
||||||
// slice $list 3 -> list[3:5] = list[3:]
|
|
||||||
func slice(list interface{}, indices ...interface{}) interface{} {
|
|
||||||
tp := reflect.TypeOf(list).Kind()
|
|
||||||
switch tp {
|
|
||||||
case reflect.Slice, reflect.Array:
|
|
||||||
l2 := reflect.ValueOf(list)
|
|
||||||
|
|
||||||
l := l2.Len()
|
|
||||||
if l == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var start, end int
|
|
||||||
if len(indices) > 0 {
|
|
||||||
start = toInt(indices[0])
|
|
||||||
}
|
|
||||||
if len(indices) < 2 {
|
|
||||||
end = l
|
|
||||||
} else {
|
|
||||||
end = toInt(indices[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
return l2.Slice(start, end).Interface()
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("list should be type of slice or array but %s", tp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
9
vendor/github.com/Masterminds/sprig/strings.go
generated
vendored
9
vendor/github.com/Masterminds/sprig/strings.go
generated
vendored
@@ -183,15 +183,6 @@ func split(sep, orig string) map[string]string {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitn(sep string, n int, orig string) map[string]string {
|
|
||||||
parts := strings.SplitN(orig, sep, n)
|
|
||||||
res := make(map[string]string, len(parts))
|
|
||||||
for i, v := range parts {
|
|
||||||
res["_"+strconv.Itoa(i)] = v
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// substring creates a substring of the given string.
|
// substring creates a substring of the given string.
|
||||||
//
|
//
|
||||||
// If start is < 0, this calls string[:length].
|
// If start is < 0, this calls string[:length].
|
||||||
|
|||||||
18
vendor/github.com/aokoli/goutils/.travis.yml
generated
vendored
18
vendor/github.com/aokoli/goutils/.travis.yml
generated
vendored
@@ -1,18 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.6
|
|
||||||
- 1.7
|
|
||||||
- 1.8
|
|
||||||
- tip
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test -v
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
webhooks:
|
|
||||||
urls:
|
|
||||||
- https://webhooks.gitter.im/e/06e3328629952dabe3e0
|
|
||||||
on_success: change # options: [always|never|change] default: always
|
|
||||||
on_failure: always # options: [always|never|change] default: always
|
|
||||||
on_start: never # options: [always|never|change] default: always
|
|
||||||
8
vendor/github.com/aokoli/goutils/CHANGELOG.md
generated
vendored
8
vendor/github.com/aokoli/goutils/CHANGELOG.md
generated
vendored
@@ -1,8 +0,0 @@
|
|||||||
# 1.0.1 (2017-05-31)
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
- #21: Fix generation of alphanumeric strings (thanks @dbarranco)
|
|
||||||
|
|
||||||
# 1.0.0 (2014-04-30)
|
|
||||||
|
|
||||||
- Initial release.
|
|
||||||
70
vendor/github.com/aokoli/goutils/README.md
generated
vendored
70
vendor/github.com/aokoli/goutils/README.md
generated
vendored
@@ -1,70 +0,0 @@
|
|||||||
GoUtils
|
|
||||||
===========
|
|
||||||
[](https://masterminds.github.io/stability/maintenance.html)
|
|
||||||
[](https://godoc.org/github.com/Masterminds/goutils) [](https://travis-ci.org/Masterminds/goutils) [](https://ci.appveyor.com/project/mattfarina/goutils)
|
|
||||||
|
|
||||||
|
|
||||||
GoUtils provides users with utility functions to manipulate strings in various ways. It is a Go implementation of some
|
|
||||||
string manipulation libraries of Java Apache Commons. GoUtils includes the following Java Apache Commons classes:
|
|
||||||
* WordUtils
|
|
||||||
* RandomStringUtils
|
|
||||||
* StringUtils (partial implementation)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
If you have Go set up on your system, from the GOPATH directory within the command line/terminal, enter this:
|
|
||||||
|
|
||||||
go get github.com/Masterminds/goutils
|
|
||||||
|
|
||||||
If you do not have Go set up on your system, please follow the [Go installation directions from the documenation](http://golang.org/doc/install), and then follow the instructions above to install GoUtils.
|
|
||||||
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
GoUtils doc is available here: [](https://godoc.org/github.com/Masterminds/goutils)
|
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
The code snippets below show examples of how to use GoUtils. Some functions return errors while others do not. The first instance below, which does not return an error, is the `Initials` function (located within the `wordutils.go` file).
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/Masterminds/goutils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
// EXAMPLE 1: A goutils function which returns no errors
|
|
||||||
fmt.Println (goutils.Initials("John Doe Foo")) // Prints out "JDF"
|
|
||||||
|
|
||||||
}
|
|
||||||
Some functions return errors mainly due to illegal arguements used as parameters. The code example below illustrates how to deal with function that returns an error. In this instance, the function is the `Random` function (located within the `randomstringutils.go` file).
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/Masterminds/goutils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
// EXAMPLE 2: A goutils function which returns an error
|
|
||||||
rand1, err1 := goutils.Random (-1, 0, 0, true, true)
|
|
||||||
|
|
||||||
if err1 != nil {
|
|
||||||
fmt.Println(err1) // Prints out error message because -1 was entered as the first parameter in goutils.Random(...)
|
|
||||||
} else {
|
|
||||||
fmt.Println(rand1)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
## License
|
|
||||||
GoUtils is licensed under the Apache License, Version 2.0. Please check the LICENSE.txt file or visit http://www.apache.org/licenses/LICENSE-2.0 for a copy of the license.
|
|
||||||
|
|
||||||
## Issue Reporting
|
|
||||||
Make suggestions or report issues using the Git issue tracker: https://github.com/Masterminds/goutils/issues
|
|
||||||
|
|
||||||
## Website
|
|
||||||
* [GoUtils webpage](http://Masterminds.github.io/goutils/)
|
|
||||||
21
vendor/github.com/aokoli/goutils/appveyor.yml
generated
vendored
21
vendor/github.com/aokoli/goutils/appveyor.yml
generated
vendored
@@ -1,21 +0,0 @@
|
|||||||
version: build-{build}.{branch}
|
|
||||||
|
|
||||||
clone_folder: C:\gopath\src\github.com\Masterminds\goutils
|
|
||||||
shallow_clone: true
|
|
||||||
|
|
||||||
environment:
|
|
||||||
GOPATH: C:\gopath
|
|
||||||
|
|
||||||
platform:
|
|
||||||
- x64
|
|
||||||
|
|
||||||
build: off
|
|
||||||
|
|
||||||
install:
|
|
||||||
- go version
|
|
||||||
- go env
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- go test -v
|
|
||||||
|
|
||||||
deploy: off
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user