mirror of
https://github.com/rclone/rclone.git
synced 2026-06-28 09:55:16 -04:00
config: fix root-relative markdown links in interactive config help - fixes #8239
Option help strings are also used to generate the website documentation, so some contain markdown links with root-relative targets such as [encoding section in the overview](/overview/#encoding). These render correctly on rclone.org but are confusing in the interactive config prompt, where the user sees the raw markdown and the link has no reachable root. Rewrite such links to text (https://rclone.org/path) when showing an option's help in the interactive config. The raw help is left unchanged so documentation generation is unaffected.
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -441,7 +442,7 @@ func backendConfig(ctx context.Context, name string, m configmap.Mapper, ri *fs.
|
||||
out.Option.Examples[1].Value == "false" &&
|
||||
out.Option.Exclusive {
|
||||
// Use Confirm for Yes/No questions as it has a nicer interface=
|
||||
fmt.Println(out.Option.Help)
|
||||
fmt.Println(renderHelpForTerminal(out.Option.Help))
|
||||
in.Result = fmt.Sprint(Confirm(Default))
|
||||
} else {
|
||||
value := ChooseOption(out.Option, name)
|
||||
@@ -483,12 +484,26 @@ func RemoteConfig(ctx context.Context, name string) error {
|
||||
return PostConfig(ctx, name, m, ri)
|
||||
}
|
||||
|
||||
// rootRelativeMarkdownLink matches a markdown link with a root-relative
|
||||
// target, e.g. [encoding section in the overview](/overview/#encoding).
|
||||
var rootRelativeMarkdownLink = regexp.MustCompile(`\[([^\]]+)\]\((/[^)]*)\)`)
|
||||
|
||||
// renderHelpForTerminal makes an option's help string readable on the
|
||||
// terminal. The same help text is also used to generate the website
|
||||
// documentation, where markdown links with root-relative targets resolve
|
||||
// correctly. On the terminal those links are confusing, so rewrite them to
|
||||
// "text (https://rclone.org/path)" using rclone.org as the implied root.
|
||||
func renderHelpForTerminal(help string) string {
|
||||
return rootRelativeMarkdownLink.ReplaceAllString(help, "$1 (https://rclone.org$2)")
|
||||
}
|
||||
|
||||
// ChooseOption asks the user to choose an option
|
||||
func ChooseOption(o *fs.Option, name string) string {
|
||||
fmt.Printf("Option %s.\n", o.Name)
|
||||
if o.Help != "" {
|
||||
// Show help string without empty lines.
|
||||
help := strings.ReplaceAll(strings.TrimSpace(o.Help), "\n\n", "\n")
|
||||
help = renderHelpForTerminal(help)
|
||||
fmt.Println(help)
|
||||
}
|
||||
|
||||
|
||||
45
fs/config/ui_internal_test.go
Normal file
45
fs/config/ui_internal_test.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRenderHelpForTerminal(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
help string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "no link",
|
||||
help: "The encoding for the backend.",
|
||||
want: "The encoding for the backend.",
|
||||
},
|
||||
{
|
||||
name: "root relative link",
|
||||
help: "See the [encoding section in the overview](/overview/#encoding) for more info.",
|
||||
want: "See the encoding section in the overview (https://rclone.org/overview/#encoding) for more info.",
|
||||
},
|
||||
{
|
||||
name: "root relative link without anchor",
|
||||
help: "See [rclone serve sftp](/commands/rclone_serve_sftp) for details.",
|
||||
want: "See rclone serve sftp (https://rclone.org/commands/rclone_serve_sftp) for details.",
|
||||
},
|
||||
{
|
||||
name: "multiple links",
|
||||
help: "[the time option docs](/docs/#time-options) and [authentication docs](/azureblob#authentication).",
|
||||
want: "the time option docs (https://rclone.org/docs/#time-options) and authentication docs (https://rclone.org/azureblob#authentication).",
|
||||
},
|
||||
{
|
||||
name: "absolute url left untouched",
|
||||
help: "See [rclone forum](https://forum.rclone.org/) for help.",
|
||||
want: "See [rclone forum](https://forum.rclone.org/) for help.",
|
||||
},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
assert.Equal(t, test.want, renderHelpForTerminal(test.help))
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user