github.com/saucelabs/saucectl@v0.175.1/internal/flags/binder.go (about)

     1  package flags
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/rs/zerolog/log"
     7  	"github.com/spf13/pflag"
     8  
     9  	"github.com/saucelabs/saucectl/internal/viper"
    10  )
    11  
    12  // SnakeCharmer because Cobra and Viper. Get it?
    13  // It's a convenience wrapper around cobra and viper, allowing the user to declare and bind flags at the same time.
    14  //
    15  // Example:
    16  //
    17  //		sc := flags.SnakeCharmer{Fmap: map[string]*pflag.Flag{}}
    18  //		sc.Fset = cmd.Flags()
    19  //		sc.String("name", "suite.name", "", "Set the name of the job as it will appear on Sauce Labs")
    20  //	 sc.BindAll()
    21  type SnakeCharmer struct {
    22  	Fset *pflag.FlagSet
    23  	// Fmap maps field names (key) to flags (value).
    24  	Fmap map[string]*pflag.Flag
    25  }
    26  
    27  // BindAll binds all previously added flags to their respective fields.
    28  func (s *SnakeCharmer) BindAll() {
    29  	for fieldName, flag := range s.Fmap {
    30  		if err := viper.BindPFlag(fieldName, flag); err != nil {
    31  			log.Fatal().Msgf("Failed to bind flags and config fields: %v", err)
    32  		}
    33  	}
    34  }
    35  
    36  // Bool defines a bool flag with specified flagName, default value, usage string and then binds it to fieldName.
    37  func (s *SnakeCharmer) Bool(flagName, fieldName string, value bool, usage string) {
    38  	s.Fset.Bool(flagName, value, usage)
    39  	s.addBind(flagName, fieldName)
    40  }
    41  
    42  // BoolP is like Bool(), but accepts a shorthand letter.
    43  func (s *SnakeCharmer) BoolP(flagName, shorthand, fieldName string, value bool, usage string) {
    44  	s.Fset.BoolP(flagName, shorthand, value, usage)
    45  	s.addBind(flagName, fieldName)
    46  }
    47  
    48  // Duration defines a duration flag with specified flagName, default value, usage string and then binds it to fieldName.
    49  func (s *SnakeCharmer) Duration(flagName string, fieldName string, value time.Duration, usage string) {
    50  	s.Fset.Duration(flagName, value, usage)
    51  	s.addBind(flagName, fieldName)
    52  }
    53  
    54  // Float64 defines a float64 flag with specified flagName, default value, usage string and then binds it to fieldName.
    55  func (s *SnakeCharmer) Float64(flagName, fieldName string, value float64, usage string) {
    56  	s.Fset.Float64(flagName, value, usage)
    57  	s.addBind(flagName, fieldName)
    58  }
    59  
    60  // Int defines an int flag with specified flagName, default value, usage string and then binds it to fieldName.
    61  func (s *SnakeCharmer) Int(flagName, fieldName string, value int, usage string) {
    62  	s.Fset.Int(flagName, value, usage)
    63  	s.addBind(flagName, fieldName)
    64  }
    65  
    66  // String defines a string flag with specified flagName, default value, usage string and then binds it to fieldName.
    67  func (s *SnakeCharmer) String(flagName, fieldName, value, usage string) {
    68  	s.Fset.String(flagName, value, usage)
    69  	s.addBind(flagName, fieldName)
    70  }
    71  
    72  // StringP is like String(), but accepts a shorthand letter.
    73  func (s *SnakeCharmer) StringP(flagName, shorthand, fieldName, value, usage string) {
    74  	s.Fset.StringP(flagName, shorthand, value, usage)
    75  	s.addBind(flagName, fieldName)
    76  }
    77  
    78  // StringSlice defines a []string flag with specified flagName, default value, usage string and then binds it to fieldName.
    79  func (s *SnakeCharmer) StringSlice(flagName, fieldName string, value []string, usage string) {
    80  	s.Fset.StringSlice(flagName, value, usage)
    81  	s.addBind(flagName, fieldName)
    82  }
    83  
    84  // StringToString defines a map[string]string flag with specified flagName, default value, usage string and then binds
    85  // it to fieldName.
    86  func (s *SnakeCharmer) StringToString(flagName, fieldName string, value map[string]string, usage string) {
    87  	s.Fset.StringToString(flagName, value, usage)
    88  	s.addBind(flagName, fieldName)
    89  }
    90  
    91  // StringToStringP is like StringToString(), but accepts a shorthand letter.
    92  func (s *SnakeCharmer) StringToStringP(flagName, shorthand, fieldName string, value map[string]string, usage string) {
    93  	s.Fset.StringToStringP(flagName, shorthand, value, usage)
    94  	s.addBind(flagName, fieldName)
    95  }
    96  
    97  func (s *SnakeCharmer) addBind(flagName, fieldName string) {
    98  	s.Fmap[fieldName] = s.Fset.Lookup(flagName)
    99  }