mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
feat: suggest similar flags for an unknown flag
tea issue list --lable bug now fails with "unknown flag: --lable; did you mean --label?". Suggestions are the command's visible flags that start with the typed name or are at most two edits away from it. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
2 files changed
+57
-1
No files matched your search
+41
-1
@@ -103,7 +103,7 @@ func NewRoot(deps Dependencies) *cobra.Command {
|
||||
root.SetIn(deps.Streams.In)
|
||||
root.SetOut(deps.Streams.Out)
|
||||
root.SetErr(deps.Streams.ErrOut)
|
||||
root.SetFlagErrorFunc(func(_ *cobra.Command, err error) error { return clierr.Wrap(clierr.Usage, err) })
|
||||
root.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error { return clierr.Wrap(clierr.Usage, suggestFlags(cmd, err)) })
|
||||
flags := root.PersistentFlags()
|
||||
flags.StringVar(&a.options.host, "host", "", "Gitea instance `URL`, including any base path")
|
||||
flags.StringVar(&a.options.user, "user", "", "Account `name` on the selected instance")
|
||||
@@ -215,6 +215,46 @@ func flagAliases(cmd *cobra.Command, aliases map[string]string) {
|
||||
})
|
||||
}
|
||||
|
||||
// suggestFlags adds the flags of cmd with a similar name to an unknown flag error, as in
|
||||
// "unknown flag: --lable; did you mean --label?".
|
||||
func suggestFlags(cmd *cobra.Command, err error) error {
|
||||
name, unknown := strings.CutPrefix(err.Error(), "unknown flag: --")
|
||||
if !unknown || len(name) < 3 {
|
||||
return err
|
||||
}
|
||||
var suggestions []string
|
||||
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
|
||||
if !flag.Hidden && (strings.HasPrefix(flag.Name, name) || editDistance(name, flag.Name) <= 2) {
|
||||
suggestions = append(suggestions, "--"+flag.Name)
|
||||
}
|
||||
})
|
||||
if len(suggestions) == 0 {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%w; did you mean %s?", err, strings.Join(suggestions, " or "))
|
||||
}
|
||||
|
||||
// editDistance counts the single-character insertions, deletions and substitutions that turn a into b.
|
||||
func editDistance(a, b string) int {
|
||||
row := make([]int, len(b)+1)
|
||||
for j := range row {
|
||||
row[j] = j
|
||||
}
|
||||
for i := 1; i <= len(a); i++ {
|
||||
diagonal := row[0]
|
||||
row[0] = i
|
||||
for j := 1; j <= len(b); j++ {
|
||||
substitution := diagonal
|
||||
if a[i-1] != b[j-1] {
|
||||
substitution++
|
||||
}
|
||||
diagonal = row[j]
|
||||
row[j] = min(row[j]+1, row[j-1]+1, substitution)
|
||||
}
|
||||
}
|
||||
return row[len(b)]
|
||||
}
|
||||
|
||||
// checkOutputFlags validates --json and --jq before a command runs. --jq alone selects every field,
|
||||
// except on commands that filter their raw JSON themselves (annotation tea.rawjson).
|
||||
func (a *application) checkOutputFlags(cmd *cobra.Command) error {
|
||||
|
||||
Reference in new issue
Block a user