diff --git a/cmd/task/task.go b/cmd/task/task.go index 86fda0a5..f3144703 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -140,7 +140,7 @@ func run() error { pflag.BoolVar(&flags.experiments, "experiments", false, "Lists all the available experiments and whether or not they are enabled.") // Gentle force experiment will override the force flag and add a new force-all flag - if experiments.GentleForce { + if experiments.GentleForce.Enabled { pflag.BoolVarP(&flags.force, "force", "f", false, "Forces execution of the directly called task.") pflag.BoolVar(&flags.forceAll, "force-all", false, "Forces execution of the called task and all its dependant tasks.") } else { @@ -148,7 +148,7 @@ func run() error { } // Remote Taskfiles experiment will adds the "download" and "offline" flags - if experiments.RemoteTaskfiles { + if experiments.RemoteTaskfiles.Enabled { pflag.BoolVar(&flags.download, "download", false, "Downloads a cached version of a remote Taskfile.") pflag.BoolVar(&flags.offline, "offline", false, "Forces Task to only use local or cached Taskfiles.") pflag.DurationVar(&flags.timeout, "timeout", time.Second*10, "Timeout for downloading remote Taskfiles.") diff --git a/internal/experiments/experiments.go b/internal/experiments/experiments.go index 94f73adb..d88fcb6b 100644 --- a/internal/experiments/experiments.go +++ b/internal/experiments/experiments.go @@ -8,29 +8,55 @@ import ( "text/tabwriter" "github.com/joho/godotenv" + "golang.org/x/exp/slices" "github.com/go-task/task/v3/internal/logger" ) const envPrefix = "TASK_X_" +type Experiment struct { + Name string + Enabled bool + Value string +} + // A list of experiments. var ( - GentleForce bool - RemoteTaskfiles bool - AnyVariables bool + GentleForce Experiment + RemoteTaskfiles Experiment + AnyVariables Experiment ) func init() { readDotEnv() - GentleForce = parseEnv("GENTLE_FORCE") - RemoteTaskfiles = parseEnv("REMOTE_TASKFILES") - AnyVariables = parseEnv("ANY_VARIABLES") + GentleForce = New("GENTLE_FORCE") + RemoteTaskfiles = New("REMOTE_TASKFILES") + AnyVariables = New("ANY_VARIABLES") } -func parseEnv(xName string) bool { +func New(xName string, enabledValues ...string) Experiment { + if len(enabledValues) == 0 { + enabledValues = []string{"1"} + } + value := getEnv(xName) + return Experiment{ + Name: xName, + Enabled: slices.Contains(enabledValues, value), + Value: value, + } +} + +func (x Experiment) String() string { + if x.Enabled { + return fmt.Sprintf("on (%s)", x.Value) + } + return "off" +} + +func getEnv(xName string) string { envName := fmt.Sprintf("%s%s", envPrefix, xName) - return os.Getenv(envName) == "1" + return os.Getenv(envName) } func readDotEnv() { @@ -43,16 +69,16 @@ func readDotEnv() { } } -func printExperiment(w io.Writer, l *logger.Logger, name string, value bool) { +func printExperiment(w io.Writer, l *logger.Logger, x Experiment) { l.FOutf(w, logger.Yellow, "* ") - l.FOutf(w, logger.Green, name) - l.FOutf(w, logger.Default, ": \t%t\n", value) + l.FOutf(w, logger.Green, x.Name) + l.FOutf(w, logger.Default, ": \t%s\n", x.String()) } func List(l *logger.Logger) error { w := tabwriter.NewWriter(os.Stdout, 0, 8, 0, ' ', 0) - printExperiment(w, l, "GENTLE_FORCE", GentleForce) - printExperiment(w, l, "REMOTE_TASKFILES", RemoteTaskfiles) - printExperiment(w, l, "ANY_VARIABLES", AnyVariables) + printExperiment(w, l, GentleForce) + printExperiment(w, l, RemoteTaskfiles) + printExperiment(w, l, AnyVariables) return w.Flush() } diff --git a/taskfile/ast/var.go b/taskfile/ast/var.go index 93f883da..69a494ef 100644 --- a/taskfile/ast/var.go +++ b/taskfile/ast/var.go @@ -80,7 +80,7 @@ type Var struct { } func (v *Var) UnmarshalYAML(node *yaml.Node) error { - if experiments.AnyVariables { + if experiments.AnyVariables.Enabled { var value any if err := node.Decode(&value); err != nil { return err diff --git a/taskfile/node.go b/taskfile/node.go index d71ede73..b8c0debe 100644 --- a/taskfile/node.go +++ b/taskfile/node.go @@ -30,7 +30,7 @@ func NewNode( // If no other scheme matches, we assume it's a file node, err = NewFileNode(uri, opts...) } - if node.Remote() && !experiments.RemoteTaskfiles { + if node.Remote() && !experiments.RemoteTaskfiles.Enabled { return nil, errors.New("task: Remote taskfiles are not enabled. You can read more about this experiment and how to enable it at https://taskfile.dev/experiments/remote-taskfiles") } return node, err