Skip to content

Commit

Permalink
Improved package index merging logic (arduino#2713)
Browse files Browse the repository at this point in the history
* Added tests

* Improved index merger for tool release flavors
  • Loading branch information
cmaglie authored Oct 7, 2024
1 parent 4ffe7d4 commit ac6ec6d
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 8 deletions.
20 changes: 12 additions & 8 deletions internal/arduino/cores/packageindex/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/json"
"errors"
"fmt"
"slices"

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

outToolRelease := outTool.GetOrCreateRelease(inToolRelease.Version)
outToolRelease.Flavors = inToolRelease.extractFlavours()
outToolRelease.Flavors = inToolRelease.extractAndMergeFlavours(outToolRelease.Flavors)
}

// extractFlavours extracts a map[OS]Flavor object from an indexToolRelease entry.
func (inToolRelease indexToolRelease) extractFlavours() []*cores.Flavor {
ret := make([]*cores.Flavor, len(inToolRelease.Systems))
for i, flavour := range inToolRelease.Systems {
// extractAndMergeFlavours extracts flavors objects from an indexToolRelease
// and adds them to the given flavors array if missing. It returns the updated array.
func (inToolRelease indexToolRelease) extractAndMergeFlavours(in []*cores.Flavor) []*cores.Flavor {
for _, flavour := range inToolRelease.Systems {
if slices.ContainsFunc(in, func(f *cores.Flavor) bool { return f.OS == flavour.OS }) {
continue
}
size, _ := flavour.Size.Int64()
ret[i] = &cores.Flavor{
in = append(in, &cores.Flavor{
OS: flavour.OS,
Resource: &resources.DownloadResource{
ArchiveFileName: flavour.ArchiveFileName,
Expand All @@ -365,9 +369,9 @@ func (inToolRelease indexToolRelease) extractFlavours() []*cores.Flavor {
URL: flavour.URL,
CachePath: "packages",
},
}
})
}
return ret
return in
}

// LoadIndex reads a package_index.json from a file and returns the corresponding Index structure.
Expand Down
46 changes: 46 additions & 0 deletions internal/arduino/cores/packagemanager/package_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,52 @@ func TestFindToolsRequiredForBoard(t *testing.T) {
require.Equal(t, bossac18.InstallDir.String(), uploadProperties.Get("runtime.tools.bossac.path"))
}

func TestIndexMerger(t *testing.T) {
t.Setenv("ARDUINO_DATA_DIR", dataDir1.String())
pmb := NewBuilder(
dataDir1,
dataDir1.Join("packages"),
nil,
dataDir1.Join("staging"),
dataDir1,
"test",
downloader.GetDefaultConfig(),
)

loadIndex := func(addr string) {
res, err := url.Parse(addr)
require.NoError(t, err)
require.NoError(t, pmb.LoadPackageIndex(res))
}
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
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

// We ignore the errors returned since they might not be necessarily blocking
// but just warnings for the user, like in the case a board is not loaded
// because of malformed menus
pmb.LoadHardware()
pm := pmb.Build()
pme, release := pm.NewExplorer()
defer release()

dfu_util := pme.GetTool("arduino:dfu-util")
require.NotNil(t, dfu_util)
dfu_release := dfu_util.GetOrCreateRelease(semver.ParseRelaxed("0.11.0-arduino5"))
require.NotNil(t, dfu_release)
require.Len(t, dfu_release.Flavors, 6)

test_tool := pme.GetTool("arduino:test-tool")
require.NotNil(t, test_tool)
test_tool_release := test_tool.GetOrCreateRelease(semver.ParseRelaxed("1.0.0"))
require.NotNil(t, test_tool_release)
// Check that the new entry has been added
require.Len(t, test_tool_release.Flavors, 2)
require.Equal(t, test_tool_release.Flavors[1].OS, "arm-linux-gnueabihf")
require.Equal(t, test_tool_release.Flavors[1].Resource.URL, "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_arm.tar.gz")
// Check that the invalid entry did not replace existing one
require.NotEqual(t, test_tool_release.Flavors[0].Resource.URL, "INVALID")
}

func TestIdentifyBoard(t *testing.T) {
pmb := NewBuilder(customHardware, customHardware, nil, customHardware, customHardware, "test", downloader.GetDefaultConfig())
pmb.LoadHardwareFromDirectory(customHardware)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"packages": [
{
"name": "arduino",
"maintainer": "Arduino",
"websiteURL": "http://www.arduino.cc/",
"email": "[email protected]",
"help": {
"online": "http://www.arduino.cc/en/Reference/HomePage"
},
"platforms": [],
"tools": [
{
"name": "test-tool",
"version": "1.0.0",
"systems": [
{
"host": "i386-apple-darwin11",
"url": "INVALID",
"archiveFileName": "INVALID",
"size": "100",
"checksum": "SHA-256:9e576c6e44f54b1e921a43ea77bcc08ec99e0e4e0905f4b9acf9ab2c979f0a22"
},
{
"host": "arm-linux-gnueabihf",
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_arm.tar.gz",
"archiveFileName": "dfu-util-0.11-arduino5-linux_arm.tar.gz",
"size": "2512819",
"checksum": "SHA-256:acd4bd283fd408515279a44dd830499ad37b0767e8f2fde5c27e878ded909dc3"
}
]
},
{
"name": "dfu-util",
"version": "0.11.0-arduino5",
"systems": []
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"packages": [
{
"name": "arduino",
"maintainer": "Arduino",
"websiteURL": "http://www.arduino.cc/",
"email": "[email protected]",
"help": {
"online": "http://www.arduino.cc/en/Reference/HomePage"
},
"platforms": [],
"tools": [
{
"name": "test-tool",
"version": "1.0.0",
"systems": [
{
"host": "i386-apple-darwin11",
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-darwin_amd64.tar.gz",
"archiveFileName": "dfu-util-0.11-arduino5-darwin_amd64.tar.gz",
"size": "72429",
"checksum": "SHA-256:9e576c6e44f54b1e921a43ea77bcc08ec99e0e4e0905f4b9acf9ab2c979f0a22"
}
]
},
{
"name": "dfu-util",
"version": "0.11.0-arduino5",
"systems": [
{
"host": "i386-apple-darwin11",
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-darwin_amd64.tar.gz",
"archiveFileName": "dfu-util-0.11-arduino5-darwin_amd64.tar.gz",
"size": "72429",
"checksum": "SHA-256:9e576c6e44f54b1e921a43ea77bcc08ec99e0e4e0905f4b9acf9ab2c979f0a22"
},
{
"host": "arm-linux-gnueabihf",
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_arm.tar.gz",
"archiveFileName": "dfu-util-0.11-arduino5-linux_arm.tar.gz",
"size": "2512819",
"checksum": "SHA-256:acd4bd283fd408515279a44dd830499ad37b0767e8f2fde5c27e878ded909dc3"
},
{
"host": "aarch64-linux-gnu",
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_arm64.tar.gz",
"archiveFileName": "dfu-util-0.11-arduino5-linux_arm64.tar.gz",
"size": "2607592",
"checksum": "SHA-256:b3f46a65da0c2fed2449dc5a3351c3c74953a868aa7f8d99ba2bb8c418344fe9"
},
{
"host": "x86_64-linux-gnu",
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_amd64.tar.gz",
"archiveFileName": "dfu-util-0.11-arduino5-linux_amd64.tar.gz",
"size": "2283425",
"checksum": "SHA-256:96c64c278561af806b585c123c85748926ad02b1aedc07e5578ca9bee2be0d2a"
},
{
"host": "i686-linux-gnu",
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-linux_386.tar.gz",
"archiveFileName": "dfu-util-0.11-arduino5-linux_386.tar.gz",
"size": "2524406",
"checksum": "SHA-256:9a707692261e5710ed79a6d8a4031ffd0bfe1e585216569934346e9b2d68d0c2"
},
{
"host": "i686-mingw32",
"url": "http://downloads.arduino.cc/tools/dfu-util-0.11-arduino5-windows_386.tar.gz",
"archiveFileName": "dfu-util-0.11-arduino5-windows_386.tar.gz",
"size": "571340",
"checksum": "SHA-256:6451e16bf77600fe2436c8708ab4b75077c49997cf8bedf03221d9d6726bb641"
}
]
}
]
}
]
}

0 comments on commit ac6ec6d

Please sign in to comment.