Skip to content

Commit ac6ec6d

Browse files
authored
Improved package index merging logic (#2713)
* Added tests * Improved index merger for tool release flavors
1 parent 4ffe7d4 commit ac6ec6d

File tree

4 files changed

+176
-8
lines changed

4 files changed

+176
-8
lines changed

Diff for: internal/arduino/cores/packageindex/index.go

+12-8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"encoding/json"
2020
"errors"
2121
"fmt"
22+
"slices"
2223

2324
"github.com/arduino/arduino-cli/internal/arduino/cores"
2425
"github.com/arduino/arduino-cli/internal/arduino/resources"
@@ -348,15 +349,18 @@ func (inToolRelease indexToolRelease) extractToolIn(outPackage *cores.Package) {
348349
outTool := outPackage.GetOrCreateTool(inToolRelease.Name)
349350

350351
outToolRelease := outTool.GetOrCreateRelease(inToolRelease.Version)
351-
outToolRelease.Flavors = inToolRelease.extractFlavours()
352+
outToolRelease.Flavors = inToolRelease.extractAndMergeFlavours(outToolRelease.Flavors)
352353
}
353354

354-
// extractFlavours extracts a map[OS]Flavor object from an indexToolRelease entry.
355-
func (inToolRelease indexToolRelease) extractFlavours() []*cores.Flavor {
356-
ret := make([]*cores.Flavor, len(inToolRelease.Systems))
357-
for i, flavour := range inToolRelease.Systems {
355+
// extractAndMergeFlavours extracts flavors objects from an indexToolRelease
356+
// and adds them to the given flavors array if missing. It returns the updated array.
357+
func (inToolRelease indexToolRelease) extractAndMergeFlavours(in []*cores.Flavor) []*cores.Flavor {
358+
for _, flavour := range inToolRelease.Systems {
359+
if slices.ContainsFunc(in, func(f *cores.Flavor) bool { return f.OS == flavour.OS }) {
360+
continue
361+
}
358362
size, _ := flavour.Size.Int64()
359-
ret[i] = &cores.Flavor{
363+
in = append(in, &cores.Flavor{
360364
OS: flavour.OS,
361365
Resource: &resources.DownloadResource{
362366
ArchiveFileName: flavour.ArchiveFileName,
@@ -365,9 +369,9 @@ func (inToolRelease indexToolRelease) extractFlavours() []*cores.Flavor {
365369
URL: flavour.URL,
366370
CachePath: "packages",
367371
},
368-
}
372+
})
369373
}
370-
return ret
374+
return in
371375
}
372376

373377
// LoadIndex reads a package_index.json from a file and returns the corresponding Index structure.

Diff for: internal/arduino/cores/packagemanager/package_manager_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,52 @@ func TestFindToolsRequiredForBoard(t *testing.T) {
567567
require.Equal(t, bossac18.InstallDir.String(), uploadProperties.Get("runtime.tools.bossac.path"))
568568
}
569569

570+
func TestIndexMerger(t *testing.T) {
571+
t.Setenv("ARDUINO_DATA_DIR", dataDir1.String())
572+
pmb := NewBuilder(
573+
dataDir1,
574+
dataDir1.Join("packages"),
575+
nil,
576+
dataDir1.Join("staging"),
577+
dataDir1,
578+
"test",
579+
downloader.GetDefaultConfig(),
580+
)
581+
582+
loadIndex := func(addr string) {
583+
res, err := url.Parse(addr)
584+
require.NoError(t, err)
585+
require.NoError(t, pmb.LoadPackageIndex(res))
586+
}
587+
loadIndex("https://test.com/package_with_regular_dfu_util_index.json") // this is not downloaded, it just picks the "local cached" file package_test_index.json
588+
loadIndex("https://test.com/package_with_empty_dfu_util_index.json") // this is not downloaded, it just picks the "local cached" file package_test_index.json
589+
590+
// We ignore the errors returned since they might not be necessarily blocking
591+
// but just warnings for the user, like in the case a board is not loaded
592+
// because of malformed menus
593+
pmb.LoadHardware()
594+
pm := pmb.Build()
595+
pme, release := pm.NewExplorer()
596+
defer release()
597+
598+
dfu_util := pme.GetTool("arduino:dfu-util")
599+
require.NotNil(t, dfu_util)
600+
dfu_release := dfu_util.GetOrCreateRelease(semver.ParseRelaxed("0.11.0-arduino5"))
601+
require.NotNil(t, dfu_release)
602+
require.Len(t, dfu_release.Flavors, 6)
603+
604+
test_tool := pme.GetTool("arduino:test-tool")
605+
require.NotNil(t, test_tool)
606+
test_tool_release := test_tool.GetOrCreateRelease(semver.ParseRelaxed("1.0.0"))
607+
require.NotNil(t, test_tool_release)
608+
// Check that the new entry has been added
609+
require.Len(t, test_tool_release.Flavors, 2)
610+
require.Equal(t, test_tool_release.Flavors[1].OS, "arm-linux-gnueabihf")
611+
require.Equal(t, test_tool_release.Flavors[1].Resource.URL, "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_arm.tar.gz")
612+
// Check that the invalid entry did not replace existing one
613+
require.NotEqual(t, test_tool_release.Flavors[0].Resource.URL, "INVALID")
614+
}
615+
570616
func TestIdentifyBoard(t *testing.T) {
571617
pmb := NewBuilder(customHardware, customHardware, nil, customHardware, customHardware, "test", downloader.GetDefaultConfig())
572618
pmb.LoadHardwareFromDirectory(customHardware)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"packages": [
3+
{
4+
"name": "arduino",
5+
"maintainer": "Arduino",
6+
"websiteURL": "http://www.arduino.cc/",
7+
"email": "[email protected]",
8+
"help": {
9+
"online": "http://www.arduino.cc/en/Reference/HomePage"
10+
},
11+
"platforms": [],
12+
"tools": [
13+
{
14+
"name": "test-tool",
15+
"version": "1.0.0",
16+
"systems": [
17+
{
18+
"host": "i386-apple-darwin11",
19+
"url": "INVALID",
20+
"archiveFileName": "INVALID",
21+
"size": "100",
22+
"checksum": "SHA-256:9e576c6e44f54b1e921a43ea77bcc08ec99e0e4e0905f4b9acf9ab2c979f0a22"
23+
},
24+
{
25+
"host": "arm-linux-gnueabihf",
26+
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_arm.tar.gz",
27+
"archiveFileName": "dfu-util-0.11-arduino5-linux_arm.tar.gz",
28+
"size": "2512819",
29+
"checksum": "SHA-256:acd4bd283fd408515279a44dd830499ad37b0767e8f2fde5c27e878ded909dc3"
30+
}
31+
]
32+
},
33+
{
34+
"name": "dfu-util",
35+
"version": "0.11.0-arduino5",
36+
"systems": []
37+
}
38+
]
39+
}
40+
]
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"packages": [
3+
{
4+
"name": "arduino",
5+
"maintainer": "Arduino",
6+
"websiteURL": "http://www.arduino.cc/",
7+
"email": "[email protected]",
8+
"help": {
9+
"online": "http://www.arduino.cc/en/Reference/HomePage"
10+
},
11+
"platforms": [],
12+
"tools": [
13+
{
14+
"name": "test-tool",
15+
"version": "1.0.0",
16+
"systems": [
17+
{
18+
"host": "i386-apple-darwin11",
19+
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-darwin_amd64.tar.gz",
20+
"archiveFileName": "dfu-util-0.11-arduino5-darwin_amd64.tar.gz",
21+
"size": "72429",
22+
"checksum": "SHA-256:9e576c6e44f54b1e921a43ea77bcc08ec99e0e4e0905f4b9acf9ab2c979f0a22"
23+
}
24+
]
25+
},
26+
{
27+
"name": "dfu-util",
28+
"version": "0.11.0-arduino5",
29+
"systems": [
30+
{
31+
"host": "i386-apple-darwin11",
32+
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-darwin_amd64.tar.gz",
33+
"archiveFileName": "dfu-util-0.11-arduino5-darwin_amd64.tar.gz",
34+
"size": "72429",
35+
"checksum": "SHA-256:9e576c6e44f54b1e921a43ea77bcc08ec99e0e4e0905f4b9acf9ab2c979f0a22"
36+
},
37+
{
38+
"host": "arm-linux-gnueabihf",
39+
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_arm.tar.gz",
40+
"archiveFileName": "dfu-util-0.11-arduino5-linux_arm.tar.gz",
41+
"size": "2512819",
42+
"checksum": "SHA-256:acd4bd283fd408515279a44dd830499ad37b0767e8f2fde5c27e878ded909dc3"
43+
},
44+
{
45+
"host": "aarch64-linux-gnu",
46+
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_arm64.tar.gz",
47+
"archiveFileName": "dfu-util-0.11-arduino5-linux_arm64.tar.gz",
48+
"size": "2607592",
49+
"checksum": "SHA-256:b3f46a65da0c2fed2449dc5a3351c3c74953a868aa7f8d99ba2bb8c418344fe9"
50+
},
51+
{
52+
"host": "x86_64-linux-gnu",
53+
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_amd64.tar.gz",
54+
"archiveFileName": "dfu-util-0.11-arduino5-linux_amd64.tar.gz",
55+
"size": "2283425",
56+
"checksum": "SHA-256:96c64c278561af806b585c123c85748926ad02b1aedc07e5578ca9bee2be0d2a"
57+
},
58+
{
59+
"host": "i686-linux-gnu",
60+
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_386.tar.gz",
61+
"archiveFileName": "dfu-util-0.11-arduino5-linux_386.tar.gz",
62+
"size": "2524406",
63+
"checksum": "SHA-256:9a707692261e5710ed79a6d8a4031ffd0bfe1e585216569934346e9b2d68d0c2"
64+
},
65+
{
66+
"host": "i686-mingw32",
67+
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-windows_386.tar.gz",
68+
"archiveFileName": "dfu-util-0.11-arduino5-windows_386.tar.gz",
69+
"size": "571340",
70+
"checksum": "SHA-256:6451e16bf77600fe2436c8708ab4b75077c49997cf8bedf03221d9d6726bb641"
71+
}
72+
]
73+
}
74+
]
75+
}
76+
]
77+
}

0 commit comments

Comments
 (0)