Skip to content

Commit

Permalink
fix(os/gcmd): cannot retrieve all args if no subcommand defined for a…
Browse files Browse the repository at this point in the history
… root command (#3850)
  • Loading branch information
gqcn authored Oct 10, 2024
1 parent 4d29939 commit e3e5c89
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 7 deletions.
2 changes: 1 addition & 1 deletion cmd/gf/gfcmd/gfcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (c *Command) Run(ctx context.Context) {
func GetCommand(ctx context.Context) (*Command, error) {
root, err := gcmd.NewFromObject(cmd.GF)
if err != nil {
panic(err)
return nil, err
}
err = root.AddObject(
cmd.Up,
Expand Down
10 changes: 7 additions & 3 deletions os/gcmd/gcmd_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@ type Command struct {
Arguments []Argument // Argument array, configuring how this command act.
Func Function // Custom function.
FuncWithValue FuncWithValue // Custom function with output parameters that can interact with command caller.
HelpFunc Function // Custom help function
HelpFunc Function // Custom help function.
Examples string // Usage examples.
Additional string // Additional info about this command, which will be appended to the end of help info.
Strict bool // Strict parsing options, which means it returns error if invalid option given.
CaseSensitive bool // CaseSensitive parsing options, which means it parses input options in case-sensitive way.
Config string // Config node name, which also retrieves the values from config component along with command line.
parent *Command // Parent command for internal usage.
commands []*Command // Sub commands of this command.
internalCommandAttributes
}

type internalCommandAttributes struct {
parent *Command // Parent command for internal usage.
commands []*Command // Sub commands of this command.
}

// Function is a custom command callback function that is bound to a certain argument.
Expand Down
9 changes: 6 additions & 3 deletions os/gcmd/gcmd_command_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,15 @@ func (c *Command) RunWithSpecificArgs(ctx context.Context, args []string) (value
return nil, err
}
parsedArgs := parser.GetArgAll()
if len(parsedArgs) == 1 {
return c.doRun(ctx, args, parser)
}

// Exclude the root binary name.
parsedArgs = parsedArgs[1:]

// If no args or no sub command, it runs standalone.
if len(parsedArgs) == 0 || len(c.commands) == 0 {
return c.doRun(ctx, args, parser)
}

// Find the matched command and run it.
// It here `fromArgIndex` set to 1 to calculate the argument index in to `newCtx`.
lastCmd, foundCmd, newCtx := c.searchCommand(ctx, parsedArgs, 1)
Expand Down Expand Up @@ -129,6 +131,7 @@ func (c *Command) doRun(ctx context.Context, args []string, parser *Parser) (val
}
return nil, c.defaultHelpFunc(ctx, parser)
}

// OpenTelemetry for command.
var (
span trace.Span
Expand Down
23 changes: 23 additions & 0 deletions os/gcmd/gcmd_z_unit_issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,26 @@ func Test_Issue3670(t *testing.T) {
t.Assert(value.(*Issue3670LastOutput).Content, `{"Country":"china","Singer":"邓丽君"}`)
})
}

func Test_Issue3701(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var (
outputArgs []string
inputArgs = []string{"abc", "def"}
ctx = gctx.New()
cmd = gcmd.Command{
Name: "main",
Usage: "main",
Brief: "...",
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
outputArgs = parser.GetArgAll()
return nil
},
}
)

_, err := cmd.RunWithSpecificArgs(ctx, inputArgs)
t.AssertNil(err)
t.Assert(outputArgs, inputArgs)
})
}

0 comments on commit e3e5c89

Please sign in to comment.