commands: use the new endpoint to detect boards (#2974) · arduino/arduino-cli@461b668 (original) (raw)
`@@ -23,6 +23,7 @@ import (
`
23
23
`"io"
`
24
24
`"net/http"
`
25
25
`"regexp"
`
``
26
`+
"slices"
`
26
27
`"sort"
`
27
28
`"strings"
`
28
29
`"time"
`
`@@ -130,14 +131,14 @@ func identifyViaCloudAPI(ctx context.Context, props *properties.Map, settings *c
`
130
131
`}
`
131
132
``
132
133
`var (
`
133
``
`-
vidPidURL = "https://builder.arduino.cc/v3/boards/byVidPid"
`
``
134
`+
vidPidURL = "https://api2.arduino.cc/boards/v1/boards"
`
134
135
`` validVidPid = regexp.MustCompile(0[xX][a-fA-F\d]{4})
``
135
136
`)
`
136
137
``
137
138
`func cachedAPIByVidPid(ctx context.Context, vid, pid string, settings *configuration.Settings) ([]*rpc.BoardListItem, error) {
`
138
139
`var resp []*rpc.BoardListItem
`
139
140
``
140
``
`-
cacheKey := fmt.Sprintf("cache.builder-api.v3/boards/byvid/pid/%s/%s", vid, pid)
`
``
141
`+
cacheKey := fmt.Sprintf("cache.api2.arduino.cc/boards/v1/boards?vid-pid=%s-%s", vid, pid)
`
141
142
`if cachedResp := inventory.Store.GetString(cacheKey + ".data"); cachedResp != "" {
`
142
143
`ts := inventory.Store.GetTime(cacheKey + ".ts")
`
143
144
`if time.Since(ts) < time.Hour*24 {
`
`@@ -169,7 +170,7 @@ func apiByVidPid(ctx context.Context, vid, pid string, settings *configuration.S
`
169
170
`return nil, errors.New(i18n.Tr("Invalid pid value: '%s'", pid))
`
170
171
` }
`
171
172
``
172
``
`-
url := fmt.Sprintf("%s/%s/%s", vidPidURL, vid, pid)
`
``
173
`+
url := fmt.Sprintf("%s?vid-pid=%s-%s", vidPidURL, vid, pid)
`
173
174
`req, _ := http.NewRequest("GET", url, nil)
`
174
175
`req.Header.Set("Content-Type", "application/json")
`
175
176
``
`@@ -198,20 +199,32 @@ func apiByVidPid(ctx context.Context, vid, pid string, settings *configuration.S
`
198
199
`return nil, err
`
199
200
` }
`
200
201
``
201
``
`-
var dat map[string]interface{}
`
``
202
`+
type boardsResponse struct {
`
``
203
`+
Items []struct {
`
``
204
`` +
Name string json:"name"
``
``
205
`` +
FQBN string json:"fqbn"
``
``
206
`` +
} json:"items"
``
``
207
`+
}
`
``
208
`+
var dat boardsResponse
`
202
209
`if err := json.Unmarshal(resp, &dat); err != nil {
`
203
210
`return nil, fmt.Errorf("%s: %w", i18n.Tr("error processing response from server"), err)
`
204
211
` }
`
205
``
`-
name, nameFound := dat["name"].(string)
`
206
``
`-
fqbn, fbqnFound := dat["fqbn"].(string)
`
207
``
`-
if !nameFound || !fbqnFound {
`
208
``
`-
return nil, errors.New(i18n.Tr("wrong format in server response"))
`
``
212
+
``
213
`+
response := make([]*rpc.BoardListItem, len(dat.Items))
`
``
214
`+
for i, v := range dat.Items {
`
``
215
`+
if v.Name == "" || v.FQBN == "" {
`
``
216
`+
return nil, errors.New(i18n.Tr("wrong format in server response"))
`
``
217
`+
}
`
``
218
`+
response[i] = &rpc.BoardListItem{Name: v.Name, Fqbn: v.FQBN}
`
209
219
` }
`
210
220
``
211
``
`-
return []*rpc.BoardListItem{
`
212
``
`-
{
`
213
``
`-
Name: name,
`
214
``
`-
Fqbn: fqbn,
`
215
``
`-
},
`
216
``
`-
}, nil
`
``
221
`+
// In case multiple platform matches the same vid-pid we put on top
`
``
222
`+
// the arduino ones
`
``
223
`+
slices.SortFunc(response, func(a, b *rpc.BoardListItem) int {
`
``
224
`+
if strings.HasPrefix(a.Fqbn, "arduino") {
`
``
225
`+
return -1
`
``
226
`+
}
`
``
227
`+
return 0
`
``
228
`+
})
`
``
229
`+
return response, nil
`
217
230
`}
`