Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): set can handle all positional args together #3722

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions internal/core/cobra_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,31 @@ func cobraRun(ctx context.Context, cmd *Command) func(*cobra.Command, []string)

results := MultiResults(nil)
rawArgs = rawArgs.RemoveAllPositional()
for _, positionalArg := range positionalArgs {
rawArgsWithPositional := rawArgs.Add(positionalArgSpec.Name, positionalArg)

if cmd.AcceptMultiplePositionalArgs {
argNameWithIndex := fmt.Sprintf("%s.%d", positionalArgSpec.Name, 0)
rawArgsWithPositional := rawArgs.Add(argNameWithIndex, positionalArgs[0])
for i := 1; i < len(positionalArgs); i++ {
argNameWithIndex = fmt.Sprintf("%s.%d", positionalArgSpec.Name, i)
rawArgsWithPositional = rawArgsWithPositional.Add(argNameWithIndex, positionalArgs[i])
}
result, err := run(ctx, cobraCmd, cmd, rawArgsWithPositional)
if err != nil {
return err
}

results = append(results, result)
} else {
for _, positionalArg := range positionalArgs {
rawArgsWithPositional := rawArgs.Add(positionalArgSpec.Name, positionalArg)

result, err := run(ctx, cobraCmd, cmd, rawArgsWithPositional)
if err != nil {
return err
}

results = append(results, result)
}
}
// If only one positional parameter was provided we return the result directly instead of
// an array of results
Expand Down
71 changes: 71 additions & 0 deletions internal/core/cobra_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/scaleway/scaleway-cli/v2/internal/core"
"github.com/stretchr/testify/assert"

"github.com/scaleway/scaleway-cli/v2/internal/args"
)
Expand All @@ -21,6 +22,11 @@ type testDate struct {
Date *time.Time
}

type testAcceptMultiPositionalArgsType struct {
NameIDs []string
Tag string
}

func testGetCommands() *core.Commands {
return core.NewCommands(
&core.Command{
Expand Down Expand Up @@ -54,6 +60,25 @@ func testGetCommands() *core.Commands {
return argsI, nil
},
},
&core.Command{
Namespace: "test",
Resource: "multi-positional",
ArgSpecs: core.ArgSpecs{
{
Name: "name-ids",
Positional: true,
},
{
Name: "tag",
},
},
AcceptMultiplePositionalArgs: true,
AllowAnonymousClient: true,
ArgsType: reflect.TypeOf(testAcceptMultiPositionalArgsType{}),
Run: func(_ context.Context, argsI interface{}) (i interface{}, e error) {
return argsI, nil
},
},
&core.Command{
Namespace: "test",
Resource: "raw-args",
Expand Down Expand Up @@ -247,3 +272,49 @@ func Test_PositionalArg(t *testing.T) {
),
}))
}

func Test_MultiPositionalArg(t *testing.T) {
t.Run("multi-positional with one positional", core.Test(&core.TestConfig{
Commands: testGetCommands(),
Cmd: "scw test multi-positional pos1 tag=tag1",
Check: core.TestCheckCombine(
core.TestCheckExitCode(0),
core.TestCheckGolden(),
func(t *testing.T, ctx *core.CheckFuncCtx) {
res := ctx.Result.(*testAcceptMultiPositionalArgsType)
assert.Equal(t, 1, len(res.NameIDs))
assert.Equal(t, "pos1", res.NameIDs[0])
assert.Equal(t, "tag1", res.Tag)
},
),
}))

t.Run("multi-positional with multi positional", core.Test(&core.TestConfig{
Commands: testGetCommands(),
Cmd: "scw test multi-positional pos1 pos2 pos3 tag=tag1",
Check: core.TestCheckCombine(
core.TestCheckExitCode(0),
Mia-Cross marked this conversation as resolved.
Show resolved Hide resolved
core.TestCheckGolden(),
func(t *testing.T, ctx *core.CheckFuncCtx) {
res := ctx.Result.(*testAcceptMultiPositionalArgsType)
assert.Equal(t, 3, len(res.NameIDs))
assert.Equal(t, "pos1", res.NameIDs[0])
assert.Equal(t, "pos2", res.NameIDs[1])
assert.Equal(t, "pos3", res.NameIDs[2])
assert.Equal(t, "tag1", res.Tag)
},
),
}))

t.Run("multi-positional with no positional", core.Test(&core.TestConfig{
Commands: testGetCommands(),
Cmd: "scw test multi-positional tag=tag1",
Check: core.TestCheckCombine(
core.TestCheckExitCode(1),
core.TestCheckError(&core.CliError{
Err: fmt.Errorf("a positional argument is required for this command"),
Hint: "Try running: scw test multi-positional <name-ids> tag=tag1",
}),
),
}))
}
4 changes: 4 additions & 0 deletions internal/core/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ type Command struct {
// ArgSpecs defines specifications for arguments.
ArgSpecs ArgSpecs

// AcceptMultiplePositionalArgs defines whether the command can accept multiple positional arguments.
// If enabled, positional argument is expected to be a list.
AcceptMultiplePositionalArgs bool

// View defines the View for this command.
// It is used to create the different options for the different Marshalers.
View *View
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟩🟩🟩 STDOUT️ 🟩🟩🟩️
NameIDs.0 pos1
NameIDs.1 pos2
NameIDs.2 pos3
Tag tag1
🟩🟩🟩 JSON STDOUT 🟩🟩🟩
{
"NameIDs": [
"pos1",
"pos2",
"pos3"
],
"Tag": "tag1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟩🟩🟩 STDOUT️ 🟩🟩🟩️
NameIDs.0 pos1
Tag tag1
🟩🟩🟩 JSON STDOUT 🟩🟩🟩
{
"NameIDs": [
"pos1"
],
"Tag": "tag1"
}
Loading