@@ -23,7 +23,6 @@ import (
23
23
"github.com/arduino/arduino-cli/arduino"
24
24
"github.com/arduino/arduino-cli/arduino/libraries/librariesindex"
25
25
"github.com/arduino/arduino-cli/arduino/libraries/librariesmanager"
26
- "github.com/arduino/arduino-cli/arduino/utils"
27
26
"github.com/arduino/arduino-cli/commands/internal/instances"
28
27
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
29
28
semver "go.bug.st/relaxed-semver"
@@ -38,128 +37,14 @@ func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.Lib
38
37
return searchLibrary (req , lm ), nil
39
38
}
40
39
41
- // matcherTokensFromQueryString parses the query string into tokens of interest
42
- // for the qualifier-value pattern matching.
43
- func matcherTokensFromQueryString (query string ) []string {
44
- escaped := false
45
- quoted := false
46
- tokens := []string {}
47
- sb := & strings.Builder {}
48
-
49
- for _ , r := range query {
50
- // Short circuit the loop on backslash so that all other paths can clear
51
- // the escaped flag.
52
- if ! escaped && r == '\\' {
53
- escaped = true
54
- continue
55
- }
56
-
57
- if r == '"' {
58
- if ! escaped {
59
- quoted = ! quoted
60
- } else {
61
- sb .WriteRune (r )
62
- }
63
- } else if ! quoted && r == ' ' {
64
- tokens = append (tokens , strings .ToLower (sb .String ()))
65
- sb .Reset ()
66
- } else {
67
- sb .WriteRune (r )
68
- }
69
- escaped = false
70
- }
71
- if sb .Len () > 0 {
72
- tokens = append (tokens , strings .ToLower (sb .String ()))
73
- }
74
-
75
- return tokens
76
- }
77
-
78
- // defaulLibraryMatchExtractor returns a string describing the library that
79
- // is used for the simple search.
80
- func defaultLibraryMatchExtractor (lib * librariesindex.Library ) string {
81
- res := lib .Name + " " +
82
- lib .Latest .Paragraph + " " +
83
- lib .Latest .Sentence + " " +
84
- lib .Latest .Author + " "
85
- for _ , include := range lib .Latest .ProvidesIncludes {
86
- res += include + " "
87
- }
88
- return res
89
- }
90
-
91
- var qualifiers map [string ]func (lib * librariesindex.Library ) string = map [string ]func (lib * librariesindex.Library ) string {
92
- "name" : func (lib * librariesindex.Library ) string { return lib .Name },
93
- "architectures" : func (lib * librariesindex.Library ) string { return strings .Join (lib .Latest .Architectures , " " ) },
94
- "author" : func (lib * librariesindex.Library ) string { return lib .Latest .Author },
95
- "category" : func (lib * librariesindex.Library ) string { return lib .Latest .Category },
96
- "dependencies" : func (lib * librariesindex.Library ) string {
97
- names := make ([]string , len (lib .Latest .Dependencies ))
98
- for i , dep := range lib .Latest .Dependencies {
99
- names [i ] = dep .GetName ()
100
- }
101
- return strings .Join (names , " " )
102
- },
103
- "maintainer" : func (lib * librariesindex.Library ) string { return lib .Latest .Maintainer },
104
- "paragraph" : func (lib * librariesindex.Library ) string { return lib .Latest .Paragraph },
105
- "sentence" : func (lib * librariesindex.Library ) string { return lib .Latest .Sentence },
106
- "types" : func (lib * librariesindex.Library ) string { return strings .Join (lib .Latest .Types , " " ) },
107
- "version" : func (lib * librariesindex.Library ) string { return lib .Latest .Version .String () },
108
- "website" : func (lib * librariesindex.Library ) string { return lib .Latest .Website },
109
- }
110
-
111
- // matcherFromQueryString returns a closure that takes a library as a
112
- // parameter and returns true if the library matches the query.
113
- func matcherFromQueryString (query string ) func (* librariesindex.Library ) bool {
114
- // A qv-query is one using <qualifier>[:=]<value> syntax.
115
- qvQuery := strings .Contains (query , ":" ) || strings .Contains (query , "=" )
116
-
117
- if ! qvQuery {
118
- queryTerms := utils .SearchTermsFromQueryString (query )
119
- return func (lib * librariesindex.Library ) bool {
120
- return utils .Match (defaultLibraryMatchExtractor (lib ), queryTerms )
121
- }
122
- }
123
-
124
- queryTerms := matcherTokensFromQueryString (query )
125
-
126
- return func (lib * librariesindex.Library ) bool {
127
- matched := true
128
- for _ , term := range queryTerms {
129
-
130
- if sepIdx := strings .IndexAny (term , "=:" ); sepIdx != - 1 {
131
- potentialKey := term [:sepIdx ]
132
- separator := term [sepIdx ]
133
-
134
- extractor , ok := qualifiers [potentialKey ]
135
- if ok {
136
- target := term [sepIdx + 1 :]
137
- if separator == ':' {
138
- matched = (matched && utils .Match (extractor (lib ), []string {target }))
139
- } else { // "="
140
- matched = (matched && strings .ToLower (extractor (lib )) == target )
141
- }
142
- } else {
143
- // Unknown qualifier names revert to basic search terms.
144
- matched = (matched && utils .Match (defaultLibraryMatchExtractor (lib ), []string {term }))
145
- }
146
- } else {
147
- // Terms that do not use qv-syntax are handled as usual.
148
- matched = (matched && utils .Match (defaultLibraryMatchExtractor (lib ), []string {term }))
149
- }
150
- }
151
- return matched
152
- }
153
- }
154
-
155
40
func searchLibrary (req * rpc.LibrarySearchRequest , lm * librariesmanager.LibrariesManager ) * rpc.LibrarySearchResponse {
156
41
res := []* rpc.SearchedLibrary {}
157
42
query := req .GetSearchArgs ()
158
43
if query == "" {
159
44
query = req .GetQuery ()
160
45
}
161
46
162
- matcher := matcherFromQueryString (query )
47
+ matcher := MatcherFromQueryString (query )
163
48
164
49
for _ , lib := range lm .Index .Libraries {
165
50
if matcher (lib ) {
0 commit comments