Skip to content

Commit

Permalink
Add ahkpm search command to find packages (#161)
Browse files Browse the repository at this point in the history
Fixes #34
  • Loading branch information
joshuacc authored Nov 21, 2022
1 parent 9a790c6 commit 6f55afe
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 11 deletions.
16 changes: 5 additions & 11 deletions src/cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
core "ahkpm/src/core"
"ahkpm/src/utils"
"fmt"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -37,18 +38,11 @@ func GetDependenciesForDisplay(set core.DependencySet) string {
}
}

output += rightPad("Name", " ", lengthOfLongestName) + "\tVersion\n"
output += rightPad("", "-", lengthOfLongestName) + "\t"
output += rightPad("", "-", lengthOfLongestVersion) + "\n"
output += utils.RightPad("Name", " ", lengthOfLongestName) + "\tVersion\n"
output += utils.RightPad("", "-", lengthOfLongestName) + "\t"
output += utils.RightPad("", "-", lengthOfLongestVersion) + "\n"
for _, dep := range set.AsArray() {
output = output + rightPad(dep.Name(), " ", lengthOfLongestName) + "\t" + dep.Version().String() + "\n"
output = output + utils.RightPad(dep.Name(), " ", lengthOfLongestName) + "\t" + dep.Version().String() + "\n"
}
return output
}

func rightPad(s string, char string, length int) string {
for len(s) < length {
s += char
}
return s
}
8 changes: 8 additions & 0 deletions src/cmd/search-long.md
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.
133 changes: 133 additions & 0 deletions src/cmd/search.go
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"`
}
33 changes: 33 additions & 0 deletions src/cmd/search_test.go
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)
}
7 changes: 7 additions & 0 deletions src/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,10 @@ func GetAutoHotkeyVersion() (string, error) {

return string(out), nil
}

func RightPad(s string, char string, length int) string {
for len(s) < length {
s += char
}
return s
}

0 comments on commit 6f55afe

Please sign in to comment.