1
0
mirror of https://github.com/go-task/task.git synced 2025-02-05 13:25:14 +02:00

Merge pull request #621 from kerma/feat/support-yaml

Add support for yaml extension
This commit is contained in:
Andrey Nering 2022-01-02 15:08:50 -03:00 committed by GitHub
commit ed37071fd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 101 additions and 27 deletions

View File

@ -1,5 +1,9 @@
# Changelog # Changelog
## Unreleased
- Add support for yaml extension ([#584](https://github.com/go-task/task/issues/584))
## v3.9.2 - 2021-12-02 ## v3.9.2 - 2021-12-02
- Upgrade [mvdan/sh](https://github.com/mvdan/sh) which contains a fix a for - Upgrade [mvdan/sh](https://github.com/mvdan/sh) which contains a fix a for

View File

@ -77,7 +77,7 @@ func main() {
pflag.BoolVar(&versionFlag, "version", false, "show Task version") pflag.BoolVar(&versionFlag, "version", false, "show Task version")
pflag.BoolVarP(&helpFlag, "help", "h", false, "shows Task usage") pflag.BoolVarP(&helpFlag, "help", "h", false, "shows Task usage")
pflag.BoolVarP(&init, "init", "i", false, "creates a new Taskfile.yml in the current folder") pflag.BoolVarP(&init, "init", "i", false, "creates a new Taskfile.yaml in the current folder")
pflag.BoolVarP(&list, "list", "l", false, "lists tasks with description of current Taskfile") pflag.BoolVarP(&list, "list", "l", false, "lists tasks with description of current Taskfile")
pflag.BoolVar(&status, "status", false, "exits with non-zero exit code if any of the given tasks is not up-to-date") pflag.BoolVar(&status, "status", false, "exits with non-zero exit code if any of the given tasks is not up-to-date")
pflag.BoolVarP(&force, "force", "f", false, "forces execution even when the task is up-to-date") pflag.BoolVarP(&force, "force", "f", false, "forces execution even when the task is up-to-date")
@ -122,8 +122,6 @@ func main() {
if entrypoint != "" { if entrypoint != "" {
dir = filepath.Dir(entrypoint) dir = filepath.Dir(entrypoint)
entrypoint = filepath.Base(entrypoint) entrypoint = filepath.Base(entrypoint)
} else {
entrypoint = "Taskfile.yml"
} }
e := task.Executor{ e := task.Executor{

View File

@ -4,7 +4,7 @@
function __list() { function __list() {
local -a scripts local -a scripts
if [ -f Taskfile.yml ]; then if [ -f Taskfile.yml ] || [ -f Taskfile.yaml ]; then
scripts=($(task -l | sed '1d' | sed 's/^\* //' | awk '{ print $1 }' | sed 's/:$//' | sed 's/:/\\:/g')) scripts=($(task -l | sed '1d' | sed 's/^\* //' | awk '{ print $1 }' | sed 's/:$//' | sed 's/:/\\:/g'))
_describe 'script' scripts _describe 'script' scripts
fi fi

View File

@ -23,7 +23,7 @@ tasks:
// InitTaskfile Taskfile creates a new Taskfile // InitTaskfile Taskfile creates a new Taskfile
func InitTaskfile(w io.Writer, dir string) error { func InitTaskfile(w io.Writer, dir string) error {
f := filepath.Join(dir, "Taskfile.yml") f := filepath.Join(dir, "Taskfile.yaml")
if _, err := os.Stat(f); err == nil { if _, err := os.Stat(f); err == nil {
return ErrTaskfileAlreadyExists return ErrTaskfileAlreadyExists
@ -32,6 +32,6 @@ func InitTaskfile(w io.Writer, dir string) error {
if err := os.WriteFile(f, []byte(defaultTaskfile), 0644); err != nil { if err := os.WriteFile(f, []byte(defaultTaskfile), 0644); err != nil {
return err return err
} }
fmt.Fprintf(w, "Taskfile.yml created in the current directory\n") fmt.Fprintf(w, "Taskfile.yaml created in the current directory\n")
return nil return nil
} }

View File

@ -105,10 +105,6 @@ func (e *Executor) Run(ctx context.Context, calls ...taskfile.Call) error {
// Setup setups Executor's internal state // Setup setups Executor's internal state
func (e *Executor) Setup() error { func (e *Executor) Setup() error {
if e.Entrypoint == "" {
e.Entrypoint = "Taskfile.yml"
}
var err error var err error
e.Taskfile, err = read.Taskfile(e.Dir, e.Entrypoint) e.Taskfile, err = read.Taskfile(e.Dir, e.Entrypoint)
if err != nil { if err != nil {

View File

@ -24,10 +24,11 @@ func init() {
// fileContentTest provides a basic reusable test-case for running a Taskfile // fileContentTest provides a basic reusable test-case for running a Taskfile
// and inspect generated files. // and inspect generated files.
type fileContentTest struct { type fileContentTest struct {
Dir string Dir string
Target string Entrypoint string
TrimSpace bool Target string
Files map[string]string TrimSpace bool
Files map[string]string
} }
func (fct fileContentTest) name(file string) string { func (fct fileContentTest) name(file string) string {
@ -40,9 +41,10 @@ func (fct fileContentTest) Run(t *testing.T) {
} }
e := &task.Executor{ e := &task.Executor{
Dir: fct.Dir, Dir: fct.Dir,
Stdout: io.Discard, Entrypoint: fct.Entrypoint,
Stderr: io.Discard, Stdout: io.Discard,
Stderr: io.Discard,
} }
assert.NoError(t, e.Setup(), "e.Setup()") assert.NoError(t, e.Setup(), "e.Setup()")
assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: fct.Target}), "e.Run(target)") assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: fct.Target}), "e.Run(target)")
@ -550,11 +552,11 @@ func TestStatusVariables(t *testing.T) {
func TestInit(t *testing.T) { func TestInit(t *testing.T) {
const dir = "testdata/init" const dir = "testdata/init"
var file = filepath.Join(dir, "Taskfile.yml") var file = filepath.Join(dir, "Taskfile.yaml")
_ = os.Remove(file) _ = os.Remove(file)
if _, err := os.Stat(file); err == nil { if _, err := os.Stat(file); err == nil {
t.Errorf("Taskfile.yml should not exist") t.Errorf("Taskfile.yaml should not exist")
} }
if err := task.InitTaskfile(io.Discard, dir); err != nil { if err := task.InitTaskfile(io.Discard, dir); err != nil {
@ -562,8 +564,9 @@ func TestInit(t *testing.T) {
} }
if _, err := os.Stat(file); err != nil { if _, err := os.Stat(file); err != nil {
t.Errorf("Taskfile.yml should exist") t.Errorf("Taskfile.yaml should exist")
} }
_ = os.Remove(file)
} }
func TestCyclicDep(t *testing.T) { func TestCyclicDep(t *testing.T) {
@ -790,6 +793,21 @@ func TestIncludesOptionalExplicitFalse(t *testing.T) {
assert.Equal(t, "stat testdata/includes_optional_explicit_false/TaskfileOptional.yml: no such file or directory", err.Error()) assert.Equal(t, "stat testdata/includes_optional_explicit_false/TaskfileOptional.yml: no such file or directory", err.Error())
} }
func TestIncludesFromCustomTaskfile(t *testing.T) {
tt := fileContentTest{
Dir: "testdata/includes_yaml",
Entrypoint: "Custom.ext",
Target: "default",
TrimSpace: true,
Files: map[string]string{
"main.txt": "main",
"included_with_yaml_extension.txt": "included_with_yaml_extension",
"included_with_custom_file.txt": "included_with_custom_file",
},
}
tt.Run(t)
}
func TestSummary(t *testing.T) { func TestSummary(t *testing.T) {
const dir = "testdata/summary" const dir = "testdata/summary"

View File

@ -19,14 +19,26 @@ var (
ErrIncludedTaskfilesCantHaveIncludes = errors.New("task: Included Taskfiles can't have includes. Please, move the include to the main Taskfile") ErrIncludedTaskfilesCantHaveIncludes = errors.New("task: Included Taskfiles can't have includes. Please, move the include to the main Taskfile")
// ErrIncludedTaskfilesCantHaveDotenvs is returned when a included Taskfile contains dotenvs // ErrIncludedTaskfilesCantHaveDotenvs is returned when a included Taskfile contains dotenvs
ErrIncludedTaskfilesCantHaveDotenvs = errors.New("task: Included Taskfiles can't have dotenv declarations. Please, move the dotenv declaration to the main Taskfile") ErrIncludedTaskfilesCantHaveDotenvs = errors.New("task: Included Taskfiles can't have dotenv declarations. Please, move the dotenv declaration to the main Taskfile")
defaultTaskfiles = []string{"Taskfile.yml", "Taskfile.yaml"}
) )
// Taskfile reads a Taskfile for a given directory // Taskfile reads a Taskfile for a given directory
// Uses current dir when dir is left empty. Uses Taskfile.yml
// or Taskfile.yaml when entrypoint is left empty
func Taskfile(dir string, entrypoint string) (*taskfile.Taskfile, error) { func Taskfile(dir string, entrypoint string) (*taskfile.Taskfile, error) {
path := filepath.Join(dir, entrypoint) if dir == "" {
if _, err := os.Stat(path); err != nil { d, err := os.Getwd()
return nil, fmt.Errorf(`task: No Taskfile found on "%s". Use "task --init" to create a new one`, path) if err != nil {
return nil, err
}
dir = d
} }
path, err := exists(filepath.Join(dir, entrypoint))
if err != nil {
return nil, err
}
t, err := readTaskfile(path) t, err := readTaskfile(path)
if err != nil { if err != nil {
return nil, err return nil, err
@ -59,16 +71,14 @@ func Taskfile(dir string, entrypoint string) (*taskfile.Taskfile, error) {
path = filepath.Join(dir, path) path = filepath.Join(dir, path)
} }
info, err := os.Stat(path) path, err = exists(path)
if err != nil { if err != nil {
if includedTask.Optional { if includedTask.Optional {
return nil return nil
} }
return err return err
} }
if info.IsDir() {
path = filepath.Join(path, "Taskfile.yml")
}
includedTaskfile, err := readTaskfile(path) includedTaskfile, err := readTaskfile(path)
if err != nil { if err != nil {
return err return err
@ -141,3 +151,22 @@ func readTaskfile(file string) (*taskfile.Taskfile, error) {
var t taskfile.Taskfile var t taskfile.Taskfile
return &t, yaml.NewDecoder(f).Decode(&t) return &t, yaml.NewDecoder(f).Decode(&t)
} }
func exists(path string) (string, error) {
fi, err := os.Stat(path)
if err != nil {
return "", err
}
if fi.Mode().IsRegular() {
return path, nil
}
for _, n := range defaultTaskfiles {
fpath := filepath.Join(path, n)
if _, err := os.Stat(fpath); err == nil {
return fpath, nil
}
}
return "", fmt.Errorf(`task: No Taskfile found in "%s". Use "task --init" to create a new one`, path)
}

1
testdata/includes_yaml/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.txt

16
testdata/includes_yaml/Custom.ext vendored Normal file
View File

@ -0,0 +1,16 @@
version: '3'
includes:
included: ./included
custom: ./included/custom.yaml
tasks:
default:
cmds:
- task: gen
- task: included:gen
- task: custom:gen
gen:
cmds:
- echo main > main.txt

View File

@ -0,0 +1,6 @@
version: '3'
tasks:
gen:
cmds:
- echo included_with_yaml_extension > included_with_yaml_extension.txt

View File

@ -0,0 +1,6 @@
version: '3'
tasks:
gen:
cmds:
- echo included_with_custom_file > included_with_custom_file.txt