github.com/taubyte/tau-cli@v0.1.13-0.20240326000942-487f0d57edfc/cli/args/args.go (about) 1 package args 2 3 import ( 4 slices "github.com/taubyte/utils/slices/string" 5 "github.com/urfave/cli/v2" 6 ) 7 8 func parseCommandArguments(commands []*cli.Command, args ...string) []string { 9 if len(args) == 1 || len(commands) == 0 { 10 return args 11 } 12 // We need to also parse sub commands 13 for _, cmd := range commands { 14 if slices.Contains(args, cmd.Name) { 15 // parse arguments after cmd.Name so that `login testprofile -provider github` becomes `login -provider github testprofile` 16 // and `login -provider github testprofile` becomes `login -provider github testprofile` 17 idx := IndexOf(args, cmd.Name) 18 19 // Check aliases 20 if idx == -1 { 21 for _, alias := range cmd.Aliases { 22 idx = IndexOf(args, alias) 23 if idx != -1 { 24 break 25 } 26 } 27 } 28 29 if idx == -1 { 30 return MovePostfixOptions(args, ParseFlags(cmd.Flags)) 31 } 32 args = append(args[:idx], append([]string{cmd.Name}, args[idx+1:]...)...) 33 34 if len(cmd.Subcommands) > 0 { 35 for _, sCmd := range cmd.Subcommands { 36 sIdx := IndexOf(args, sCmd.Name) 37 if sIdx == -1 { 38 for _, alias := range sCmd.Aliases { 39 sIdx = IndexOf(args, alias) 40 if sIdx != -1 { 41 break 42 } 43 } 44 } 45 46 if sIdx != -1 { 47 subArgs := MovePostfixOptions(args[sIdx:], ParseFlags(sCmd.Flags)) 48 args = append(args[:sIdx], subArgs...) 49 } 50 } 51 } 52 53 return MovePostfixOptions(args, ParseFlags(cmd.Flags)) 54 } 55 } 56 57 return args 58 } 59 60 func ParseArguments(globalFlags []cli.Flag, commands []*cli.Command, args ...string) []string { 61 if len(args) == 1 { // Args can only be >= 1 62 return args 63 } 64 65 // Move commands without the program name 66 args = append(args[:1], MovePostFixCommands(args[1:], commands)...) 67 68 validGlobalFlags := ParseFlags(globalFlags) 69 argsWithGlobalsMoved := MovePostfixOptions(args, validGlobalFlags) 70 71 var commandStartIdx int 72 73 validCommands := make([]string, len(commands)) 74 for idx, command := range commands { 75 // TODO handle config aliases 76 validCommands[idx] = command.Name 77 } 78 79 for idx, arg := range argsWithGlobalsMoved[1:] { 80 if commandStartIdx != 0 { 81 break 82 } 83 84 for _, cmd := range validCommands { 85 if arg == cmd { 86 commandStartIdx = idx + 1 // We do +1 because we start at 1: 87 break 88 } 89 } 90 } 91 92 commandArgs := parseCommandArguments(commands, argsWithGlobalsMoved[commandStartIdx:]...) 93 94 return append(argsWithGlobalsMoved[:commandStartIdx], commandArgs...) 95 } 96 97 // Places the command being called at the beginning of the args slice for parsing 98 func MovePostFixCommands(args []string, commands []*cli.Command) []string { 99 // find which command is being called 100 cmd_args := []string{} 101 102 for _, cmd := range commands { 103 argName := cmd.Name 104 idx := IndexOf(args, argName) 105 if idx == -1 { 106 for _, alias := range cmd.Aliases { 107 idx = IndexOf(args, alias) 108 if idx != -1 { 109 argName = alias 110 break 111 } 112 } 113 } 114 if idx == -1 { 115 continue 116 } 117 118 // remove argName from args 119 args = append(args[:idx], args[idx+1:]...) 120 121 // add argName to cmd_args 122 cmd_args = append(cmd_args, argName) 123 124 if len(cmd.Subcommands) > 0 { 125 args = MovePostFixCommands(args, cmd.Subcommands) 126 } 127 } 128 129 return append(cmd_args, args...) 130 }