feat: add slack docs search subcommand #433
feat: add slack docs search subcommand #433lukegalbraithrussell wants to merge 20 commits intomainfrom
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #433 +/- ##
==========================================
+ Coverage 70.42% 71.11% +0.68%
==========================================
Files 221 222 +1
Lines 18539 18569 +30
==========================================
+ Hits 13057 13205 +148
+ Misses 4307 4183 -124
- Partials 1175 1181 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
cmd/docs/search.go
Outdated
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const docsSearchAPIURL = "https://docs-slack-d-search-api-duu9zr.herokuapp.com/api/search" |
There was a problem hiding this comment.
This will be updated to docs.slack.dev once api endpoint PR is merged in private docs repo
There was a problem hiding this comment.
| const docsSearchAPIURL = "https://docs-slack-d-search-api-duu9zr.herokuapp.com/api/search" | |
| const docsURL = "https://docs-slack-d-search-api-duu9zr.herokuapp.com/" |
🪬 suggestion: We might want to abstract this to the docs/docs.go file since we target it in multiple places? It might be useful for testing changes too?
There was a problem hiding this comment.
🔬 note: Thanks for also including these as now separate variables:
Line 29 in 671b4c8
slack-cli/internal/api/docs.go
Line 27 in 671b4c8
srtaalej
left a comment
There was a problem hiding this comment.
left some comments about terminal ouput and tests but these changes are looking really good ⭐ ! lets get those addressed so we can merge 😝
cmd/docs/search.go
Outdated
| return nil | ||
| } | ||
|
|
||
| func fetchAndOutputSearchResults(ctx context.Context, clients *shared.ClientFactory, query string, limit int, httpClient *http.Client) error { |
There was a problem hiding this comment.
it'd be nice if URLs were full https://docs.slack.dev URLs so they're cmd+clickable in the terminal
{
"url": "https://docs.slack.dev/block-kit/",
"title": "Block Kit"
},right now the json outputs as
{
"url": "/block-kit/",
"title": "Block Kit"
},There was a problem hiding this comment.
📚 thought: I agree listing entire links is ideal and might suggest we add a text format with this?
$ slack docs search "Block Kit" --output=text👾 ramble: If this format is supported it seems awkward to write that flag instead of defaulting to it but this is personal preference I think!
There was a problem hiding this comment.
@lukegalbraithrussell This is an awesome feature to be bringing 📚 ✨
I'm leaving a handful of comments that do request changes, but I'm hoping we can work through these:
- The API method logic is included with command: I understand we reach a different host but we might still find
apipackage useful. - Defaulting outputs for the person reading: I'm a fan of JSON but find this jarring when hoping for a quick search in terminal. I instead suggest a default
textoutput to use section formatting:
$ slack docs search "Block Kit"- Deprecating the "--search" flag: Can we make this a separate PR? Adding JSON outputs might be blocking this PR from merging now, but I think those changes have a faster review 🏁
- Standardizing the
docs.slack.devAPI client: We're starting to find the same URL in multiple places and I'm hoping changes toward a standard place for this has good pattern? - Erroring for unexpected inputs: One comment also notes that we should error instead of opening browsers for unexpected output types 👻
Please do let me know if I can share more toward these changes. I'd love to see this land 💌
cmd/docs/docs.go
Outdated
| } | ||
|
|
||
| cmd.Flags().BoolVar(&searchMode, "search", false, "open Slack docs search page or search with query") | ||
| cmd.Flags().BoolVar(&searchMode, "search", false, "[DEPRECATED] open Slack docs search page or search with query (use 'docs search' subcommand instead)") |
There was a problem hiding this comment.
| cmd.Flags().BoolVar(&searchMode, "search", false, "[DEPRECATED] open Slack docs search page or search with query (use 'docs search' subcommand instead)") | |
| // DEPRECATED(semver:major): Remove in favor of "search" command | |
| cmd.Flags().BoolVar(&searchMode, "search", false, "open Slack docs search page or search with query") | |
| cmd.Flag("search").Hidden = true |
🔭 suggestion: Let's prefer to hide deprecated features!
There was a problem hiding this comment.
🪓 note: We might now consider breaking this for the next update. I'm starting to think removing these fallbacks can be alright in this PR? @lukegalbraithrussell
cmd/docs/search.go
Outdated
| return nil | ||
| } | ||
|
|
||
| func fetchAndOutputSearchResults(ctx context.Context, clients *shared.ClientFactory, query string, limit int, httpClient *http.Client) error { |
There was a problem hiding this comment.
📚 thought: I agree listing entire links is ideal and might suggest we add a text format with this?
$ slack docs search "Block Kit" --output=text👾 ramble: If this format is supported it seems awkward to write that flag instead of defaulting to it but this is personal preference I think!
cmd/docs/search.go
Outdated
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const docsSearchAPIURL = "https://docs-slack-d-search-api-duu9zr.herokuapp.com/api/search" |
There was a problem hiding this comment.
| const docsSearchAPIURL = "https://docs-slack-d-search-api-duu9zr.herokuapp.com/api/search" | |
| const docsURL = "https://docs-slack-d-search-api-duu9zr.herokuapp.com/" |
🪬 suggestion: We might want to abstract this to the docs/docs.go file since we target it in multiple places? It might be useful for testing changes too?
zimeg
left a comment
There was a problem hiding this comment.
@lukegalbraithrussell I'm fascinated with the first test I ran... Amazing! 📚 ✨
$ slack docs search chat.postmessage
chat.postMessage method
https://docs.slack.dev/reference/methods/chat.postMessage/
Here are some new thoughts I have since review:
- Breaking search: We might be alright to avoid fallbacks for the "--search" flag with upcoming releases happening soon? I understand our releases are not too predictable at this time and I apologize for the thrash on this.
- No results found: When I search for more obtuse terms I find no output appears! This is confusing to me when I'd at least like to know nothing was found but perhaps personal preference 📚
- Section formats: The text format is amazing to read. An example similar of the
samplescommand shows how we might want these outputs to appear more perhaps before landing this?
I also made a handful of changes during review to find patterns we're moving toward in the api package and tests. I hope pushing these direct was alright since I found words were failing me...
All testing is working superb for me too so I'm marking this as approved with confidence 🤓 The comments remaining are suggestions toward polished experience and maintenance ongoing.
Super nice work on bringing this to life! 🏆
| func buildDocsSearchURL(query string) string { | ||
| encodedQuery := url.QueryEscape(query) | ||
| return fmt.Sprintf("%s/search/?q=%s", docsURL, encodedQuery) | ||
| } |
There was a problem hiding this comment.
🎁 suggestion(non-blocking): I understand this is shared between this file and search.go but perhaps it'd be alright to move to the search file?
There was a problem hiding this comment.
👾 ramble: If we do decide to remove the "--search" flag let's also perhaps inline this!
There was a problem hiding this comment.
🔬 note: With these changes let's update remediation for an invalid docs command to suggest the "search" command also:
$ slack docs apps
🚫 Invalid docs command. Did you mean to search? (docs_search_flag_required)
💡 Suggestion
Use --search flag: slack docs --search "apps"
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const docsURL = "https://docs.slack.dev" |
There was a problem hiding this comment.
🔗 praise: This is a nice constant to share I'll claim! Global variables sometimes can give me stress...
cmd/docs/search.go
Outdated
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const docsSearchAPIURL = "https://docs-slack-d-search-api-duu9zr.herokuapp.com/api/search" |
There was a problem hiding this comment.
🔬 note: Thanks for also including these as now separate variables:
Line 29 in 671b4c8
slack-cli/internal/api/docs.go
Line 27 in 671b4c8
cmd/docs/docs.go
Outdated
| } | ||
|
|
||
| cmd.Flags().BoolVar(&searchMode, "search", false, "open Slack docs search page or search with query") | ||
| cmd.Flags().BoolVar(&searchMode, "search", false, "[DEPRECATED] open Slack docs search page or search with query (use 'docs search' subcommand instead)") |
There was a problem hiding this comment.
🪓 note: We might now consider breaking this for the next update. I'm starting to think removing these fallbacks can be alright in this PR? @lukegalbraithrussell
cmd/docs/search.go
Outdated
| case "json": | ||
| return fetchAndOutputSearchResults(ctx, clients, query, cfg.limit) | ||
| case "text": | ||
| return fetchAndOutputTextResults(ctx, clients, query, cfg.limit) |
There was a problem hiding this comment.
🪩 quibble: I'd support inlining these functions to avoid jumping around the page but not a blocker!
zimeg
left a comment
There was a problem hiding this comment.
👾 One note more after continued testing. This is a nice development build to use!
| Command: "docs search \"api\" --output=json --limit=5", | ||
| }, | ||
| }), | ||
| Args: cobra.MinimumNArgs(1), |
There was a problem hiding this comment.
| Args: cobra.MinimumNArgs(1), | |
| Args: cobra.MinimumNArgs(0), |
👾 issue: We might want to default to opening the browser if no arguments are provided?
zimeg
left a comment
There was a problem hiding this comment.
🙀 note: Another thought on dog food!
Changelog
Adds
slack docs searchsubcommand. It can output search results as JSONSummary
slack docs search<query>--outputtexttext' , 'browserorjson--limit20Examples
Code coverage notes
The following lines in
search.gohave incomplete test coverage. They seemed cumbersome to cover.(Summarized by Claude)
Lines 88-89 (
if cfg.output == "json"branch): Conditional routing logic that's difficult to test through the command framework. The actual JSON output logic is thoroughly tested via direct function calls.Lines 129-130 (JSON encoding error handling): Defensive error handling for an unrealistic scenario (broken pipe when piping output). Most CLI tools don't explicitly handle this edge case.
Requirements