Skip to content

Commit

Permalink
Create command abstraction and split up command builder
Browse files Browse the repository at this point in the history
  • Loading branch information
thschmitt committed Oct 1, 2024
1 parent 3959adf commit 7e1ecbd
Show file tree
Hide file tree
Showing 8 changed files with 569 additions and 542 deletions.
43 changes: 15 additions & 28 deletions commandline/autocomplete_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ import (
"os"
"path/filepath"
"strings"

"github.com/urfave/cli/v2"
)

const AutocompletePowershell = "powershell"
const AutocompleteBash = "bash"

const directoryPermissions = 0755
const filePermissions = 0644

const Powershell = "powershell"
const Bash = "bash"

const completeHandlerEnabledCheck = "uipath_auto_complete"

const powershellCompleteHandler = `
Expand Down Expand Up @@ -55,8 +53,8 @@ type autoCompleteHandler struct {
}

func (a autoCompleteHandler) EnableCompleter(shell string, filePath string) (string, error) {
if shell != Powershell && shell != Bash {
return "", fmt.Errorf("Invalid shell, supported values: %s, %s", Powershell, Bash)
if shell != AutocompletePowershell && shell != AutocompleteBash {
return "", fmt.Errorf("Invalid shell, supported values: %s, %s", AutocompletePowershell, AutocompleteBash)
}

profileFilePath, err := a.profileFilePath(shell, filePath)
Expand All @@ -71,14 +69,14 @@ func (a autoCompleteHandler) profileFilePath(shell string, filePath string) (str
if filePath != "" {
return filePath, nil
}
if shell == Powershell {
if shell == AutocompletePowershell {
return PowershellProfilePath()
}
return BashrcPath()
}

func (a autoCompleteHandler) completeHandler(shell string) string {
if shell == Powershell {
if shell == AutocompletePowershell {
return powershellCompleteHandler
}
return bashCompleteHandler
Expand Down Expand Up @@ -136,17 +134,12 @@ func (a autoCompleteHandler) writeCompleterHandler(filePath string, completerHan
return nil
}

func (a autoCompleteHandler) Find(commandText string, commands []*cli.Command, exclude []string) []string {
func (a autoCompleteHandler) Find(commandText string, command *commandDefinition, exclude []string) []string {
words := strings.Split(commandText, " ")
if len(words) < 2 {
return []string{}
}

command := &cli.Command{
Name: "uipath",
Subcommands: commands,
}

for _, word := range words[1 : len(words)-1] {
if strings.HasPrefix(word, "-") {
break
Expand All @@ -164,7 +157,7 @@ func (a autoCompleteHandler) Find(commandText string, commands []*cli.Command, e
return a.searchCommands(lastWord, command.Subcommands, exclude)
}

func (a autoCompleteHandler) findCommand(name string, commands []*cli.Command) *cli.Command {
func (a autoCompleteHandler) findCommand(name string, commands []*commandDefinition) *commandDefinition {
for _, command := range commands {
if command.Name == name {
return command
Expand All @@ -173,7 +166,7 @@ func (a autoCompleteHandler) findCommand(name string, commands []*cli.Command) *
return nil
}

func (a autoCompleteHandler) searchCommands(word string, commands []*cli.Command, exclude []string) []string {
func (a autoCompleteHandler) searchCommands(word string, commands []*commandDefinition, exclude []string) []string {
result := []string{}
for _, command := range commands {
if strings.HasPrefix(command.Name, word) {
Expand All @@ -188,22 +181,16 @@ func (a autoCompleteHandler) searchCommands(word string, commands []*cli.Command
return a.removeDuplicates(a.removeExcluded(result, exclude))
}

func (a autoCompleteHandler) searchFlags(word string, command *cli.Command, exclude []string) []string {
func (a autoCompleteHandler) searchFlags(word string, command *commandDefinition, exclude []string) []string {
result := []string{}
for _, flag := range command.Flags {
flagNames := flag.Names()
for _, flagName := range flagNames {
if strings.HasPrefix(flagName, word) {
result = append(result, "--"+flagName)
}
if strings.HasPrefix(flag.Name, word) {
result = append(result, "--"+flag.Name)
}
}
for _, flag := range command.Flags {
flagNames := flag.Names()
for _, flagName := range flagNames {
if strings.Contains(flagName, word) {
result = append(result, "--"+flagName)
}
if strings.Contains(flag.Name, word) {
result = append(result, "--"+flag.Name)
}
}
return a.removeDuplicates(a.removeExcluded(result, exclude))
Expand Down
135 changes: 132 additions & 3 deletions commandline/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ func (c Cli) run(args []string, input utils.Stream) error {
PluginExecutor: c.pluginExecutor,
DefinitionProvider: c.definitionProvider,
}
flags := CommandBuilder.CreateDefaultFlags(false)

flagBuilder := newFlagBuilder()
flagBuilder.AddDefaultFlags(false)
flags := flagBuilder.ToList()

commands, err := CommandBuilder.Create(args)
if err != nil {
return err
Expand All @@ -51,8 +55,8 @@ func (c Cli) run(args []string, input utils.Stream) error {
Usage: "Command-Line Interface for UiPath Services",
UsageText: "uipath <service> <operation> --parameter",
Version: "1.0",
Flags: flags,
Commands: commands,
Flags: c.convertFlags(flags...),
Commands: c.convertCommands(commands...),
Writer: c.stdOut,
ErrWriter: c.stdErr,
HideVersion: true,
Expand Down Expand Up @@ -89,3 +93,128 @@ func NewCli(
) *Cli {
return &Cli{stdIn, stdOut, stdErr, colors, definitionProvider, configProvider, executor, pluginExecutor}
}

func (c Cli) convertCommand(command *commandDefinition) *cli.Command {
result := cli.Command{
Name: command.Name,
Usage: command.Summary,
Description: command.Description,
Flags: c.convertFlags(command.Flags...),
Subcommands: c.convertCommands(command.Subcommands...),
CustomHelpTemplate: command.CustomHelpTemplate,
Hidden: command.Hidden,
HideHelp: true,
}
if command.Action != nil {
result.Action = func(context *cli.Context) error {
return command.Action(&CommandExecContext{context})
}
}
return &result
}

func (c Cli) convertCommands(commands ...*commandDefinition) []*cli.Command {
result := []*cli.Command{}
for _, command := range commands {
result = append(result, c.convertCommand(command))
}
return result
}

func (c Cli) convertStringSliceFlag(flag *flagDefinition) *cli.StringSliceFlag {
envVars := []string{}
if flag.EnvVarName != "" {
envVars = append(envVars, flag.EnvVarName)
}
var value *cli.StringSlice
if flag.Value != nil {
value = cli.NewStringSlice(flag.Value.([]string)...)
}
return &cli.StringSliceFlag{
Name: flag.Name,
Usage: flag.Summary,
EnvVars: envVars,
Required: flag.Required,
Hidden: flag.Hidden,
Value: value,
}
}

func (c Cli) convertIntFlag(flag *flagDefinition) *cli.IntFlag {
envVars := []string{}
if flag.EnvVarName != "" {
envVars = append(envVars, flag.EnvVarName)
}
var value int
if flag.Value != nil {
value = flag.Value.(int)
}
return &cli.IntFlag{
Name: flag.Name,
Usage: flag.Summary,
EnvVars: envVars,
Required: flag.Required,
Hidden: flag.Hidden,
Value: value,
}
}

func (c Cli) convertBoolFlag(flag *flagDefinition) *cli.BoolFlag {
envVars := []string{}
if flag.EnvVarName != "" {
envVars = append(envVars, flag.EnvVarName)
}
var value bool
if flag.Value != nil {
value = flag.Value.(bool)
}
return &cli.BoolFlag{
Name: flag.Name,
Usage: flag.Summary,
EnvVars: envVars,
Required: flag.Required,
Hidden: flag.Hidden,
Value: value,
}
}

func (c Cli) convertStringFlag(flag *flagDefinition) *cli.StringFlag {
envVars := []string{}
if flag.EnvVarName != "" {
envVars = append(envVars, flag.EnvVarName)
}
var value string
if flag.Value != nil {
value = flag.Value.(string)
}
return &cli.StringFlag{
Name: flag.Name,
Usage: flag.Summary,
EnvVars: envVars,
Required: flag.Required,
Hidden: flag.Hidden,
Value: value,
}
}

func (c Cli) convertFlag(flag *flagDefinition) cli.Flag {
switch flag.Type {
case FlagTypeStringArray:
return c.convertStringSliceFlag(flag)
case FlagTypeInteger:
return c.convertIntFlag(flag)
case FlagTypeBoolean:
return c.convertBoolFlag(flag)
case FlagTypeString:
return c.convertStringFlag(flag)
}
panic(fmt.Sprintf("Unknown flag type: %s", flag.Type.String()))
}

func (c Cli) convertFlags(flags ...*flagDefinition) []cli.Flag {
result := []cli.Flag{}
for _, flag := range flags {
result = append(result, c.convertFlag(flag))
}
return result
}
Loading

0 comments on commit 7e1ecbd

Please sign in to comment.