Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BREAKING] Support only compatible platform versions #2285

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions arduino/cores/cores.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ type PlatformRelease struct {
PluggableDiscoveryAware bool `json:"-"` // true if the Platform supports pluggable discovery (no compatibility layer required)
Monitors map[string]*MonitorDependency `json:"-"`
MonitorsDevRecipes map[string]string `json:"-"`
Compatible bool `json:"-"` // true if at all ToolDependencies are available for the current OS/ARCH.
alessio-perugini marked this conversation as resolved.
Show resolved Hide resolved
}

// BoardManifest contains information about a board. These metadata are usually
Expand Down Expand Up @@ -229,6 +230,21 @@ func (platform *Platform) GetLatestRelease() *PlatformRelease {
return platform.FindReleaseWithVersion(latestVersion)
}

// GetLatestCompatibleRelease returns the latest compatible release of this platform, or nil if no
// compatible releases are available.
func (platform *Platform) GetLatestCompatibleRelease() *PlatformRelease {
var maximum *PlatformRelease
for _, release := range platform.Releases {
if !release.IsCompatible() {
continue
}
if maximum == nil || release.Version.GreaterThan(maximum.Version) {
maximum = release
}
}
return maximum
}

// GetAllReleases returns all the releases of this platform, or an empty
// slice if no releases are available
func (platform *Platform) GetAllReleases() []*PlatformRelease {
Expand All @@ -249,6 +265,18 @@ func (platform *Platform) GetAllReleasesVersions() []*semver.Version {
return versions
}

// GetAllCompatibleReleasesVersions returns all the version numbers in this Platform Package that contains compatible tools.
func (platform *Platform) GetAllCompatibleReleasesVersions() []*semver.Version {
versions := []*semver.Version{}
for _, release := range platform.Releases {
if !release.IsCompatible() {
continue
}
versions = append(versions, release.Version)
}
return versions
}

// latestReleaseVersion obtains latest version number, or nil if no release available
func (platform *Platform) latestReleaseVersion() *semver.Version {
// TODO: Cache latest version using a field in Platform
Expand All @@ -266,6 +294,18 @@ func (platform *Platform) latestReleaseVersion() *semver.Version {
return max
}

// latestCompatibleReleaseVersion obtains latest version number, for platforms that contains compatible tools, or nil if no release available
func (platform *Platform) latestCompatibleReleaseVersion() *semver.Version {
versions := platform.GetAllCompatibleReleasesVersions()
var maxVer *semver.Version
for _, v := range versions {
if maxVer == nil || v.GreaterThan(maxVer) {
maxVer = v
}
}
return maxVer
}

// GetAllInstalled returns all installed PlatformRelease
func (platform *Platform) GetAllInstalled() []*PlatformRelease {
res := []*PlatformRelease{}
Expand Down Expand Up @@ -422,3 +462,9 @@ func (release *PlatformRelease) HasMetadata() bool {
installedJSONPath := release.InstallDir.Join("installed.json")
return installedJSONPath.Exist()
}

// IsCompatible returns true if all the tools dependencies of a PlatformRelease
// are available in the current OS/ARCH.
func (release *PlatformRelease) IsCompatible() bool {
return release.Compatible
}
4 changes: 2 additions & 2 deletions arduino/cores/packagemanager/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ func (pme *Explorer) FindPlatformReleaseDependencies(item *PlatformReference) (*
return nil, nil, fmt.Errorf(tr("required version %[1]s not found for platform %[2]s"), item.PlatformVersion, platform.String())
}
} else {
release = platform.GetLatestRelease()
release = platform.GetLatestCompatibleRelease()
if release == nil {
return nil, nil, fmt.Errorf(tr("platform %s has no available releases"), platform.String())
return nil, nil, fmt.Errorf(tr("platform is not available for your OS"))
}
}

Expand Down
2 changes: 1 addition & 1 deletion arduino/cores/packagemanager/install_uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (pme *Explorer) DownloadAndInstallPlatformUpgrades(
if installed == nil {
return nil, &arduino.PlatformNotFoundError{Platform: platformRef.String()}
}
latest := platform.GetLatestRelease()
latest := platform.GetLatestCompatibleRelease()
if !latest.Version.GreaterThan(installed.Version) {
return installed, &arduino.PlatformAlreadyAtTheLatestVersionError{Platform: platformRef.String()}
}
Expand Down
37 changes: 37 additions & 0 deletions arduino/cores/packagemanager/package_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,50 @@ func (pmb *Builder) Build() *PackageManager {
}
}

// calculate Compatible PlatformRelease
func (pmb *Builder) calculateCompatibleReleases() {
for _, op := range pmb.packages {
for _, p := range op.Platforms {
for _, pr := range p.Releases {
platformHasAllCompatibleTools := func() bool {
for _, td := range pr.ToolDependencies {
if td == nil {
return false
}

_, ok := pmb.packages[td.ToolPackager]
if !ok {
return false
}
tool := pmb.packages[td.ToolPackager].Tools[td.ToolName]
if tool == nil {
return false
}
tr := tool.Releases[td.ToolVersion.NormalizedString()]
if tr == nil {
return false
}

if tr.GetCompatibleFlavour() == nil {
return false
}
}
return true
}
pr.Compatible = platformHasAllCompatibleTools()
}
}
}
}

// NewBuilder creates a Builder with the same configuration
// of this PackageManager. A "commit" function callback is returned: calling
// this function will make the builder write the new configuration into this
// PackageManager.
func (pm *PackageManager) NewBuilder() (builder *Builder, commit func()) {
pmb := NewBuilder(pm.IndexDir, pm.PackagesDir, pm.DownloadDir, pm.tempDir, pm.userAgent)
return pmb, func() {
pmb.calculateCompatibleReleases()
pmb.BuildIntoExistingPackageManager(pm)
}
}
Expand Down
1 change: 1 addition & 0 deletions arduino/cores/packagemanager/package_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,7 @@ func TestFindToolsRequiredFromPlatformRelease(t *testing.T) {
func TestFindPlatformReleaseDependencies(t *testing.T) {
pmb := NewBuilder(nil, nil, nil, nil, "test")
pmb.LoadPackageIndexFromFile(paths.New("testdata", "package_tooltest_index.json"))
pmb.calculateCompatibleReleases()
alessio-perugini marked this conversation as resolved.
Show resolved Hide resolved
pm := pmb.Build()
pme, release := pm.NewExplorer()
defer release()
Expand Down
2 changes: 1 addition & 1 deletion commands/board/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func Search(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchR
foundBoards := []*rpc.BoardListItem{}
for _, targetPackage := range pme.GetPackages() {
for _, platform := range targetPackage.Platforms {
latestPlatformRelease := platform.GetLatestRelease()
latestPlatformRelease := platform.GetLatestCompatibleRelease()
installedPlatformRelease := pme.GetInstalledPlatformRelease(platform)

if latestPlatformRelease == nil && installedPlatformRelease == nil {
Expand Down
1 change: 1 addition & 0 deletions commands/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,6 @@ func PlatformReleaseToRPC(platformRelease *cores.PlatformRelease) *rpc.PlatformR
MissingMetadata: missingMetadata,
Type: []string{platformRelease.Category},
Deprecated: platformRelease.Deprecated,
Compatible: platformRelease.IsCompatible(),
}
}
37 changes: 9 additions & 28 deletions commands/core/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse

// Discard platforms with no releases
latestRelease := platform.GetLatestRelease()
if latestRelease == nil {
continue
}
if latestRelease.Name == "" {
if latestRelease == nil || latestRelease.Name == "" {
continue
}

Expand Down Expand Up @@ -86,41 +83,25 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse
out := []*rpc.PlatformSummary{}
for _, platform := range res {
rpcPlatformSummary := &rpc.PlatformSummary{
Metadata: commands.PlatformToRPCPlatformMetadata(platform),
Releases: map[string]*rpc.PlatformRelease{},
}

rpcPlatformSummary.Metadata = commands.PlatformToRPCPlatformMetadata(platform)

installed := pme.GetInstalledPlatformRelease(platform)
latest := platform.GetLatestRelease()
if installed != nil {
if installed := pme.GetInstalledPlatformRelease(platform); installed != nil {
rpcPlatformSummary.InstalledVersion = installed.Version.String()
}
if latest != nil {
rpcPlatformSummary.LatestVersion = latest.Version.String()
if latestCompatible := platform.GetLatestCompatibleRelease(); latestCompatible != nil {
rpcPlatformSummary.LatestVersion = latestCompatible.Version.String()
}
if req.AllVersions {
for _, platformRelease := range platform.GetAllReleases() {
rpcPlatformRelease := commands.PlatformReleaseToRPC(platformRelease)
rpcPlatformSummary.Releases[rpcPlatformRelease.Version] = rpcPlatformRelease
}
} else {
if installed != nil {
rpcPlatformRelease := commands.PlatformReleaseToRPC(installed)
rpcPlatformSummary.Releases[installed.Version.String()] = rpcPlatformRelease
}
if latest != nil {
rpcPlatformRelease := commands.PlatformReleaseToRPC(latest)
rpcPlatformSummary.Releases[latest.Version.String()] = rpcPlatformRelease
}
for _, platformRelease := range platform.GetAllReleases() {
rpcPlatformRelease := commands.PlatformReleaseToRPC(platformRelease)
rpcPlatformSummary.Releases[rpcPlatformRelease.Version] = rpcPlatformRelease
}
out = append(out, rpcPlatformSummary)
}

// Sort result alphabetically and put deprecated platforms at the bottom
sort.Slice(out, func(i, j int) bool {
return strings.ToLower(out[i].GetReleases()[out[i].GetLatestVersion()].Name) <
strings.ToLower(out[j].GetReleases()[out[j].GetLatestVersion()].Name)
return strings.ToLower(out[i].GetMetadata().GetId()) < strings.ToLower(out[j].GetMetadata().GetId())
})
sort.SliceStable(out, func(i, j int) bool {
return !out[i].GetMetadata().Deprecated && out[j].GetMetadata().Deprecated
Expand Down
Loading
Loading