Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 36 additions & 26 deletions compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,6 @@ func (c *Compiler) getVariables(t *ast.Task, call *Call, evaluateShVars bool) (*
}
rangeFunc := getRangeFunc(c.Dir)

var taskRangeFunc func(k string, v ast.Var) error
if t != nil {
// NOTE(@andreynering): We're manually joining these paths here because
// this is the raw task, not the compiled one.
cache := &templater.Cache{Vars: result}
dir := templater.Replace(t.Dir, cache)
if err := cache.Err(); err != nil {
return nil, err
}
dir = filepathext.SmartJoin(c.Dir, dir)
taskRangeFunc = getRangeFunc(dir)
}

for k, v := range c.TaskfileEnv.All() {
if err := rangeFunc(k, v); err != nil {
return nil, err
Expand All @@ -114,31 +101,54 @@ func (c *Compiler) getVariables(t *ast.Task, call *Call, evaluateShVars bool) (*
return nil, err
}
}

if t != nil {
for k, v := range t.IncludeVars.All() {
if err := rangeFunc(k, v); err != nil {
return nil, err
}
}

if !evaluateShVars {
// Add includedTaskfile.Vars, and replace/overwrite taskfile.Vars,
// _before_ calculating the t.Dir using the templater. Because
// evaluateShVars is not set, the dir used when creating rangeFunc
// will not be used (sh vars are evaluated on subsequent calls).
for k, v := range t.IncludedTaskfileVars.All() {
if err := rangeFunc(k, v); err != nil {
return nil, err
}
}
}

// Calculate the taskDir for evaluation of IncludeVars. If the original TaskDir
// was saved to t.IncludeTaskDir then that path needs to be used.
cache := &templater.Cache{Vars: result}
t.Dir = templater.Replace(t.Dir, cache)
if len(t.IncludeTaskDir) > 0 {
// If the included TaskDir is absolute, then it will become
// the TaskDir, otherwise join with the existing TaskDir.
taskDir := templater.Replace(t.IncludeTaskDir, cache)
t.Dir = filepathext.SmartJoin(t.Dir, taskDir)
}
taskRangeFunc := getRangeFunc(t.Dir)

for k, v := range t.IncludedTaskfileVars.All() {
if err := taskRangeFunc(k, v); err != nil {
return nil, err
}
}
}

if t == nil || call == nil {
return result, nil
}

for k, v := range call.Vars.All() {
if err := rangeFunc(k, v); err != nil {
return nil, err
if call != nil {
for k, v := range call.Vars.All() {
if err := rangeFunc(k, v); err != nil {
return nil, err
}
}
}
}
for k, v := range t.Vars.All() {
if err := taskRangeFunc(k, v); err != nil {
return nil, err
for k, v := range t.Vars.All() {
if err := taskRangeFunc(k, v); err != nil {
return nil, err
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions internal/filepathext/filepathext.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"strings"
)

// SmartJoin joins two paths, but only if the second is not already an
// absolute path.
// SmartJoin joins two paths when the second path is not absolute, otherwise
// it returns the second (absolute) path.
func SmartJoin(a, b string) string {
if IsAbs(b) {
return b
Expand All @@ -28,6 +28,7 @@ func IsAbs(path string) bool {
var knownAbsDirs = []string{
".ROOT_DIR",
".TASKFILE_DIR",
".TASK_DIR",
".USER_WORKING_DIR",
}

Expand Down
17 changes: 17 additions & 0 deletions task_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,23 @@ func TestIncludedTaskfileVarMerging(t *testing.T) {
}
}

func TestIncludedDirWithTemplate(t *testing.T) {
t.Parallel()

const dir = "testdata/included_dir_with_template"
var buff bytes.Buffer
e := task.NewExecutor(
task.WithDir(dir),
task.WithStdout(&buff),
task.WithStderr(&buff),
task.WithSilent(true),
)
require.NoError(t, e.Setup())
err := e.Run(t.Context(), &task.Call{Task: "default"})
require.NoError(t, err)
assert.Contains(t, buff.String(), "Build WORKING_DIR: /tmp")
}

func TestInternalTask(t *testing.T) {
t.Parallel()

Expand Down
1 change: 1 addition & 0 deletions taskfile/ast/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Task struct {
Failfast bool
// Populated during merging
Namespace string `hash:"ignore"`
IncludeTaskDir string
IncludeVars *Vars
IncludedTaskfileVars *Vars

Expand Down
10 changes: 9 additions & 1 deletion taskfile/ast/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,15 @@ func (t1 *Tasks) Merge(t2 *Tasks, include *Include, includedTaskfileVars *Vars)
}

if include.AdvancedImport {
task.Dir = filepathext.SmartJoin(include.Dir, task.Dir)
if filepathext.IsAbs(task.Dir) {
// TaskDir with (obvious) absolute path has priority.
} else {
// TaskDir will be either <IncludeDir> or <IncludeDir>/<TaskDir>, however
// task.Dir may still compile to an absolute path. Set/save now and resolve
// later in Compiler.getVariables.
task.IncludeTaskDir = task.Dir
task.Dir = include.Dir
}
if task.IncludeVars == nil {
task.IncludeVars = NewVars()
}
Expand Down
8 changes: 8 additions & 0 deletions testdata/included_dir_with_template/taskfile.builder.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: '3'

tasks:
build:
dir: '{{.WORKING_DIR}}'
cmds:
- |
echo "Build WORKING_DIR: $(pwd)"
12 changes: 12 additions & 0 deletions testdata/included_dir_with_template/taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: '3'

vars:
WORKING_DIR: '/tmp'

includes:
builder: ./taskfile.builder.yml

tasks:
default:
cmds:
- task: builder:build
Loading