Skip to content

Commit 7cb8576

Browse files
committed
Better handling of 'core list' results
1 parent 0176a3b commit 7cb8576

File tree

5 files changed

+206
-14
lines changed

5 files changed

+206
-14
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
name: github.com/iancoleman/orderedmap
3+
version: v0.3.0
4+
type: go
5+
summary:
6+
homepage: https://pkg.go.dev/github.com/iancoleman/orderedmap
7+
license: mit
8+
licenses:
9+
- sources: LICENSE
10+
text: |
11+
The MIT License (MIT)
12+
13+
Copyright (c) 2017 Ian Coleman
14+
15+
Permission is hereby granted, free of charge, to any person obtaining a copy
16+
of this software and associated documentation files (the "Software"), to deal
17+
in the Software without restriction, including without limitation the rights
18+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19+
copies of the Software, and to permit persons to whom the Software is
20+
furnished to do so, Subject to the following conditions:
21+
22+
The above copyright notice and this permission notice shall be included in all
23+
copies or Substantial portions of the Software.
24+
25+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31+
SOFTWARE.
32+
notices: []

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ require (
1717
github.com/djherbis/nio/v3 v3.0.1
1818
github.com/fatih/color v1.7.0
1919
github.com/gofrs/uuid/v5 v5.0.0
20+
github.com/iancoleman/orderedmap v0.3.0
2021
github.com/leonelquinteros/gotext v1.4.0
2122
github.com/mailru/easyjson v0.7.7
2223
github.com/marcinbor85/gohex v0.0.0-20210308104911-55fb1c624d84

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
208208
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
209209
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
210210
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
211+
github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc=
212+
github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE=
211213
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
212214
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
213215
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=

internal/cli/core/list.go

+25-14
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"github.com/arduino/arduino-cli/commands/core"
2323
"github.com/arduino/arduino-cli/internal/cli/feedback"
24+
"github.com/arduino/arduino-cli/internal/cli/feedback/result"
2425
"github.com/arduino/arduino-cli/internal/cli/instance"
2526
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2627
"github.com/arduino/arduino-cli/table"
@@ -55,7 +56,7 @@ func runListCommand(args []string, all bool, updatableOnly bool) {
5556
// List gets and prints a list of installed platforms.
5657
func List(inst *rpc.Instance, all bool, updatableOnly bool) {
5758
platforms := GetList(inst, all, updatableOnly)
58-
feedback.PrintResult(installedResult{platforms})
59+
feedback.PrintResult(newCoreListResult(platforms))
5960
}
6061

6162
// GetList returns a list of installed platforms.
@@ -81,34 +82,44 @@ func GetList(inst *rpc.Instance, all bool, updatableOnly bool) []*rpc.PlatformSu
8182
return result
8283
}
8384

84-
// output from this command requires special formatting, let's create a dedicated
85-
// feedback.Result implementation
86-
type installedResult struct {
87-
platforms []*rpc.PlatformSummary
85+
func newCoreListResult(in []*rpc.PlatformSummary) *coreListResult {
86+
res := &coreListResult{}
87+
for _, platformSummary := range in {
88+
res.platforms = append(res.platforms, result.NewPlatformResult(platformSummary))
89+
}
90+
return res
91+
}
92+
93+
type coreListResult struct {
94+
platforms []*result.Platform
8895
}
8996

90-
func (ir installedResult) Data() interface{} {
97+
// Data implements Result interface
98+
func (ir coreListResult) Data() interface{} {
9199
return ir.platforms
92100
}
93101

94-
func (ir installedResult) String() string {
102+
// String implements Result interface
103+
func (ir coreListResult) String() string {
95104
if len(ir.platforms) == 0 {
96105
return tr("No platforms installed.")
97106
}
98107
t := table.New()
99108
t.SetHeader(tr("ID"), tr("Installed"), tr("Latest"), tr("Name"))
100109
for _, platform := range ir.platforms {
101-
installedRelease := platform.GetInstalledRelease()
102-
latestRelease := platform.GetLatestRelease()
103-
104-
name := installedRelease.GetName()
110+
name := ""
111+
if installed := platform.GetLatestRelease(); installed != nil {
112+
name = installed.Name
113+
}
105114
if name == "" {
106-
name = latestRelease.GetName()
115+
if latest := platform.GetLatestRelease(); latest != nil {
116+
name = latest.Name
117+
}
107118
}
108-
if platform.Metadata.Deprecated {
119+
if platform.Deprecated {
109120
name = fmt.Sprintf("[%s] %s", tr("DEPRECATED"), name)
110121
}
111-
t.AddRow(platform.Metadata.Id, platform.InstalledVersion, platform.LatestVersion, name)
122+
t.AddRow(platform.Id, platform.InstalledVersion, platform.LatestVersion, name)
112123
}
113124

114125
return t.Render()

internal/cli/feedback/result/rpc.go

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2020 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to [email protected].
15+
16+
package result
17+
18+
import (
19+
"slices"
20+
21+
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
22+
"github.com/iancoleman/orderedmap"
23+
semver "go.bug.st/relaxed-semver"
24+
)
25+
26+
// NewPlatformResult creates a new result.Platform from rpc.PlatformSummary
27+
func NewPlatformResult(in *rpc.PlatformSummary) *Platform {
28+
meta := in.Metadata
29+
res := &Platform{
30+
Id: meta.Id,
31+
Maintainer: meta.Maintainer,
32+
Website: meta.Website,
33+
Email: meta.Email,
34+
ManuallyInstalled: meta.ManuallyInstalled,
35+
Deprecated: meta.Deprecated,
36+
Indexed: meta.Indexed,
37+
38+
Releases: orderedmap.New(),
39+
InstalledVersion: in.InstalledVersion,
40+
LatestVersion: in.LatestVersion,
41+
}
42+
43+
for k, v := range in.Releases {
44+
res.Releases.Set(k, NewPlatformReleaseResult(v))
45+
}
46+
res.Releases.SortKeys(func(keys []string) {
47+
slices.SortFunc(keys, func(x, y string) int {
48+
return semver.ParseRelaxed(x).CompareTo(semver.ParseRelaxed(y))
49+
})
50+
})
51+
52+
versions := []*semver.RelaxedVersion{}
53+
for version := range in.Releases {
54+
versions = append(versions, semver.ParseRelaxed(version))
55+
}
56+
slices.SortFunc(versions, (*semver.RelaxedVersion).CompareTo)
57+
for _, version := range versions {
58+
res.Releases.Set(version.String(), NewPlatformReleaseResult(in.Releases[version.String()]))
59+
}
60+
return res
61+
}
62+
63+
// Platform maps a rpc.Platform
64+
type Platform struct {
65+
Id string `json:"id,omitempty"`
66+
Maintainer string `json:"maintainer,omitempty"`
67+
Website string `json:"website,omitempty"`
68+
Email string `json:"email,omitempty"`
69+
ManuallyInstalled bool `json:"manually_installed,omitempty"`
70+
Deprecated bool `json:"deprecated,omitempty"`
71+
Indexed bool `json:"indexed,omitempty"`
72+
73+
Releases *orderedmap.OrderedMap `json:"releases,omitempty"`
74+
75+
InstalledVersion string `json:"installed_version,omitempty"`
76+
LatestVersion string `json:"latest_version,omitempty"`
77+
}
78+
79+
// GetLatestRelease returns the latest relase of this platform or nil if none available.
80+
func (p *Platform) GetLatestRelease() *PlatformRelease {
81+
res, ok := p.Releases.Get(p.LatestVersion)
82+
if !ok {
83+
return nil
84+
}
85+
return res.(*PlatformRelease)
86+
}
87+
88+
// GetInstalledRelease returns the installed relase of this platform or nil if none available.
89+
func (p *Platform) GetInstalledRelease() *PlatformRelease {
90+
res, ok := p.Releases.Get(p.InstalledVersion)
91+
if !ok {
92+
return nil
93+
}
94+
return res.(*PlatformRelease)
95+
}
96+
97+
// NewPlatformReleaseResult creates a new result.PlatformRelease from rpc.PlatformRelease
98+
func NewPlatformReleaseResult(in *rpc.PlatformRelease) *PlatformRelease {
99+
var boards []*Board
100+
for _, board := range in.Boards {
101+
boards = append(boards, &Board{
102+
Name: board.Name,
103+
Fqbn: board.Fqbn,
104+
})
105+
}
106+
var help *HelpResource
107+
if in.Help != nil {
108+
help = &HelpResource{
109+
Online: in.Help.Online,
110+
}
111+
}
112+
res := &PlatformRelease{
113+
Name: in.Name,
114+
Version: in.Version,
115+
Type: in.Type,
116+
Installed: in.Installed,
117+
Boards: boards,
118+
Help: help,
119+
MissingMetadata: in.MissingMetadata,
120+
Deprecated: in.Deprecated,
121+
}
122+
return res
123+
}
124+
125+
// PlatformRelease maps a rpc.PlatformRelease
126+
type PlatformRelease struct {
127+
Name string `json:"name,omitempty"`
128+
Version string `json:"version,omitempty"`
129+
Type []string `json:"type,omitempty"`
130+
Installed bool `json:"installed,omitempty"`
131+
Boards []*Board `json:"boards,omitempty"`
132+
Help *HelpResource `json:"help,omitempty"`
133+
MissingMetadata bool `json:"missing_metadata,omitempty"`
134+
Deprecated bool `json:"deprecated,omitempty"`
135+
}
136+
137+
// Board maps a rpc.Board
138+
type Board struct {
139+
Name string `json:"name,omitempty"`
140+
Fqbn string `json:"fqbn,omitempty"`
141+
}
142+
143+
// HelpResource maps a rpc.HelpResource
144+
type HelpResource struct {
145+
Online string `json:"online,omitempty"`
146+
}

0 commit comments

Comments
 (0)