refactor(msg): single space between keyword and message, improve config suggestions
Tightens keyword formatting (ok/FAIL/hint/etc.) from two spaces to one. Makes config key suggestions more generous: normalises spaces to underscores, matches against leaf segments, and uses substring matching. Updates all golden files.
This commit is contained in:
parent
db607ac696
commit
c9b448d508
47 changed files with 144 additions and 118 deletions
|
|
@ -2,6 +2,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/agnivade/levenshtein"
|
||||
)
|
||||
|
|
@ -69,16 +70,36 @@ func findConfigField(fields []ConfigField, key string) *ConfigField {
|
|||
return nil
|
||||
}
|
||||
|
||||
// suggestConfigKey returns Levenshtein-based suggestions for a mistyped config key.
|
||||
// suggestConfigKey returns suggestions for a mistyped config key. More generous
|
||||
// than key/store suggestions since the config key space is small (~11 keys).
|
||||
// Normalises spaces to underscores and matches against both the full dotted key
|
||||
// and the leaf segment (part after the last dot).
|
||||
func suggestConfigKey(fields []ConfigField, target string) []string {
|
||||
minThreshold := 1
|
||||
maxThreshold := 4
|
||||
threshold := min(max(len(target)/3, minThreshold), maxThreshold)
|
||||
normalized := strings.ReplaceAll(target, " ", "_")
|
||||
var suggestions []string
|
||||
for _, f := range fields {
|
||||
if levenshtein.ComputeDistance(target, f.Key) <= threshold {
|
||||
if matchesConfigKey(normalized, f.Key) {
|
||||
suggestions = append(suggestions, f.Key)
|
||||
}
|
||||
}
|
||||
return suggestions
|
||||
}
|
||||
|
||||
func matchesConfigKey(input, key string) bool {
|
||||
// Substring match (either direction)
|
||||
if strings.Contains(key, input) || strings.Contains(input, key) {
|
||||
return true
|
||||
}
|
||||
// Levenshtein against full dotted key
|
||||
if levenshtein.ComputeDistance(input, key) <= max(len(key)/3, 4) {
|
||||
return true
|
||||
}
|
||||
// Levenshtein against leaf segment
|
||||
if i := strings.LastIndex(key, "."); i >= 0 {
|
||||
leaf := key[i+1:]
|
||||
if levenshtein.ComputeDistance(input, leaf) <= max(len(leaf)/3, 1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ func runDoctor(w io.Writer) bool {
|
|||
code = "31"
|
||||
hasError = true
|
||||
}
|
||||
fmt.Fprintf(w, "%s %s\n", keyword(code, level, tty), msg)
|
||||
fmt.Fprintf(w, "%s %s\n", keyword(code, level, tty), msg)
|
||||
}
|
||||
|
||||
tree := func(items []string) {
|
||||
|
|
@ -279,7 +279,7 @@ func runDoctor(w io.Writer) bool {
|
|||
if parseErrors > 0 {
|
||||
emit("FAIL", fmt.Sprintf("%d store(s), %d with parse errors", len(stores), parseErrors))
|
||||
} else {
|
||||
emit("ok", fmt.Sprintf("%d store(s), %d key(s), %d secret(s), %s total",
|
||||
emit("ok", fmt.Sprintf("%d store(s), %d key(s), %d secret(s), %s total size",
|
||||
len(stores), totalKeys, totalSecrets, formatSize(int(totalSize))))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
cmd/msg.go
16
cmd/msg.go
|
|
@ -48,41 +48,41 @@ func keyword(code, word string, tty bool) string {
|
|||
}
|
||||
|
||||
func printError(err error) {
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("31", "FAIL", stderrIsTerminal()), err)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("31", "FAIL", stderrIsTerminal()), err)
|
||||
}
|
||||
|
||||
func printHint(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("2", "hint", stderrIsTerminal()), msg)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("2", "hint", stderrIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func warnf(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("33", "WARN", stderrIsTerminal()), msg)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("33", "WARN", stderrIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func infof(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("34", "info", stderrIsTerminal()), msg)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("34", "info", stderrIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func okf(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("32", "ok", stderrIsTerminal()), msg)
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", keyword("32", "ok", stderrIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func promptf(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stdout, "%s %s\n", keyword("36", "???", stdoutIsTerminal()), msg)
|
||||
fmt.Fprintf(os.Stdout, "%s %s\n", keyword("36", "???", stdoutIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func progressf(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(os.Stdout, "%s %s\n", keyword("2", ">", stdoutIsTerminal()), msg)
|
||||
fmt.Fprintf(os.Stdout, "%s %s\n", keyword("2", ">", stdoutIsTerminal()), msg)
|
||||
}
|
||||
|
||||
func scanln(dest *string) error {
|
||||
fmt.Fprintf(os.Stdout, "%s ", keyword("2", "==>", stdoutIsTerminal()))
|
||||
fmt.Fprintf(os.Stdout, "%s ", keyword("2", "==>", stdoutIsTerminal()))
|
||||
_, err := fmt.Scanln(dest)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue