Skip to content

Commit b0e28d9

Browse files
[BREAKING] Support only compatible platform versions (#2285)
1 parent f09ad56 commit b0e28d9

File tree

26 files changed

+713
-328
lines changed

26 files changed

+713
-328
lines changed

Diff for: arduino/cores/cores.go

+46
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ type PlatformRelease struct {
7575
PluggableDiscoveryAware bool `json:"-"` // true if the Platform supports pluggable discovery (no compatibility layer required)
7676
Monitors map[string]*MonitorDependency `json:"-"`
7777
MonitorsDevRecipes map[string]string `json:"-"`
78+
Compatible bool `json:"-"` // true if at all ToolDependencies are available for the current OS/ARCH.
7879
}
7980

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

233+
// GetLatestCompatibleRelease returns the latest compatible release of this platform, or nil if no
234+
// compatible releases are available.
235+
func (platform *Platform) GetLatestCompatibleRelease() *PlatformRelease {
236+
var maximum *PlatformRelease
237+
for _, release := range platform.Releases {
238+
if !release.IsCompatible() {
239+
continue
240+
}
241+
if maximum == nil || release.Version.GreaterThan(maximum.Version) {
242+
maximum = release
243+
}
244+
}
245+
return maximum
246+
}
247+
232248
// GetAllReleases returns all the releases of this platform, or an empty
233249
// slice if no releases are available
234250
func (platform *Platform) GetAllReleases() []*PlatformRelease {
@@ -249,6 +265,18 @@ func (platform *Platform) GetAllReleasesVersions() []*semver.Version {
249265
return versions
250266
}
251267

268+
// GetAllCompatibleReleasesVersions returns all the version numbers in this Platform Package that contains compatible tools.
269+
func (platform *Platform) GetAllCompatibleReleasesVersions() []*semver.Version {
270+
versions := []*semver.Version{}
271+
for _, release := range platform.Releases {
272+
if !release.IsCompatible() {
273+
continue
274+
}
275+
versions = append(versions, release.Version)
276+
}
277+
return versions
278+
}
279+
252280
// latestReleaseVersion obtains latest version number, or nil if no release available
253281
func (platform *Platform) latestReleaseVersion() *semver.Version {
254282
// TODO: Cache latest version using a field in Platform
@@ -266,6 +294,18 @@ func (platform *Platform) latestReleaseVersion() *semver.Version {
266294
return max
267295
}
268296

297+
// latestCompatibleReleaseVersion obtains latest version number, for platforms that contains compatible tools, or nil if no release available
298+
func (platform *Platform) latestCompatibleReleaseVersion() *semver.Version {
299+
versions := platform.GetAllCompatibleReleasesVersions()
300+
var maxVer *semver.Version
301+
for _, v := range versions {
302+
if maxVer == nil || v.GreaterThan(maxVer) {
303+
maxVer = v
304+
}
305+
}
306+
return maxVer
307+
}
308+
269309
// GetAllInstalled returns all installed PlatformRelease
270310
func (platform *Platform) GetAllInstalled() []*PlatformRelease {
271311
res := []*PlatformRelease{}
@@ -422,3 +462,9 @@ func (release *PlatformRelease) HasMetadata() bool {
422462
installedJSONPath := release.InstallDir.Join("installed.json")
423463
return installedJSONPath.Exist()
424464
}
465+
466+
// IsCompatible returns true if all the tools dependencies of a PlatformRelease
467+
// are available in the current OS/ARCH.
468+
func (release *PlatformRelease) IsCompatible() bool {
469+
return release.Compatible
470+
}

Diff for: arduino/cores/packagemanager/download.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ func (pme *Explorer) FindPlatformReleaseDependencies(item *PlatformReference) (*
8787
return nil, nil, fmt.Errorf(tr("required version %[1]s not found for platform %[2]s"), item.PlatformVersion, platform.String())
8888
}
8989
} else {
90-
release = platform.GetLatestRelease()
90+
release = platform.GetLatestCompatibleRelease()
9191
if release == nil {
92-
return nil, nil, fmt.Errorf(tr("platform %s has no available releases"), platform.String())
92+
return nil, nil, fmt.Errorf(tr("platform is not available for your OS"))
9393
}
9494
}
9595

Diff for: arduino/cores/packagemanager/install_uninstall.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (pme *Explorer) DownloadAndInstallPlatformUpgrades(
5353
if installed == nil {
5454
return nil, &arduino.PlatformNotFoundError{Platform: platformRef.String()}
5555
}
56-
latest := platform.GetLatestRelease()
56+
latest := platform.GetLatestCompatibleRelease()
5757
if !latest.Version.GreaterThan(installed.Version) {
5858
return installed, &arduino.PlatformAlreadyAtTheLatestVersionError{Platform: platformRef.String()}
5959
}

Diff for: arduino/cores/packagemanager/package_manager.go

+37
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,50 @@ func (pmb *Builder) Build() *PackageManager {
121121
}
122122
}
123123

124+
// calculate Compatible PlatformRelease
125+
func (pmb *Builder) calculateCompatibleReleases() {
126+
for _, op := range pmb.packages {
127+
for _, p := range op.Platforms {
128+
for _, pr := range p.Releases {
129+
platformHasAllCompatibleTools := func() bool {
130+
for _, td := range pr.ToolDependencies {
131+
if td == nil {
132+
return false
133+
}
134+
135+
_, ok := pmb.packages[td.ToolPackager]
136+
if !ok {
137+
return false
138+
}
139+
tool := pmb.packages[td.ToolPackager].Tools[td.ToolName]
140+
if tool == nil {
141+
return false
142+
}
143+
tr := tool.Releases[td.ToolVersion.NormalizedString()]
144+
if tr == nil {
145+
return false
146+
}
147+
148+
if tr.GetCompatibleFlavour() == nil {
149+
return false
150+
}
151+
}
152+
return true
153+
}
154+
pr.Compatible = platformHasAllCompatibleTools()
155+
}
156+
}
157+
}
158+
}
159+
124160
// NewBuilder creates a Builder with the same configuration
125161
// of this PackageManager. A "commit" function callback is returned: calling
126162
// this function will make the builder write the new configuration into this
127163
// PackageManager.
128164
func (pm *PackageManager) NewBuilder() (builder *Builder, commit func()) {
129165
pmb := NewBuilder(pm.IndexDir, pm.PackagesDir, pm.DownloadDir, pm.tempDir, pm.userAgent)
130166
return pmb, func() {
167+
pmb.calculateCompatibleReleases()
131168
pmb.BuildIntoExistingPackageManager(pm)
132169
}
133170
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ func TestFindToolsRequiredFromPlatformRelease(t *testing.T) {
744744
func TestFindPlatformReleaseDependencies(t *testing.T) {
745745
pmb := NewBuilder(nil, nil, nil, nil, "test")
746746
pmb.LoadPackageIndexFromFile(paths.New("testdata", "package_tooltest_index.json"))
747+
pmb.calculateCompatibleReleases()
747748
pm := pmb.Build()
748749
pme, release := pm.NewExplorer()
749750
defer release()

Diff for: commands/board/search.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func Search(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchR
4141
foundBoards := []*rpc.BoardListItem{}
4242
for _, targetPackage := range pme.GetPackages() {
4343
for _, platform := range targetPackage.Platforms {
44-
latestPlatformRelease := platform.GetLatestRelease()
44+
latestPlatformRelease := platform.GetLatestCompatibleRelease()
4545
installedPlatformRelease := pme.GetInstalledPlatformRelease(platform)
4646

4747
if latestPlatformRelease == nil && installedPlatformRelease == nil {

Diff for: commands/core.go

+1
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,6 @@ func PlatformReleaseToRPC(platformRelease *cores.PlatformRelease) *rpc.PlatformR
7474
MissingMetadata: missingMetadata,
7575
Type: []string{platformRelease.Category},
7676
Deprecated: platformRelease.Deprecated,
77+
Compatible: platformRelease.IsCompatible(),
7778
}
7879
}

Diff for: commands/core/search.go

+9-28
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,7 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse
5555

5656
// Discard platforms with no releases
5757
latestRelease := platform.GetLatestRelease()
58-
if latestRelease == nil {
59-
continue
60-
}
61-
if latestRelease.Name == "" {
58+
if latestRelease == nil || latestRelease.Name == "" {
6259
continue
6360
}
6461

@@ -86,41 +83,25 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse
8683
out := []*rpc.PlatformSummary{}
8784
for _, platform := range res {
8885
rpcPlatformSummary := &rpc.PlatformSummary{
86+
Metadata: commands.PlatformToRPCPlatformMetadata(platform),
8987
Releases: map[string]*rpc.PlatformRelease{},
9088
}
91-
92-
rpcPlatformSummary.Metadata = commands.PlatformToRPCPlatformMetadata(platform)
93-
94-
installed := pme.GetInstalledPlatformRelease(platform)
95-
latest := platform.GetLatestRelease()
96-
if installed != nil {
89+
if installed := pme.GetInstalledPlatformRelease(platform); installed != nil {
9790
rpcPlatformSummary.InstalledVersion = installed.Version.String()
9891
}
99-
if latest != nil {
100-
rpcPlatformSummary.LatestVersion = latest.Version.String()
92+
if latestCompatible := platform.GetLatestCompatibleRelease(); latestCompatible != nil {
93+
rpcPlatformSummary.LatestVersion = latestCompatible.Version.String()
10194
}
102-
if req.AllVersions {
103-
for _, platformRelease := range platform.GetAllReleases() {
104-
rpcPlatformRelease := commands.PlatformReleaseToRPC(platformRelease)
105-
rpcPlatformSummary.Releases[rpcPlatformRelease.Version] = rpcPlatformRelease
106-
}
107-
} else {
108-
if installed != nil {
109-
rpcPlatformRelease := commands.PlatformReleaseToRPC(installed)
110-
rpcPlatformSummary.Releases[installed.Version.String()] = rpcPlatformRelease
111-
}
112-
if latest != nil {
113-
rpcPlatformRelease := commands.PlatformReleaseToRPC(latest)
114-
rpcPlatformSummary.Releases[latest.Version.String()] = rpcPlatformRelease
115-
}
95+
for _, platformRelease := range platform.GetAllReleases() {
96+
rpcPlatformRelease := commands.PlatformReleaseToRPC(platformRelease)
97+
rpcPlatformSummary.Releases[rpcPlatformRelease.Version] = rpcPlatformRelease
11698
}
11799
out = append(out, rpcPlatformSummary)
118100
}
119101

120102
// Sort result alphabetically and put deprecated platforms at the bottom
121103
sort.Slice(out, func(i, j int) bool {
122-
return strings.ToLower(out[i].GetReleases()[out[i].GetLatestVersion()].Name) <
123-
strings.ToLower(out[j].GetReleases()[out[j].GetLatestVersion()].Name)
104+
return strings.ToLower(out[i].GetMetadata().GetId()) < strings.ToLower(out[j].GetMetadata().GetId())
124105
})
125106
sort.SliceStable(out, func(i, j int) bool {
126107
return !out[i].GetMetadata().Deprecated && out[j].GetMetadata().Deprecated

0 commit comments

Comments
 (0)