Add alias support

Signed-off-by: jolheiser <john.olheiser@gmail.com>
main v0.0.3
jolheiser 2022-09-03 21:32:49 -05:00
parent da2620a37f
commit 359d89bc7d
Signed by: jolheiser
GPG Key ID: B853ADA5DA7BBF7A
4 changed files with 118 additions and 4 deletions

View File

@ -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
-----

View File

@ -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
View File

@ -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 {

View File

@ -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}}