mirror of
https://github.com/go-task/task.git
synced 2025-08-10 22:42:19 +02:00
Merge branch 'go-task:master' into configurable_watch_interval_#813
This commit is contained in:
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,5 +1,21 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
- Add support to marking tasks and includes as internal, which will hide them
|
||||||
|
from `--list` and `--list-all`
|
||||||
|
([#818](https://github.com/go-task/task/pull/818)).
|
||||||
|
|
||||||
|
## v3.15.2 - 2022-09-08
|
||||||
|
|
||||||
|
- Fix error when using variable in `env:` introduced in the previous release
|
||||||
|
([#858](https://github.com/go-task/task/issues/858), [#866](https://github.com/go-task/task/pull/866)).
|
||||||
|
- Fix handling of `CLI_ARGS` (`--`) in Bash completion
|
||||||
|
([#863](https://github.com/go-task/task/pull/863)).
|
||||||
|
- On zsh completion, add ability to replace `--list-all` with `--list` as
|
||||||
|
already possible on the Bash completion
|
||||||
|
([#861](https://github.com/go-task/task/pull/861)).
|
||||||
|
|
||||||
## v3.15.0 - 2022-09-03
|
## v3.15.0 - 2022-09-03
|
||||||
|
|
||||||
- Add new special variables `ROOT_DIR` and `TASKFILE_DIR`. This was a highly
|
- Add new special variables `ROOT_DIR` and `TASKFILE_DIR`. This was a highly
|
||||||
|
13
Taskfile.yml
13
Taskfile.yml
@@ -80,6 +80,19 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- goreleaser --snapshot --rm-dist
|
- goreleaser --snapshot --rm-dist
|
||||||
|
|
||||||
|
docs:changelog:
|
||||||
|
desc: Copy CHANGELOG.md to the documentation website
|
||||||
|
vars:
|
||||||
|
FILE: docs/docs/changelog.md
|
||||||
|
cmds:
|
||||||
|
- rm {{.FILE}}
|
||||||
|
- 'echo "---" >> {{.FILE}}'
|
||||||
|
- 'echo "slug: /changelog/" >> {{.FILE}}'
|
||||||
|
- 'echo "sidebar_position: 6" >> {{.FILE}}'
|
||||||
|
- 'echo "---" >> {{.FILE}}'
|
||||||
|
- 'echo "" >> {{.FILE}}'
|
||||||
|
- 'cat CHANGELOG.md >> {{.FILE}}'
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
cmds:
|
cmds:
|
||||||
- echo '{{.GO_PACKAGES}}'
|
- echo '{{.GO_PACKAGES}}'
|
||||||
|
@@ -7,6 +7,18 @@ function _task()
|
|||||||
local cur prev words cword
|
local cur prev words cword
|
||||||
_init_completion -n : || return
|
_init_completion -n : || return
|
||||||
|
|
||||||
|
# Check for `--` within command-line and quit or strip suffix.
|
||||||
|
local i
|
||||||
|
for i in "${!words[@]}"; do
|
||||||
|
if [ "${words[$i]}" == "--" ]; then
|
||||||
|
# Do not complete words following `--` passed to CLI_ARGS.
|
||||||
|
[ $cword -gt $i ] && return
|
||||||
|
# Remove the words following `--` to not put --list in CLI_ARGS.
|
||||||
|
words=( "${words[@]:0:$i}" )
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# Handle special arguments of options.
|
# Handle special arguments of options.
|
||||||
case "$prev" in
|
case "$prev" in
|
||||||
-d|--dir)
|
-d|--dir)
|
||||||
@@ -33,7 +45,7 @@ function _task()
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
# Prepare task name completions.
|
# Prepare task name completions.
|
||||||
local tasks=( $( "${COMP_WORDS[@]}" --silent $_GO_TASK_COMPLETION_LIST_OPTION 2> /dev/null ) )
|
local tasks=( $( "${words[@]}" --silent $_GO_TASK_COMPLETION_LIST_OPTION 2> /dev/null ) )
|
||||||
COMPREPLY=( $( compgen -W "${tasks[*]}" -- "$cur" ) )
|
COMPREPLY=( $( compgen -W "${tasks[*]}" -- "$cur" ) )
|
||||||
|
|
||||||
# Post-process because task names might contain colons.
|
# Post-process because task names might contain colons.
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
local context state state_descr line
|
local context state state_descr line
|
||||||
typeset -A opt_args
|
typeset -A opt_args
|
||||||
|
|
||||||
|
_GO_TASK_COMPLETION_LIST_OPTION="${GO_TASK_COMPLETION_LIST_OPTION:---list-all}"
|
||||||
|
|
||||||
# Listing commands from Taskfile.yml
|
# Listing commands from Taskfile.yml
|
||||||
function __task_list() {
|
function __task_list() {
|
||||||
local -a scripts cmd
|
local -a scripts cmd
|
||||||
@@ -27,7 +29,7 @@ function __task_list() {
|
|||||||
(( enabled )) || return 0
|
(( enabled )) || return 0
|
||||||
|
|
||||||
scripts=()
|
scripts=()
|
||||||
for item in "${(@)${(f)$("${cmd[@]}" --list-all)}[2,-1]#\* }"; do
|
for item in "${(@)${(f)$("${cmd[@]}" $_GO_TASK_COMPLETION_LIST_OPTION)}[2,-1]#\* }"; do
|
||||||
task="${item%%:[[:space:]]*}"
|
task="${item%%:[[:space:]]*}"
|
||||||
desc="${item##[^[:space:]]##[[:space:]]##}"
|
desc="${item##[^[:space:]]##[[:space:]]##}"
|
||||||
scripts+=( "${task//:/\\:}:$desc" )
|
scripts+=( "${task//:/\\:}:$desc" )
|
||||||
|
@@ -97,6 +97,7 @@ Some environment variables can be overriden to adjust Task behavior.
|
|||||||
| `taskfile` | `string` | | The path for the Taskfile or directory to be included. If a directory, Task will look for files named `Taskfile.yml` or `Taskfile.yaml` inside that directory. If a relative path, resolved relative to the directory containing the including Taskfile. |
|
| `taskfile` | `string` | | The path for the Taskfile or directory to be included. If a directory, Task will look for files named `Taskfile.yml` or `Taskfile.yaml` inside that directory. If a relative path, resolved relative to the directory containing the including Taskfile. |
|
||||||
| `dir` | `string` | The parent Taskfile directory | The working directory of the included tasks when run. |
|
| `dir` | `string` | The parent Taskfile directory | The working directory of the included tasks when run. |
|
||||||
| `optional` | `bool` | `false` | If `true`, no errors will be thrown if the specified file does not exist. |
|
| `optional` | `bool` | `false` | If `true`, no errors will be thrown if the specified file does not exist. |
|
||||||
|
| `internal` | `bool` | `false` | If `true`, tasks will be omitted from both `--list` and `--list-all`. |
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
|
|
||||||
@@ -119,6 +120,7 @@ includes:
|
|||||||
| `dir` | `string` | | The current directory which this task should run. |
|
| `dir` | `string` | | The current directory which this task should run. |
|
||||||
| `method` | `string` | `checksum` | Method used by this task. Default to the one declared globally or `checksum`. Available options: `checksum`, `timestamp` and `none` |
|
| `method` | `string` | `checksum` | Method used by this task. Default to the one declared globally or `checksum`. Available options: `checksum`, `timestamp` and `none` |
|
||||||
| `silent` | `bool` | `false` | Skips some output for this task. Note that STDOUT and STDERR of the commands will still be redirected. |
|
| `silent` | `bool` | `false` | Skips some output for this task. Note that STDOUT and STDERR of the commands will still be redirected. |
|
||||||
|
| `internal` | `bool` | `false` | If `true`, omit this task from both `--list` and `--list-all`. |
|
||||||
| `run` | `string` | The one declared globally in the Taskfile or `always` | Specifies whether the task should run again or not if called more than once. Available options: `always`, `once` and `when_changed`. |
|
| `run` | `string` | The one declared globally in the Taskfile or `always` | Specifies whether the task should run again or not if called more than once. Available options: `always`, `once` and `when_changed`. |
|
||||||
| `prefix` | `string` | | Allows to override the prefix print before the STDOUT. Only relevant when using the `prefixed` output mode. |
|
| `prefix` | `string` | | Allows to override the prefix print before the STDOUT. Only relevant when using the `prefixed` output mode. |
|
||||||
| `ignore_error` | `bool` | `false` | Continue execution if errors happen while executing the commands. |
|
| `ignore_error` | `bool` | `false` | Continue execution if errors happen while executing the commands. |
|
||||||
|
@@ -5,6 +5,16 @@ sidebar_position: 6
|
|||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v3.15.2 - 2022-09-08
|
||||||
|
|
||||||
|
- Fix error when using variable in `env:` introduced in the previous release
|
||||||
|
([#858](https://github.com/go-task/task/issues/858), [#866](https://github.com/go-task/task/pull/866)).
|
||||||
|
- Fix handling of `CLI_ARGS` (`--`) in Bash completion
|
||||||
|
([#863](https://github.com/go-task/task/pull/863)).
|
||||||
|
- On zsh completion, add ability to replace `--list-all` with `--list` as
|
||||||
|
already possible on the Bash completion
|
||||||
|
([#861](https://github.com/go-task/task/pull/861)).
|
||||||
|
|
||||||
## v3.15.0 - 2022-09-03
|
## v3.15.0 - 2022-09-03
|
||||||
|
|
||||||
- Add new special variables `ROOT_DIR` and `TASKFILE_DIR`. This was a highly
|
- Add new special variables `ROOT_DIR` and `TASKFILE_DIR`. This was a highly
|
||||||
|
@@ -194,6 +194,22 @@ tasks:
|
|||||||
- echo "This command can still be successfully executed if ./tests/Taskfile.yml does not exist"
|
- echo "This command can still be successfully executed if ./tests/Taskfile.yml does not exist"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Internal includes
|
||||||
|
|
||||||
|
Includes marked as internal will set all the tasks of the included file to be
|
||||||
|
internal as well (see the [Internal tasks](#internal-tasks) section below).
|
||||||
|
This is useful when including utility tasks that are not intended to be used
|
||||||
|
directly by the user.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
includes:
|
||||||
|
tests:
|
||||||
|
taskfile: ./taskfiles/Utils.yml
|
||||||
|
internal: true
|
||||||
|
```
|
||||||
|
|
||||||
### Vars of included Taskfiles
|
### Vars of included Taskfiles
|
||||||
|
|
||||||
You can also specify variables when including a Taskfile. This may be useful
|
You can also specify variables when including a Taskfile. This may be useful
|
||||||
@@ -223,6 +239,29 @@ use the [default function](https://go-task.github.io/slim-sprig/defaults.html):
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
## Internal tasks
|
||||||
|
|
||||||
|
Internal tasks are tasks that cannot be called directly by the user. They will
|
||||||
|
not appear in the output when running `task --list|--list-all`. Other tasks may
|
||||||
|
call internal tasks in the usual way. This is useful for creating reusable,
|
||||||
|
function-like tasks that have no useful purpose on the command line.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build-image-1:
|
||||||
|
cmds:
|
||||||
|
- task: build-image
|
||||||
|
vars:
|
||||||
|
DOCKER_IMAGE: image-1
|
||||||
|
|
||||||
|
build-image:
|
||||||
|
internal: true
|
||||||
|
cmds:
|
||||||
|
- docker build -t {{.DOCKER_IMAGE}} .
|
||||||
|
```
|
||||||
|
|
||||||
## Task directory
|
## Task directory
|
||||||
|
|
||||||
By default, tasks will be executed in the directory where the Taskfile is
|
By default, tasks will be executed in the directory where the Taskfile is
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
// Note: type annotations allow type checking and IDEs autocompletion
|
// Note: type annotations allow type checking and IDEs autocompletion
|
||||||
|
|
||||||
const lightCodeTheme = require('prism-react-renderer/themes/github');
|
const lightCodeTheme = require('./src/themes/prismLight');
|
||||||
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
|
const darkCodeTheme = require('./src/themes/prismDark');
|
||||||
|
|
||||||
const GITHUB_URL = 'https://github.com/go-task/task';
|
const GITHUB_URL = 'https://github.com/go-task/task';
|
||||||
const TWITTER_URL = 'https://twitter.com/taskfiledev';
|
const TWITTER_URL = 'https://twitter.com/taskfiledev';
|
||||||
|
79
docs/src/themes/prismDark.js
Normal file
79
docs/src/themes/prismDark.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const darkTheme = require('prism-react-renderer/themes/vsDark/index.cjs.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plain: {
|
||||||
|
color: '#D4D4D4',
|
||||||
|
backgroundColor: '#212121'
|
||||||
|
},
|
||||||
|
styles: [
|
||||||
|
...darkTheme.styles,
|
||||||
|
{
|
||||||
|
types: ['title'],
|
||||||
|
style: {
|
||||||
|
color: '#569CD6',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['property', 'parameter'],
|
||||||
|
style: {
|
||||||
|
color: '#9CDCFE'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['script'],
|
||||||
|
style: {
|
||||||
|
color: '#D4D4D4'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['boolean', 'arrow', 'atrule', 'tag'],
|
||||||
|
style: {
|
||||||
|
color: '#569CD6'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['number', 'color', 'unit'],
|
||||||
|
style: {
|
||||||
|
color: '#B5CEA8'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['font-matter'],
|
||||||
|
style: {
|
||||||
|
color: '#CE9178'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['keyword', 'rule'],
|
||||||
|
style: {
|
||||||
|
color: '#C586C0'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['regex'],
|
||||||
|
style: {
|
||||||
|
color: '#D16969'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['maybe-class-name'],
|
||||||
|
style: {
|
||||||
|
color: '#4EC9B0'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['constant'],
|
||||||
|
style: {
|
||||||
|
color: '#4FC1FF'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
100
docs/src/themes/prismLight.js
Normal file
100
docs/src/themes/prismLight.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const lightTheme = require('prism-react-renderer/themes/github/index.cjs.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
...lightTheme,
|
||||||
|
styles: [
|
||||||
|
...lightTheme.styles,
|
||||||
|
{
|
||||||
|
types: ['title'],
|
||||||
|
style: {
|
||||||
|
color: '#0550AE',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['parameter'],
|
||||||
|
style: {
|
||||||
|
color: '#953800'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['boolean', 'rule', 'color', 'number', 'constant', 'property'],
|
||||||
|
style: {
|
||||||
|
color: '#005CC5'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['atrule', 'tag'],
|
||||||
|
style: {
|
||||||
|
color: '#22863A'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['script'],
|
||||||
|
style: {
|
||||||
|
color: '#24292E'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['operator', 'unit', 'rule'],
|
||||||
|
style: {
|
||||||
|
color: '#D73A49'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['font-matter', 'string', 'attr-value'],
|
||||||
|
style: {
|
||||||
|
color: '#C6105F'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['class-name'],
|
||||||
|
style: {
|
||||||
|
color: '#116329'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['attr-name'],
|
||||||
|
style: {
|
||||||
|
color: '#0550AE'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['keyword'],
|
||||||
|
style: {
|
||||||
|
color: '#CF222E'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['function'],
|
||||||
|
style: {
|
||||||
|
color: '#8250DF'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['selector'],
|
||||||
|
style: {
|
||||||
|
color: '#6F42C1'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['variable'],
|
||||||
|
style: {
|
||||||
|
color: '#E36209'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
types: ['comment'],
|
||||||
|
style: {
|
||||||
|
color: '#6B6B6B'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
BIN
docs/static/img/og-image.png
vendored
BIN
docs/static/img/og-image.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 27 KiB |
15
docs/static/js/carbon.js
vendored
15
docs/static/js/carbon.js
vendored
@@ -1,6 +1,6 @@
|
|||||||
(function () {
|
(function () {
|
||||||
function attachAd() {
|
function attachAd() {
|
||||||
const el = document.createElement('script');
|
var el = document.createElement('script');
|
||||||
el.setAttribute('type', 'text/javascript');
|
el.setAttribute('type', 'text/javascript');
|
||||||
el.setAttribute('id', '_carbonads_js');
|
el.setAttribute('id', '_carbonads_js');
|
||||||
el.setAttribute(
|
el.setAttribute(
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
);
|
);
|
||||||
el.setAttribute('async', 'async');
|
el.setAttribute('async', 'async');
|
||||||
|
|
||||||
const wrapper = document.getElementById('sidebar-ads');
|
var wrapper = document.getElementById('sidebar-ads');
|
||||||
wrapper.innerHTML = '';
|
wrapper.innerHTML = '';
|
||||||
wrapper.appendChild(el);
|
wrapper.appendChild(el);
|
||||||
}
|
}
|
||||||
@@ -17,8 +17,13 @@
|
|||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
attachAd();
|
attachAd();
|
||||||
|
|
||||||
window.addEventListener('popstate', function () {
|
var currentPath = window.location.pathname;
|
||||||
attachAd();
|
|
||||||
});
|
setInterval(function () {
|
||||||
|
if (currentPath !== window.location.pathname) {
|
||||||
|
currentPath = window.location.pathname;
|
||||||
|
attachAd();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
})();
|
})();
|
||||||
|
@@ -20,6 +20,14 @@ func (err *taskNotFoundError) Error() string {
|
|||||||
return fmt.Sprintf(`task: Task %q not found`, err.taskName)
|
return fmt.Sprintf(`task: Task %q not found`, err.taskName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type taskInternalError struct {
|
||||||
|
taskName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err *taskInternalError) Error() string {
|
||||||
|
return fmt.Sprintf(`task: Task "%s" is internal`, err.taskName)
|
||||||
|
}
|
||||||
|
|
||||||
type TaskRunError struct {
|
type TaskRunError struct {
|
||||||
taskName string
|
taskName string
|
||||||
err error
|
err error
|
||||||
|
8
help.go
8
help.go
@@ -52,7 +52,9 @@ func (e *Executor) printTasks(listAll bool) {
|
|||||||
func (e *Executor) allTaskNames() (tasks []*taskfile.Task) {
|
func (e *Executor) allTaskNames() (tasks []*taskfile.Task) {
|
||||||
tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
|
tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
|
||||||
for _, task := range e.Taskfile.Tasks {
|
for _, task := range e.Taskfile.Tasks {
|
||||||
tasks = append(tasks, task)
|
if !task.Internal {
|
||||||
|
tasks = append(tasks, task)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sort.Slice(tasks, func(i, j int) bool { return tasks[i].Task < tasks[j].Task })
|
sort.Slice(tasks, func(i, j int) bool { return tasks[i].Task < tasks[j].Task })
|
||||||
return
|
return
|
||||||
@@ -61,7 +63,7 @@ func (e *Executor) allTaskNames() (tasks []*taskfile.Task) {
|
|||||||
func (e *Executor) tasksWithDesc() (tasks []*taskfile.Task) {
|
func (e *Executor) tasksWithDesc() (tasks []*taskfile.Task) {
|
||||||
tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
|
tasks = make([]*taskfile.Task, 0, len(e.Taskfile.Tasks))
|
||||||
for _, task := range e.Taskfile.Tasks {
|
for _, task := range e.Taskfile.Tasks {
|
||||||
if task.Desc != "" {
|
if !task.Internal && task.Desc != "" {
|
||||||
compiledTask, err := e.FastCompiledTask(taskfile.Call{Task: task.Task})
|
compiledTask, err := e.FastCompiledTask(taskfile.Call{Task: task.Task})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
task = compiledTask
|
task = compiledTask
|
||||||
@@ -92,7 +94,7 @@ func (e *Executor) ListTaskNames(allTasks bool) {
|
|||||||
// create a string slice from all map values (*taskfile.Task)
|
// create a string slice from all map values (*taskfile.Task)
|
||||||
s := make([]string, 0, len(e.Taskfile.Tasks))
|
s := make([]string, 0, len(e.Taskfile.Tasks))
|
||||||
for _, t := range e.Taskfile.Tasks {
|
for _, t := range e.Taskfile.Tasks {
|
||||||
if allTasks || t.Desc != "" {
|
if (allTasks || t.Desc != "") && !t.Internal {
|
||||||
s = append(s, strings.TrimRight(t.Task, ":"))
|
s = append(s, strings.TrimRight(t.Task, ":"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
task.go
7
task.go
@@ -65,11 +65,16 @@ type Executor struct {
|
|||||||
func (e *Executor) Run(ctx context.Context, calls ...taskfile.Call) error {
|
func (e *Executor) Run(ctx context.Context, calls ...taskfile.Call) error {
|
||||||
// check if given tasks exist
|
// check if given tasks exist
|
||||||
for _, c := range calls {
|
for _, c := range calls {
|
||||||
if _, ok := e.Taskfile.Tasks[c.Task]; !ok {
|
t, ok := e.Taskfile.Tasks[c.Task]
|
||||||
|
if !ok {
|
||||||
// FIXME: move to the main package
|
// FIXME: move to the main package
|
||||||
e.ListTasksWithDesc()
|
e.ListTasksWithDesc()
|
||||||
return &taskNotFoundError{taskName: c.Task}
|
return &taskNotFoundError{taskName: c.Task}
|
||||||
}
|
}
|
||||||
|
if t.Internal {
|
||||||
|
e.ListTasksWithDesc()
|
||||||
|
return &taskInternalError{taskName: c.Task}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Summary {
|
if e.Summary {
|
||||||
|
80
task_test.go
80
task_test.go
@@ -959,6 +959,86 @@ func TestIncludesRelativePath(t *testing.T) {
|
|||||||
assert.Contains(t, buff.String(), "testdata/includes_rel_path/common")
|
assert.Contains(t, buff.String(), "testdata/includes_rel_path/common")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIncludesInternal(t *testing.T) {
|
||||||
|
const dir = "testdata/internal_task"
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
task string
|
||||||
|
expectedErr bool
|
||||||
|
expectedOutput string
|
||||||
|
}{
|
||||||
|
{"included internal task via task", "task-1", false, "Hello, World!\n"},
|
||||||
|
{"included internal task via dep", "task-2", false, "Hello, World!\n"},
|
||||||
|
{
|
||||||
|
"included internal direct",
|
||||||
|
"included:task-3",
|
||||||
|
true,
|
||||||
|
"task: No tasks with description available. Try --list-all to list all tasks\n",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
var buff bytes.Buffer
|
||||||
|
e := task.Executor{
|
||||||
|
Dir: dir,
|
||||||
|
Stdout: &buff,
|
||||||
|
Stderr: &buff,
|
||||||
|
Silent: true,
|
||||||
|
}
|
||||||
|
assert.NoError(t, e.Setup())
|
||||||
|
|
||||||
|
err := e.Run(context.Background(), taskfile.Call{Task: test.task})
|
||||||
|
if test.expectedErr {
|
||||||
|
assert.Error(t, err, test.expectedErr)
|
||||||
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, test.expectedOutput, buff.String())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInternalTask(t *testing.T) {
|
||||||
|
const dir = "testdata/internal_task"
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
task string
|
||||||
|
expectedErr bool
|
||||||
|
expectedOutput string
|
||||||
|
}{
|
||||||
|
{"internal task via task", "task-1", false, "Hello, World!\n"},
|
||||||
|
{"internal task via dep", "task-2", false, "Hello, World!\n"},
|
||||||
|
{
|
||||||
|
"internal direct",
|
||||||
|
"task-3",
|
||||||
|
true,
|
||||||
|
"task: No tasks with description available. Try --list-all to list all tasks\n",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
var buff bytes.Buffer
|
||||||
|
e := task.Executor{
|
||||||
|
Dir: dir,
|
||||||
|
Stdout: &buff,
|
||||||
|
Stderr: &buff,
|
||||||
|
Silent: true,
|
||||||
|
}
|
||||||
|
assert.NoError(t, e.Setup())
|
||||||
|
|
||||||
|
err := e.Run(context.Background(), taskfile.Call{Task: test.task})
|
||||||
|
if test.expectedErr {
|
||||||
|
assert.Error(t, err, test.expectedErr)
|
||||||
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, test.expectedOutput, buff.String())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSupportedFileNames(t *testing.T) {
|
func TestSupportedFileNames(t *testing.T) {
|
||||||
fileNames := []string{
|
fileNames := []string{
|
||||||
"Taskfile.yml",
|
"Taskfile.yml",
|
||||||
|
@@ -16,6 +16,7 @@ type IncludedTaskfile struct {
|
|||||||
Taskfile string
|
Taskfile string
|
||||||
Dir string
|
Dir string
|
||||||
Optional bool
|
Optional bool
|
||||||
|
Internal bool
|
||||||
AdvancedImport bool
|
AdvancedImport bool
|
||||||
Vars *Vars
|
Vars *Vars
|
||||||
BaseDir string // The directory from which the including taskfile was loaded; used to resolve relative paths
|
BaseDir string // The directory from which the including taskfile was loaded; used to resolve relative paths
|
||||||
@@ -101,6 +102,7 @@ func (it *IncludedTaskfile) UnmarshalYAML(unmarshal func(interface{}) error) err
|
|||||||
Taskfile string
|
Taskfile string
|
||||||
Dir string
|
Dir string
|
||||||
Optional bool
|
Optional bool
|
||||||
|
Internal bool
|
||||||
Vars *Vars
|
Vars *Vars
|
||||||
}
|
}
|
||||||
if err := unmarshal(&includedTaskfile); err != nil {
|
if err := unmarshal(&includedTaskfile); err != nil {
|
||||||
@@ -109,6 +111,7 @@ func (it *IncludedTaskfile) UnmarshalYAML(unmarshal func(interface{}) error) err
|
|||||||
it.Taskfile = includedTaskfile.Taskfile
|
it.Taskfile = includedTaskfile.Taskfile
|
||||||
it.Dir = includedTaskfile.Dir
|
it.Dir = includedTaskfile.Dir
|
||||||
it.Optional = includedTaskfile.Optional
|
it.Optional = includedTaskfile.Optional
|
||||||
|
it.Internal = includedTaskfile.Internal
|
||||||
it.AdvancedImport = true
|
it.AdvancedImport = true
|
||||||
it.Vars = includedTaskfile.Vars
|
it.Vars = includedTaskfile.Vars
|
||||||
return nil
|
return nil
|
||||||
|
@@ -9,7 +9,7 @@ import (
|
|||||||
const NamespaceSeparator = ":"
|
const NamespaceSeparator = ":"
|
||||||
|
|
||||||
// Merge merges the second Taskfile into the first
|
// Merge merges the second Taskfile into the first
|
||||||
func Merge(t1, t2 *Taskfile, namespaces ...string) error {
|
func Merge(t1, t2 *Taskfile, internal bool, namespaces ...string) error {
|
||||||
if t1.Version != t2.Version {
|
if t1.Version != t2.Version {
|
||||||
return fmt.Errorf(`task: Taskfiles versions should match. First is "%s" but second is "%s"`, t1.Version, t2.Version)
|
return fmt.Errorf(`task: Taskfiles versions should match. First is "%s" but second is "%s"`, t1.Version, t2.Version)
|
||||||
}
|
}
|
||||||
@@ -43,6 +43,8 @@ func Merge(t1, t2 *Taskfile, namespaces ...string) error {
|
|||||||
// have serious side-effects in the future, since we're editing
|
// have serious side-effects in the future, since we're editing
|
||||||
// the original references instead of deep copying them.
|
// the original references instead of deep copying them.
|
||||||
|
|
||||||
|
v.Internal = v.Internal || internal
|
||||||
|
|
||||||
t1.Tasks[taskNameWithNamespace(k, namespaces...)] = v
|
t1.Tasks[taskNameWithNamespace(k, namespaces...)] = v
|
||||||
|
|
||||||
for _, dep := range v.Deps {
|
for _, dep := range v.Deps {
|
||||||
|
@@ -27,6 +27,9 @@ func Dotenv(c compiler.Compiler, tf *taskfile.Taskfile, dir string) (*taskfile.V
|
|||||||
|
|
||||||
for _, dotEnvPath := range tf.Dotenv {
|
for _, dotEnvPath := range tf.Dotenv {
|
||||||
dotEnvPath = tr.Replace(dotEnvPath)
|
dotEnvPath = tr.Replace(dotEnvPath)
|
||||||
|
if dotEnvPath == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
dotEnvPath = filepathext.SmartJoin(dir, dotEnvPath)
|
dotEnvPath = filepathext.SmartJoin(dir, dotEnvPath)
|
||||||
|
|
||||||
if _, err := os.Stat(dotEnvPath); os.IsNotExist(err) {
|
if _, err := os.Stat(dotEnvPath); os.IsNotExist(err) {
|
||||||
|
@@ -78,6 +78,7 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, error) {
|
|||||||
Taskfile: tr.Replace(includedTask.Taskfile),
|
Taskfile: tr.Replace(includedTask.Taskfile),
|
||||||
Dir: tr.Replace(includedTask.Dir),
|
Dir: tr.Replace(includedTask.Dir),
|
||||||
Optional: includedTask.Optional,
|
Optional: includedTask.Optional,
|
||||||
|
Internal: includedTask.Internal,
|
||||||
AdvancedImport: includedTask.AdvancedImport,
|
AdvancedImport: includedTask.AdvancedImport,
|
||||||
Vars: includedTask.Vars,
|
Vars: includedTask.Vars,
|
||||||
BaseDir: includedTask.BaseDir,
|
BaseDir: includedTask.BaseDir,
|
||||||
@@ -148,7 +149,7 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = taskfile.Merge(t, includedTaskfile, namespace); err != nil {
|
if err = taskfile.Merge(t, includedTaskfile, includedTask.Internal, namespace); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -164,7 +165,7 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err = taskfile.Merge(t, osTaskfile); err != nil {
|
if err = taskfile.Merge(t, osTaskfile, false); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ type Task struct {
|
|||||||
Env *Vars
|
Env *Vars
|
||||||
Silent bool
|
Silent bool
|
||||||
Interactive bool
|
Interactive bool
|
||||||
|
Internal bool
|
||||||
Method string
|
Method string
|
||||||
Prefix string
|
Prefix string
|
||||||
IgnoreError bool
|
IgnoreError bool
|
||||||
@@ -64,6 +65,7 @@ func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
Env *Vars
|
Env *Vars
|
||||||
Silent bool
|
Silent bool
|
||||||
Interactive bool
|
Interactive bool
|
||||||
|
Internal bool
|
||||||
Method string
|
Method string
|
||||||
Prefix string
|
Prefix string
|
||||||
IgnoreError bool `yaml:"ignore_error"`
|
IgnoreError bool `yaml:"ignore_error"`
|
||||||
@@ -86,6 +88,7 @@ func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
t.Env = task.Env
|
t.Env = task.Env
|
||||||
t.Silent = task.Silent
|
t.Silent = task.Silent
|
||||||
t.Interactive = task.Interactive
|
t.Interactive = task.Interactive
|
||||||
|
t.Internal = task.Internal
|
||||||
t.Method = task.Method
|
t.Method = task.Method
|
||||||
t.Prefix = task.Prefix
|
t.Prefix = task.Prefix
|
||||||
t.IgnoreError = task.IgnoreError
|
t.IgnoreError = task.IgnoreError
|
||||||
|
15
testdata/includes_internal/Taskfile.yml
vendored
Normal file
15
testdata/includes_internal/Taskfile.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
includes:
|
||||||
|
included:
|
||||||
|
taskfile: Taskfile2.yml
|
||||||
|
internal: true
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
task-1:
|
||||||
|
cmds:
|
||||||
|
- task: included:default
|
||||||
|
|
||||||
|
task-2:
|
||||||
|
deps:
|
||||||
|
- included:default
|
6
testdata/includes_internal/Taskfile2.yml
vendored
Normal file
6
testdata/includes_internal/Taskfile2.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
task-3:
|
||||||
|
cmds:
|
||||||
|
- echo "Hello, World!"
|
15
testdata/internal_task/Taskfile.yml
vendored
Normal file
15
testdata/internal_task/Taskfile.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
task-1:
|
||||||
|
cmds:
|
||||||
|
- task: task-3
|
||||||
|
|
||||||
|
task-2:
|
||||||
|
deps:
|
||||||
|
- task-3
|
||||||
|
|
||||||
|
task-3:
|
||||||
|
internal: true
|
||||||
|
cmds:
|
||||||
|
- echo "Hello, World!"
|
@@ -57,6 +57,7 @@ func (e *Executor) compiledTask(call taskfile.Call, evaluateShVars bool) (*taskf
|
|||||||
Env: nil,
|
Env: nil,
|
||||||
Silent: origTask.Silent,
|
Silent: origTask.Silent,
|
||||||
Interactive: origTask.Interactive,
|
Interactive: origTask.Interactive,
|
||||||
|
Internal: origTask.Internal,
|
||||||
Method: r.Replace(origTask.Method),
|
Method: r.Replace(origTask.Method),
|
||||||
Prefix: r.Replace(origTask.Prefix),
|
Prefix: r.Replace(origTask.Prefix),
|
||||||
IgnoreError: origTask.IgnoreError,
|
IgnoreError: origTask.IgnoreError,
|
||||||
|
Reference in New Issue
Block a user