go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/flag/nestedflagset/nestedflagset.go (about) 1 // Copyright 2016 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package nestedflagset 16 17 import ( 18 "flag" 19 "fmt" 20 "strings" 21 ) 22 23 // FlagSet is a flag.Flag implementation that parses into a nested flag.FlagSet. 24 // 25 // The FlagSet's flag value is parsed broken into a series of sub-options, which 26 // are then loaded into the nested flag set (FlagSet.F). 27 type FlagSet struct { 28 F flag.FlagSet // The underlying FlagSet, populated on Parse. 29 } 30 31 var _ flag.Value = (*FlagSet)(nil) 32 33 // Parse parses a one-line option string into the underlying flag set. 34 func (fs *FlagSet) Parse(line string) error { 35 var args []string 36 for _, token := range lexer(line, ',').split() { 37 name, value := token.split() 38 args = append(args, fmt.Sprintf("-%s", name)) 39 if value != "" { 40 args = append(args, value) 41 } 42 } 43 44 return fs.F.Parse(args) 45 } 46 47 // Usage constructs a one-line usage string for all of the options defined in 48 // Flags. 49 func (fs *FlagSet) Usage() string { 50 var flags []string 51 52 // If there is no "help" flag defined, we will use it to display help/usage 53 // (default FlagSet). 54 if fs.F.Lookup("help") == nil { 55 flags = append(flags, "help") 56 } 57 58 fs.F.VisitAll(func(f *flag.Flag) { 59 comma := "" 60 if len(flags) > 0 { 61 comma = "," 62 } 63 flags = append(flags, fmt.Sprintf("[%s%s]", comma, f.Name)) 64 }) 65 return strings.Join(flags, "") 66 } 67 68 // Set implements flags.Value. 69 func (fs *FlagSet) Set(value string) error { 70 return fs.Parse(value) 71 } 72 73 // String implements flags.Value. 74 func (fs *FlagSet) String() string { 75 return fs.Usage() 76 }