Compare commits

...

11 Commits

Author SHA1 Message Date
Andrey Nering
47d3011c85 v3.2.2 2021-01-12 13:21:36 -03:00
Andrey Nering
cec713a47a Update CHANGELOG 2021-01-12 12:09:03 -03:00
Andrey Nering
bf6d0c0a74 Improve performance of --list and --summary flags
Closes #332
2021-01-12 12:03:04 -03:00
Andrey Nering
c11672fca3 Envs should be overridable
System-wide environment variable should have priority. That's how it
works for .env files, so this is consistent.

Closes #425
2021-01-12 11:32:49 -03:00
Andrey Nering
e086b654aa Environment from .env file should be available as variables
Fixes #379
2021-01-12 11:11:40 -03:00
Andrey Nering
1107f691ea Update install script
Closes #428

Co-authored-by: odidev <odidev@puresoftware.com>
2021-01-12 10:43:45 -03:00
Andrey Nering
b095ca5756 v3.2.1 2021-01-09 13:57:20 -03:00
Andrey Nering
4afc0e8ed0 Fixed some bugs and regressions regarding dynamic variables and directories
Closes #426
2021-01-09 13:51:06 -03:00
Andrey Nering
141b377b4e Partly revert 59d2733b88
Keep the old behavior on v2
2021-01-09 10:55:18 -03:00
Andrey Nering
402a478785 Update CHANGELOG 2021-01-09 10:46:53 -03:00
Andrey Nering
73680584f3 Upgrade github.com/go-task/slim-sprig 2021-01-07 13:56:07 -03:00
21 changed files with 268 additions and 144 deletions

View File

@@ -1,5 +1,25 @@
# Changelog # Changelog
## v3.2.2
- Improve performance of `--list` and `--summary` by skipping running shell
variables for these flags
([#332](https://github.com/go-task/task/issues/332)).
- Fixed a bug where an environment in a Taskfile was not always overridable
by the system environment
([#425](https://github.com/go-task/task/issues/425)).
- Fixed environment from .env files not being available as variables
([#379](https://github.com/go-task/task/issues/379)).
- The install script is now working for ARM platforms
([#428](https://github.com/go-task/task/pull/428)).
## v3.2.1
- Fixed some bugs and regressions regarding dynamic variables and directories
([#426](https://github.com/go-task/task/issues/426)).
- The [slim-sprig](https://github.com/go-task/slim-sprig) package was updated
with the upstream [sprig](https://github.com/Masterminds/sprig).
## v3.2.0 ## v3.2.0
- Fix the `.task` directory being created in the task directory instead of the - Fix the `.task` directory being created in the task directory instead of the

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
set -e set -e
# Code generated by godownloader on 2018-04-07T17:47:38Z. DO NOT EDIT. # Code generated by godownloader on 2021-01-12T13:40:40Z. DO NOT EDIT.
# #
usage() { usage() {
@@ -27,11 +27,12 @@ parse_args() {
# over-ridden by flag below # over-ridden by flag below
BINDIR=${BINDIR:-./bin} BINDIR=${BINDIR:-./bin}
while getopts "b:dh?" arg; do while getopts "b:dh?x" arg; do
case "$arg" in case "$arg" in
b) BINDIR="$OPTARG" ;; b) BINDIR="$OPTARG" ;;
d) log_set_priority 10 ;; d) log_set_priority 10 ;;
h | \?) usage "$0" ;; h | \?) usage "$0" ;;
x) set -x ;;
esac esac
done done
shift $((OPTIND - 1)) shift $((OPTIND - 1))
@@ -42,46 +43,41 @@ parse_args() {
# network, either nothing will happen or will syntax error # network, either nothing will happen or will syntax error
# out preventing half-done work # out preventing half-done work
execute() { execute() {
tmpdir=$(mktmpdir) tmpdir=$(mktemp -d)
log_debug "downloading files into ${tmpdir}" log_debug "downloading files into ${tmpdir}"
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}" http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}" http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}" hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
srcdir="${tmpdir}" srcdir="${tmpdir}"
(cd "${tmpdir}" && untar "${TARBALL}") (cd "${tmpdir}" && untar "${TARBALL}")
install -d "${BINDIR}" test ! -d "${BINDIR}" && install -d "${BINDIR}"
for binexe in "task" ; do for binexe in $BINARIES; do
if [ "$OS" = "windows" ]; then if [ "$OS" = "windows" ]; then
binexe="${binexe}.exe" binexe="${binexe}.exe"
fi fi
install "${srcdir}/${binexe}" "${BINDIR}/" install "${srcdir}/${binexe}" "${BINDIR}/"
log_info "installed ${BINDIR}/${binexe}" log_info "installed ${BINDIR}/${binexe}"
done done
rm -rf "${tmpdir}"
} }
is_supported_platform() { get_binaries() {
platform=$1 case "$PLATFORM" in
found=1 darwin/amd64) BINARIES="task" ;;
case "$platform" in darwin/arm64) BINARIES="task" ;;
windows/386) found=0 ;; darwin/armv6) BINARIES="task" ;;
windows/amd64) found=0 ;; linux/386) BINARIES="task" ;;
darwin/386) found=0 ;; linux/amd64) BINARIES="task" ;;
darwin/amd64) found=0 ;; linux/arm64) BINARIES="task" ;;
linux/386) found=0 ;; linux/armv6) BINARIES="task" ;;
linux/amd64) found=0 ;; windows/386) BINARIES="task" ;;
windows/amd64) BINARIES="task" ;;
windows/arm64) BINARIES="task" ;;
windows/armv6) BINARIES="task" ;;
*)
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
;;
esac 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() { tag_to_version() {
if [ -z "${TAG}" ]; then if [ -z "${TAG}" ]; then
@@ -99,8 +95,8 @@ tag_to_version() {
VERSION=${TAG#v} VERSION=${TAG#v}
} }
adjust_format() { adjust_format() {
# change format (tar.gz or zip) based on ARCH # change format (tar.gz or zip) based on OS
case ${ARCH} in case ${OS} in
windows) FORMAT=zip ;; windows) FORMAT=zip ;;
esac esac
true true
@@ -174,7 +170,9 @@ log_crit() {
uname_os() { uname_os() {
os=$(uname -s | tr '[:upper:]' '[:lower:]') os=$(uname -s | tr '[:upper:]' '[:lower:]')
case "$os" in case "$os" in
msys_nt) os="windows" ;; cygwin_nt*) os="windows" ;;
mingw*) os="windows" ;;
msys_nt*) os="windows" ;;
esac esac
echo "$os" echo "$os"
} }
@@ -186,9 +184,9 @@ uname_arch() {
i686) arch="386" ;; i686) arch="386" ;;
i386) arch="386" ;; i386) arch="386" ;;
aarch64) arch="arm64" ;; aarch64) arch="arm64" ;;
armv5*) arch="arm5" ;; armv5*) arch="armv5" ;;
armv6*) arch="arm6" ;; armv6*) arch="armv6" ;;
armv7*) arch="arm7" ;; armv7*) arch="armv7" ;;
esac esac
echo ${arch} echo ${arch}
} }
@@ -234,8 +232,8 @@ uname_arch_check() {
untar() { untar() {
tarball=$1 tarball=$1
case "${tarball}" in case "${tarball}" in
*.tar.gz | *.tgz) tar -xzf "${tarball}" ;; *.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;;
*.tar) tar -xf "${tarball}" ;; *.tar) tar --no-same-owner -xf "${tarball}" ;;
*.zip) unzip "${tarball}" ;; *.zip) unzip "${tarball}" ;;
*) *)
log_err "untar unknown archive format for ${tarball}" log_err "untar unknown archive format for ${tarball}"
@@ -243,11 +241,6 @@ untar() {
;; ;;
esac esac
} }
mktmpdir() {
test -z "$TMPDIR" && TMPDIR="$(mktemp -d)"
mkdir -p "${TMPDIR}"
echo "${TMPDIR}"
}
http_download_curl() { http_download_curl() {
local_file=$1 local_file=$1
source_url=$2 source_url=$2
@@ -368,7 +361,7 @@ uname_arch_check "$ARCH"
parse_args "$@" parse_args "$@"
check_platform get_binaries
tag_to_version tag_to_version

2
go.mod
View File

@@ -2,7 +2,7 @@ module github.com/go-task/task/v3
require ( require (
github.com/fatih/color v1.7.0 github.com/fatih/color v1.7.0
github.com/go-task/slim-sprig v0.0.0-20200516131648-f9bac4e523eb github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0
github.com/joho/godotenv v1.3.0 github.com/joho/godotenv v1.3.0
github.com/mattn/go-colorable v0.1.2 // indirect github.com/mattn/go-colorable v0.1.2 // indirect
github.com/mattn/go-zglob v0.0.1 github.com/mattn/go-zglob v0.0.1

4
go.sum
View File

@@ -8,8 +8,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/go-task/slim-sprig v0.0.0-20200516131648-f9bac4e523eb h1:/qbv1F67s6ehqX9mG23cJOeca3FWpOVKgtPfPUMAi0k= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20200516131648-f9bac4e523eb/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=

View File

@@ -30,7 +30,7 @@ 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.Desc != "" {
compiledTask, err := e.CompiledTask(taskfile.Call{Task: task.Task}) compiledTask, err := e.FastCompiledTask(taskfile.Call{Task: task.Task})
if err == nil { if err == nil {
task = compiledTask task = compiledTask
} }

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
set -e set -e
# Code generated by godownloader on 2018-04-07T17:47:38Z. DO NOT EDIT. # Code generated by godownloader on 2021-01-12T13:40:40Z. DO NOT EDIT.
# #
usage() { usage() {
@@ -27,11 +27,12 @@ parse_args() {
# over-ridden by flag below # over-ridden by flag below
BINDIR=${BINDIR:-./bin} BINDIR=${BINDIR:-./bin}
while getopts "b:dh?" arg; do while getopts "b:dh?x" arg; do
case "$arg" in case "$arg" in
b) BINDIR="$OPTARG" ;; b) BINDIR="$OPTARG" ;;
d) log_set_priority 10 ;; d) log_set_priority 10 ;;
h | \?) usage "$0" ;; h | \?) usage "$0" ;;
x) set -x ;;
esac esac
done done
shift $((OPTIND - 1)) shift $((OPTIND - 1))
@@ -42,46 +43,41 @@ parse_args() {
# network, either nothing will happen or will syntax error # network, either nothing will happen or will syntax error
# out preventing half-done work # out preventing half-done work
execute() { execute() {
tmpdir=$(mktmpdir) tmpdir=$(mktemp -d)
log_debug "downloading files into ${tmpdir}" log_debug "downloading files into ${tmpdir}"
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}" http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}" http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}" hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
srcdir="${tmpdir}" srcdir="${tmpdir}"
(cd "${tmpdir}" && untar "${TARBALL}") (cd "${tmpdir}" && untar "${TARBALL}")
install -d "${BINDIR}" test ! -d "${BINDIR}" && install -d "${BINDIR}"
for binexe in "task" ; do for binexe in $BINARIES; do
if [ "$OS" = "windows" ]; then if [ "$OS" = "windows" ]; then
binexe="${binexe}.exe" binexe="${binexe}.exe"
fi fi
install "${srcdir}/${binexe}" "${BINDIR}/" install "${srcdir}/${binexe}" "${BINDIR}/"
log_info "installed ${BINDIR}/${binexe}" log_info "installed ${BINDIR}/${binexe}"
done done
rm -rf "${tmpdir}"
} }
is_supported_platform() { get_binaries() {
platform=$1 case "$PLATFORM" in
found=1 darwin/amd64) BINARIES="task" ;;
case "$platform" in darwin/arm64) BINARIES="task" ;;
windows/386) found=0 ;; darwin/armv6) BINARIES="task" ;;
windows/amd64) found=0 ;; linux/386) BINARIES="task" ;;
darwin/386) found=0 ;; linux/amd64) BINARIES="task" ;;
darwin/amd64) found=0 ;; linux/arm64) BINARIES="task" ;;
linux/386) found=0 ;; linux/armv6) BINARIES="task" ;;
linux/amd64) found=0 ;; windows/386) BINARIES="task" ;;
windows/amd64) BINARIES="task" ;;
windows/arm64) BINARIES="task" ;;
windows/armv6) BINARIES="task" ;;
*)
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
;;
esac 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() { tag_to_version() {
if [ -z "${TAG}" ]; then if [ -z "${TAG}" ]; then
@@ -99,8 +95,8 @@ tag_to_version() {
VERSION=${TAG#v} VERSION=${TAG#v}
} }
adjust_format() { adjust_format() {
# change format (tar.gz or zip) based on ARCH # change format (tar.gz or zip) based on OS
case ${ARCH} in case ${OS} in
windows) FORMAT=zip ;; windows) FORMAT=zip ;;
esac esac
true true
@@ -174,7 +170,9 @@ log_crit() {
uname_os() { uname_os() {
os=$(uname -s | tr '[:upper:]' '[:lower:]') os=$(uname -s | tr '[:upper:]' '[:lower:]')
case "$os" in case "$os" in
msys_nt) os="windows" ;; cygwin_nt*) os="windows" ;;
mingw*) os="windows" ;;
msys_nt*) os="windows" ;;
esac esac
echo "$os" echo "$os"
} }
@@ -186,9 +184,9 @@ uname_arch() {
i686) arch="386" ;; i686) arch="386" ;;
i386) arch="386" ;; i386) arch="386" ;;
aarch64) arch="arm64" ;; aarch64) arch="arm64" ;;
armv5*) arch="arm5" ;; armv5*) arch="armv5" ;;
armv6*) arch="arm6" ;; armv6*) arch="armv6" ;;
armv7*) arch="arm7" ;; armv7*) arch="armv7" ;;
esac esac
echo ${arch} echo ${arch}
} }
@@ -234,8 +232,8 @@ uname_arch_check() {
untar() { untar() {
tarball=$1 tarball=$1
case "${tarball}" in case "${tarball}" in
*.tar.gz | *.tgz) tar -xzf "${tarball}" ;; *.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;;
*.tar) tar -xf "${tarball}" ;; *.tar) tar --no-same-owner -xf "${tarball}" ;;
*.zip) unzip "${tarball}" ;; *.zip) unzip "${tarball}" ;;
*) *)
log_err "untar unknown archive format for ${tarball}" log_err "untar unknown archive format for ${tarball}"
@@ -243,11 +241,6 @@ untar() {
;; ;;
esac esac
} }
mktmpdir() {
test -z "$TMPDIR" && TMPDIR="$(mktemp -d)"
mkdir -p "${TMPDIR}"
echo "${TMPDIR}"
}
http_download_curl() { http_download_curl() {
local_file=$1 local_file=$1
source_url=$2 source_url=$2
@@ -368,7 +361,7 @@ uname_arch_check "$ARCH"
parse_args "$@" parse_args "$@"
check_platform get_binaries
tag_to_version tag_to_version

View File

@@ -8,6 +8,7 @@ import (
// E.g. variable merger, template processing, etc. // E.g. variable merger, template processing, etc.
type Compiler interface { type Compiler interface {
GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error)
FastGetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error)
HandleDynamicVar(v taskfile.Var, dir string) (string, error) HandleDynamicVar(v taskfile.Var, dir string) (string, error)
ResetCache() ResetCache()
} }

View File

@@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"path/filepath"
"strings" "strings"
"sync" "sync"
@@ -31,6 +30,11 @@ type CompilerV2 struct {
muDynamicCache sync.Mutex muDynamicCache sync.Mutex
} }
// FastGetVariables is a no-op on v2
func (c *CompilerV2) FastGetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error) {
return c.GetVariables(t, call)
}
// GetVariables returns fully resolved variables following the priority order: // GetVariables returns fully resolved variables following the priority order:
// 1. Task variables // 1. Task variables
// 2. Call variables // 2. Call variables
@@ -38,16 +42,8 @@ type CompilerV2 struct {
// 4. Taskvars file variables // 4. Taskvars file variables
// 5. Environment variables // 5. Environment variables
func (c *CompilerV2) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error) { func (c *CompilerV2) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error) {
// NOTE(@andreynering): We're manually joining these paths here because
// this is the raw task, not the compiled one.
dir := t.Dir
if !filepath.IsAbs(dir) {
dir = filepath.Join(c.Dir, dir)
}
vr := varResolver{ vr := varResolver{
c: c, c: c,
dir: dir,
vars: compiler.GetEnviron(), vars: compiler.GetEnviron(),
} }
vr.vars.Set("TASK", taskfile.Var{Static: t.Task}) vr.vars.Set("TASK", taskfile.Var{Static: t.Task})
@@ -62,7 +58,6 @@ func (c *CompilerV2) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfi
type varResolver struct { type varResolver struct {
c *CompilerV2 c *CompilerV2
dir string
vars *taskfile.Vars vars *taskfile.Vars
err error err error
} }
@@ -77,7 +72,7 @@ func (vr *varResolver) merge(vars *taskfile.Vars) {
Static: tr.Replace(v.Static), Static: tr.Replace(v.Static),
Sh: tr.Replace(v.Sh), Sh: tr.Replace(v.Sh),
} }
static, err := vr.c.HandleDynamicVar(v, vr.dir) static, err := vr.c.HandleDynamicVar(v, "")
if err != nil { if err != nil {
vr.err = err vr.err = err
return err return err
@@ -88,7 +83,7 @@ func (vr *varResolver) merge(vars *taskfile.Vars) {
vr.err = tr.Err() vr.err = tr.Err()
} }
func (c *CompilerV2) HandleDynamicVar(v taskfile.Var, dir string) (string, error) { func (c *CompilerV2) HandleDynamicVar(v taskfile.Var, _ string) (string, error) {
if v.Static != "" || v.Sh == "" { if v.Static != "" || v.Sh == "" {
return v.Static, nil return v.Static, nil
} }
@@ -106,7 +101,6 @@ func (c *CompilerV2) HandleDynamicVar(v taskfile.Var, dir string) (string, error
var stdout bytes.Buffer var stdout bytes.Buffer
opts := &execext.RunCommandOptions{ opts := &execext.RunCommandOptions{
Command: v.Sh, Command: v.Sh,
Dir: dir,
Stdout: &stdout, Stdout: &stdout,
Stderr: c.Logger.Stderr, Stderr: c.Logger.Stderr,
} }

View File

@@ -20,6 +20,7 @@ var _ compiler.Compiler = &CompilerV3{}
type CompilerV3 struct { type CompilerV3 struct {
Dir string Dir string
TaskfileEnv *taskfile.Vars
TaskfileVars *taskfile.Vars TaskfileVars *taskfile.Vars
Logger *logger.Logger Logger *logger.Logger
@@ -29,40 +30,67 @@ type CompilerV3 struct {
} }
func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error) { func (c *CompilerV3) GetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error) {
return c.getVariables(t, call, true)
}
func (c *CompilerV3) FastGetVariables(t *taskfile.Task, call taskfile.Call) (*taskfile.Vars, error) {
return c.getVariables(t, call, false)
}
func (c *CompilerV3) getVariables(t *taskfile.Task, call taskfile.Call, evaluateShVars bool) (*taskfile.Vars, error) {
result := compiler.GetEnviron() result := compiler.GetEnviron()
result.Set("TASK", taskfile.Var{Static: t.Task}) result.Set("TASK", taskfile.Var{Static: t.Task})
// NOTE(@andreynering): We're manually joining these paths here because getRangeFunc := func(dir string) func(k string, v taskfile.Var) error {
// this is the raw task, not the compiled one. return func(k string, v taskfile.Var) error {
dir := t.Dir tr := templater.Templater{Vars: result, RemoveNoValue: true}
if !filepath.IsAbs(dir) {
dir = filepath.Join(c.Dir, dir)
}
rangeFunc := func(k string, v taskfile.Var) error { if !evaluateShVars {
tr := templater.Templater{Vars: result, RemoveNoValue: true} result.Set(k, taskfile.Var{Static: tr.Replace(v.Static)})
v = taskfile.Var{ return nil
Static: tr.Replace(v.Static), }
Sh: tr.Replace(v.Sh),
}
if err := tr.Err(); err != nil {
return err
}
static, err := c.HandleDynamicVar(v, dir)
if err != nil {
return err
}
result.Set(k, taskfile.Var{Static: static})
return nil
}
v = taskfile.Var{
Static: tr.Replace(v.Static),
Sh: tr.Replace(v.Sh),
Dir: v.Dir,
}
if err := tr.Err(); err != nil {
return err
}
static, err := c.HandleDynamicVar(v, dir)
if err != nil {
return err
}
result.Set(k, taskfile.Var{Static: static})
return nil
}
}
rangeFunc := getRangeFunc(c.Dir)
if err := c.TaskfileEnv.Range(rangeFunc); err != nil {
return nil, err
}
if err := c.TaskfileVars.Range(rangeFunc); err != nil { if err := c.TaskfileVars.Range(rangeFunc); err != nil {
return nil, err return nil, err
} }
if err := call.Vars.Range(rangeFunc); err != nil { if err := call.Vars.Range(rangeFunc); err != nil {
return nil, err return nil, err
} }
if err := t.Vars.Range(rangeFunc); err != nil {
// NOTE(@andreynering): We're manually joining these paths here because
// this is the raw task, not the compiled one.
tr := templater.Templater{Vars: result, RemoveNoValue: true}
dir := tr.Replace(t.Dir)
if err := tr.Err(); err != nil {
return nil, err
}
if !filepath.IsAbs(dir) {
dir = filepath.Join(c.Dir, dir)
}
taskRangeFunc := getRangeFunc(dir)
if err := t.Vars.Range(taskRangeFunc); err != nil {
return nil, err return nil, err
} }
@@ -84,6 +112,11 @@ func (c *CompilerV3) HandleDynamicVar(v taskfile.Var, dir string) (string, error
return result, nil return result, nil
} }
// NOTE(@andreynering): If a var have a specific dir, use this instead
if v.Dir != "" {
dir = v.Dir
}
var stdout bytes.Buffer var stdout bytes.Buffer
opts := &execext.RunCommandOptions{ opts := &execext.RunCommandOptions{
Command: v.Sh, Command: v.Sh,

16
task.go
View File

@@ -71,7 +71,7 @@ func (e *Executor) Run(ctx context.Context, calls ...taskfile.Call) error {
if e.Summary { if e.Summary {
for i, c := range calls { for i, c := range calls {
compiledTask, err := e.CompiledTask(c) compiledTask, err := e.FastCompiledTask(c)
if err != nil { if err != nil {
return nil return nil
} }
@@ -168,6 +168,7 @@ func (e *Executor) Setup() error {
} else { } else {
e.Compiler = &compilerv3.CompilerV3{ e.Compiler = &compilerv3.CompilerV3{
Dir: e.Dir, Dir: e.Dir,
TaskfileEnv: e.Taskfile.Env,
TaskfileVars: e.Taskfile.Vars, TaskfileVars: e.Taskfile.Vars,
Logger: e.Logger, Logger: e.Logger,
} }
@@ -396,10 +397,19 @@ func getEnviron(t *taskfile.Task) []string {
} }
environ := os.Environ() environ := os.Environ()
for k, v := range t.Env.ToCacheMap() { for k, v := range t.Env.ToCacheMap() {
if s, ok := v.(string); ok { str, isString := v.(string)
environ = append(environ, fmt.Sprintf("%s=%s", k, s)) if !isString {
continue
} }
if _, alreadySet := os.LookupEnv(k); alreadySet {
continue
}
environ = append(environ, fmt.Sprintf("%s=%s", k, str))
} }
return environ return environ
} }

View File

@@ -126,6 +126,7 @@ func TestVarsV3(t *testing.T) {
"var-order.txt": "ABCDEF\n", "var-order.txt": "ABCDEF\n",
"dependent-sh.txt": "123456\n", "dependent-sh.txt": "123456\n",
"with-call.txt": "Hi, ABC123!\n", "with-call.txt": "Hi, ABC123!\n",
"from-dot-env.txt": "From .env file\n",
}, },
} }
tt.Run(t) tt.Run(t)
@@ -308,7 +309,7 @@ func TestGenerates(t *testing.T) {
const ( const (
srcTask = "sub/src.txt" srcTask = "sub/src.txt"
relTask = "rel.txt" relTask = "rel.txt"
absTask = "sub/abs.txt" absTask = "abs.txt"
fileWithSpaces = "my text file.txt" fileWithSpaces = "my text file.txt"
) )
@@ -805,7 +806,10 @@ func TestDynamicVariablesShouldRunOnTheTaskDir(t *testing.T) {
Target: "default", Target: "default",
TrimSpace: false, TrimSpace: false,
Files: map[string]string{ Files: map[string]string{
"subdirectory/dir.txt": "subdirectory\n", "subdirectory/from_root_taskfile.txt": "subdirectory\n",
"subdirectory/from_included_taskfile.txt": "subdirectory\n",
"subdirectory/from_included_taskfile_task.txt": "subdirectory\n",
"subdirectory/from_interpolated_dir.txt": "subdirectory\n",
}, },
} }
tt.Run(t) tt.Run(t)

View File

@@ -97,6 +97,17 @@ func Taskfile(dir string, entrypoint string) (*taskfile.Taskfile, error) {
} }
if includedTask.AdvancedImport { if includedTask.AdvancedImport {
for k, v := range includedTaskfile.Vars.Mapping {
o := v
o.Dir = filepath.Join(dir, includedTask.Dir)
includedTaskfile.Vars.Mapping[k] = o
}
for k, v := range includedTaskfile.Env.Mapping {
o := v
o.Dir = filepath.Join(dir, includedTask.Dir)
includedTaskfile.Env.Mapping[k] = o
}
for _, task := range includedTaskfile.Tasks { for _, task := range includedTaskfile.Tasks {
if !filepath.IsAbs(task.Dir) { if !filepath.IsAbs(task.Dir) {
task.Dir = filepath.Join(includedTask.Dir, task.Dir) task.Dir = filepath.Join(includedTask.Dir, task.Dir)

View File

@@ -98,6 +98,7 @@ type Var struct {
Static string Static string
Live interface{} Live interface{}
Sh string Sh string
Dir string
} }
// UnmarshalYAML implements yaml.Unmarshaler interface. // UnmarshalYAML implements yaml.Unmarshaler interface.

View File

@@ -1 +1 @@
subdirectory/dir.txt *.txt

View File

@@ -1,11 +1,33 @@
version: '3' version: '3'
includes:
sub:
taskfile: subdirectory
dir: subdirectory
vars:
DIRECTORY: subdirectory
tasks: tasks:
default: default:
- task: from-root-taskfile
- task: sub:from-included-taskfile
- task: sub:from-included-taskfile-task
- task: from-interpolated-dir
from-root-taskfile:
cmds: cmds:
- echo '{{.FOLDER}}' > dir.txt - echo '{{.TASK_DIR}}' > from_root_taskfile.txt
dir: subdirectory dir: subdirectory
vars: vars:
FOLDER: TASK_DIR:
sh: basename $(pwd) sh: basename $(pwd)
silent: true silent: true
from-interpolated-dir:
cmds:
- echo '{{.INTERPOLATED_DIR}}' > from_interpolated_dir.txt
dir: '{{.DIRECTORY}}'
vars:
INTERPOLATED_DIR:
sh: basename $(pwd)

View File

@@ -0,0 +1,19 @@
version: '3'
vars:
TASKFILE_DIR:
sh: basename $(pwd)
tasks:
from-included-taskfile:
cmds:
- echo '{{.TASKFILE_DIR}}' > from_included_taskfile.txt
silent: true
from-included-taskfile-task:
cmds:
- echo '{{.TASKFILE_TASK_DIR}}' > from_included_taskfile_task.txt
silent: true
vars:
TASKFILE_TASK_DIR:
sh: basename $(pwd)

View File

@@ -1 +0,0 @@
subdirectory

View File

@@ -1,10 +1,11 @@
version: '3' version: '3'
vars: vars:
BUILD_DIR: $pwd BUILD_DIR:
sh: pwd
tasks: tasks:
sub/abs.txt: abs.txt:
desc: generates dest file based on absolute paths desc: generates dest file based on absolute paths
deps: deps:
- sub/src.txt - sub/src.txt

1
testdata/vars/v3/.env vendored Normal file
View File

@@ -0,0 +1 @@
DOT_ENV_VAR=From .env file

View File

@@ -1,5 +1,7 @@
version: '3' version: '3'
dotenv: [.env]
vars: vars:
VAR_A: A VAR_A: A
VAR_B: '{{.VAR_A}}B' VAR_B: '{{.VAR_A}}B'
@@ -15,6 +17,7 @@ tasks:
- task: var-order - task: var-order
- task: dependent-sh - task: dependent-sh
- task: with-call - task: with-call
- task: from-dot-env
missing-var: echo '{{.NON_EXISTING_VAR}}' > missing-var.txt missing-var: echo '{{.NON_EXISTING_VAR}}' > missing-var.txt
@@ -44,3 +47,5 @@ tasks:
MESSAGE: Hi, {{.ABC123}}! MESSAGE: Hi, {{.ABC123}}!
cmds: cmds:
- echo "{{.MESSAGE}}" > with-call.txt - echo "{{.MESSAGE}}" > with-call.txt
from-dot-env: echo '{{.DOT_ENV_VAR}}' > from-dot-env.txt

View File

@@ -13,12 +13,27 @@ import (
// 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
// properties using the Go template package. // properties using the Go template package.
func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) { func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) {
return e.compiledTask(call, true)
}
// FastCompiledTask is like CompiledTask, but it skippes dynamic variables.
func (e *Executor) FastCompiledTask(call taskfile.Call) (*taskfile.Task, error) {
return e.compiledTask(call, false)
}
func (e *Executor) compiledTask(call taskfile.Call, evaluateShVars bool) (*taskfile.Task, error) {
origTask, ok := e.Taskfile.Tasks[call.Task] origTask, ok := e.Taskfile.Tasks[call.Task]
if !ok { if !ok {
return nil, &taskNotFoundError{call.Task} return nil, &taskNotFoundError{call.Task}
} }
vars, err := e.Compiler.GetVariables(origTask, call) var vars *taskfile.Vars
var err error
if evaluateShVars {
vars, err = e.Compiler.GetVariables(origTask, call)
} else {
vars, err = e.Compiler.FastGetVariables(origTask, call)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -59,16 +74,18 @@ func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) {
new.Env = &taskfile.Vars{} new.Env = &taskfile.Vars{}
new.Env.Merge(r.ReplaceVars(e.Taskfile.Env)) new.Env.Merge(r.ReplaceVars(e.Taskfile.Env))
new.Env.Merge(r.ReplaceVars(origTask.Env)) new.Env.Merge(r.ReplaceVars(origTask.Env))
err = new.Env.Range(func(k string, v taskfile.Var) error { if evaluateShVars {
static, err := e.Compiler.HandleDynamicVar(v, new.Dir) err = new.Env.Range(func(k string, v taskfile.Var) error {
static, err := e.Compiler.HandleDynamicVar(v, new.Dir)
if err != nil {
return err
}
new.Env.Set(k, taskfile.Var{Static: static})
return nil
})
if err != nil { if err != nil {
return err return nil, err
} }
new.Env.Set(k, taskfile.Var{Static: static})
return nil
})
if err != nil {
return nil, err
} }
if len(origTask.Cmds) > 0 { if len(origTask.Cmds) > 0 {