diff --git a/cli/lib/search.go b/cli/lib/search.go index 7a3885f5c31..294c3cf8112 100644 --- a/cli/lib/search.go +++ b/cli/lib/search.go @@ -34,24 +34,23 @@ import ( semver "go.bug.st/relaxed-semver" ) -var ( - namesOnly bool // if true outputs lib names only. -) - func initSearchCommand() *cobra.Command { + var namesOnly bool // if true outputs lib names only. searchCommand := &cobra.Command{ Use: fmt.Sprintf("search [%s]", tr("LIBRARY_NAME")), Short: tr("Searches for one or more libraries data."), Long: tr("Search for one or more libraries data (case insensitive search)."), Example: " " + os.Args[0] + " lib search audio", Args: cobra.ArbitraryArgs, - Run: runSearchCommand, + Run: func(cmd *cobra.Command, args []string) { + runSearchCommand(args, namesOnly) + }, } searchCommand.Flags().BoolVar(&namesOnly, "names", false, tr("Show library names only.")) return searchCommand } -func runSearchCommand(cmd *cobra.Command, args []string) { +func runSearchCommand(args []string, namesOnly bool) { inst, status := instance.Create() logrus.Info("Executing `arduino-cli lib search`") @@ -73,7 +72,7 @@ func runSearchCommand(cmd *cobra.Command, args []string) { searchResp, err := lib.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ Instance: inst, - Query: (strings.Join(args, " ")), + Query: strings.Join(args, " "), }) if err != nil { feedback.Errorf(tr("Error searching for Libraries: %v"), err) @@ -125,11 +124,6 @@ func (res result) String() string { return tr("No libraries matching your search.") } - // get a sorted slice of results - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) - var out strings.Builder if res.results.GetStatus() == rpc.LibrarySearchStatus_LIBRARY_SEARCH_STATUS_FAILED { diff --git a/commands/lib/search.go b/commands/lib/search.go index 2766a2d6bba..7d0ff1c8e32 100644 --- a/commands/lib/search.go +++ b/commands/lib/search.go @@ -17,6 +17,8 @@ package lib import ( "context" + "sort" + "strings" "github.com/arduino/arduino-cli/arduino" "github.com/arduino/arduino-cli/arduino/libraries/librariesindex" @@ -38,7 +40,8 @@ func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.Lib func searchLibrary(req *rpc.LibrarySearchRequest, lm *librariesmanager.LibrariesManager) *rpc.LibrarySearchResponse { res := []*rpc.SearchedLibrary{} - queryTerms := utils.SearchTermsFromQueryString(req.GetQuery()) + query := req.GetQuery() + queryTerms := utils.SearchTermsFromQueryString(query) for _, lib := range lm.Index.Libraries { toTest := lib.Name + " " + @@ -54,6 +57,19 @@ func searchLibrary(req *rpc.LibrarySearchRequest, lm *librariesmanager.Libraries } } + // get a sorted slice of results + sort.Slice(res, func(i, j int) bool { + // Sort by name, but bubble up exact matches + equalsI := strings.EqualFold(res[i].Name, query) + equalsJ := strings.EqualFold(res[j].Name, query) + if equalsI && !equalsJ { + return true + } else if !equalsI && equalsJ { + return false + } + return res[i].Name < res[j].Name + }) + return &rpc.LibrarySearchResponse{Libraries: res, Status: rpc.LibrarySearchStatus_LIBRARY_SEARCH_STATUS_SUCCESS} } diff --git a/commands/lib/search_test.go b/commands/lib/search_test.go index 01dc2f16c82..6785bee808c 100644 --- a/commands/lib/search_test.go +++ b/commands/lib/search_test.go @@ -1,7 +1,6 @@ package lib import ( - "sort" "strings" "testing" @@ -52,7 +51,6 @@ func TestSearchLibraryFields(t *testing.T) { for _, lib := range searchLibrary(&rpc.LibrarySearchRequest{Query: q}, lm).Libraries { libs = append(libs, lib.Name) } - sort.Strings(libs) return libs } @@ -76,4 +74,8 @@ func TestSearchLibraryFields(t *testing.T) { require.Len(t, res, 2) require.Equal(t, "Arduino_ConnectionHandler", res[0]) require.Equal(t, "FlashStorage_SAMD", res[1]) + + res = query("flashstorage") + require.Len(t, res, 19) + require.Equal(t, "FlashStorage", res[0]) }