feat: display allowed values when vars are not provided (#2052)

This commit is contained in:
Valentin Maerten
2025-02-20 20:08:14 +01:00
committed by GitHub
parent 2b4d9bfba7
commit 35ea4e0460
4 changed files with 44 additions and 18 deletions

View File

@@ -141,21 +141,37 @@ func (err *TaskCancelledNoTerminalError) Code() int {
return CodeTaskCancelled return CodeTaskCancelled
} }
// TaskMissingRequiredVars is returned when a task is missing required variables. // TaskMissingRequiredVarsError is returned when a task is missing required variables.
type TaskMissingRequiredVars struct {
type MissingVar struct {
Name string
AllowedValues []string
}
type TaskMissingRequiredVarsError struct {
TaskName string TaskName string
MissingVars []string MissingVars []MissingVar
} }
func (err *TaskMissingRequiredVars) Error() string { func (v MissingVar) String() string {
if len(v.AllowedValues) == 0 {
return v.Name
}
return fmt.Sprintf("%s (allowed values: %v)", v.Name, v.AllowedValues)
}
func (err *TaskMissingRequiredVarsError) Error() string {
var vars []string
for _, v := range err.MissingVars {
vars = append(vars, v.String())
}
return fmt.Sprintf( return fmt.Sprintf(
`task: Task %q cancelled because it is missing required variables: %s`, `task: Task %q cancelled because it is missing required variables: %s`,
err.TaskName, err.TaskName,
strings.Join(err.MissingVars, ", "), strings.Join(vars, ", "))
)
} }
func (err *TaskMissingRequiredVars) Code() int { func (err *TaskMissingRequiredVarsError) Code() int {
return CodeTaskMissingRequiredVars return CodeTaskMissingRequiredVars
} }
@@ -165,12 +181,12 @@ type NotAllowedVar struct {
Name string Name string
} }
type TaskNotAllowedVars struct { type TaskNotAllowedVarsError struct {
TaskName string TaskName string
NotAllowedVars []NotAllowedVar NotAllowedVars []NotAllowedVar
} }
func (err *TaskNotAllowedVars) Error() string { func (err *TaskNotAllowedVarsError) Error() string {
var builder strings.Builder var builder strings.Builder
builder.WriteString(fmt.Sprintf("task: Task %q cancelled because it is missing required variables:\n", err.TaskName)) builder.WriteString(fmt.Sprintf("task: Task %q cancelled because it is missing required variables:\n", err.TaskName))
@@ -181,6 +197,6 @@ func (err *TaskNotAllowedVars) Error() string {
return builder.String() return builder.String()
} }
func (err *TaskNotAllowedVars) Code() int { func (err *TaskNotAllowedVarsError) Code() int {
return CodeTaskNotAllowedVars return CodeTaskNotAllowedVars
} }

View File

@@ -12,16 +12,19 @@ func (e *Executor) areTaskRequiredVarsSet(t *ast.Task) error {
return nil return nil
} }
var missingVars []string var missingVars []errors.MissingVar
for _, requiredVar := range t.Requires.Vars { for _, requiredVar := range t.Requires.Vars {
_, ok := t.Vars.Get(requiredVar.Name) _, ok := t.Vars.Get(requiredVar.Name)
if !ok { if !ok {
missingVars = append(missingVars, requiredVar.Name) missingVars = append(missingVars, errors.MissingVar{
Name: requiredVar.Name,
AllowedValues: requiredVar.Enum,
})
} }
} }
if len(missingVars) > 0 { if len(missingVars) > 0 {
return &errors.TaskMissingRequiredVars{ return &errors.TaskMissingRequiredVarsError{
TaskName: t.Name(), TaskName: t.Name(),
MissingVars: missingVars, MissingVars: missingVars,
} }
@@ -51,7 +54,7 @@ func (e *Executor) areTaskRequiredVarsAllowedValuesSet(t *ast.Task) error {
} }
if len(notAllowedValuesVars) > 0 { if len(notAllowedValuesVars) > 0 {
return &errors.TaskNotAllowedVars{ return &errors.TaskNotAllowedVarsError{
TaskName: t.Name(), TaskName: t.Name(),
NotAllowedVars: notAllowedValuesVars, NotAllowedVars: notAllowedValuesVars,
} }

View File

@@ -186,23 +186,30 @@ func TestRequires(t *testing.T) {
vars := ast.NewVars() vars := ast.NewVars()
vars.Set("FOO", ast.Var{Value: "bar"}) vars.Set("FOO", ast.Var{Value: "bar"})
require.NoError(t, e.Run(context.Background(), &ast.Call{ require.NoError(t, e.Run(context.Background(), &ast.Call{
Task: "missing-var", Task: "missing-var",
Vars: vars, Vars: vars,
})) }))
buff.Reset() buff.Reset()
vars.Set("ENV", ast.Var{Value: "dev"})
require.NoError(t, e.Setup()) require.NoError(t, e.Setup())
require.ErrorContains(t, e.Run(context.Background(), &ast.Call{Task: "validation-var", Vars: vars}), "task: Task \"validation-var\" cancelled because it is missing required variables:\n - FOO has an invalid value : 'bar' (allowed values : [one two])") require.ErrorContains(t, e.Run(context.Background(), &ast.Call{Task: "validation-var", Vars: vars}), "task: Task \"validation-var\" cancelled because it is missing required variables:\n - FOO has an invalid value : 'bar' (allowed values : [one two])")
buff.Reset() buff.Reset()
require.NoError(t, e.Setup()) require.NoError(t, e.Setup())
require.NoError(t, e.Run(context.Background(), &ast.Call{Task: "validation-var-dynamic", Vars: vars})) vars.Set("FOO", ast.Var{Value: "one"})
require.NoError(t, e.Run(context.Background(), &ast.Call{Task: "validation-var", Vars: vars}))
buff.Reset()
vars = ast.NewVars()
require.NoError(t, e.Setup())
require.ErrorContains(t, e.Run(context.Background(), &ast.Call{Task: "validation-var", Vars: vars}), "task: Task \"validation-var\" cancelled because it is missing required variables: ENV, FOO (allowed values: [one two])")
buff.Reset() buff.Reset()
require.NoError(t, e.Setup()) require.NoError(t, e.Setup())
vars.Set("FOO", ast.Var{Value: "one"}) require.NoError(t, e.Run(context.Background(), &ast.Call{Task: "validation-var-dynamic", Vars: vars}))
require.NoError(t, e.Run(context.Background(), &ast.Call{Task: "validation-var", Vars: vars}))
buff.Reset() buff.Reset()
require.NoError(t, e.Setup()) require.NoError(t, e.Setup())

View File

@@ -33,10 +33,10 @@ tasks:
validation-var: validation-var:
requires: requires:
vars: vars:
- ENV
- name: FOO - name: FOO
enum: ['one', 'two'] enum: ['one', 'two']
require-before-compile: require-before-compile:
requires: requires:
vars: [ MY_VAR ] vars: [ MY_VAR ]