1
0
mirror of https://github.com/go-task/task.git synced 2025-03-03 14:52:13 +02:00
task/internal/taskfile/read/taskfile.go

136 lines
3.2 KiB
Go
Raw Normal View History

package read
import (
"errors"
"fmt"
2020-08-03 16:18:38 -06:00
"github.com/joho/godotenv"
"os"
"path/filepath"
"runtime"
2018-11-04 21:23:35 -02:00
"github.com/go-task/task/v2/internal/taskfile"
"github.com/go-task/task/v2/internal/templater"
2020-03-28 11:27:49 -03:00
"gopkg.in/yaml.v3"
)
var (
// ErrIncludedTaskfilesCantHaveIncludes is returned when a included Taskfile contains includes
ErrIncludedTaskfilesCantHaveIncludes = errors.New("task: Included Taskfiles can't have includes. Please, move the include to the main Taskfile")
2020-08-03 16:18:38 -06:00
ErrIncludedTaskfilesCantHaveDotenvs = errors.New("task: Included Taskfiles can't have dotenv declarations. Please, move the dotenv declaration to the main Taskfile")
)
// Taskfile reads a Taskfile for a given directory
func Taskfile(dir string, entrypoint string) (*taskfile.Taskfile, error) {
path := filepath.Join(dir, entrypoint)
if _, err := os.Stat(path); err != nil {
return nil, fmt.Errorf(`task: No Taskfile found on "%s". Use "task --init" to create a new one`, path)
}
t, err := readTaskfile(path)
if err != nil {
return nil, err
}
v, err := t.ParsedVersion()
if err != nil {
return nil, err
}
2020-08-03 16:18:38 -06:00
if v >= 3.0 {
if len(t.Dotenv) > 0 {
for _, envFile := range t.Dotenv {
var envFilePath string
if filepath.IsAbs(envFile) {
envFilePath = envFile
} else {
envFilePath = filepath.Join(dir, envFile)
}
if err = godotenv.Load(envFilePath); err != nil {
return nil, err
}
}
}
}
for namespace, includedTask := range t.Includes {
if v >= 3.0 {
tr := templater.Templater{Vars: &taskfile.Vars{}, RemoveNoValue: true}
includedTask = taskfile.IncludedTaskfile{
Taskfile: tr.Replace(includedTask.Taskfile),
Dir: tr.Replace(includedTask.Dir),
AdvancedImport: includedTask.AdvancedImport,
}
if err := tr.Err(); err != nil {
return nil, err
}
}
if filepath.IsAbs(includedTask.Taskfile) {
path = includedTask.Taskfile
} else {
path = filepath.Join(dir, includedTask.Taskfile)
}
2018-09-09 22:29:29 -03:00
info, err := os.Stat(path)
if err != nil {
return nil, err
}
if info.IsDir() {
path = filepath.Join(path, "Taskfile.yml")
}
includedTaskfile, err := readTaskfile(path)
if err != nil {
return nil, err
}
if len(includedTaskfile.Includes) > 0 {
return nil, ErrIncludedTaskfilesCantHaveIncludes
}
2020-08-03 16:18:38 -06:00
if v >= 3.0 {
if len(includedTaskfile.Dotenv) > 0 {
return nil, ErrIncludedTaskfilesCantHaveDotenvs
}
}
if includedTask.AdvancedImport {
for _, task := range includedTaskfile.Tasks {
if !filepath.IsAbs(task.Dir) {
task.Dir = filepath.Join(includedTask.Dir, task.Dir)
}
}
}
2018-09-09 22:29:29 -03:00
if err = taskfile.Merge(t, includedTaskfile, namespace); err != nil {
return nil, err
}
}
if v < 3.0 {
path = filepath.Join(dir, fmt.Sprintf("Taskfile_%s.yml", runtime.GOOS))
if _, err = os.Stat(path); err == nil {
osTaskfile, err := readTaskfile(path)
if err != nil {
return nil, err
}
if err = taskfile.Merge(t, osTaskfile); err != nil {
return nil, err
}
}
}
for name, task := range t.Tasks {
task.Task = name
}
return t, nil
}
func readTaskfile(file string) (*taskfile.Taskfile, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
var t taskfile.Taskfile
return &t, yaml.NewDecoder(f).Decode(&t)
}