Skip to content

Commit 0f69582

Browse files
committed
Currently broken, not sure what's up
1 parent 34dd638 commit 0f69582

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

cmd/src/cmd.go

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (c *command) matches(name string) bool {
4242
// commander represents a top-level command with subcommands.
4343
type commander []*command
4444

45-
// run runs the command.
45+
// Run the command
4646
func (c commander) run(flagSet *flag.FlagSet, cmdName, usageText string, args []string) {
4747

4848
// Check if --help args are anywhere in the command; if yes, then
@@ -67,22 +67,24 @@ func (c commander) run(flagSet *flag.FlagSet, cmdName, usageText string, args []
6767
}
6868
}
6969

70-
// Parse flags.
70+
// Define the usage function from usageText
7171
flagSet.Usage = func() {
7272
_, _ = fmt.Fprint(flag.CommandLine.Output(), usageText)
7373
}
74+
75+
// Parse the command's flags, if not already parsed
7476
if !flagSet.Parsed() {
7577
_ = flagSet.Parse(filteredArgs)
7678
}
7779

78-
// If no subcommands remain (or help requested with no subcommands), print usage.
80+
// If no subcommands remain (or help requested with no subcommands), print usage
7981
if flagSet.NArg() == 0 {
8082
flagSet.SetOutput(os.Stdout)
8183
flagSet.Usage()
8284
os.Exit(0)
8385
}
8486

85-
// Configure default usage funcs for commands.
87+
// Configure default usage funcs for all commands.
8688
for _, cmd := range c {
8789
cmd := cmd
8890

@@ -101,39 +103,60 @@ func (c commander) run(flagSet *flag.FlagSet, cmdName, usageText string, args []
101103
}
102104
}
103105

104-
// Find the subcommand to execute.
106+
// Find the subcommand to execute
107+
// Assume the subcommand is the first arg in the flagSet
105108
name := flagSet.Arg(0)
109+
110+
// Loop through the list of all registered subcommands
106111
for _, cmd := range c {
112+
113+
// If the first arg is not this registered commmand in the loop, try the next registered command
107114
if !cmd.matches(name) {
108115
continue
109116
}
117+
// If the first arg is this registered commmand in the loop, then try and run it, then exit
110118

111-
// Read global configuration now.
119+
// Read global configuration
112120
var err error
113121
cfg, err = readConfig()
114122
if err != nil {
115123
log.Fatal("reading config: ", err)
116124
}
117125

118-
// Get subcommand args, and re-add help flag if it was requested
126+
// Get the remaining args, to pass to the subcommand, as an unparsed array of previously parsed args
119127
args := flagSet.Args()[1:]
120-
if helpRequested {
121-
args = append(args, "-h")
122-
}
123128

124129
// Set output to stdout for help (flag package defaults to stderr)
125130
cmd.flagSet.SetOutput(os.Stdout)
126131
flag.CommandLine.SetOutput(os.Stdout)
127132

133+
// Note: We can't parse flags here because commanders need to pass unparsed args to subcommand handlers
134+
// Each handler is responsible for parsing its own flags
135+
// All commands must use `flagSet := flag.NewFlagSet("<name>", flag.ExitOnError)` to ensure usage helper text is printed automatically on arg parse errors
136+
// Parse the subcommand's args, on its behalf, to test if flag.ExitOnError is not set
137+
// if err := cmd.flagSet.Parse(args); err != nil {
138+
// fmt.Printf("Error parsing subcommand flags: %s\n", err)
139+
// panic(fmt.Sprintf("all registered commands should use flag.ExitOnError: error: %s", err))
140+
// }
141+
142+
// If the --help arg was provided, re-add it here for the lowest command to parse and action
143+
if helpRequested {
144+
args = append(args, "-h")
145+
}
146+
128147
// Execute the subcommand
129148
if err := cmd.handler(args); err != nil {
149+
150+
// If the subcommand returns a UsageError, then print the error and usage helper text
130151
if _, ok := err.(*cmderrors.UsageError); ok {
131152
log.Printf("error: %s\n\n", err)
132153
cmd.flagSet.SetOutput(os.Stderr)
133154
flag.CommandLine.SetOutput(os.Stderr)
134155
cmd.flagSet.Usage()
135156
os.Exit(2)
136157
}
158+
159+
// If the subcommand returns any other error, then print the error
137160
if e, ok := err.(*cmderrors.ExitCodeError); ok {
138161
if e.HasError() {
139162
log.Println(e)
@@ -142,8 +165,12 @@ func (c commander) run(flagSet *flag.FlagSet, cmdName, usageText string, args []
142165
}
143166
log.Fatal(err)
144167
}
168+
169+
// If no error was returned, then exit the application
145170
os.Exit(0)
146171
}
172+
173+
// If the first arg didn't match any registered commands, print errors and exit the application
147174
log.Printf("%s: unknown subcommand %q", cmdName, name)
148175
log.Fatalf("Run '%s help' for usage.", cmdName)
149176
}

0 commit comments

Comments
 (0)