diff --git a/cmd/uncloud/service/exec.go b/cmd/uncloud/service/exec.go index 445627f3..b05f0051 100644 --- a/cmd/uncloud/service/exec.go +++ b/cmd/uncloud/service/exec.go @@ -48,8 +48,7 @@ If the service has multiple replicas and no container ID is specified, the comma Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { uncli := cmd.Context().Value("cli").(*cli.CLI) - serviceName := args[0] - command := args[1:] + serviceName, command := normalizeExecArgs(args) if len(command) == 0 { command = DEFAULT_COMMAND } @@ -82,6 +81,15 @@ If the service has multiple replicas and no container ID is specified, the comma return execCmd } +func normalizeExecArgs(args []string) (serviceName string, command []string) { + serviceName = args[0] + command = args[1:] + if len(command) > 0 && command[0] == "--" { + command = command[1:] + } + return serviceName, command +} + func runExec(ctx context.Context, uncli *cli.CLI, serviceName string, command []string, opts execCliOptions) error { // Disable TTY allocation if not connected to a terminal if !tui.IsStdoutTerminal() { diff --git a/cmd/uncloud/service/exec_test.go b/cmd/uncloud/service/exec_test.go new file mode 100644 index 00000000..f1c355e1 --- /dev/null +++ b/cmd/uncloud/service/exec_test.go @@ -0,0 +1,61 @@ +package service + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNormalizeExecArgs(t *testing.T) { + tests := []struct { + name string + args []string + wantServiceName string + wantCommand []string + }{ + { + name: "service only", + args: []string{"test-service"}, + wantServiceName: "test-service", + wantCommand: []string{}, + }, + { + name: "service with command", + args: []string{"test-service", "echo", "hello"}, + wantServiceName: "test-service", + wantCommand: []string{"echo", "hello"}, + }, + { + name: "service with separator and command", + args: []string{"test-service", "--", "echo", "hello"}, + wantServiceName: "test-service", + wantCommand: []string{"echo", "hello"}, + }, + { + name: "service with separator only", + args: []string{"test-service", "--"}, + wantServiceName: "test-service", + wantCommand: []string{}, + }, + { + name: "separator preserves command flag", + args: []string{"test-service", "--", "--help"}, + wantServiceName: "test-service", + wantCommand: []string{"--help"}, + }, + { + name: "only first separator is removed", + args: []string{"test-service", "--", "cmd", "--", "arg"}, + wantServiceName: "test-service", + wantCommand: []string{"cmd", "--", "arg"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotServiceName, gotCommand := normalizeExecArgs(tt.args) + assert.Equal(t, tt.wantServiceName, gotServiceName) + assert.Equal(t, tt.wantCommand, gotCommand) + }) + } +}