Files
task/experiments/experiment.go
2026-07-02 17:22:26 +00:00

96 lines
2.3 KiB
Go

package experiments
import (
"fmt"
"slices"
"strconv"
"github.com/go-task/task/v3/taskrc/ast"
)
type Experiment struct {
Name string // The name of the experiment.
AllowedValues []int // The values that can enable this experiment.
Value int // The version of the experiment that is enabled.
InactiveReason string // If not active, the reason why it is inactive.
}
func getValue(xName string, config *ast.TaskRC) int {
var value int
if config != nil {
value = config.Experiments[xName]
}
if value == 0 {
value, _ = strconv.Atoi(getEnv(xName))
}
return value
}
// New creates a new experiment with the given name and sets the values that can
// enable it.
func New(xName string, config *ast.TaskRC, allowedValues ...int) Experiment {
x := Experiment{
Name: xName,
AllowedValues: allowedValues,
Value: getValue(xName, config),
}
xList = append(xList, x)
return x
}
// NewReleased creates a new experiment that is released and no longer needs to
// be enabled. It will always be inactive and cannot be enabled.
func NewReleased(xName string, config *ast.TaskRC) Experiment {
x := Experiment{
Name: xName,
Value: getValue(xName, config),
InactiveReason: "is released and no longer needs to be enabled",
}
xList = append(xList, x)
return x
}
// NewAbandoned creates a new experiment that has been abandoned and is no
// longer supported. It will always be inactive and cannot be enabled.
func NewAbandoned(xName string, config *ast.TaskRC) Experiment {
x := Experiment{
Name: xName,
Value: getValue(xName, config),
InactiveReason: "has been abandoned and is no longer supported",
}
xList = append(xList, x)
return x
}
func (x Experiment) Enabled() bool {
return slices.Contains(x.AllowedValues, x.Value)
}
func (x Experiment) Active() bool {
return len(x.AllowedValues) > 0
}
func (x Experiment) Valid() error {
if !x.Active() && x.Value != 0 {
return &InactiveError{
Name: x.Name,
Reason: x.InactiveReason,
}
}
if !x.Enabled() && x.Value != 0 {
return &InvalidValueError{
Name: x.Name,
AllowedValues: x.AllowedValues,
Value: x.Value,
}
}
return nil
}
func (x Experiment) String() string {
if x.Enabled() {
return fmt.Sprintf("on (%d)", x.Value)
}
return "off"
}