Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 36 additions & 15 deletions docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,10 @@ func prepareFlags(
// flagDetails returns a string containing the flags metadata
func flagDetails(flag cli.DocGenerationFlag) string {
description := flag.GetUsage()
value := getFlagDefaultValue(flag)
if value != "" {
value, defaultText := getFlagDefaultValue(flag)
if defaultText != "" {
description += " (default: " + defaultText + ")"
} else if value != "" {
description += " (default: " + value + ")"
}
return ": " + description
Expand Down Expand Up @@ -402,18 +404,25 @@ func (tt tabularTemplate) PrepareFlags(flags []cli.Flag) []cliTabularFlagTemplat
continue
}

var f = cliTabularFlagTemplate{
value, defaultText := getFlagDefaultValue(flag)
defaultValue := ""
if defaultText != "" {
defaultValue = defaultText
} else if value != "" {
defaultValue = fmt.Sprintf("`%s`", value)
}
if boolFlag, isBool := appFlag.(*cli.BoolFlag); isBool && defaultText == "" {
defaultValue = fmt.Sprintf("`%s`", strconv.FormatBool(boolFlag.Value))
}

f := cliTabularFlagTemplate{
Usage: tt.PrepareMultilineString(flag.GetUsage()),
EnvVars: flag.GetEnvVars(),
TakesValue: flag.TakesValue(),
Default: getFlagDefaultValue(flag),
Default: defaultValue,
Type: flag.TypeName(),
}

if boolFlag, isBool := appFlag.(*cli.BoolFlag); isBool {
f.Default = strconv.FormatBool(boolFlag.Value)
}

for i, name := range appFlag.Names() {
name = strings.TrimSpace(name)

Expand Down Expand Up @@ -562,29 +571,41 @@ func (tabularTemplate) Prettify(s string) string {
// a GetValue string method, but it was removed in https://github.com/urfave/cli/pull/1988.
// This function serves as a workaround, attempting to retrieve the value using the removed method; if that fails, it
// tries to obtain it via reflection (the [cli.FlagBase] still has a Value field).
func getFlagDefaultValue(f cli.DocGenerationFlag) string {
// It also checks if there is a DefaultText and if set returns it.
func getFlagDefaultValue(f cli.DocGenerationFlag) (value, text string) {
if !f.TakesValue() {
return ""
return "", ""
}

if _, ok := f.(interface{ GetDefaultText() string }); ok {
// GetDefaultText also returns GetValue so we have to use reflection
if ref := reflect.ValueOf(f); ref.Kind() == reflect.Ptr && ref.Elem().Kind() == reflect.Struct {
if val := ref.Elem().FieldByName("DefaultText"); val.IsValid() && val.Type().Kind() == reflect.String {
if defaultText := val.Interface().(string); defaultText != "" {
return "", defaultText
}
}
}
}

if v, ok := f.(interface{ GetValue() string }); ok {
return v.GetValue()
return v.GetValue(), ""
}

var ref = reflect.ValueOf(f)
if ref.Kind() != reflect.Ptr {
return ""
return "", ""
} else {
ref = ref.Elem()
}

if ref.Kind() != reflect.Struct {
return ""
return "", ""
}

if val := ref.FieldByName("Value"); val.IsValid() && val.Type().Kind() != reflect.Bool {
return fmt.Sprintf("%v", val.Interface())
return fmt.Sprintf("%v", val.Interface()), ""
}

return ""
return "", ""
}
35 changes: 20 additions & 15 deletions docs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ func expectFileContent(t *testing.T, file, got string) {
r := require.New(t)
r.NoError(err)
r.Equal(
string(normalizeNewlines([]byte(got))),
string(normalizeNewlines(data)),
string(normalizeNewlines([]byte(got))),
)
}

Expand All @@ -39,7 +39,7 @@ func normalizeNewlines(d []byte) []byte {
)
}

func buildExtendedTestCommand() *cli.Command {
func buildExtendedTestCommand(t *testing.T) *cli.Command {
return &cli.Command{
Writer: io.Discard,
Name: "greet",
Expand All @@ -62,6 +62,11 @@ func buildExtendedTestCommand() *cli.Command {
Name: "hidden-flag",
Hidden: true,
},
&cli.StringFlag{
Name: "temp-dir",
Value: t.TempDir(),
DefaultText: "test temp dir",
},
},
Commands: []*cli.Command{{
Aliases: []string{"c"},
Expand Down Expand Up @@ -154,14 +159,14 @@ Should be a part of the same code block
}

func TestToMarkdownFull(t *testing.T) {
cmd := buildExtendedTestCommand()
cmd := buildExtendedTestCommand(t)
res, err := ToMarkdown(cmd)
require.NoError(t, err)
expectFileContent(t, "testdata/expected-doc-full.md", res)
}

func TestToTabularMarkdown(t *testing.T) {
app := buildExtendedTestCommand()
app := buildExtendedTestCommand(t)

t.Run("full", func(t *testing.T) {
res, err := ToTabularMarkdown(app, "app")
Expand All @@ -188,7 +193,7 @@ func TestToTabularMarkdownFailed(t *testing.T) {

MarkdownTabularDocTemplate = "{{ .Foo }}"

app := buildExtendedTestCommand()
app := buildExtendedTestCommand(t)

res, err := ToTabularMarkdown(app, "")

Expand Down Expand Up @@ -223,7 +228,7 @@ Some other text`)
r.NoError(err)
_ = tmpFile.Close()

r.NoError(ToTabularToFileBetweenTags(buildExtendedTestCommand(), "app", tmpFile.Name()))
r.NoError(ToTabularToFileBetweenTags(buildExtendedTestCommand(t), "app", tmpFile.Name()))

content, err := os.ReadFile(tmpFile.Name())
r.NoError(err)
Expand Down Expand Up @@ -263,7 +268,7 @@ Some other text`)
r.NoError(err)
_ = tmpFile.Close()

r.NoError(ToTabularToFileBetweenTags(buildExtendedTestCommand(), "app", tmpFile.Name(), "foo_BAR|baz", "lorem+ipsum"))
r.NoError(ToTabularToFileBetweenTags(buildExtendedTestCommand(t), "app", tmpFile.Name(), "foo_BAR|baz", "lorem+ipsum"))

content, err := os.ReadFile(tmpFile.Name())
r.NoError(err)
Expand Down Expand Up @@ -293,15 +298,15 @@ Some other text`))

r.NoError(os.Remove(tmpFile.Name()))

err = ToTabularToFileBetweenTags(buildExtendedTestCommand(), "app", tmpFile.Name())
err = ToTabularToFileBetweenTags(buildExtendedTestCommand(t), "app", tmpFile.Name())

r.ErrorIs(err, fs.ErrNotExist)
})
}

func TestToMarkdown(t *testing.T) {
t.Run("no flags", func(t *testing.T) {
app := buildExtendedTestCommand()
app := buildExtendedTestCommand(t)
app.Flags = nil

res, err := ToMarkdown(app)
Expand All @@ -311,7 +316,7 @@ func TestToMarkdown(t *testing.T) {
})

t.Run("no commands", func(t *testing.T) {
app := buildExtendedTestCommand()
app := buildExtendedTestCommand(t)
app.Commands = nil

res, err := ToMarkdown(app)
Expand All @@ -321,7 +326,7 @@ func TestToMarkdown(t *testing.T) {
})

t.Run("no authors", func(t *testing.T) {
app := buildExtendedTestCommand()
app := buildExtendedTestCommand(t)
app.Authors = []any{}

res, err := ToMarkdown(app)
Expand All @@ -331,7 +336,7 @@ func TestToMarkdown(t *testing.T) {
})

t.Run("no usage text", func(t *testing.T) {
app := buildExtendedTestCommand()
app := buildExtendedTestCommand(t)
app.UsageText = ""

res, err := ToMarkdown(app)
Expand All @@ -342,7 +347,7 @@ func TestToMarkdown(t *testing.T) {
}

func TestToMan(t *testing.T) {
app := buildExtendedTestCommand()
app := buildExtendedTestCommand(t)

res, err := ToMan(app)

Expand All @@ -351,7 +356,7 @@ func TestToMan(t *testing.T) {
}

func TestToManParseError(t *testing.T) {
app := buildExtendedTestCommand()
app := buildExtendedTestCommand(t)

tmp := MarkdownDocTemplate
t.Cleanup(func() { MarkdownDocTemplate = tmp })
Expand All @@ -363,7 +368,7 @@ func TestToManParseError(t *testing.T) {
}

func TestToManWithSection(t *testing.T) {
cmd := buildExtendedTestCommand()
cmd := buildExtendedTestCommand(t)

res, err := ToManWithSection(cmd, 8)

Expand Down
2 changes: 1 addition & 1 deletion markdown_tabular.md.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{{- /**/ -}} | `{{ $flag.Name }}{{ if $flag.TakesValue }}="…"{{ end }}` {{ if $flag.Aliases }}(`{{ join $flag.Aliases "`, `" }}`) {{ end }}
{{- /**/ -}} | {{ $flag.Usage }}
{{- /**/ -}} | {{ $flag.Type }}
{{- /**/ -}} | {{ if $flag.Default }}`{{ $flag.Default }}`{{ end }}
{{- /**/ -}} | {{ if $flag.Default }}{{ $flag.Default }}{{ end }}
{{- /**/ -}} | {{ if $flag.EnvVars }}`{{ join $flag.EnvVars "`, `" }}`{{ else }}*none*{{ end }}
{{- /**/ -}} |
{{ end }}
Expand Down
4 changes: 4 additions & 0 deletions testdata/expected-doc-full.man
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ greet
[--another-flag|-b]
[--flag|--fl|-f]=[value]
[--socket|-s]=[value]
[--temp-dir]=[value]

.fi
.RE
Expand Down Expand Up @@ -49,6 +50,9 @@ app [first_arg] [second_arg]
.PP
\fB--socket, -s\fP="": some 'usage' text (default: value)

.PP
\fB--temp-dir\fP="": (default: test temp dir)


.SH COMMANDS
.SH config, c
Expand Down
3 changes: 3 additions & 0 deletions testdata/expected-doc-full.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ greet
[--another-flag|-b]
[--flag|--fl|-f]=[value]
[--socket|-s]=[value]
[--temp-dir]=[value]
```

# DESCRIPTION
Expand All @@ -30,6 +31,8 @@ app [first_arg] [second_arg]

**--socket, -s**="": some 'usage' text (default: value)

**--temp-dir**="": (default: test temp dir)


# COMMANDS

Expand Down
3 changes: 3 additions & 0 deletions testdata/expected-doc-no-authors.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ greet
[--another-flag|-b]
[--flag|--fl|-f]=[value]
[--socket|-s]=[value]
[--temp-dir]=[value]
```

# DESCRIPTION
Expand All @@ -30,6 +31,8 @@ app [first_arg] [second_arg]

**--socket, -s**="": some 'usage' text (default: value)

**--temp-dir**="": (default: test temp dir)


# COMMANDS

Expand Down
3 changes: 3 additions & 0 deletions testdata/expected-doc-no-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ greet
[--another-flag|-b]
[--flag|--fl|-f]=[value]
[--socket|-s]=[value]
[--temp-dir]=[value]
```

# DESCRIPTION
Expand All @@ -30,3 +31,5 @@ app [first_arg] [second_arg]

**--socket, -s**="": some 'usage' text (default: value)

**--temp-dir**="": (default: test temp dir)

3 changes: 3 additions & 0 deletions testdata/expected-doc-no-usagetext.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ greet
[--another-flag|-b]
[--flag|--fl|-f]=[value]
[--socket|-s]=[value]
[--temp-dir]=[value]
```

# DESCRIPTION
Expand All @@ -30,6 +31,8 @@ greet [GLOBAL OPTIONS] [command [COMMAND OPTIONS]] [ARGUMENTS...]

**--socket, -s**="": some 'usage' text (default: value)

**--temp-dir**="": (default: test temp dir)


# COMMANDS

Expand Down
1 change: 1 addition & 0 deletions testdata/expected-tabular-markdown-custom-app-path.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Global flags:
| `--socket="…"` (`-s`) | some 'usage' text | string | `value` | *none* |
| `--flag="…"` (`--fl`, `-f`) | | string | | *none* |
| `--another-flag` (`-b`) | another usage text | bool | `false` | `EXAMPLE_VARIABLE_NAME` |
| `--temp-dir="…"` | | string | test temp dir | *none* |

### `config` command (aliases: `c`)

Expand Down
1 change: 1 addition & 0 deletions testdata/expected-tabular-markdown-full.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Global flags:
| `--socket="…"` (`-s`) | some 'usage' text | string | `value` | *none* |
| `--flag="…"` (`--fl`, `-f`) | | string | | *none* |
| `--another-flag` (`-b`) | another usage text | bool | `false` | `EXAMPLE_VARIABLE_NAME` |
| `--temp-dir="…"` | | string | test temp dir | *none* |

### `config` command (aliases: `c`)

Expand Down
Loading