Skip to content

Commit

Permalink
perf: optimize cli loading (#2697)
Browse files Browse the repository at this point in the history
  • Loading branch information
Codelax committed Dec 26, 2022
1 parent 87eb1a0 commit b272743
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 38 deletions.
2 changes: 1 addition & 1 deletion internal/core/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func Bootstrap(config *BootstrapConfig) (exitCode int, result interface{}, err e

// cobraBuilder will build a Cobra root command from a list of Command
builder := cobraBuilder{
commands: config.Commands.GetSortedCommand(),
commands: config.Commands,
meta: meta,
ctx: ctx,
}
Expand Down
6 changes: 3 additions & 3 deletions internal/core/cobra_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func init() {
// Cobra root command is a tree data struct. During the build process we
// use an index to attache leaf command to their parent.
type cobraBuilder struct {
commands []*Command
commands *Commands
meta *meta
ctx context.Context
}
Expand All @@ -41,7 +41,7 @@ func (b *cobraBuilder) build() *cobra.Command {

rootCmd.SetOut(b.meta.stderr)

for _, cmd := range b.commands {
for _, cmd := range b.commands.GetSortedCommand() {
// If namespace command has not yet been created. We create an empty cobra command to allow leaf to be attached.
if _, namespaceExist := index[cmd.Namespace]; !namespaceExist {
cobraCmd := &cobra.Command{Use: cmd.Namespace}
Expand Down Expand Up @@ -134,7 +134,7 @@ func (b *cobraBuilder) hydrateCobra(cobraCmd *cobra.Command, cmd *Command) {
cobraCmd.PersistentFlags().BoolP("wait", "w", false, "wait until the "+cmd.Resource+" is ready")
}

cobraCmd.Annotations["CommandUsage"] = cmd.GetUsage(ExtractBinaryName(b.ctx), NewCommands(b.commands...))
cobraCmd.Annotations["CommandUsage"] = cmd.GetUsage(ExtractBinaryName(b.ctx), b.commands)
}

const usageTemplate = `USAGE:
Expand Down
31 changes: 28 additions & 3 deletions internal/core/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ type Command struct {

// WaitFunc will be called if non-nil when the -w (--wait) flag is passed.
WaitFunc WaitFunc

// cache command path
path string
}

// CommandPreValidateFunc allows to manipulate args before validation.
Expand All @@ -94,6 +97,9 @@ func (c *Command) Override(builder func(command *Command) *Command) {
}

func (c *Command) getPath() string {
if c.path != "" {
return c.path
}
path := []string(nil)
if c.Namespace != "" {
path = append(path, c.Namespace)
Expand All @@ -105,7 +111,8 @@ func (c *Command) getPath() string {
path = append(path, c.Verb)
}

return strings.Join(path, indexCommandSeparator)
c.path = strings.Join(path, indexCommandSeparator)
return c.path
}

func (c *Command) GetCommandLine(binaryName string) string {
Expand Down Expand Up @@ -162,8 +169,8 @@ type Commands struct {

func NewCommands(cmds ...*Command) *Commands {
c := &Commands{
commands: []*Command(nil),
commandIndex: map[string]*Command{},
commands: make([]*Command, 0, len(cmds)),
commandIndex: make(map[string]*Command, len(cmds)),
}

for _, cmd := range cmds {
Expand All @@ -173,6 +180,24 @@ func NewCommands(cmds ...*Command) *Commands {
return c
}

func NewCommandsMerge(cmdsList ...*Commands) *Commands {
cmdCount := 0
for _, cmds := range cmdsList {
cmdCount += len(cmds.commands)
}
c := &Commands{
commands: make([]*Command, 0, cmdCount),
commandIndex: make(map[string]*Command, cmdCount),
}
for _, cmds := range cmdsList {
for _, cmd := range cmds.commands {
c.Add(cmd)
}
}

return c
}

func (c *Commands) MustFind(path ...string) *Command {
cmd, exist := c.find(path...)
if exist {
Expand Down
63 changes: 32 additions & 31 deletions internal/namespaces/get_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,37 +40,38 @@ import (
func GetCommands(beta ...bool) *core.Commands {
// Import all commands available in CLI from various packages.
// NB: Merge order impacts scw usage sort.
commands := core.NewCommands()
commands.Merge(iam.GetCommands())
commands.Merge(instance.GetCommands())
commands.Merge(baremetal.GetCommands())
commands.Merge(k8s.GetCommands())
commands.Merge(marketplace.GetCommands())
commands.Merge(initNamespace.GetCommands())
commands.Merge(configNamespace.GetCommands())
commands.Merge(account.GetCommands())
commands.Merge(accountv2.GetCommands())
commands.Merge(autocompleteNamespace.GetCommands())
commands.Merge(object.GetCommands())
commands.Merge(versionNamespace.GetCommands())
commands.Merge(registry.GetCommands())
commands.Merge(feedback.GetCommands())
commands.Merge(info.GetCommands())
commands.Merge(rdb.GetCommands())
commands.Merge(lb.GetCommands())
commands.Merge(iot.GetCommands())
commands.Merge(help.GetCommands())
commands.Merge(vpc.GetCommands())
commands.Merge(domain.GetCommands())
commands.Merge(applesilicon.GetCommands())
commands.Merge(flexibleip.GetCommands())
commands.Merge(container.GetCommands())
commands.Merge(function.GetCommands())
commands.Merge(vpcgw.GetCommands())
commands.Merge(redis.GetCommands())
commands.Merge(shell.GetCommands())
commands.Merge(tem.GetCommands())
commands.Merge(mnq.GetCommands())
commands := core.NewCommandsMerge(
iam.GetCommands(),
instance.GetCommands(),
baremetal.GetCommands(),
k8s.GetCommands(),
marketplace.GetCommands(),
initNamespace.GetCommands(),
configNamespace.GetCommands(),
account.GetCommands(),
accountv2.GetCommands(),
autocompleteNamespace.GetCommands(),
object.GetCommands(),
versionNamespace.GetCommands(),
registry.GetCommands(),
feedback.GetCommands(),
info.GetCommands(),
rdb.GetCommands(),
lb.GetCommands(),
iot.GetCommands(),
help.GetCommands(),
vpc.GetCommands(),
domain.GetCommands(),
applesilicon.GetCommands(),
flexibleip.GetCommands(),
container.GetCommands(),
function.GetCommands(),
vpcgw.GetCommands(),
redis.GetCommands(),
shell.GetCommands(),
tem.GetCommands(),
mnq.GetCommands(),
)

return commands
}

0 comments on commit b272743

Please sign in to comment.