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  }