code.cestus.io/tools/fabricator@v0.4.3/pkg/cmd/cmd.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "strings" 8 9 "code.cestus.io/tools/fabricator/pkg/cmd/help" 10 "code.cestus.io/tools/fabricator/pkg/cmd/plugin" 11 "code.cestus.io/tools/fabricator/pkg/cmd/version" 12 "code.cestus.io/tools/fabricator/pkg/fabricator" 13 "github.com/spf13/cobra" 14 "github.com/spf13/pflag" 15 ) 16 17 // NewDefaultFabricatorCommand creates the `fabricator` command with default arguments 18 func NewDefaultFabricatorCommand(ctx context.Context, io fabricator.IOStreams, flagParser fabricator.FlagParser) *cobra.Command { 19 return NewDefaultFabricatorCommandWithArgs(ctx, NewDefaultPluginHandler(plugin.ValidPluginFilenamePrefixes, io), os.Args, io, flagParser) 20 } 21 22 // NewDefaultFabricatorCommandWithArgs creates the `fabricator` command with arguments 23 func NewDefaultFabricatorCommandWithArgs(ctx context.Context, pluginHandler plugin.PluginHandler, args []string, io fabricator.IOStreams, flagparser fabricator.FlagParser) *cobra.Command { 24 cmd := NewFabricatorCommand(io, flagparser) 25 26 if pluginHandler == nil { 27 return cmd 28 } 29 30 if len(args) > 1 { 31 cmdPathPieces := args[1:] 32 33 // only look for suitable extension executables if 34 // the specified command does not already exist 35 if _, _, err := cmd.Find(cmdPathPieces); err != nil { 36 cmd.AddCommand(plugin.NewPluginWrapper(ctx, io, pluginHandler, flagparser, cmdPathPieces)) 37 } 38 } 39 40 return cmd 41 } 42 43 type options struct { 44 fabricator.RootOptions 45 fabricator.IOStreams 46 } 47 48 // NewOptions returns initialized Options 49 func NewOptions(ioStreams fabricator.IOStreams, flagset *pflag.FlagSet) *options { 50 o := options{ 51 IOStreams: ioStreams, 52 } 53 o.RootOptions.RegisterOptions(flagset) 54 return &o 55 } 56 57 // NewFabricatorCommand creates the `fabricator` command and its nested children. 58 func NewFabricatorCommand(io fabricator.IOStreams, flagparser fabricator.FlagParser) *cobra.Command { 59 // Parent command to which all subcommands are added. 60 cmds := &cobra.Command{ 61 Use: "fabricator", 62 Short: "fabricator is the swiss army knive for code generation", 63 Long: `"fabricator is the swiss army knive for code generation"`, 64 Run: runHelp, 65 // Hook before and after Run 66 PersistentPreRunE: func(*cobra.Command, []string) error { 67 return nil 68 }, 69 PersistentPostRunE: func(*cobra.Command, []string) error { 70 return nil 71 }, 72 } 73 74 flags := cmds.PersistentFlags() 75 _ = NewOptions(io, cmds.LocalFlags()) 76 flags.SetNormalizeFunc(WarnWordSepNormalizeFunc) // Warn for "_" flags 77 78 // Normalize all flags that are coming from other packages or pre-configurations 79 // a.k.a. change all "_" to "-". e.g. glog package 80 flags.SetNormalizeFunc(WordSepNormalizeFunc) 81 82 //cmds.PersistentFlags().AddGoFlagSet(flagset) 83 84 // From this point and forward we get warnings on flags that contain "_" separators 85 cmds.SetGlobalNormalizationFunc(WarnWordSepNormalizeFunc) 86 87 cmds.AddCommand(plugin.NewCmdPlugin(io, flagparser)) 88 cmds.AddCommand(version.NewCmdVersion(io)) 89 help := help.NewHelpCommand(io) 90 cmds.AddCommand(help) 91 cmds.SetHelpCommand(help) 92 93 return cmds 94 } 95 96 func runHelp(cmd *cobra.Command, args []string) { 97 cmd.Help() 98 } 99 100 // WarnWordSepNormalizeFunc changes and warns for flags that contain "_" separators 101 func WarnWordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName { 102 if strings.Contains(name, "_") { 103 nname := strings.Replace(name, "_", "-", -1) 104 if _, alreadyWarned := underscoreWarnings[name]; !alreadyWarned { 105 fmt.Printf("using an underscore in a flag name is not supported. %s has been converted to %s.", name, nname) 106 underscoreWarnings[name] = true 107 } 108 109 return pflag.NormalizedName(nname) 110 } 111 return pflag.NormalizedName(name) 112 } 113 114 // WordSepNormalizeFunc changes all flags that contain "_" separators 115 func WordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName { 116 if strings.Contains(name, "_") { 117 return pflag.NormalizedName(strings.Replace(name, "_", "-", -1)) 118 } 119 return pflag.NormalizedName(name) 120 } 121 122 var underscoreWarnings = make(map[string]bool)