Skip to content
Open
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
17 changes: 15 additions & 2 deletions task.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,21 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error {

if err = e.startExecution(ctx, t, func(ctx context.Context) error {
e.Logger.VerboseErrf(logger.Magenta, "task: %q started\n", call.Task)
if err := e.runDeps(ctx, t); err != nil {
return err

if len(t.Deps) > 0 {
if err := e.runDeps(ctx, t); err != nil {
return err
}
if len(t.Dotenv) > 0 {
origTask, err := e.GetTask(call)
if err != nil {
return err
}
t.Env, err = e.taskEnv(t, origTask.Env, nil, true)
if err != nil {
return err
}
}
}

skipFingerprinting := e.ForceAll || (!call.Indirect && e.Force)
Expand Down
37 changes: 37 additions & 0 deletions task_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1802,6 +1802,43 @@ func TestTaskDotenvWithVarName(t *testing.T) {
})
}

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

tt := []fileContentTest{
{
Dir: "testdata/dotenv_task/generated",
Target: "dotenv-dep-gen-default",
TrimSpace: true,
Files: map[string]string{
"dotenv-dep-gen-default.txt": "gen-bar",
},
},
{
Dir: "testdata/dotenv_task/generated",
Target: "dotenv-dep-gen-var",
TrimSpace: true,
Files: map[string]string{
"dotenv-dep-gen-var.txt": "var-bar",
},
},
{
Dir: "testdata/dotenv_task/generated",
Target: "dotenv-gen-seq",
TrimSpace: true,
Files: map[string]string{
"dotenv-gen-seq.txt": "seq-bar",
},
},
}
for _, test := range tt {
t.Run("", func(t *testing.T) {
t.Parallel()
test.Run(t)
})
}
}

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

Expand Down
1 change: 1 addition & 0 deletions testdata/dotenv_task/generated/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.txt
47 changes: 47 additions & 0 deletions testdata/dotenv_task/generated/Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
version: '3'

env:
FOO: global

tasks:
dotenv-gen:
vars:
DOTENV: '{{.DOTENV | default "gen-env.txt" }}'
DOTVAL: '{{.DOTVAL | default "gen-bar" }}'
cmds:
- echo "BAR={{.DOTVAL}}" > {{.DOTENV}}

dotenv-dep-gen-default:
dotenv:
- gen-env.txt
deps:
- task: dotenv-gen
cmds:
- echo "$BAR" > dotenv-dep-gen-default.txt

dotenv-dep-gen-var:
dotenv:
- gen-var-env.txt
deps:
- task: dotenv-gen
vars:
DOTENV: gen-var-env.txt
DOTVAL: var-bar
cmds:
- echo "$BAR" > dotenv-dep-gen-var.txt

dotenv-gen-echo:
dotenv:
- gen-env.txt
cmds:
- echo $BAR
- echo "$BAR" > {{.ECHOFILE}}

dotenv-gen-seq:
cmds:
- task: dotenv-gen
vars:
DOTVAL: seq-bar
- task: dotenv-gen-echo
vars:
ECHOFILE: dotenv-gen-seq.txt
87 changes: 51 additions & 36 deletions variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,54 @@ func (e *Executor) CompiledTaskForTaskList(call *Call) (*ast.Task, error) {
}, nil
}

func (e *Executor) taskEnv(t *ast.Task, origTaskEnv *ast.Vars, cache *templater.Cache, evaluateShVars bool) (*ast.Vars, error) {
taskEnv := ast.NewVars()
if cache == nil {
cache = &templater.Cache{Vars: t.Vars}
}

// Load dotenv files based on the templated list of t.Dotenv files.
dotenvEnvs := ast.NewVars()
if len(t.Dotenv) > 0 {
for _, dotEnvPath := range t.Dotenv {
dotEnvPath = filepathext.SmartJoin(t.Dir, dotEnvPath)
if _, err := os.Stat(dotEnvPath); os.IsNotExist(err) {
continue
}
envs, err := godotenv.Read(dotEnvPath)
if err != nil {
return nil, err
}
for key, value := range envs {
if _, ok := dotenvEnvs.Get(key); !ok {
dotenvEnvs.Set(key, ast.Var{Value: value})
}
}
}
}

// Merge the Task envars => destination (by-caller) is typically t.Env
taskEnv.Merge(templater.ReplaceVars(e.Taskfile.Env, cache), nil)
taskEnv.Merge(templater.ReplaceVars(dotenvEnvs, cache), nil)
taskEnv.Merge(templater.ReplaceVars(origTaskEnv, cache), nil)
if evaluateShVars {
for k, v := range taskEnv.All() {
// If the variable is not dynamic, we can set it and return
if v.Value != nil || v.Sh == nil {
taskEnv.Set(k, ast.Var{Value: v.Value})
continue
}
static, err := e.Compiler.HandleDynamicVar(v, t.Dir, env.GetFromVars(taskEnv))
if err != nil {
return nil, err
}
taskEnv.Set(k, ast.Var{Value: static})
}
}

return taskEnv, nil
}

func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, error) {
origTask, err := e.GetTask(call)
if err != nil {
Expand Down Expand Up @@ -143,42 +191,9 @@ func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, err
new.Prefix = new.Task
}

dotenvEnvs := ast.NewVars()
if len(new.Dotenv) > 0 {
for _, dotEnvPath := range new.Dotenv {
dotEnvPath = filepathext.SmartJoin(new.Dir, dotEnvPath)
if _, err := os.Stat(dotEnvPath); os.IsNotExist(err) {
continue
}
envs, err := godotenv.Read(dotEnvPath)
if err != nil {
return nil, err
}
for key, value := range envs {
if _, ok := dotenvEnvs.Get(key); !ok {
dotenvEnvs.Set(key, ast.Var{Value: value})
}
}
}
}

new.Env = ast.NewVars()
new.Env.Merge(templater.ReplaceVars(e.Taskfile.Env, cache), nil)
new.Env.Merge(templater.ReplaceVars(dotenvEnvs, cache), nil)
new.Env.Merge(templater.ReplaceVars(origTask.Env, cache), nil)
if evaluateShVars {
for k, v := range new.Env.All() {
// If the variable is not dynamic, we can set it and return
if v.Value != nil || v.Sh == nil {
new.Env.Set(k, ast.Var{Value: v.Value})
continue
}
static, err := e.Compiler.HandleDynamicVar(v, new.Dir, env.GetFromVars(new.Env))
if err != nil {
return nil, err
}
new.Env.Set(k, ast.Var{Value: static})
}
new.Env, err = e.taskEnv(&new, origTask.Env, cache, evaluateShVars)
if err != nil {
return nil, err
}

if len(origTask.Sources) > 0 && origTask.Method != "none" {
Expand Down
Loading