Unverified Commit d5eb0b75 authored by Cristian Maglie's avatar Cristian Maglie Committed by GitHub

Improved version matching in `lib` and `core` commands. (#2110)

* Added test

* Use normalized version as keys for matching versions in maps

* Use normalized version as keys for matching versions in maps for platforms and tools

* Updated relaxed-semver to 0.10.0
parent d1eedf58
---
name: go.bug.st/relaxed-semver
version: v0.9.0
version: v0.10.0
type: go
summary:
summary:
homepage: https://pkg.go.dev/go.bug.st/relaxed-semver
license: bsd-3-clause
licenses:
......@@ -42,3 +42,4 @@ licenses:
POSSIBILITY OF SUCH DAMAGE.
notices: []
...
......@@ -40,10 +40,10 @@ type Platform struct {
Architecture string // The name of the architecture of this package.
Name string
Category string
Releases map[string]*PlatformRelease // The Releases of this platform, labeled by version.
Package *Package `json:"-"`
ManuallyInstalled bool // true if the Platform has been installed without the CLI
Deprecated bool // true if the Platform has been deprecated
Releases map[semver.NormalizedString]*PlatformRelease // The Releases of this platform, labeled by version.
Package *Package `json:"-"`
ManuallyInstalled bool // true if the Platform has been installed without the CLI
Deprecated bool // true if the Platform has been deprecated
}
// PlatformReleaseHelp represents the help URL for this Platform release
......@@ -191,9 +191,9 @@ func (d *MonitorDependency) String() string {
// GetOrCreateRelease returns the specified release corresponding the provided version,
// or creates a new one if not found.
func (platform *Platform) GetOrCreateRelease(version *semver.Version) *PlatformRelease {
tag := ""
var tag semver.NormalizedString
if version != nil {
tag = version.String()
tag = version.NormalizedString()
}
if release, ok := platform.Releases[tag]; ok {
return release
......@@ -213,7 +213,7 @@ func (platform *Platform) GetOrCreateRelease(version *semver.Version) *PlatformR
// or nil if not found.
func (platform *Platform) FindReleaseWithVersion(version *semver.Version) *PlatformRelease {
// use as an fmt.Stringer
return platform.Releases[version.String()]
return platform.Releases[version.NormalizedString()]
}
// GetLatestRelease returns the latest release of this platform, or nil if no releases
......
......@@ -73,7 +73,7 @@ func TestRequiresToolReleaseDiscovery(t *testing.T) {
Version: semver.ParseRelaxed("0.1.0"),
Tool: &Tool{
Name: toolDependencyName + "not",
Releases: map[string]*ToolRelease{
Releases: map[semver.NormalizedString]*ToolRelease{
"1.0.0": {Version: semver.ParseRelaxed("1.0.0")},
"0.1.0": {Version: semver.ParseRelaxed("0.1.0")},
"0.0.1": {Version: semver.ParseRelaxed("0.0.1")},
......
......@@ -106,7 +106,7 @@ func TestIndexFromPlatformRelease(t *testing.T) {
Tools: map[string]*cores.Tool{
"serial-discovery": {
Name: "serial-discovery",
Releases: map[string]*cores.ToolRelease{
Releases: map[semver.NormalizedString]*cores.ToolRelease{
"1.0.0": {
Version: semver.ParseRelaxed("1.0.0"),
Flavors: []*cores.Flavor{
......@@ -157,7 +157,7 @@ func TestIndexFromPlatformRelease(t *testing.T) {
},
"ble-discovery": {
Name: "ble-discovery",
Releases: map[string]*cores.ToolRelease{
Releases: map[semver.NormalizedString]*cores.ToolRelease{
"1.0.0": {
Version: semver.ParseRelaxed("1.0.0"),
Flavors: []*cores.Flavor{
......@@ -209,7 +209,7 @@ func TestIndexFromPlatformRelease(t *testing.T) {
},
"bossac": {
Name: "bossac",
Releases: map[string]*cores.ToolRelease{
Releases: map[semver.NormalizedString]*cores.ToolRelease{
"1.6.1-arduino": {
Version: semver.ParseRelaxed("1.6.1-arduino"),
Flavors: []*cores.Flavor{
......@@ -260,7 +260,7 @@ func TestIndexFromPlatformRelease(t *testing.T) {
},
"arm-none-eabi-gcc": {
Name: "arm-none-eabi-gcc",
Releases: map[string]*cores.ToolRelease{
Releases: map[semver.NormalizedString]*cores.ToolRelease{
"4.8.3-2014q1": {
Version: semver.ParseRelaxed("4.8.3-2014q1"),
Flavors: []*cores.Flavor{
......
......@@ -61,7 +61,7 @@ func (pme *Explorer) FindPlatformRelease(ref *PlatformReference) *cores.Platform
if platform == nil {
return nil
}
platformRelease, ok := platform.Releases[ref.PlatformVersion.String()]
platformRelease, ok := platform.Releases[ref.PlatformVersion.NormalizedString()]
if !ok {
return nil
}
......
......@@ -20,6 +20,7 @@ import (
"fmt"
"github.com/pmylund/sortutil"
semver "go.bug.st/relaxed-semver"
)
// Packages represents a set of Packages
......@@ -91,7 +92,7 @@ func (packages Packages) GetPlatformReleaseToolDependencies(release *PlatformRel
if !exists {
return nil, fmt.Errorf(tr("tool %s not found"), dep.ToolName)
}
toolRelease, exists := tool.Releases[dep.ToolVersion.String()]
toolRelease, exists := tool.Releases[dep.ToolVersion.NormalizedString()]
if !exists {
return nil, fmt.Errorf(tr("tool version %s not found"), dep.ToolVersion)
}
......@@ -162,7 +163,7 @@ func (targetPackage *Package) GetOrCreatePlatform(architecture string) *Platform
}
targetPlatform := &Platform{
Architecture: architecture,
Releases: map[string]*PlatformRelease{},
Releases: map[semver.NormalizedString]*PlatformRelease{},
Package: targetPackage,
}
targetPackage.Platforms[architecture] = targetPlatform
......@@ -178,7 +179,7 @@ func (targetPackage *Package) GetOrCreateTool(name string) *Tool {
tool := &Tool{
Name: name,
Package: targetPackage,
Releases: map[string]*ToolRelease{},
Releases: map[semver.NormalizedString]*ToolRelease{},
}
targetPackage.Tools[name] = tool
return tool
......
......@@ -27,9 +27,9 @@ import (
// Tool represents a single Tool, part of a Package.
type Tool struct {
Name string `json:"name"` // The Name of the Tool.
Releases map[string]*ToolRelease `json:"releases"` // Maps Version to Release.
Package *Package `json:"-"`
Name string `json:"name"` // The Name of the Tool.
Releases map[semver.NormalizedString]*ToolRelease `json:"releases"` // Maps Version to Release.
Package *Package `json:"-"`
}
// ToolRelease represents a single release of a tool
......@@ -49,21 +49,21 @@ type Flavor struct {
// GetOrCreateRelease returns the ToolRelease object with the specified version
// or creates a new one if not found
func (tool *Tool) GetOrCreateRelease(version *semver.RelaxedVersion) *ToolRelease {
if release, ok := tool.Releases[version.String()]; ok {
if release, ok := tool.Releases[version.NormalizedString()]; ok {
return release
}
release := &ToolRelease{
Version: version,
Tool: tool,
}
tool.Releases[version.String()] = release
tool.Releases[version.NormalizedString()] = release
return release
}
// FindReleaseWithRelaxedVersion returns the specified release corresponding the provided version,
// or nil if not found.
func (tool *Tool) FindReleaseWithRelaxedVersion(version *semver.RelaxedVersion) *ToolRelease {
return tool.Releases[version.String()]
return tool.Releases[version.NormalizedString()]
}
// GetAllReleasesVersions returns all the version numbers in this Core Package.
......
......@@ -35,7 +35,7 @@ var EmptyIndex = &Index{Libraries: map[string]*Library{}}
// Library is a library available for download
type Library struct {
Name string
Releases map[string]*Release
Releases map[semver.NormalizedString]*Release
Latest *Release `json:"-"`
Index *Index `json:"-"`
}
......@@ -117,7 +117,7 @@ func (idx *Index) FindRelease(ref *Reference) *Release {
if ref.Version == nil {
return library.Latest
}
return library.Releases[ref.Version.String()]
return library.Releases[ref.Version.NormalizedString()]
}
return nil
}
......@@ -173,13 +173,10 @@ func (idx *Index) ResolveDependencies(lib *Release) []*Release {
// Versions returns an array of all versions available of the library
func (library *Library) Versions() []*semver.Version {
res := []*semver.Version{}
for version := range library.Releases {
v, err := semver.Parse(version)
if err == nil {
res = append(res, v)
}
res := semver.List{}
for _, release := range library.Releases {
res = append(res, release.Version)
}
sort.Sort(semver.List(res))
sort.Sort(res)
return res
}
......@@ -90,7 +90,7 @@ func (indexLib *indexRelease) extractLibraryIn(index *Index) {
if !exist {
library = &Library{
Name: indexLib.Name,
Releases: map[string]*Release{},
Releases: map[semver.NormalizedString]*Release{},
}
index.Libraries[indexLib.Name] = library
}
......@@ -120,7 +120,7 @@ func (indexLib *indexRelease) extractReleaseIn(library *Library) {
License: indexLib.License,
ProvidesIncludes: indexLib.ProvidesIncludes,
}
library.Releases[indexLib.Version.String()] = release
library.Releases[indexLib.Version.NormalizedString()] = release
if library.Latest == nil || library.Latest.Version.LessThan(release.Version) {
library.Latest = release
}
......
......@@ -78,8 +78,8 @@ func indexLibraryToRPCSearchLibrary(lib *librariesindex.Library, omitReleasesDet
var releases map[string]*rpc.LibraryRelease
if !omitReleasesDetails {
releases = map[string]*rpc.LibraryRelease{}
for str, rel := range lib.Releases {
releases[str] = getLibraryParameters(rel)
for _, rel := range lib.Releases {
releases[rel.Version.String()] = getLibraryParameters(rel)
}
}
......
......@@ -541,6 +541,18 @@ func TestInstall(t *testing.T) {
_, stderr, err := cli.Run("lib", "install", "MD_Parola@3.2.0")
require.Error(t, err)
require.Contains(t, string(stderr), "No valid dependencies solution found: dependency 'MD_MAX72xx' is not available")
// Test installing a library with a "relaxed" version
// https://github.com/arduino/arduino-cli/issues/1727
_, _, err = cli.Run("lib", "install", "ILI9341_t3@1.0")
require.NoError(t, err)
stdout, _, err := cli.Run("lib", "list", "--format", "json")
require.NoError(t, err)
requirejson.Parse(t, stdout).Query(`.[] | select(.library.name == "ILI9341_t3") | .library.version`).MustEqual(`"1.0"`)
_, _, err = cli.Run("lib", "install", "ILI9341_t3@1")
require.NoError(t, err)
_, _, err = cli.Run("lib", "install", "ILI9341_t3@1.0.0")
require.NoError(t, err)
}
func TestInstallLibraryWithDependencies(t *testing.T) {
......
......@@ -23,6 +23,7 @@ import (
"github.com/arduino/arduino-cli/legacy/builder/types"
properties "github.com/arduino/go-properties-orderedmap"
"github.com/stretchr/testify/require"
semver "go.bug.st/relaxed-semver"
)
func TestRewriteHardwareKeys(t *testing.T) {
......@@ -41,7 +42,7 @@ func TestRewriteHardwareKeys(t *testing.T) {
}
aPackage.Platforms["dummy"] = &cores.Platform{
Architecture: "dummy",
Releases: map[string]*cores.PlatformRelease{
Releases: map[semver.NormalizedString]*cores.PlatformRelease{
"": platform,
},
}
......@@ -82,7 +83,7 @@ func TestRewriteHardwareKeysWithRewritingDisabled(t *testing.T) {
}
aPackage.Platforms["dummy"] = &cores.Platform{
Architecture: "dummy",
Releases: map[string]*cores.PlatformRelease{
Releases: map[semver.NormalizedString]*cores.PlatformRelease{
"": platform,
},
}
......
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