wails/v3/internal/commands/task_test.go
Lea Anthony bf805b4152
Update CLI to pass through variables (#4488)
* feat: Update CLI to pass parameters through to Task commands

- Modified build and package commands to accept otherArgs parameter
- Updated task wrapper to forward CLI variables to Task
- Enhanced task.go to properly parse and handle CLI variables (KEY=VALUE format)
- Fixes issue where 'wails3 build' and 'wails3 package' commands weren't forwarding parameters

Fixes #4422

* Update changelog

* Apply suggestion from @coderabbitai[bot]

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Fix cli.mdx

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-09 21:44:30 +10:00

188 lines
No EOL
4.7 KiB
Go

package commands
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/wailsapp/task/v3/taskfile/ast"
)
func TestParseTaskAndVars(t *testing.T) {
tests := []struct {
name string
options *RunTaskOptions
otherArgs []string
osArgs []string
expectedTask string
expectedVars map[string]string
}{
{
name: "Task name in options with CLI variables",
options: &RunTaskOptions{Name: "build"},
otherArgs: []string{"PLATFORM=linux", "CONFIG=production"},
expectedTask: "build",
expectedVars: map[string]string{
"PLATFORM": "linux",
"CONFIG": "production",
},
},
{
name: "Task name and variables in otherArgs",
options: &RunTaskOptions{},
otherArgs: []string{"test", "ENV=staging", "DEBUG=true"},
expectedTask: "test",
expectedVars: map[string]string{
"ENV": "staging",
"DEBUG": "true",
},
},
{
name: "Only task name, no variables",
options: &RunTaskOptions{},
otherArgs: []string{"deploy"},
expectedTask: "deploy",
expectedVars: map[string]string{},
},
{
name: "Default task when no args provided",
options: &RunTaskOptions{},
otherArgs: []string{},
osArgs: []string{"wails3", "task"}, // Set explicit os.Args to avoid test framework interference
expectedTask: "default",
expectedVars: map[string]string{},
},
{
name: "Variables with equals signs in values",
options: &RunTaskOptions{Name: "build"},
otherArgs: []string{"URL=https://example.com?key=value", "CONFIG=key1=val1,key2=val2"},
expectedTask: "build",
expectedVars: map[string]string{
"URL": "https://example.com?key=value",
"CONFIG": "key1=val1,key2=val2",
},
},
{
name: "Skip non-variable arguments",
options: &RunTaskOptions{Name: "build"},
otherArgs: []string{"PLATFORM=linux", "some-arg", "CONFIG=debug", "--flag"},
expectedTask: "build",
expectedVars: map[string]string{
"PLATFORM": "linux",
"CONFIG": "debug",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save original os.Args
originalArgs := os.Args
defer func() { os.Args = originalArgs }()
if tt.osArgs != nil {
os.Args = tt.osArgs
}
// Parse the task and variables
call := parseTaskCall(tt.options, tt.otherArgs)
// Verify task name
assert.Equal(t, tt.expectedTask, call.Task)
// Verify variables
if len(tt.expectedVars) > 0 {
require.NotNil(t, call.Vars)
// Check each expected variable
for key, expectedValue := range tt.expectedVars {
var actualValue string
call.Vars.Range(func(k string, v ast.Var) error {
if k == key {
actualValue = v.Value.(string)
}
return nil
})
assert.Equal(t, expectedValue, actualValue, "Variable %s mismatch", key)
}
} else if call.Vars != nil {
// Ensure no variables were set when none expected
count := 0
call.Vars.Range(func(k string, v ast.Var) error {
count++
return nil
})
assert.Equal(t, 0, count, "Expected no variables but found %d", count)
}
})
}
}
// Helper function to extract the task parsing logic for testing
func parseTaskCall(options *RunTaskOptions, otherArgs []string) *ast.Call {
var tasksAndVars []string
// Check if we have a task name specified in options
if options.Name != "" {
// If task name is provided via options, use it and treat otherArgs as CLI variables
tasksAndVars = append([]string{options.Name}, otherArgs...)
} else if len(otherArgs) > 0 {
// Use otherArgs directly if provided
tasksAndVars = otherArgs
} else {
// Fall back to parsing os.Args for backward compatibility
var index int
var arg string
for index, arg = range os.Args[2:] {
if len(arg) > 0 && arg[0] != '-' {
break
}
}
for _, taskAndVar := range os.Args[index+2:] {
if taskAndVar == "--" {
break
}
tasksAndVars = append(tasksAndVars, taskAndVar)
}
}
// Default task
if len(tasksAndVars) == 0 {
tasksAndVars = []string{"default"}
}
// Parse task name and CLI variables
taskName := tasksAndVars[0]
cliVars := tasksAndVars[1:]
// Create call with CLI variables
call := &ast.Call{
Task: taskName,
Vars: &ast.Vars{},
}
// Parse CLI variables (format: KEY=VALUE)
for _, v := range cliVars {
if idx := findEquals(v); idx != -1 {
key := v[:idx]
value := v[idx+1:]
call.Vars.Set(key, ast.Var{
Value: value,
})
}
}
return call
}
// Helper to find the first equals sign
func findEquals(s string) int {
for i, r := range s {
if r == '=' {
return i
}
}
return -1
}