Merge pull request '[agent/codex:gpt-5.4-mini] Read ~/spec/code/core/go/cli/RFC.md fully. Find features des...' (#59) from agent/read---spec-code-core-go-cli-rfc-md-full into dev
Some checks are pending
Security Scan / security (push) Waiting to run

This commit is contained in:
Virgil 2026-04-02 06:27:14 +00:00
commit 194d53f12d
2 changed files with 76 additions and 15 deletions

View file

@ -24,7 +24,7 @@ func AddHelpCommands(root *cli.Command) {
catalog := gohelp.DefaultCatalog() catalog := gohelp.DefaultCatalog()
if searchQuery != "" { if searchQuery != "" {
return renderSearchResults(catalog.Search(searchQuery), searchQuery) return searchHelpTopics(catalog, searchQuery)
} }
if len(args) == 0 { if len(args) == 0 {
@ -47,6 +47,25 @@ func AddHelpCommands(root *cli.Command) {
}, },
} }
searchCmd := &cli.Command{
Use: "search [query]",
Short: "Search help topics",
Args: cobra.ArbitraryArgs,
}
var searchCmdQuery string
searchCmd.Flags().StringVarP(&searchCmdQuery, "query", "q", "", "Search query")
searchCmd.RunE = func(cmd *cli.Command, args []string) error {
catalog := gohelp.DefaultCatalog()
query := strings.TrimSpace(searchCmdQuery)
if query == "" {
query = strings.TrimSpace(strings.Join(args, " "))
}
if query == "" {
return cli.Err("help search query is required")
}
return searchHelpTopics(catalog, query)
}
var serveAddr string var serveAddr string
serveCmd := &cli.Command{ serveCmd := &cli.Command{
Use: "serve", Use: "serve",
@ -59,10 +78,15 @@ func AddHelpCommands(root *cli.Command) {
serveCmd.Flags().StringVar(&serveAddr, "addr", ":8080", "HTTP listen address") serveCmd.Flags().StringVar(&serveAddr, "addr", ":8080", "HTTP listen address")
helpCmd.AddCommand(serveCmd) helpCmd.AddCommand(serveCmd)
helpCmd.AddCommand(searchCmd)
helpCmd.Flags().StringVarP(&searchQuery, "search", "s", "", "Search help topics") helpCmd.Flags().StringVarP(&searchQuery, "search", "s", "", "Search help topics")
root.AddCommand(helpCmd) root.AddCommand(helpCmd)
} }
func searchHelpTopics(catalog *gohelp.Catalog, query string) error {
return renderSearchResults(catalog.Search(query), query)
}
func renderSearchResults(results []*gohelp.SearchResult, query string) error { func renderSearchResults(results []*gohelp.SearchResult, query string) error {
if len(results) == 0 { if len(results) == 0 {
return cli.Err("no help topics matched %q", query) return cli.Err("no help topics matched %q", query)

View file

@ -45,6 +45,23 @@ func newHelpCommand(t *testing.T) *cli.Command {
return cmd return cmd
} }
func searchableHelpQuery(t *testing.T) string {
t.Helper()
catalog := gohelp.DefaultCatalog()
for _, candidate := range []string{"configuration", "docs", "search", "topic", "help"} {
if _, err := catalog.Get(candidate); err == nil {
continue
}
if len(catalog.Search(candidate)) > 0 {
return candidate
}
}
t.Skip("no suitable query found with suggestions")
return ""
}
func TestAddHelpCommands_Good(t *testing.T) { func TestAddHelpCommands_Good(t *testing.T) {
cmd := newHelpCommand(t) cmd := newHelpCommand(t)
@ -83,6 +100,26 @@ func TestAddHelpCommands_Good_Serve(t *testing.T) {
assert.Equal(t, "127.0.0.1:9090", gotAddr) assert.Equal(t, "127.0.0.1:9090", gotAddr)
} }
func TestAddHelpCommands_Good_Search(t *testing.T) {
root := &cli.Command{Use: "core"}
AddHelpCommands(root)
cmd, _, err := root.Find([]string{"help", "search"})
require.NoError(t, err)
require.NotNil(t, cmd)
query := searchableHelpQuery(t)
require.NoError(t, cmd.Flags().Set("query", query))
out := captureOutput(t, func() {
err := cmd.RunE(cmd, nil)
require.NoError(t, err)
})
assert.Contains(t, out, "SEARCH RESULTS")
assert.Contains(t, out, query)
}
func TestRenderSearchResults_Good(t *testing.T) { func TestRenderSearchResults_Good(t *testing.T) {
out := captureOutput(t, func() { out := captureOutput(t, func() {
err := renderSearchResults([]*gohelp.SearchResult{ err := renderSearchResults([]*gohelp.SearchResult{
@ -129,6 +166,19 @@ func TestAddHelpCommands_Bad(t *testing.T) {
assert.Contains(t, err.Error(), "no help topics matched") assert.Contains(t, err.Error(), "no help topics matched")
}) })
t.Run("missing search query", func(t *testing.T) {
root := &cli.Command{Use: "core"}
AddHelpCommands(root)
cmd, _, err := root.Find([]string{"help", "search"})
require.NoError(t, err)
require.NotNil(t, cmd)
err = cmd.RunE(cmd, nil)
require.Error(t, err)
assert.Contains(t, err.Error(), "help search query is required")
})
t.Run("missing topic", func(t *testing.T) { t.Run("missing topic", func(t *testing.T) {
cmd := newHelpCommand(t) cmd := newHelpCommand(t)
err := cmd.RunE(cmd, []string{"definitely-not-a-real-topic"}) err := cmd.RunE(cmd, []string{"definitely-not-a-real-topic"})
@ -137,20 +187,7 @@ func TestAddHelpCommands_Bad(t *testing.T) {
}) })
t.Run("missing topic shows suggestions when available", func(t *testing.T) { t.Run("missing topic shows suggestions when available", func(t *testing.T) {
catalog := gohelp.DefaultCatalog() query := searchableHelpQuery(t)
query := ""
for _, candidate := range []string{"configuration", "docs", "search", "topic", "help"} {
if _, err := catalog.Get(candidate); err == nil {
continue
}
if len(catalog.Search(candidate)) > 0 {
query = candidate
break
}
}
if query == "" {
t.Skip("no suitable query found with suggestions")
}
cmd := newHelpCommand(t) cmd := newHelpCommand(t)
out := captureOutput(t, func() { out := captureOutput(t, func() {