main.go 2.6 KB

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