Skip to content

Commit 91da775

Browse files
fix: per-command :HELP filtering, sort by name, clarify README
- :HELP <command> now shows help for a single command (case-insensitive) - Unknown command names fall through to the full help listing - Sort help entries by help text (stable: all start with command name) - README: clarify :perftrace requires -p flag for timing data - Add tests for per-command help, case-insensitive lookup, and unknown command fallback
1 parent 748fec8 commit 91da775

3 files changed

Lines changed: 53 additions & 6 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ client_interface_name go-mssqldb
164164
program_name sqlcmd
165165
```
166166

167-
- `:perftrace` redirects performance statistics output to a file, stderr, or stdout. Use in conjunction with `-p` flag.
167+
- `:perftrace` redirects performance statistics output to a file, stderr, or stdout. Requires the `-p` flag (print statistics) to produce timing data.
168168

169169
```
170170
1> :perftrace c:/logs/perf.txt

pkg/sqlcmd/commands.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -618,16 +618,33 @@ func xmlCommand(s *Sqlcmd, args []string, line uint) error {
618618
}
619619

620620
func helpCommand(s *Sqlcmd, args []string, line uint) error {
621-
entries := make([]string, 0, len(s.Cmd))
621+
// :HELP <command> shows help for a single command
622+
if len(args) > 0 && strings.TrimSpace(args[0]) != "" {
623+
key := strings.ToUpper(strings.TrimSpace(args[0]))
624+
if cmd, ok := s.Cmd[key]; ok && cmd.help != "" {
625+
_, err := s.GetOutput().Write([]byte(cmd.help))
626+
return err
627+
}
628+
// Unknown command name -- fall through to full listing
629+
}
630+
631+
// Collect and sort by command name for stable output order
632+
type entry struct {
633+
name string
634+
help string
635+
}
636+
entries := make([]entry, 0, len(s.Cmd))
622637
for _, cmd := range s.Cmd {
623638
if cmd.help != "" {
624-
entries = append(entries, cmd.help)
639+
entries = append(entries, entry{cmd.name, cmd.help})
625640
}
626641
}
627-
sort.Strings(entries)
642+
sort.Slice(entries, func(i, j int) bool {
643+
return entries[i].help < entries[j].help
644+
})
628645
var b strings.Builder
629-
for _, entry := range entries {
630-
b.WriteString(entry)
646+
for _, e := range entries {
647+
b.WriteString(e.help)
631648
}
632649
_, err := s.GetOutput().Write([]byte(b.String()))
633650
return err

pkg/sqlcmd/commands_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ func TestCommandParsing(t *testing.T) {
5656
{`RESET`, "RESET", []string{""}},
5757
{`:HELP`, "HELP", []string{""}},
5858
{`:help`, "HELP", []string{""}},
59+
{`:HELP CONNECT`, "HELP", []string{"CONNECT"}},
60+
{`:help exit`, "HELP", []string{"exit"}},
5961
{`:PERFTRACE stderr`, "PERFTRACE", []string{"stderr"}},
6062
{`:perftrace c:/logs/perf.txt`, "PERFTRACE", []string{"c:/logs/perf.txt"}},
6163
}
@@ -480,6 +482,34 @@ func TestHelpCommand(t *testing.T) {
480482
"help output missing text for command %s", name)
481483
}
482484
}
485+
486+
// :HELP <command> should show only that command's help
487+
buf.buf.Reset()
488+
err = helpCommand(s, []string{"CONNECT"}, 1)
489+
assert.NoError(t, err, "helpCommand CONNECT should not error")
490+
output = buf.buf.String()
491+
assert.Contains(t, output, ":connect", "HELP CONNECT should show connect help")
492+
assert.NotContains(t, output, ":exit", "HELP CONNECT should not show exit help")
493+
494+
// Case-insensitive lookup
495+
buf.buf.Reset()
496+
err = helpCommand(s, []string{"exit"}, 1)
497+
assert.NoError(t, err, "helpCommand exit should not error")
498+
output = buf.buf.String()
499+
assert.Contains(t, output, ":exit", "HELP exit should show exit help")
500+
assert.NotContains(t, output, ":connect", "HELP exit should not show connect help")
501+
502+
// Unknown command falls through to full listing
503+
buf.buf.Reset()
504+
err = helpCommand(s, []string{"NOSUCHCMD"}, 1)
505+
assert.NoError(t, err, "helpCommand unknown should not error")
506+
output = buf.buf.String()
507+
for name, cmd := range s.Cmd {
508+
if cmd.help != "" {
509+
assert.Contains(t, output, cmd.help,
510+
"unknown command should show full help, missing %s", name)
511+
}
512+
}
483513
}
484514

485515
func TestAllCommandsHaveHelp(t *testing.T) {

0 commit comments

Comments
 (0)