main.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package mtool
  2. // The package implements fast way
  3. // to make multitool CLI applications.
  4. import (
  5. "flag"
  6. "os"
  7. "time"
  8. )
  9. type Flags struct {
  10. *flag.FlagSet
  11. tool *Tool
  12. args []string
  13. parsedArgs []string
  14. envNameMap map[string] []string
  15. envMap map[string]string
  16. }
  17. type ToolMap map[string] *Tool
  18. func (flags *Flags) wasPassed(name string) bool {
  19. found := false
  20. flags.Visit(func(f *flag.Flag){
  21. if f.Name == name {
  22. found = true
  23. }
  24. })
  25. return found
  26. }
  27. func (flags *Flags) setEnv(
  28. name string,
  29. env []string,
  30. ) bool {
  31. flags.envNameMap[name] = env
  32. for _, k := range env {
  33. value, has := os.LookupEnv(k)
  34. if !has {
  35. continue
  36. }
  37. flags.envMap[name] = value
  38. return true
  39. }
  40. return false
  41. }
  42. // Set new string variable
  43. // to parse.
  44. func (flags *Flags) StringVar(
  45. p *string,
  46. name string,
  47. value string,
  48. usage string,
  49. env ...string,
  50. ) {
  51. flags.FlagSet.StringVar(p, name, value, usage)
  52. flags.setEnv(name, env)
  53. }
  54. // Set new int variable to parse.
  55. func (flags *Flags) IntVar(
  56. p *int,
  57. name string,
  58. value int,
  59. usage string,
  60. env ...string,
  61. ) {
  62. flags.FlagSet.IntVar(p, name, value, usage)
  63. flags.setEnv(name, env)
  64. }
  65. // Set new int64 variable to parse.
  66. func (flags *Flags) Int64Var(
  67. p *int64,
  68. name string,
  69. value int64,
  70. usage string,
  71. env ...string,
  72. ) {
  73. flags.FlagSet.Int64Var(p, name, value, usage)
  74. flags.setEnv(name, env)
  75. }
  76. // Set new bool variable to parse.
  77. func (flags *Flags) BoolVar(
  78. p *bool,
  79. name string,
  80. value bool,
  81. usage string,
  82. env ...string,
  83. ) {
  84. flags.FlagSet.BoolVar(p, name, value, usage)
  85. flags.setEnv(name, env)
  86. }
  87. // Set new float64 variable to parse.
  88. func (flags *Flags) Float64Var(
  89. p *float64,
  90. name string,
  91. value float64,
  92. usage string,
  93. env ...string,
  94. ) {
  95. flags.FlagSet.Float64Var(p, name, value, usage)
  96. flags.setEnv(name, env)
  97. }
  98. // Set new duration variable to parse.
  99. func (flags *Flags) DurationVar(
  100. p *time.Duration,
  101. name string,
  102. value time.Duration,
  103. usage string,
  104. env ...string,
  105. ) {
  106. flags.FlagSet.DurationVar(p, name, value, usage)
  107. flags.setEnv(name, env)
  108. }
  109. func (flags *Flags) Parse() []string {
  110. flags.FlagSet.Parse(flags.args)
  111. for name, v := range flags.envMap {
  112. if !flags.wasPassed(name) {
  113. flags.FlagSet.Set(name, v)
  114. }
  115. }
  116. flags.parsedArgs = flags.FlagSet.Args()
  117. return flags.parsedArgs
  118. }
  119. // Get all the arguments, including the
  120. // parsed ones.
  121. func (flags *Flags) AllArgs() []string {
  122. return flags.args
  123. }
  124. // Get all the arguments going after options.
  125. func (flags *Flags) Args() []string {
  126. return flags.parsedArgs
  127. }
  128. // Get the tool currently called.
  129. func (flags *Flags) Tool() *Tool {
  130. return flags.tool
  131. }