Skip to content

Commit 29ee8ee

Browse files
updates to be better
1 parent 1d12927 commit 29ee8ee

3 files changed

Lines changed: 47 additions & 38 deletions

File tree

cmd/docs/docs.go

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"net/url"
2020

2121
"github.com/slackapi/slack-cli/internal/shared"
22+
"github.com/slackapi/slack-cli/internal/slackerror"
2223
"github.com/slackapi/slack-cli/internal/slacktrace"
2324
"github.com/slackapi/slack-cli/internal/style"
2425
"github.com/spf13/cobra"
@@ -37,25 +38,20 @@ func NewCommand(clients *shared.ClientFactory) *cobra.Command {
3738
Command: "docs",
3839
},
3940
{
40-
Meaning: "Open Slack docs search page",
41-
Command: "docs --search",
42-
},
43-
{
44-
Meaning: "Search Slack docs",
41+
Meaning: "Search Slack developer docs for Block Kit",
4542
Command: "docs --search \"Block Kit\"",
4643
},
4744
{
48-
Meaning: "Search Slack docs without search flag",
49-
Command: "docs \"Block Kit\"",
45+
Meaning: "Open Slack docs search page",
46+
Command: "docs --search",
5047
},
5148
}),
52-
Args: cobra.MaximumNArgs(1), // Allow 0-1 arguments for search query
5349
RunE: func(cmd *cobra.Command, args []string) error {
5450
return runDocsCommand(clients, cmd, args)
5551
},
5652
}
5753

58-
cmd.Flags().BoolVar(&searchMode, "search", false, "open Slack docs search page")
54+
cmd.Flags().BoolVar(&searchMode, "search", false, "open Slack docs search page or search with query")
5955

6056
return cmd
6157
}
@@ -67,17 +63,27 @@ func runDocsCommand(clients *shared.ClientFactory, cmd *cobra.Command, args []st
6763
var docsURL string
6864
var sectionText string
6965

70-
if len(args) > 0 {
71-
// Search query provided as positional argument: slack docs "query"
72-
searchQuery := url.QueryEscape(args[0])
73-
docsURL = fmt.Sprintf("https://docs.slack.dev/search/?q=%s", searchQuery)
74-
sectionText = "Docs Search"
75-
} else if searchMode {
76-
// Search flag provided without query: slack docs --search
77-
docsURL = "https://docs.slack.dev/search/"
78-
sectionText = "Docs Search"
66+
// Validate: if there are arguments, --search flag must be used
67+
if len(args) > 0 && !cmd.Flags().Changed("search") {
68+
return slackerror.New(slackerror.ErrDocsSearchFlagRequired).WithRemediation(
69+
"Use --search flag: %s",
70+
style.Commandf(fmt.Sprintf("docs --search \"%s\"", args[0]), false),
71+
)
72+
}
73+
74+
if cmd.Flags().Changed("search") {
75+
if len(args) > 0 {
76+
// --search "query" (space-separated) - use the first arg as the query
77+
encodedQuery := url.QueryEscape(args[0])
78+
docsURL = fmt.Sprintf("https://docs.slack.dev/search/?q=%s", encodedQuery)
79+
sectionText = "Docs Search"
80+
} else {
81+
// --search (no argument) - open search page
82+
docsURL = "https://docs.slack.dev/search/"
83+
sectionText = "Docs Search"
84+
}
7985
} else {
80-
// Default homepage: slack docs
86+
// No search flag: default homepage
8187
docsURL = "https://docs.slack.dev"
8288
sectionText = "Docs Open"
8389
}
@@ -92,10 +98,10 @@ func runDocsCommand(clients *shared.ClientFactory, cmd *cobra.Command, args []st
9298

9399
clients.Browser().OpenURL(docsURL)
94100

95-
if len(args) > 0 || searchMode {
101+
if cmd.Flags().Changed("search") {
96102
traceValue := ""
97103
if len(args) > 0 {
98-
traceValue = args[0]
104+
traceValue = args[0] // For space-separated syntax
99105
}
100106
clients.IO.PrintTrace(ctx, slacktrace.DocsSearchSuccess, traceValue)
101107
} else {

cmd/docs/docs_test.go

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,16 @@ func Test_Docs_DocsCommand(t *testing.T) {
4040
"https://docs.slack.dev",
4141
},
4242
},
43-
"opens docs with basic search query": {
44-
CmdArgs: []string{"messaging"},
43+
"fails when positional argument provided without search flag": {
44+
CmdArgs: []string{"Block Kit"},
45+
ExpectedErrorStrings: []string{"Invalid docs command. Did you mean to search?"},
46+
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
47+
// No browser calls should be made when command fails
48+
cm.Browser.AssertNotCalled(t, "OpenURL")
49+
},
50+
},
51+
"opens docs with search query using space syntax": {
52+
CmdArgs: []string{"--search", "messaging"},
4553
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
4654
expectedURL := "https://docs.slack.dev/search/?q=messaging"
4755
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
@@ -53,7 +61,7 @@ func Test_Docs_DocsCommand(t *testing.T) {
5361
},
5462
},
5563
"handles search query with multiple words": {
56-
CmdArgs: []string{"socket mode"},
64+
CmdArgs: []string{"--search", "socket mode"},
5765
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
5866
expectedURL := "https://docs.slack.dev/search/?q=socket+mode"
5967
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
@@ -65,7 +73,7 @@ func Test_Docs_DocsCommand(t *testing.T) {
6573
},
6674
},
6775
"handles special characters in search query": {
68-
CmdArgs: []string{"messages & webhooks"},
76+
CmdArgs: []string{"--search", "messages & webhooks"},
6977
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
7078
expectedURL := "https://docs.slack.dev/search/?q=messages+%26+webhooks"
7179
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
@@ -77,7 +85,7 @@ func Test_Docs_DocsCommand(t *testing.T) {
7785
},
7886
},
7987
"handles search query with quotes": {
80-
CmdArgs: []string{"webhook \"send message\""},
88+
CmdArgs: []string{"--search", "webhook \"send message\""},
8189
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
8290
expectedURL := "https://docs.slack.dev/search/?q=webhook+%22send+message%22"
8391
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
@@ -88,18 +96,6 @@ func Test_Docs_DocsCommand(t *testing.T) {
8896
"https://docs.slack.dev/search/?q=webhook+%22send+message%22",
8997
},
9098
},
91-
"handles empty search query": {
92-
CmdArgs: []string{""},
93-
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
94-
expectedURL := "https://docs.slack.dev/search/?q="
95-
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
96-
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.DocsSearchSuccess, mock.Anything)
97-
},
98-
ExpectedOutputs: []string{
99-
"Docs Search",
100-
"https://docs.slack.dev/search/?q=",
101-
},
102-
},
10399
"handles search flag without argument": {
104100
CmdArgs: []string{"--search"},
105101
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {

internal/slackerror/errors.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ const (
9696
ErrDenoNotFound = "deno_not_found"
9797
ErrDeployedAppNotSupported = "deployed_app_not_supported"
9898
ErrDocumentationGenerationFailed = "documentation_generation_failed"
99+
ErrDocsSearchFlagRequired = "docs_search_flag_required"
99100
ErrEnterpriseNotFound = "enterprise_not_found"
100101
ErrFailedAddingCollaborator = "failed_adding_collaborator"
101102
ErrFailedCreatingApp = "failed_creating_app"
@@ -679,6 +680,12 @@ Otherwise start your app for local development with: %s`,
679680
Message: "Failed to generate documentation",
680681
},
681682

683+
ErrDocsSearchFlagRequired: {
684+
Code: ErrDocsSearchFlagRequired,
685+
Message: "Invalid docs command. Did you mean to search?",
686+
Remediation: fmt.Sprintf("Use --search flag: %s", style.Commandf("docs --search \"<query>\"", false)),
687+
},
688+
682689
ErrEnterpriseNotFound: {
683690
Code: ErrEnterpriseNotFound,
684691
Message: "The `enterprise` was not found",

0 commit comments

Comments
 (0)