parent
da2620a37f
commit
359d89bc7d
|
@ -0,0 +1,39 @@
|
||||||
|
# myapp
|
||||||
|
|
||||||
|
myapp
|
||||||
|
|
||||||
|
```
|
||||||
|
myapp
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
[--bool-flag,-bf]
|
||||||
|
[--duration-flag,-df]=[value]
|
||||||
|
[--help]
|
||||||
|
[--int-flag,-if]=[value]
|
||||||
|
[--string-flag,-sf]=[value]
|
||||||
|
```
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
myapp [FLAGS] [ARGS...]
|
||||||
|
```
|
||||||
|
|
||||||
|
**--bool-flag,-bf**: Bool flag
|
||||||
|
|
||||||
|
|
||||||
|
**--duration-flag,-df**="": Duration flag
|
||||||
|
|
||||||
|
|
||||||
|
**--help**: Show help
|
||||||
|
|
||||||
|
|
||||||
|
**--int-flag,-if**="": Int flag
|
||||||
|
|
||||||
|
|
||||||
|
**--string-flag,-sf**="": String flag
|
||||||
|
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
//go:build generate
|
||||||
|
// +build generate
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"github.com/peterbourgon/ff/v3/ffcli"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"go.jolheiser.com/ffmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
func main() {
|
||||||
|
fs := flag.NewFlagSet("myapp", flag.ExitOnError)
|
||||||
|
stringFlag := fs.String("string-flag", "", "String flag")
|
||||||
|
fs.StringVar(stringFlag, "sf", *stringFlag, "--string-flag")
|
||||||
|
intFlag := fs.Int("int-flag", 0, "Int flag")
|
||||||
|
fs.IntVar(intFlag, "if", *intFlag, "--int-flag")
|
||||||
|
boolFlag := fs.Bool("bool-flag", false, "Bool flag")
|
||||||
|
fs.BoolVar(boolFlag, "bf", *boolFlag, "--bool-flag")
|
||||||
|
durFlag := fs.Duration("duration-flag", 0, "Duration flag")
|
||||||
|
fs.DurationVar(durFlag, "df", *durFlag, "--duration-flag")
|
||||||
|
|
||||||
|
cmd := &ffcli.Command{
|
||||||
|
Name: "myapp",
|
||||||
|
FlagSet: fs,
|
||||||
|
Subcommands: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
md, err := ffmd.Command(cmd)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
write("README.md", md)
|
||||||
|
}
|
||||||
|
|
||||||
|
func write(path, content string) {
|
||||||
|
fi, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer fi.Close()
|
||||||
|
if _, err := fi.WriteString(content); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
31
ffmd.go
31
ffmd.go
|
@ -3,6 +3,7 @@ package ffmd
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -30,6 +31,9 @@ func FlagSet(fs *flag.FlagSet) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromCommand(cmd *ffcli.Command, section int) (string, error) {
|
func fromCommand(cmd *ffcli.Command, section int) (string, error) {
|
||||||
|
if cmd.FlagSet == nil {
|
||||||
|
return "", errors.New("all commands should have a flagset, even if empty")
|
||||||
|
}
|
||||||
c := flagSetCommand(cmd.FlagSet, section)
|
c := flagSetCommand(cmd.FlagSet, section)
|
||||||
c.Name = cmd.Name
|
c.Name = cmd.Name
|
||||||
c.Usage = fmt.Sprintf("%s [FLAGS] [ARGS...]", cmd.Name)
|
c.Usage = fmt.Sprintf("%s [FLAGS] [ARGS...]", cmd.Name)
|
||||||
|
@ -77,19 +81,33 @@ func flagSetCommand(fs *flag.FlagSet, section int) command {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
aliases := make(map[string][]string)
|
||||||
fs.VisitAll(func(f *flag.Flag) {
|
fs.VisitAll(func(f *flag.Flag) {
|
||||||
_, isBool := f.Value.(boolFlag)
|
_, isBool := f.Value.(boolFlag)
|
||||||
def := f.DefValue
|
def := f.DefValue
|
||||||
if isZeroValue(f, def) {
|
if isZeroValue(f, def) {
|
||||||
def = ""
|
def = ""
|
||||||
}
|
}
|
||||||
a.Flags = append(a.Flags, appFlag{
|
af := appFlag{
|
||||||
Name: f.Name,
|
Name: f.Name,
|
||||||
Usage: f.Usage,
|
Usage: f.Usage,
|
||||||
Default: def,
|
Default: def,
|
||||||
IsBool: isBool,
|
IsBool: isBool,
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(af.Usage, "--") {
|
||||||
|
aliasOf := strings.TrimPrefix(af.Usage, "--")
|
||||||
|
if _, ok := aliases[aliasOf]; !ok {
|
||||||
|
aliases[aliasOf] = make([]string, 0)
|
||||||
|
}
|
||||||
|
aliases[aliasOf] = append(aliases[aliasOf], af.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
a.Flags = append(a.Flags, af)
|
||||||
})
|
})
|
||||||
})
|
for idx, f := range a.Flags {
|
||||||
|
f.Aliases = aliases[f.Name]
|
||||||
|
a.Flags[idx] = f
|
||||||
|
}
|
||||||
sort.Slice(a.Flags, func(i, j int) bool {
|
sort.Slice(a.Flags, func(i, j int) bool {
|
||||||
return a.Flags[i].Name < a.Flags[j].Name
|
return a.Flags[i].Name < a.Flags[j].Name
|
||||||
})
|
})
|
||||||
|
@ -119,11 +137,20 @@ func (c command) Markdown() (string, error) {
|
||||||
|
|
||||||
type appFlag struct {
|
type appFlag struct {
|
||||||
Name string
|
Name string
|
||||||
|
Aliases []string
|
||||||
Usage string
|
Usage string
|
||||||
Default string
|
Default string
|
||||||
IsBool bool
|
IsBool bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a appFlag) AllNames() string {
|
||||||
|
names := []string{"--" + a.Name}
|
||||||
|
for _, alias := range a.Aliases {
|
||||||
|
names = append(names, "-"+alias)
|
||||||
|
}
|
||||||
|
return strings.Join(names, ",")
|
||||||
|
}
|
||||||
|
|
||||||
// From stdlib
|
// From stdlib
|
||||||
|
|
||||||
func isZeroValue(f *flag.Flag, value string) bool {
|
func isZeroValue(f *flag.Flag, value string) bool {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
```{{range $flag := .Flags}}
|
```{{range $flag := .Flags}}
|
||||||
[--{{$flag.Name}}]{{if not $flag.IsBool}}=[value]{{end}}
|
[{{$flag.AllNames}}]{{if not $flag.IsBool}}=[value]{{end}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
```
|
```
|
||||||
{{- if .Usage}}
|
{{- if .Usage}}
|
||||||
|
@ -22,5 +22,5 @@
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{range $flag := .Flags}}
|
{{range $flag := .Flags}}
|
||||||
|
|
||||||
**--{{$flag.Name}}**{{if not $flag.IsBool}}=""{{end}}: {{$flag.Usage}}{{if $flag.Default}} (default: `{{$flag.Default}}`){{end}}
|
**{{$flag.AllNames}}**{{if not $flag.IsBool}}=""{{end}}: {{$flag.Usage}}{{if $flag.Default}} (default: `{{$flag.Default}}`){{end}}
|
||||||
{{end}}
|
{{end}}
|
Loading…
Reference in New Issue