From c8ff2489997c3071cf8f4fcf1c863257c12b07cd Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Tue, 22 Apr 2025 08:48:34 +0200 Subject: [PATCH 1/9] feat: read cache expiry from taskrc and env --- experiments/experiments.go | 11 +++-- internal/flags/flags.go | 71 ++++++++++++++++++++++++++++++- taskrc/ast/taskrc.go | 10 ++++- website/static/schema-taskrc.json | 9 ++++ 4 files changed, 95 insertions(+), 6 deletions(-) diff --git a/experiments/experiments.go b/experiments/experiments.go index 9e646c57b7..00d2cac706 100644 --- a/experiments/experiments.go +++ b/experiments/experiments.go @@ -2,6 +2,7 @@ package experiments import ( "fmt" + "github.com/go-task/task/v3/taskrc/ast" "os" "path/filepath" "strings" @@ -31,9 +32,6 @@ var ( var xList []Experiment func Parse(dir string) { - // Read any .env files - readDotEnv(dir) - // Create a node for the Task config reader node, _ := taskrc.NewNode("", dir) @@ -41,6 +39,13 @@ func Parse(dir string) { reader := taskrc.NewReader() config, _ := reader.Read(node) + ParseWithConfig(dir, config) +} + +func ParseWithConfig(dir string, config *ast.TaskRC) { + // Read any .env files + readDotEnv(dir) + // Initialize the experiments GentleForce = New("GENTLE_FORCE", config, 1) RemoteTaskfiles = New("REMOTE_TASKFILES", config, 1) diff --git a/internal/flags/flags.go b/internal/flags/flags.go index dab9fdf8f4..4911408c71 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -2,6 +2,7 @@ package flags import ( "cmp" + "github.com/go-task/task/v3/taskrc" "log" "os" "path/filepath" @@ -95,7 +96,14 @@ func init() { // Parse the experiments dir = cmp.Or(dir, filepath.Dir(entrypoint)) - experiments.Parse(dir) + + node, _ := taskrc.NewNode("", dir) + + reader := taskrc.NewReader() + config, _ := reader.Read(node) + + expiry := getDurationValue(config.Remote.Expiry, "REMOTE_EXPIRY", 0) + experiments.ParseWithConfig(dir, config) // Parse the rest of the flags log.SetFlags(0) @@ -153,7 +161,7 @@ func init() { pflag.BoolVar(&Offline, "offline", offline, "Forces Task to only use local or cached Taskfiles.") pflag.DurationVar(&Timeout, "timeout", time.Second*10, "Timeout for downloading remote Taskfiles.") pflag.BoolVar(&ClearCache, "clear-cache", false, "Clear the remote cache.") - pflag.DurationVar(&CacheExpiryDuration, "expiry", 0, "Expiry duration for cached remote Taskfiles.") + pflag.DurationVar(&CacheExpiryDuration, "expiry", expiry, "Expiry duration for cached remote Taskfiles.") } pflag.Parse() @@ -251,3 +259,62 @@ func (o *flagsOption) ApplyToExecutor(e *task.Executor) { task.WithVersionCheck(true), ) } + +//func getEffectiveValueFromConfig[T any](config any, fieldName string, envVar string, defaultValue T) T { +// v := reflect.ValueOf(config) +// if v.Kind() == reflect.Ptr { +// v = v.Elem() +// } +// +// if v.Kind() != reflect.Struct { +// return defaultValue +// } +// +// field := v.FieldByName(fieldName) +// if field.IsValid() && !field.IsZero() && field.Kind() == reflect.Ptr { +// // Return value from struct +// actual := field.Elem() +// if actual.IsValid() { +// return actual.Interface().(T) +// } +// } +// +// envVal := os.Getenv(envVar) +// if envVal != "" { +// var parsed any +// var err error +// +// switch any(defaultValue).(type) { +// case int: +// parsedInt, e := strconv.Atoi(envVal) +// parsed, err = parsedInt, e +// case string: +// parsed = envVal +// case bool: +// parsedBool, e := strconv.ParseBool(envVal) +// parsed, err = parsedBool, e +// default: +// return defaultValue // unsupported type +// } +// +// if err == nil { +// return parsed.(T) +// } +// } +// +// return defaultValue +//} + +func getDurationValue(configValue *time.Duration, envVarName string, defaultValue time.Duration) time.Duration { + if configValue != nil { + return *configValue + } + + if envVal := env.GetTaskEnv(envVarName); envVal != "" { + if intVal, err := time.ParseDuration(envVal); err == nil { + return intVal + } + } + + return defaultValue +} diff --git a/taskrc/ast/taskrc.go b/taskrc/ast/taskrc.go index f82452a94d..9ff8c09553 100644 --- a/taskrc/ast/taskrc.go +++ b/taskrc/ast/taskrc.go @@ -1,8 +1,16 @@ package ast -import "github.com/Masterminds/semver/v3" +import ( + "github.com/Masterminds/semver/v3" + "time" +) type TaskRC struct { Version *semver.Version `yaml:"version"` Experiments map[string]int `yaml:"experiments"` + Remote remote `yaml:"remote"` +} + +type remote struct { + Expiry *time.Duration `yaml:"expiry"` } diff --git a/website/static/schema-taskrc.json b/website/static/schema-taskrc.json index 4ed35be313..594d5212dc 100644 --- a/website/static/schema-taskrc.json +++ b/website/static/schema-taskrc.json @@ -9,6 +9,15 @@ "additionalProperties": { "type": "integer" } + }, "remote": { + "type": "object", + "properties": { + "cache-expiry": { + "type": "string", + "description": "Duration format (e.g. '5s', '10m', '1h30m') compatible with Go time.Duration" + } + }, + "additionalProperties": false } }, "additionalProperties": false From c8a3ecc7fa70bc5932e33cfe9c9512080df08374 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Wed, 23 Apr 2025 10:44:21 +0200 Subject: [PATCH 2/9] rename const --- internal/flags/flags.go | 2 +- taskrc/ast/taskrc.go | 2 +- website/static/schema-taskrc.json | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/flags/flags.go b/internal/flags/flags.go index 4911408c71..b4c89f7db8 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -102,7 +102,7 @@ func init() { reader := taskrc.NewReader() config, _ := reader.Read(node) - expiry := getDurationValue(config.Remote.Expiry, "REMOTE_EXPIRY", 0) + expiry := getDurationValue(config.Remote.CacheExpiry, "REMOTE_CACHE_EXPIRY", 0) experiments.ParseWithConfig(dir, config) // Parse the rest of the flags diff --git a/taskrc/ast/taskrc.go b/taskrc/ast/taskrc.go index 9ff8c09553..cdbe8fd173 100644 --- a/taskrc/ast/taskrc.go +++ b/taskrc/ast/taskrc.go @@ -12,5 +12,5 @@ type TaskRC struct { } type remote struct { - Expiry *time.Duration `yaml:"expiry"` + CacheExpiry *time.Duration `yaml:"cache-expiry"` } diff --git a/website/static/schema-taskrc.json b/website/static/schema-taskrc.json index 594d5212dc..6ac80142f7 100644 --- a/website/static/schema-taskrc.json +++ b/website/static/schema-taskrc.json @@ -9,7 +9,8 @@ "additionalProperties": { "type": "integer" } - }, "remote": { + }, + "remote": { "type": "object", "properties": { "cache-expiry": { From f75fb739858e4b5b257747fc70fc9819e73e67d5 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 25 Apr 2025 12:47:24 +0200 Subject: [PATCH 3/9] remove comment --- internal/flags/flags.go | 45 ----------------------------------------- 1 file changed, 45 deletions(-) diff --git a/internal/flags/flags.go b/internal/flags/flags.go index b4c89f7db8..5fcc2ae7c3 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -260,51 +260,6 @@ func (o *flagsOption) ApplyToExecutor(e *task.Executor) { ) } -//func getEffectiveValueFromConfig[T any](config any, fieldName string, envVar string, defaultValue T) T { -// v := reflect.ValueOf(config) -// if v.Kind() == reflect.Ptr { -// v = v.Elem() -// } -// -// if v.Kind() != reflect.Struct { -// return defaultValue -// } -// -// field := v.FieldByName(fieldName) -// if field.IsValid() && !field.IsZero() && field.Kind() == reflect.Ptr { -// // Return value from struct -// actual := field.Elem() -// if actual.IsValid() { -// return actual.Interface().(T) -// } -// } -// -// envVal := os.Getenv(envVar) -// if envVal != "" { -// var parsed any -// var err error -// -// switch any(defaultValue).(type) { -// case int: -// parsedInt, e := strconv.Atoi(envVal) -// parsed, err = parsedInt, e -// case string: -// parsed = envVal -// case bool: -// parsedBool, e := strconv.ParseBool(envVal) -// parsed, err = parsedBool, e -// default: -// return defaultValue // unsupported type -// } -// -// if err == nil { -// return parsed.(T) -// } -// } -// -// return defaultValue -//} - func getDurationValue(configValue *time.Duration, envVarName string, defaultValue time.Duration) time.Duration { if configValue != nil { return *configValue From 614ef72fd3280edbf4b4ab26c522df821d9d5f67 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 25 Apr 2025 13:10:25 +0200 Subject: [PATCH 4/9] fix lint --- experiments/experiments.go | 3 ++- internal/flags/flags.go | 3 ++- taskrc/ast/taskrc.go | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/experiments/experiments.go b/experiments/experiments.go index 00d2cac706..b46d0fe01b 100644 --- a/experiments/experiments.go +++ b/experiments/experiments.go @@ -2,11 +2,12 @@ package experiments import ( "fmt" - "github.com/go-task/task/v3/taskrc/ast" "os" "path/filepath" "strings" + "github.com/go-task/task/v3/taskrc/ast" + "github.com/joho/godotenv" "github.com/go-task/task/v3/taskrc" diff --git a/internal/flags/flags.go b/internal/flags/flags.go index 5fcc2ae7c3..246c0a542c 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -2,13 +2,14 @@ package flags import ( "cmp" - "github.com/go-task/task/v3/taskrc" "log" "os" "path/filepath" "strconv" "time" + "github.com/go-task/task/v3/taskrc" + "github.com/spf13/pflag" "github.com/go-task/task/v3" diff --git a/taskrc/ast/taskrc.go b/taskrc/ast/taskrc.go index cdbe8fd173..fdd0b2b305 100644 --- a/taskrc/ast/taskrc.go +++ b/taskrc/ast/taskrc.go @@ -1,8 +1,9 @@ package ast import ( - "github.com/Masterminds/semver/v3" "time" + + "github.com/Masterminds/semver/v3" ) type TaskRC struct { From 0fae9a6346652edb3345c4188052dafea1a7b3b7 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 28 Apr 2025 14:23:25 +0200 Subject: [PATCH 5/9] add docs --- website/docs/experiments/remote_taskfiles.mdx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/website/docs/experiments/remote_taskfiles.mdx b/website/docs/experiments/remote_taskfiles.mdx index b9c2d1f2cb..ef9c9b82eb 100644 --- a/website/docs/experiments/remote_taskfiles.mdx +++ b/website/docs/experiments/remote_taskfiles.mdx @@ -224,8 +224,18 @@ internet and cached locally. This cached file will be used for all future invocations of the Taskfile until the cache expires. Once it expires, Task will download the latest copy of the file and update the cache. By default, the cache is set to expire immediately. This means that Task will always fetch the latest -version. However, the cache expiry duration can be modified by setting the -`--expiry` flag. +version. However, the cache expiry duration can be modified by: +- Setting the `--expiry` flag +- Configuring it in your taskrc file: +```yaml +remote: + cache-expiry: 24h +``` + +The expiry duration should be specified in a format like "24h", "30m", "1h30m", etc. + + + If for any reason you lose access to the internet or you are running Task in offline mode (via the `--offline` flag or `TASK_OFFLINE` environment variable), From 3ee80f8f3558a75b49aea6cfad397c0beee4db1d Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 28 Apr 2025 14:25:35 +0200 Subject: [PATCH 6/9] lint import --- experiments/experiments.go | 3 +-- internal/flags/flags.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/experiments/experiments.go b/experiments/experiments.go index b46d0fe01b..af1c8898e2 100644 --- a/experiments/experiments.go +++ b/experiments/experiments.go @@ -6,11 +6,10 @@ import ( "path/filepath" "strings" + "github.com/go-task/task/v3/taskrc" "github.com/go-task/task/v3/taskrc/ast" "github.com/joho/godotenv" - - "github.com/go-task/task/v3/taskrc" ) const envPrefix = "TASK_X_" diff --git a/internal/flags/flags.go b/internal/flags/flags.go index 246c0a542c..59890268e0 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -8,8 +8,6 @@ import ( "strconv" "time" - "github.com/go-task/task/v3/taskrc" - "github.com/spf13/pflag" "github.com/go-task/task/v3" @@ -18,6 +16,7 @@ import ( "github.com/go-task/task/v3/internal/env" "github.com/go-task/task/v3/internal/sort" "github.com/go-task/task/v3/taskfile/ast" + "github.com/go-task/task/v3/taskrc" ) const usage = `Usage: task [flags...] [task...] From 911370cb8899133098b387702615d94fcc0ee892 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 28 Apr 2025 14:28:41 +0200 Subject: [PATCH 7/9] chore: Empty-Commit to trigger CI From 320887a84a6a7a84fd6799a6e4aa87313d518cd8 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 28 Apr 2025 14:30:33 +0200 Subject: [PATCH 8/9] lint --- experiments/experiments.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/experiments.go b/experiments/experiments.go index af1c8898e2..59722e1feb 100644 --- a/experiments/experiments.go +++ b/experiments/experiments.go @@ -6,10 +6,10 @@ import ( "path/filepath" "strings" + "github.com/joho/godotenv" + "github.com/go-task/task/v3/taskrc" "github.com/go-task/task/v3/taskrc/ast" - - "github.com/joho/godotenv" ) const envPrefix = "TASK_X_" From 7a32da5c2f8fae6f30fc490d763683aabd4db725 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 28 Apr 2025 14:33:43 +0200 Subject: [PATCH 9/9] better doc --- website/docs/experiments/remote_taskfiles.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docs/experiments/remote_taskfiles.mdx b/website/docs/experiments/remote_taskfiles.mdx index ef9c9b82eb..6246de4398 100644 --- a/website/docs/experiments/remote_taskfiles.mdx +++ b/website/docs/experiments/remote_taskfiles.mdx @@ -231,6 +231,7 @@ version. However, the cache expiry duration can be modified by: remote: cache-expiry: 24h ``` +- Setting the `TASK_REMOTE_CACHE_EXPIRY` environment variable The expiry duration should be specified in a format like "24h", "30m", "1h30m", etc.