-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
ahkpm search
command to find packages (#161)
Fixes #34
- Loading branch information
Showing
5 changed files
with
186 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
Searches GitHub for any ahkpm packages which match the specified query. The | ||
search is limited to GitHub repositories in the `ahkpm-package` topic. | ||
|
||
So `ahkpm search testing` will return any GitHub repositories that both match | ||
"testing" and are tagged with `ahkpm-package`. | ||
|
||
If no search terms are specified, it will provide an unfiltered list of ahkpm | ||
packages. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package cmd | ||
|
||
import ( | ||
"ahkpm/src/utils" | ||
_ "embed" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"net/url" | ||
"strings" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
//go:embed search-long.md | ||
var searchLong string | ||
|
||
var searchCmd = &cobra.Command{ | ||
Use: "search <searchTerm>...", | ||
Short: "Searches GitHub for packages matching the specified query", | ||
Long: searchLong, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
rawQuery := strings.Join(args, " ") + " topic:ahkpm-package" | ||
fullUrl := "https://api.github.com/search/repositories?q=" + url.QueryEscape(rawQuery) | ||
resp, err := http.Get(fullUrl) | ||
if err != nil { | ||
utils.Exit("Error searching for packages. Unable to reach GitHub.") | ||
} | ||
defer resp.Body.Close() | ||
body, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
utils.Exit("Error reading response body") | ||
} | ||
|
||
var searchResponse SearchResponse | ||
err = json.Unmarshal(body, &searchResponse) | ||
if err != nil { | ||
utils.Exit("Error parsing response body") | ||
} | ||
|
||
fmt.Println(GetSearchResultsTable(searchResponse.Items)) | ||
}, | ||
} | ||
|
||
func init() { | ||
RootCmd.AddCommand(searchCmd) | ||
} | ||
|
||
func GetSearchResultsTable(items []SearchResponseItem) string { | ||
lengthOfLongestName := 0 | ||
lengthOfLongestDescription := 0 | ||
for _, item := range items { | ||
if len(item.FullName) > lengthOfLongestName { | ||
lengthOfLongestName = len(item.FullName) | ||
} | ||
if len(item.Description) > lengthOfLongestDescription { | ||
lengthOfLongestDescription = len(item.Description) | ||
} | ||
} | ||
|
||
ghPrefix := "github.com/" | ||
|
||
maxNameLength := lengthOfLongestName + len(ghPrefix) | ||
nameHeader := utils.RightPad("Name", " ", maxNameLength) | ||
descriptionHeader := utils.RightPad("Description", " ", lengthOfLongestDescription) | ||
nameUnderline := strings.Repeat("-", maxNameLength) | ||
descriptionUnderline := strings.Repeat("-", lengthOfLongestDescription) | ||
|
||
var table strings.Builder | ||
table.WriteString(nameHeader + "\t" + descriptionHeader + "\n") | ||
table.WriteString(nameUnderline + "\t" + descriptionUnderline + "\n") | ||
for _, item := range items { | ||
table.WriteString(fmt.Sprintf( | ||
"%s\t%s\n", | ||
utils.RightPad(ghPrefix+item.FullName, " ", maxNameLength), | ||
utils.RightPad(item.Description, " ", lengthOfLongestDescription), | ||
)) | ||
} | ||
return table.String() | ||
} | ||
|
||
type SearchResponse struct { | ||
TotalCount int `json:"total_count"` | ||
IncompleteResults bool | ||
Items []SearchResponseItem | ||
} | ||
|
||
type SearchResponseItem struct { | ||
Id int | ||
Name string | ||
FullName string `json:"full_name"` | ||
Owner SearchResponseItemOwner | ||
Private bool | ||
HtmlUrl string `json:"html_url"` | ||
Description string | ||
Fork bool | ||
Url string | ||
CreatedAt string `json:"created_at"` | ||
UpdatedAt string `json:"updated_at"` | ||
PushedAt string `json:"pushed_at"` | ||
Homepage string | ||
Size int | ||
StargazersCount int `json:"stargazers_count"` | ||
WatchersCount int `json:"watchers_count"` | ||
Language string | ||
ForksCount int `json:"forks_count"` | ||
OpenIssuesCount int `json:"open_issues_count"` | ||
MasterBranch string `json:"master_branch"` | ||
DefaultBranch string `json:"default_branch"` | ||
Score float64 | ||
} | ||
|
||
type SearchResponseItemOwner struct { | ||
Login string | ||
Id int | ||
NodeId string `json:"node_id"` | ||
AvatarUrl string `json:"avatar_url"` | ||
GravatarId string `json:"gravatar_id"` | ||
Url string | ||
HtmlUrl string `json:"html_url"` | ||
FollowersUrl string `json:"followers_url"` | ||
FollowingUrl string `json:"following_url"` | ||
GistsUrl string `json:"gists_url"` | ||
StarredUrl string `json:"starred_url"` | ||
SubscriptionsUrl string `json:"subscriptions_url"` | ||
OrganizationsURL string `json:"organizations_url"` | ||
ReposUrl string `json:"repos_url"` | ||
EventsUrl string `json:"events_url"` | ||
ReceivedEventsUrl string `json:"received_events_url"` | ||
Type string | ||
SiteAdmin bool `json:"site_admin"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package cmd_test | ||
|
||
import ( | ||
"ahkpm/src/cmd" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestGetSearchResultsTable(t *testing.T) { | ||
items := []cmd.SearchResponseItem{ | ||
{ | ||
FullName: "test/test", | ||
Description: "test", | ||
}, | ||
{ | ||
FullName: "something/or-other", | ||
Description: "frobnicates the quux", | ||
}, | ||
} | ||
|
||
var expectedBuilder strings.Builder | ||
expectedBuilder.WriteString("Name \tDescription \n") | ||
expectedBuilder.WriteString("-----------------------------\t--------------------\n") | ||
expectedBuilder.WriteString("github.com/test/test \ttest \n") | ||
expectedBuilder.WriteString("github.com/something/or-other\tfrobnicates the quux\n") | ||
expected := expectedBuilder.String() | ||
|
||
actual := cmd.GetSearchResultsTable(items) | ||
|
||
assert.Equal(t, expected, actual) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters