mirror of
				https://github.com/go-task/task.git
				synced 2025-10-30 23:58:01 +02:00 
			
		
		
		
	feat: use semver package for taskfile schema version
This commit is contained in:
		| @@ -178,11 +178,6 @@ func main() { | ||||
| 	if err := e.Setup(); err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	v, err := e.Taskfile.ParsedVersion() | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if listOptions.ShouldListTasks() { | ||||
| 		if foundTasks, err := e.ListTasks(listOptions); !foundTasks || err != nil { | ||||
| @@ -201,7 +196,7 @@ func main() { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if v >= 3.0 { | ||||
| 	if e.Taskfile.Version.Compare(taskfile.V3) >= 0 { | ||||
| 		calls, globals = args.ParseV3(tasksAndVars...) | ||||
| 	} else { | ||||
| 		calls, globals = args.ParseV2(tasksAndVars...) | ||||
|   | ||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | ||||
| module github.com/go-task/task/v3 | ||||
|  | ||||
| require ( | ||||
| 	github.com/Masterminds/semver/v3 v3.2.0 | ||||
| 	github.com/fatih/color v1.14.1 | ||||
| 	github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 | ||||
| 	github.com/joho/godotenv v1.5.1 | ||||
|   | ||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @@ -1,3 +1,5 @@ | ||||
| github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= | ||||
| github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= | ||||
| github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= | ||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||
|   | ||||
							
								
								
									
										66
									
								
								setup.go
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								setup.go
									
									
									
									
									
								
							| @@ -9,6 +9,9 @@ import ( | ||||
| 	"strings" | ||||
| 	"sync" | ||||
|  | ||||
| 	"github.com/Masterminds/semver/v3" | ||||
| 	"github.com/sajari/fuzzy" | ||||
|  | ||||
| 	compilerv2 "github.com/go-task/task/v3/internal/compiler/v2" | ||||
| 	compilerv3 "github.com/go-task/task/v3/internal/compiler/v3" | ||||
| 	"github.com/go-task/task/v3/internal/execext" | ||||
| @@ -17,8 +20,6 @@ import ( | ||||
| 	"github.com/go-task/task/v3/internal/output" | ||||
| 	"github.com/go-task/task/v3/taskfile" | ||||
| 	"github.com/go-task/task/v3/taskfile/read" | ||||
|  | ||||
| 	"github.com/sajari/fuzzy" | ||||
| ) | ||||
|  | ||||
| func (e *Executor) Setup() error { | ||||
| @@ -32,11 +33,6 @@ func (e *Executor) Setup() error { | ||||
|  | ||||
| 	e.setupFuzzyModel() | ||||
|  | ||||
| 	v, err := e.Taskfile.ParsedVersion() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := e.setupTempDir(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -45,17 +41,17 @@ func (e *Executor) Setup() error { | ||||
| 	if err := e.setupOutput(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if err := e.setupCompiler(v); err != nil { | ||||
| 	if err := e.setupCompiler(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if err := e.readDotEnvFiles(v); err != nil { | ||||
| 	if err := e.readDotEnvFiles(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := e.doVersionChecks(v); err != nil { | ||||
| 	if err := e.doVersionChecks(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	e.setupDefaults(v) | ||||
| 	e.setupDefaults() | ||||
| 	e.setupConcurrencyState() | ||||
|  | ||||
| 	return nil | ||||
| @@ -163,8 +159,8 @@ func (e *Executor) setupOutput() error { | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (e *Executor) setupCompiler(v float64) error { | ||||
| 	if v < 3 { | ||||
| func (e *Executor) setupCompiler() error { | ||||
| 	if e.Taskfile.Version.LessThan(taskfile.V3) { | ||||
| 		var err error | ||||
| 		e.taskvars, err = read.Taskvars(e.Dir) | ||||
| 		if err != nil { | ||||
| @@ -195,8 +191,8 @@ func (e *Executor) setupCompiler(v float64) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (e *Executor) readDotEnvFiles(v float64) error { | ||||
| 	if v < 3.0 { | ||||
| func (e *Executor) readDotEnvFiles() error { | ||||
| 	if e.Taskfile.Version.LessThan(taskfile.V3) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| @@ -214,14 +210,14 @@ func (e *Executor) readDotEnvFiles(v float64) error { | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (e *Executor) setupDefaults(v float64) { | ||||
| func (e *Executor) setupDefaults() { | ||||
| 	// Color available only on v3 | ||||
| 	if v < 3 { | ||||
| 	if e.Taskfile.Version.LessThan(taskfile.V3) { | ||||
| 		e.Logger.Color = false | ||||
| 	} | ||||
|  | ||||
| 	if e.Taskfile.Method == "" { | ||||
| 		if v >= 3 { | ||||
| 		if e.Taskfile.Version.Compare(taskfile.V3) >= 0 { | ||||
| 			e.Taskfile.Method = "checksum" | ||||
| 		} else { | ||||
| 			e.Taskfile.Method = "timestamp" | ||||
| @@ -248,37 +244,41 @@ func (e *Executor) setupConcurrencyState() { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (e *Executor) doVersionChecks(v float64) error { | ||||
| 	if v < 2 { | ||||
| func (e *Executor) doVersionChecks() error { | ||||
| 	// Copy the version to avoid modifying the original | ||||
| 	v := &semver.Version{} | ||||
| 	*v = *e.Taskfile.Version | ||||
|  | ||||
| 	if v.LessThan(taskfile.V2) { | ||||
| 		return fmt.Errorf(`task: Taskfile versions prior to v2 are not supported anymore`) | ||||
| 	} | ||||
|  | ||||
| 	// consider as equal to the greater version if round | ||||
| 	if v == 2.0 { | ||||
| 		v = 2.6 | ||||
| 	if v.Equal(taskfile.V2) { | ||||
| 		v = semver.MustParse("2.6") | ||||
| 	} | ||||
| 	if v == 3.0 { | ||||
| 		v = 3.8 | ||||
| 	if v.Equal(taskfile.V3) { | ||||
| 		v = semver.MustParse("3.8") | ||||
| 	} | ||||
|  | ||||
| 	if v > 3.8 { | ||||
| 	if v.GreaterThan(semver.MustParse("3.8")) { | ||||
| 		return fmt.Errorf(`task: Taskfile versions greater than v3.8 not implemented in the version of Task`) | ||||
| 	} | ||||
|  | ||||
| 	if v < 2.1 && !e.Taskfile.Output.IsSet() { | ||||
| 	if v.LessThan(semver.MustParse("2.1")) && !e.Taskfile.Output.IsSet() { | ||||
| 		return fmt.Errorf(`task: Taskfile option "output" is only available starting on Taskfile version v2.1`) | ||||
| 	} | ||||
| 	if v < 2.2 && e.Taskfile.Includes.Len() > 0 { | ||||
| 	if v.LessThan(semver.MustParse("2.2")) && e.Taskfile.Includes.Len() > 0 { | ||||
| 		return fmt.Errorf(`task: Including Taskfiles is only available starting on Taskfile version v2.2`) | ||||
| 	} | ||||
| 	if v >= 3.0 && e.Taskfile.Expansions > 2 { | ||||
| 	if v.Compare(taskfile.V3) >= 0 && e.Taskfile.Expansions > 2 { | ||||
| 		return fmt.Errorf(`task: The "expansions" setting is not available anymore on v3.0`) | ||||
| 	} | ||||
| 	if v < 3.8 && e.Taskfile.Output.Group.IsSet() { | ||||
| 	if v.LessThan(semver.MustParse("3.8")) && e.Taskfile.Output.Group.IsSet() { | ||||
| 		return fmt.Errorf(`task: Taskfile option "output.group" is only available starting on Taskfile version v3.8`) | ||||
| 	} | ||||
|  | ||||
| 	if v <= 2.1 { | ||||
| 	if v.Compare(semver.MustParse("2.1")) <= 0 { | ||||
| 		err := errors.New(`task: Taskfile option "ignore_error" is only available starting on Taskfile version v2.1`) | ||||
|  | ||||
| 		for _, task := range e.Taskfile.Tasks { | ||||
| @@ -293,7 +293,7 @@ func (e *Executor) doVersionChecks(v float64) error { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if v < 2.6 { | ||||
| 	if v.LessThan(semver.MustParse("2.6")) { | ||||
| 		for _, task := range e.Taskfile.Tasks { | ||||
| 			if len(task.Preconditions) > 0 { | ||||
| 				return errors.New(`task: Task option "preconditions" is only available starting on Taskfile version v2.6`) | ||||
| @@ -301,7 +301,7 @@ func (e *Executor) doVersionChecks(v float64) error { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if v < 3 { | ||||
| 	if v.LessThan(taskfile.V3) { | ||||
| 		err := e.Taskfile.Includes.Range(func(_ string, taskfile taskfile.IncludedTaskfile) error { | ||||
| 			if taskfile.AdvancedImport { | ||||
| 				return errors.New(`task: Import with additional parameters is only available starting on Taskfile version v3`) | ||||
| @@ -313,7 +313,7 @@ func (e *Executor) doVersionChecks(v float64) error { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if v < 3.7 { | ||||
| 	if v.LessThan(semver.MustParse("3.7")) { | ||||
| 		if e.Taskfile.Run != "" { | ||||
| 			return errors.New(`task: Setting the "run" type is only available starting on Taskfile version v3.7`) | ||||
| 		} | ||||
|   | ||||
| @@ -11,6 +11,7 @@ import ( | ||||
| 	"strings" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/Masterminds/semver/v3" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
|  | ||||
| 	"github.com/go-task/task/v3" | ||||
| @@ -726,9 +727,9 @@ func TestCyclicDep(t *testing.T) { | ||||
| func TestTaskVersion(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		Dir     string | ||||
| 		Version string | ||||
| 		Version *semver.Version | ||||
| 	}{ | ||||
| 		{"testdata/version/v2", "2"}, | ||||
| 		{"testdata/version/v2", semver.MustParse("2")}, | ||||
| 	} | ||||
|  | ||||
| 	for _, test := range tests { | ||||
|   | ||||
| @@ -10,7 +10,7 @@ const NamespaceSeparator = ":" | ||||
|  | ||||
| // Merge merges the second Taskfile into the first | ||||
| func Merge(t1, t2 *Taskfile, includedTaskfile *IncludedTaskfile, namespaces ...string) error { | ||||
| 	if t1.Version != t2.Version { | ||||
| 	if !t1.Version.Equal(t2.Version) { | ||||
| 		return fmt.Errorf(`task: Taskfiles versions should match. First is "%s" but second is "%s"`, t1.Version, t2.Version) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -58,11 +58,6 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, string, error) { | ||||
| 		return nil, "", err | ||||
| 	} | ||||
|  | ||||
| 	v, err := t.ParsedVersion() | ||||
| 	if err != nil { | ||||
| 		return nil, "", err | ||||
| 	} | ||||
|  | ||||
| 	// Annotate any included Taskfile reference with a base directory for resolving relative paths | ||||
| 	_ = t.Includes.Range(func(key string, includedFile taskfile.IncludedTaskfile) error { | ||||
| 		// Set the base directory for resolving relative paths, but only if not already set | ||||
| @@ -74,7 +69,7 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, string, error) { | ||||
| 	}) | ||||
|  | ||||
| 	err = t.Includes.Range(func(namespace string, includedTask taskfile.IncludedTaskfile) error { | ||||
| 		if v >= 3.0 { | ||||
| 		if t.Version.Compare(taskfile.V3) >= 0 { | ||||
| 			tr := templater.Templater{Vars: t.Vars, RemoveNoValue: true} | ||||
| 			includedTask = taskfile.IncludedTaskfile{ | ||||
| 				Taskfile:       tr.Replace(includedTask.Taskfile), | ||||
| @@ -123,7 +118,7 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, string, error) { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		if v >= 3.0 && len(includedTaskfile.Dotenv) > 0 { | ||||
| 		if t.Version.Compare(taskfile.V3) >= 0 && len(includedTaskfile.Dotenv) > 0 { | ||||
| 			return ErrIncludedTaskfilesCantHaveDotenvs | ||||
| 		} | ||||
|  | ||||
| @@ -168,7 +163,7 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, string, error) { | ||||
| 		return nil, "", err | ||||
| 	} | ||||
|  | ||||
| 	if v < 3.0 { | ||||
| 	if t.Version.Compare(taskfile.V3) < 0 { | ||||
| 		path = filepathext.SmartJoin(readerNode.Dir, fmt.Sprintf("Taskfile_%s.yml", runtime.GOOS)) | ||||
| 		if _, err = os.Stat(path); err == nil { | ||||
| 			osTaskfile, err := readTaskfile(path) | ||||
|   | ||||
| @@ -2,15 +2,20 @@ package taskfile | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/Masterminds/semver/v3" | ||||
| 	"gopkg.in/yaml.v3" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	V3 = semver.MustParse("3") | ||||
| 	V2 = semver.MustParse("2") | ||||
| ) | ||||
|  | ||||
| // Taskfile represents a Taskfile.yml | ||||
| type Taskfile struct { | ||||
| 	Version    string | ||||
| 	Version    *semver.Version | ||||
| 	Expansions int | ||||
| 	Output     Output | ||||
| 	Method     string | ||||
| @@ -31,7 +36,7 @@ func (tf *Taskfile) UnmarshalYAML(node *yaml.Node) error { | ||||
|  | ||||
| 	case yaml.MappingNode: | ||||
| 		var taskfile struct { | ||||
| 			Version    string | ||||
| 			Version    *semver.Version | ||||
| 			Expansions int | ||||
| 			Output     Output | ||||
| 			Method     string | ||||
| @@ -77,12 +82,3 @@ func (tf *Taskfile) UnmarshalYAML(node *yaml.Node) error { | ||||
|  | ||||
| 	return fmt.Errorf("yaml: line %d: cannot unmarshal %s into taskfile", node.Line, node.ShortTag()) | ||||
| } | ||||
|  | ||||
| // ParsedVersion returns the version as a float64 | ||||
| func (tf *Taskfile) ParsedVersion() (float64, error) { | ||||
| 	v, err := strconv.ParseFloat(tf.Version, 64) | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf(`task: Could not parse taskfile version "%s": %v`, tf.Version, err) | ||||
| 	} | ||||
| 	return v, nil | ||||
| } | ||||
|   | ||||
| @@ -40,12 +40,7 @@ func (e *Executor) compiledTask(call taskfile.Call, evaluateShVars bool) (*taskf | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	v, err := e.Taskfile.ParsedVersion() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	r := templater.Templater{Vars: vars, RemoveNoValue: v >= 3.0} | ||||
| 	r := templater.Templater{Vars: vars, RemoveNoValue: e.Taskfile.Version.Compare(taskfile.V3) >= 0} | ||||
|  | ||||
| 	new := taskfile.Task{ | ||||
| 		Task:                 origTask.Task, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user