github.com/bilus/oya@v0.0.3-0.20190301162104-da4acbd394c6/pkg/flags/flags.go (about)

     1  package flags
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  )
     7  
     8  var switchFlagRx = regexp.MustCompile("^--([a-z][-a-zA-z_0-9]*)$")
     9  var valueFlagRx = regexp.MustCompile("^--([a-z][-a-zA-z_0-9]*)=\"?([^\"]*)\"?$")
    10  var maybeFlagRx = regexp.MustCompile("^--.*")
    11  
    12  const TrueValue = "true"
    13  
    14  type ErrRepeatedFlag struct {
    15  	Arg string
    16  }
    17  
    18  func (err ErrRepeatedFlag) Error() string {
    19  	return fmt.Sprintf("Flag %q specified more than once", err.Arg)
    20  }
    21  
    22  type ErrInvalidFlag struct {
    23  	Arg string
    24  }
    25  
    26  func (err ErrInvalidFlag) Error() string {
    27  	return fmt.Sprintf("Flag syntax invalid: %q", err.Arg)
    28  }
    29  
    30  func Parse(args []string) ([]string, map[string]string, error) {
    31  	positionalArgs := make([]string, 0, len(args))
    32  	flags := make(map[string]string)
    33  	for _, arg := range args {
    34  		flag, value, ok, err := parseFlag(arg)
    35  		if err != nil {
    36  			return nil, nil, err
    37  		}
    38  		if ok {
    39  			if _, exists := flags[flag]; exists {
    40  				return nil, nil, ErrRepeatedFlag{
    41  					Arg: arg,
    42  				}
    43  			}
    44  			flags[flag] = value
    45  		} else {
    46  			positionalArgs = append(positionalArgs, arg)
    47  		}
    48  	}
    49  	return positionalArgs, flags, nil
    50  }
    51  
    52  func parseFlag(arg string) (string, string, bool, error) {
    53  	if maybeFlagRx.MatchString(arg) {
    54  		if matches := switchFlagRx.FindStringSubmatch(arg); len(matches) == 2 {
    55  			return matches[1], TrueValue, true, nil
    56  
    57  		} else if matches := valueFlagRx.FindStringSubmatch(arg); len(matches) == 3 {
    58  			return matches[1], matches[2], true, nil
    59  		}
    60  		return "", "", false, ErrInvalidFlag{Arg: arg}
    61  	}
    62  	return arg, arg, false, nil
    63  }