Skip to content

Commit 4b88710

Browse files
committed
Includes: Support templating in included 'task.dir' field.
1 parent 7901cce commit 4b88710

File tree

6 files changed

+89
-28
lines changed

6 files changed

+89
-28
lines changed

compiler.go

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,6 @@ func (c *Compiler) getVariables(t *ast.Task, call *Call, evaluateShVars bool) (*
9090
}
9191
rangeFunc := getRangeFunc(c.Dir)
9292

93-
var taskRangeFunc func(k string, v ast.Var) error
94-
if t != nil {
95-
// NOTE(@andreynering): We're manually joining these paths here because
96-
// this is the raw task, not the compiled one.
97-
cache := &templater.Cache{Vars: result}
98-
dir := templater.Replace(t.Dir, cache)
99-
if err := cache.Err(); err != nil {
100-
return nil, err
101-
}
102-
dir = filepathext.SmartJoin(c.Dir, dir)
103-
taskRangeFunc = getRangeFunc(dir)
104-
}
105-
10693
for k, v := range c.TaskfileEnv.All() {
10794
if err := rangeFunc(k, v); err != nil {
10895
return nil, err
@@ -113,31 +100,60 @@ func (c *Compiler) getVariables(t *ast.Task, call *Call, evaluateShVars bool) (*
113100
return nil, err
114101
}
115102
}
103+
116104
if t != nil {
117105
for k, v := range t.IncludeVars.All() {
118106
if err := rangeFunc(k, v); err != nil {
119107
return nil, err
120108
}
121109
}
110+
111+
if !evaluateShVars {
112+
// Add includedTaskfile.Vars, and replace/overwrite taskfile.Vars,
113+
// _before_ calculating the t.Dir using the templater. Because
114+
// evaluateShVars is not set, the dir used when creating rangeFunc
115+
// will not be used (sh vars are evaluated on subsequent calls).
116+
for k, v := range t.IncludedTaskfileVars.All() {
117+
if err := rangeFunc(k, v); err != nil {
118+
return nil, err
119+
}
120+
}
121+
}
122+
123+
// Calculate the t.Dir now based on values saved during AST parsing
124+
// and then get a Task RangeFunc.
125+
dir := c.Dir
126+
if len(t.Dir) == 0 {
127+
// Use the saved include task.Dir.
128+
t.Dir = t.IncludeTaskDir
129+
} else {
130+
cache := &templater.Cache{Vars: result}
131+
taskDir := templater.Replace(t.Dir, cache)
132+
if err := cache.Err(); err != nil {
133+
return nil, err
134+
}
135+
t.Dir = filepathext.SmartJoin(t.IncludeDir, taskDir)
136+
// Update dir (esp. if taskDir is a relative path).
137+
dir = filepathext.SmartJoin(c.Dir, taskDir)
138+
}
139+
taskRangeFunc := getRangeFunc(dir)
140+
122141
for k, v := range t.IncludedTaskfileVars.All() {
123142
if err := taskRangeFunc(k, v); err != nil {
124143
return nil, err
125144
}
126145
}
127-
}
128-
129-
if t == nil || call == nil {
130-
return result, nil
131-
}
132-
133-
for k, v := range call.Vars.All() {
134-
if err := rangeFunc(k, v); err != nil {
135-
return nil, err
146+
if call != nil {
147+
for k, v := range call.Vars.All() {
148+
if err := rangeFunc(k, v); err != nil {
149+
return nil, err
150+
}
151+
}
136152
}
137-
}
138-
for k, v := range t.Vars.All() {
139-
if err := taskRangeFunc(k, v); err != nil {
140-
return nil, err
153+
for k, v := range t.Vars.All() {
154+
if err := taskRangeFunc(k, v); err != nil {
155+
return nil, err
156+
}
141157
}
142158
}
143159

task_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,23 @@ func TestIncludedTaskfileVarMerging(t *testing.T) {
13101310
}
13111311
}
13121312

1313+
func TestIncludedDirWithTemplate(t *testing.T) {
1314+
t.Parallel()
1315+
1316+
const dir = "testdata/included_dir_with_template"
1317+
var buff bytes.Buffer
1318+
e := task.NewExecutor(
1319+
task.WithDir(dir),
1320+
task.WithStdout(&buff),
1321+
task.WithStderr(&buff),
1322+
task.WithSilent(true),
1323+
)
1324+
require.NoError(t, e.Setup())
1325+
err := e.Run(t.Context(), &task.Call{Task: "default"})
1326+
require.NoError(t, err)
1327+
assert.Contains(t, buff.String(), "Build WORKING_DIR: /tmp")
1328+
}
1329+
13131330
func TestInternalTask(t *testing.T) {
13141331
t.Parallel()
13151332

taskfile/ast/task.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ type Task struct {
4444
Location *Location
4545
// Populated during merging
4646
Namespace string `hash:"ignore"`
47+
IncludeDir string
48+
IncludeTaskDir string
4749
IncludeVars *Vars
4850
IncludedTaskfileVars *Vars
4951

taskfile/ast/tasks.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"go.yaml.in/yaml/v4"
1212

1313
"github.com/go-task/task/v3/errors"
14-
"github.com/go-task/task/v3/internal/filepathext"
1514
"github.com/go-task/task/v3/internal/sort"
1615
)
1716

@@ -171,7 +170,14 @@ func (t1 *Tasks) Merge(t2 *Tasks, include *Include, includedTaskfileVars *Vars)
171170
}
172171

173172
if include.AdvancedImport {
174-
task.Dir = filepathext.SmartJoin(include.Dir, task.Dir)
173+
// Save the include.Dir and task.Dir so that the final task.dir can
174+
// be calculated when the task is compiled (and templating is available).
175+
task.IncludeDir = include.Dir
176+
task.IncludeTaskDir = task.Dir
177+
// If task.dir is not set then use the include.dir.
178+
if len(task.Dir) == 0 {
179+
task.Dir = include.Dir
180+
}
175181
if task.IncludeVars == nil {
176182
task.IncludeVars = NewVars()
177183
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
version: '3'
2+
3+
tasks:
4+
build:
5+
dir: '{{.WORKING_DIR}}'
6+
cmds:
7+
- |
8+
echo "Build WORKING_DIR: $(pwd)"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: '3'
2+
3+
vars:
4+
WORKING_DIR: '/tmp'
5+
6+
includes:
7+
builder: ./taskfile.builder.yml
8+
9+
tasks:
10+
default:
11+
cmds:
12+
- task: builder:build

0 commit comments

Comments
 (0)