Unverified Commit 1021e76f authored by Cristian Maglie's avatar Cristian Maglie Committed by GitHub

Made `core search` results more similar to Arduino IDE 1.8.x search dialog (#1904)

* Factored function to get search terms

* Made 'core search' logic identical to Arduino IDE 1.8.x search dialog

* Drastically simplified search algorithm for libs

* Fixed SearchTermsFromQueryString function

* Moving SearchTermsFromQueryString into proper place
parent ce7b0620
...@@ -43,6 +43,16 @@ func removeDiatrics(s string) (string, error) { ...@@ -43,6 +43,16 @@ func removeDiatrics(s string) (string, error) {
return s, nil return s, nil
} }
// SearchTermsFromQueryString returns the terms inside the query string.
// All non alphanumeric characters (expect ':') are considered separators.
// All search terms are converted to lowercase.
func SearchTermsFromQueryString(query string) []string {
// Split on anything but 0-9, a-z or :
return strings.FieldsFunc(strings.ToLower(query), func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r) && r != ':'
})
}
// Match returns true if all substrings are contained in str. // Match returns true if all substrings are contained in str.
// Both str and substrings are transforms to lower case and have their // Both str and substrings are transforms to lower case and have their
// accents and other unicode diatrics removed. // accents and other unicode diatrics removed.
......
...@@ -29,8 +29,6 @@ import ( ...@@ -29,8 +29,6 @@ import (
// PlatformSearch FIXMEDOC // PlatformSearch FIXMEDOC
func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) {
searchArgs := strings.TrimSpace(req.SearchArgs)
allVersions := req.AllVersions
pme, release := commands.GetPackageManagerExplorer(req) pme, release := commands.GetPackageManagerExplorer(req)
if pme == nil { if pme == nil {
return nil, &arduino.InvalidInstanceError{} return nil, &arduino.InvalidInstanceError{}
...@@ -38,14 +36,14 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse ...@@ -38,14 +36,14 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse
defer release() defer release()
res := []*cores.PlatformRelease{} res := []*cores.PlatformRelease{}
if isUsb, _ := regexp.MatchString("[0-9a-f]{4}:[0-9a-f]{4}", searchArgs); isUsb { if isUsb, _ := regexp.MatchString("[0-9a-f]{4}:[0-9a-f]{4}", req.SearchArgs); isUsb {
vid, pid := searchArgs[:4], searchArgs[5:] vid, pid := req.SearchArgs[:4], req.SearchArgs[5:]
res = pme.FindPlatformReleaseProvidingBoardsWithVidPid(vid, pid) res = pme.FindPlatformReleaseProvidingBoardsWithVidPid(vid, pid)
} else { } else {
searchArgs := utils.SearchTermsFromQueryString(req.SearchArgs)
allVersions := req.AllVersions
for _, targetPackage := range pme.GetPackages() { for _, targetPackage := range pme.GetPackages() {
for _, platform := range targetPackage.Platforms { for _, platform := range targetPackage.Platforms {
// discard invalid platforms
// Users can install platforms manually in the Sketchbook hardware folder, // Users can install platforms manually in the Sketchbook hardware folder,
// the core search command must operate only on platforms installed through // the core search command must operate only on platforms installed through
// the PlatformManager, thus we skip the manually installed ones. // the PlatformManager, thus we skip the manually installed ones.
...@@ -53,34 +51,32 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse ...@@ -53,34 +51,32 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse
continue continue
} }
// discard invalid releases // Discard platforms with no releases
platformRelease := platform.GetLatestRelease() latestRelease := platform.GetLatestRelease()
if platformRelease == nil { if latestRelease == nil {
continue continue
} }
// Gather all strings that can be used for searching // Gather all strings that can be used for searching
toTest := []string{ toTest := platform.String() + " " +
platform.String(), platform.Name + " " +
platform.Name, platform.Architecture + " " +
platform.Architecture, targetPackage.Name + " " +
targetPackage.Name, targetPackage.Maintainer + " " +
targetPackage.Maintainer, targetPackage.WebsiteURL
targetPackage.WebsiteURL, for _, board := range latestRelease.BoardsManifest {
} toTest += board.Name + " "
for _, board := range platformRelease.BoardsManifest {
toTest = append(toTest, board.Name)
} }
// Search // Search
if !utils.MatchAny(searchArgs, toTest) { if !utils.Match(toTest, searchArgs) {
continue continue
} }
if allVersions { if allVersions {
res = append(res, platform.GetAllReleases()...) res = append(res, platform.GetAllReleases()...)
} else { } else {
res = append(res, platformRelease) res = append(res, latestRelease)
} }
} }
} }
......
...@@ -17,11 +17,11 @@ package lib ...@@ -17,11 +17,11 @@ package lib
import ( import (
"context" "context"
"strings"
"github.com/arduino/arduino-cli/arduino" "github.com/arduino/arduino-cli/arduino"
"github.com/arduino/arduino-cli/arduino/libraries/librariesindex" "github.com/arduino/arduino-cli/arduino/libraries/librariesindex"
"github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager"
"github.com/arduino/arduino-cli/arduino/utils"
"github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands"
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
semver "go.bug.st/relaxed-semver" semver "go.bug.st/relaxed-semver"
...@@ -38,42 +38,23 @@ func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.Lib ...@@ -38,42 +38,23 @@ func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.Lib
func searchLibrary(req *rpc.LibrarySearchRequest, lm *librariesmanager.LibrariesManager) *rpc.LibrarySearchResponse { func searchLibrary(req *rpc.LibrarySearchRequest, lm *librariesmanager.LibrariesManager) *rpc.LibrarySearchResponse {
res := []*rpc.SearchedLibrary{} res := []*rpc.SearchedLibrary{}
status := rpc.LibrarySearchStatus_LIBRARY_SEARCH_STATUS_SUCCESS queryTerms := utils.SearchTermsFromQueryString(req.GetQuery())
// Split on anything but 0-9, a-z or :
queryTerms := strings.FieldsFunc(strings.ToLower(req.GetQuery()), func(r rune) bool {
return !((r >= '0' && r <= '9') || (r >= 'a' && r <= 'z') || r == ':')
})
for _, lib := range lm.Index.Libraries { for _, lib := range lm.Index.Libraries {
matchTerm := func(x string) bool { toTest := lib.Name + " " +
if strings.Contains(strings.ToLower(lib.Name), x) || lib.Latest.Paragraph + " " +
strings.Contains(strings.ToLower(lib.Latest.Paragraph), x) || lib.Latest.Sentence + " " +
strings.Contains(strings.ToLower(lib.Latest.Sentence), x) || lib.Latest.Author + " "
strings.Contains(strings.ToLower(lib.Latest.Author), x) { for _, include := range lib.Latest.ProvidesIncludes {
return true toTest += include + " "
}
for _, include := range lib.Latest.ProvidesIncludes {
if strings.Contains(strings.ToLower(include), x) {
return true
}
}
return false
}
match := func() bool {
for _, term := range queryTerms {
if !matchTerm(term) {
return false
}
}
return true
} }
if match() {
if utils.Match(toTest, queryTerms) {
res = append(res, indexLibraryToRPCSearchLibrary(lib)) res = append(res, indexLibraryToRPCSearchLibrary(lib))
} }
} }
return &rpc.LibrarySearchResponse{Libraries: res, Status: status} return &rpc.LibrarySearchResponse{Libraries: res, Status: rpc.LibrarySearchStatus_LIBRARY_SEARCH_STATUS_SUCCESS}
} }
// indexLibraryToRPCSearchLibrary converts a librariindex.Library to rpc.SearchLibrary // indexLibraryToRPCSearchLibrary converts a librariindex.Library to rpc.SearchLibrary
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment