Skip to content

Commit 4f13099

Browse files
authored
Merge branch 'main' into ale-accessibility-flag
2 parents 95a713e + 955c925 commit 4f13099

37 files changed

+1312
-444
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ jobs:
113113
default: "dev-build"
114114
docker: # run the steps with Docker
115115
# CircleCI Go images available at: https://hub.docker.com/r/circleci/golang/
116-
- image: cimg/go:1.26.1
116+
- image: cimg/go:1.26.2
117117
steps: # steps that comprise the `build` job
118118
- checkout # check out source code to working directory
119119
- restore_cache: # restores saved cache if no changes are detected since last run

.github/workflows/e2e_tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
steps:
2323
- name: Trigger CircleCI 'local' workflow
2424
if: ${{ github.event.inputs.status == 'false' }}
25-
uses: promiseofcake/circleci-trigger-action@a72a9ff0b0c663613c13e47d53301ea55d7da5d9 # v3.0.1
25+
uses: promiseofcake/circleci-trigger-action@e182462eba499cd888af8e3376038a2aeb58fa02 # v3.0.2
2626
with:
2727
user-token: ${{ secrets.CIRCLECI_TOKEN }}
2828
project-slug: slackapi/slack-cli
@@ -31,7 +31,7 @@ jobs:
3131
payload: '{"run_local_build_test_workflow": true}'
3232
- name: Trigger CircleCI 'e2e' workflow
3333
if: ${{ github.event.inputs.status == 'true' }}
34-
uses: promiseofcake/circleci-trigger-action@a72a9ff0b0c663613c13e47d53301ea55d7da5d9 # v3.0.1
34+
uses: promiseofcake/circleci-trigger-action@e182462eba499cd888af8e3376038a2aeb58fa02 # v3.0.2
3535
with:
3636
user-token: ${{ secrets.CIRCLECI_TOKEN }}
3737
project-slug: slackapi/slack-cli

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
- name: Set up Go
2626
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
2727
with:
28-
go-version: "1.26.1"
28+
go-version: "1.26.2"
2929
- name: Lint
3030
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
3131
with:
@@ -57,7 +57,7 @@ jobs:
5757
- name: Set up Go
5858
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
5959
with:
60-
go-version: "1.26.1"
60+
go-version: "1.26.2"
6161
- name: Report health score
6262
uses: slackapi/slack-health-score@d58a419f15cdaff97e9aa7f09f95772830ab66f7 # v0.1.1
6363
with:

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ tag:
8484
exit 1; \
8585
fi
8686
@printf "$(FONT_BOLD)Updating Docs$(FONT_RESET)\n"
87+
rm -rf ./docs/reference/commands ./docs/reference/errors.md
8788
./bin/slack docgen ./docs/reference --skip-update
8889
sed -i.bak -E "s#slack_cli_[0-9]+\.[0-9]+\.[0-9]+_macOS_arm64\.tar\.gz#slack_cli_$(RELEASE_VERSION)_macOS_arm64.tar.gz#" docs/guides/installing-the-slack-cli-for-mac-and-linux.md
8990
sed -i.bak -E "s#slack_cli_[0-9]+\.[0-9]+\.[0-9]+_macOS_amd64\.tar\.gz#slack_cli_$(RELEASE_VERSION)_macOS_amd64.tar.gz#" docs/guides/installing-the-slack-cli-for-mac-and-linux.md

cmd/docs/docs.go

Lines changed: 14 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,101 +15,61 @@
1515
package docs
1616

1717
import (
18-
"fmt"
19-
"net/url"
20-
"strings"
21-
2218
"github.com/slackapi/slack-cli/internal/shared"
23-
"github.com/slackapi/slack-cli/internal/slackerror"
2419
"github.com/slackapi/slack-cli/internal/slacktrace"
2520
"github.com/slackapi/slack-cli/internal/style"
2621
"github.com/spf13/cobra"
2722
)
2823

29-
var searchMode bool
24+
const docsURL = "https://docs.slack.dev"
3025

3126
func NewCommand(clients *shared.ClientFactory) *cobra.Command {
3227
cmd := &cobra.Command{
3328
Use: "docs",
3429
Short: "Open Slack developer docs",
35-
Long: "Open the Slack developer docs in your browser, with optional search functionality",
30+
Long: "Open the Slack developer docs in your browser or search them using the search subcommand",
3631
Example: style.ExampleCommandsf([]style.ExampleCommand{
3732
{
3833
Meaning: "Open Slack developer docs homepage",
3934
Command: "docs",
4035
},
4136
{
4237
Meaning: "Search Slack developer docs for Block Kit",
43-
Command: "docs --search \"Block Kit\"",
38+
Command: "docs search \"Block Kit\"",
4439
},
4540
{
46-
Meaning: "Open Slack docs search page",
47-
Command: "docs --search",
41+
Meaning: "Search docs and open results in browser",
42+
Command: "docs search \"Block Kit\" --output=browser",
4843
},
4944
}),
45+
Args: cobra.NoArgs,
5046
RunE: func(cmd *cobra.Command, args []string) error {
51-
return runDocsCommand(clients, cmd, args)
47+
return runDocsCommand(clients, cmd)
5248
},
49+
// Disable automatic suggestions for unknown commands
50+
DisableSuggestions: true,
5351
}
5452

55-
cmd.Flags().BoolVar(&searchMode, "search", false, "open Slack docs search page or search with query")
53+
// Add the search subcommand
54+
cmd.AddCommand(NewSearchCommand(clients))
5655

5756
return cmd
5857
}
5958

6059
// runDocsCommand opens Slack developer docs in the browser
61-
func runDocsCommand(clients *shared.ClientFactory, cmd *cobra.Command, args []string) error {
60+
func runDocsCommand(clients *shared.ClientFactory, cmd *cobra.Command) error {
6261
ctx := cmd.Context()
6362

64-
var docsURL string
65-
var sectionText string
66-
67-
// Validate: if there are arguments, --search flag must be used
68-
if len(args) > 0 && !cmd.Flags().Changed("search") {
69-
query := strings.Join(args, " ")
70-
return slackerror.New(slackerror.ErrDocsSearchFlagRequired).WithRemediation(
71-
"Use --search flag: %s",
72-
style.Commandf(fmt.Sprintf("docs --search \"%s\"", query), false),
73-
)
74-
}
75-
76-
if cmd.Flags().Changed("search") {
77-
if len(args) > 0 {
78-
// --search "query" (space-separated) - join all args as the query
79-
query := strings.Join(args, " ")
80-
encodedQuery := url.QueryEscape(query)
81-
docsURL = fmt.Sprintf("https://docs.slack.dev/search/?q=%s", encodedQuery)
82-
sectionText = "Docs Search"
83-
} else {
84-
// --search (no argument) - open search page
85-
docsURL = "https://docs.slack.dev/search/"
86-
sectionText = "Docs Search"
87-
}
88-
} else {
89-
// No search flag: default homepage
90-
docsURL = "https://docs.slack.dev"
91-
sectionText = "Docs Open"
92-
}
93-
9463
clients.IO.PrintInfo(ctx, false, "\n%s", style.Sectionf(style.TextSection{
9564
Emoji: "books",
96-
Text: sectionText,
65+
Text: "Docs Open",
9766
Secondary: []string{
9867
docsURL,
9968
},
10069
}))
10170

10271
clients.Browser().OpenURL(docsURL)
103-
104-
if cmd.Flags().Changed("search") {
105-
traceValue := ""
106-
if len(args) > 0 {
107-
traceValue = strings.Join(args, " ")
108-
}
109-
clients.IO.PrintTrace(ctx, slacktrace.DocsSearchSuccess, traceValue)
110-
} else {
111-
clients.IO.PrintTrace(ctx, slacktrace.DocsSuccess)
112-
}
72+
clients.IO.PrintTrace(ctx, slacktrace.DocsSuccess)
11373

11474
return nil
11575
}

cmd/docs/docs_test.go

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727

2828
func Test_Docs_DocsCommand(t *testing.T) {
2929
testutil.TableTestCommand(t, testutil.CommandTests{
30-
"opens docs homepage without search": {
30+
"opens docs homepage": {
3131
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
3232
},
3333
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
@@ -40,93 +40,9 @@ func Test_Docs_DocsCommand(t *testing.T) {
4040
"https://docs.slack.dev",
4141
},
4242
},
43-
"fails when positional argument provided without search flag": {
43+
"rejects positional arguments": {
4444
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-
"fails when multiple positional arguments provided without search flag": {
52-
CmdArgs: []string{"webhook", "send", "message"},
53-
ExpectedErrorStrings: []string{"Invalid docs command. Did you mean to search?"},
54-
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
55-
// No browser calls should be made when command fails
56-
cm.Browser.AssertNotCalled(t, "OpenURL")
57-
},
58-
},
59-
"opens docs with search query using space syntax": {
60-
CmdArgs: []string{"--search", "messaging"},
61-
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
62-
expectedURL := "https://docs.slack.dev/search/?q=messaging"
63-
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
64-
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.DocsSearchSuccess, mock.Anything)
65-
},
66-
ExpectedOutputs: []string{
67-
"Docs Search",
68-
"https://docs.slack.dev/search/?q=messaging",
69-
},
70-
},
71-
"handles search with multiple arguments": {
72-
CmdArgs: []string{"--search", "Block", "Kit", "Element"},
73-
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
74-
expectedURL := "https://docs.slack.dev/search/?q=Block+Kit+Element"
75-
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
76-
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.DocsSearchSuccess, mock.Anything)
77-
},
78-
ExpectedOutputs: []string{
79-
"Docs Search",
80-
"https://docs.slack.dev/search/?q=Block+Kit+Element",
81-
},
82-
},
83-
"handles search query with multiple words": {
84-
CmdArgs: []string{"--search", "socket mode"},
85-
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
86-
expectedURL := "https://docs.slack.dev/search/?q=socket+mode"
87-
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
88-
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.DocsSearchSuccess, mock.Anything)
89-
},
90-
ExpectedOutputs: []string{
91-
"Docs Search",
92-
"https://docs.slack.dev/search/?q=socket+mode",
93-
},
94-
},
95-
"handles special characters in search query": {
96-
CmdArgs: []string{"--search", "messages & webhooks"},
97-
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
98-
expectedURL := "https://docs.slack.dev/search/?q=messages+%26+webhooks"
99-
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
100-
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.DocsSearchSuccess, mock.Anything)
101-
},
102-
ExpectedOutputs: []string{
103-
"Docs Search",
104-
"https://docs.slack.dev/search/?q=messages+%26+webhooks",
105-
},
106-
},
107-
"handles search query with quotes": {
108-
CmdArgs: []string{"--search", "webhook \"send message\""},
109-
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
110-
expectedURL := "https://docs.slack.dev/search/?q=webhook+%22send+message%22"
111-
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
112-
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.DocsSearchSuccess, mock.Anything)
113-
},
114-
ExpectedOutputs: []string{
115-
"Docs Search",
116-
"https://docs.slack.dev/search/?q=webhook+%22send+message%22",
117-
},
118-
},
119-
"handles search flag without argument": {
120-
CmdArgs: []string{"--search"},
121-
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
122-
expectedURL := "https://docs.slack.dev/search/"
123-
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
124-
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.DocsSearchSuccess, mock.Anything)
125-
},
126-
ExpectedOutputs: []string{
127-
"Docs Search",
128-
"https://docs.slack.dev/search/",
129-
},
45+
ExpectedErrorStrings: []string{"unknown command"},
13046
},
13147
}, func(cf *shared.ClientFactory) *cobra.Command {
13248
return NewCommand(cf)

0 commit comments

Comments
 (0)