Skip to content

Commit 9f728ce

Browse files
committed
Fix invalid JSON output for outdated command
Fixes issue #2104 The code for `internal/cli/core` and `internal/cli/lib` has been refactored so that we can use only the `Get` functions from `internal/cli/outdated` package and compose there the table and JSON object. For regular text output, the new table will have some extra fields that either for platforms or for libraries will be blank. For JSON output, the resulting object will be an array of two arrays: the outdated platforms and the outdated libraries. Signed-off-by: Lluís Martínez <[email protected]>
1 parent 2493b56 commit 9f728ce

File tree

3 files changed

+126
-6
lines changed

3 files changed

+126
-6
lines changed

Diff for: internal/cli/core/list.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,14 @@ func runListCommand(args []string, all bool, updatableOnly bool) {
5252
List(inst, all, updatableOnly)
5353
}
5454

55-
// List print a list of installed platforms.
55+
// List gets and prints a list of installed platforms.
5656
func List(inst *rpc.Instance, all bool, updatableOnly bool) {
57+
platforms := GetList(inst, all, updatableOnly)
58+
PrintList(platforms)
59+
}
60+
61+
// GetList returns a list of installed platforms.
62+
func GetList(inst *rpc.Instance, all bool, updatableOnly bool) []*rpc.Platform {
5763
platforms, err := core.GetPlatforms(&rpc.PlatformListRequest{
5864
Instance: inst,
5965
UpdatableOnly: updatableOnly,
@@ -62,7 +68,11 @@ func List(inst *rpc.Instance, all bool, updatableOnly bool) {
6268
if err != nil {
6369
feedback.Fatal(tr("Error listing platforms: %v", err), feedback.ErrGeneric)
6470
}
71+
return platforms
72+
}
6573

74+
// PrintList prints a list of installed platforms.
75+
func PrintList(platforms []*rpc.Platform) {
6676
feedback.PrintResult(installedResult{platforms})
6777
}
6878

Diff for: internal/cli/lib/list.go

+18-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,20 @@ func runListCommand(args []string, all bool, updatable bool) {
6060
List(instance, args, all, updatable)
6161
}
6262

63-
// List lists all the installed libraries.
63+
// List gets and prints a list of installed libraries.
6464
func List(instance *rpc.Instance, args []string, all bool, updatable bool) {
65+
installedLibs := GetList(instance, args, all, updatable)
66+
PrintList(updatable, installedLibs)
67+
logrus.Info("Done")
68+
}
69+
70+
// GetList returns a list of installed libraries.
71+
func GetList(
72+
instance *rpc.Instance,
73+
args []string,
74+
all bool,
75+
updatable bool,
76+
) []*rpc.InstalledLibrary {
6577
name := ""
6678
if len(args) > 0 {
6779
name = args[0]
@@ -95,11 +107,15 @@ func List(instance *rpc.Instance, args []string, all bool, updatable bool) {
95107
libs = []*rpc.InstalledLibrary{}
96108
}
97109

110+
return libs
111+
}
112+
113+
// PrintList prints a list of installed libraries.
114+
func PrintList(updatable bool, libs []*rpc.InstalledLibrary) {
98115
feedback.PrintResult(installedResult{
99116
onlyUpdates: updatable,
100117
installedLibs: libs,
101118
})
102-
logrus.Info("Done")
103119
}
104120

105121
// output from this command requires special formatting, let's create a dedicated

Diff for: internal/cli/outdated/outdated.go

+97-3
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@
1616
package outdated
1717

1818
import (
19+
"fmt"
1920
"os"
21+
"sort"
22+
"strings"
2023

2124
"github.com/arduino/arduino-cli/i18n"
2225
"github.com/arduino/arduino-cli/internal/cli/core"
26+
"github.com/arduino/arduino-cli/internal/cli/feedback"
2327
"github.com/arduino/arduino-cli/internal/cli/instance"
2428
"github.com/arduino/arduino-cli/internal/cli/lib"
2529
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
30+
"github.com/arduino/arduino-cli/table"
2631
"github.com/sirupsen/logrus"
2732
"github.com/spf13/cobra"
2833
)
@@ -49,8 +54,97 @@ func runOutdatedCommand(cmd *cobra.Command, args []string) {
4954
Outdated(inst)
5055
}
5156

52-
// Outdated returns a list of outdated platforms and libraries
57+
// Outdated prints a list of outdated platforms and libraries
5358
func Outdated(inst *rpc.Instance) {
54-
core.List(inst, false, true)
55-
lib.List(inst, []string{}, false, true)
59+
feedback.PrintResult(
60+
outdatedResult{core.GetList(inst, false, true), lib.GetList(inst, []string{}, false, true)},
61+
)
62+
}
63+
64+
// output from this command requires special formatting, let's create a dedicated
65+
// feedback.Result implementation
66+
type outdatedResult struct {
67+
platforms []*rpc.Platform
68+
installedLibs []*rpc.InstalledLibrary
69+
}
70+
71+
func (ir outdatedResult) Data() interface{} {
72+
return []interface{}{ir.platforms, ir.installedLibs}
73+
}
74+
75+
func (ir outdatedResult) String() string {
76+
if len(ir.platforms) == 0 && len(ir.installedLibs) == 0 {
77+
return tr("No outdated platforms or libraries found.")
78+
}
79+
80+
// A table useful both for platforms and libraries, where some of the fields will be blank.
81+
t := table.New()
82+
t.SetHeader(
83+
tr("ID"),
84+
tr("Name"),
85+
tr("Installed"),
86+
tr("Latest"),
87+
tr("Location"),
88+
tr("Description"),
89+
)
90+
t.SetColumnWidthMode(2, table.Average)
91+
t.SetColumnWidthMode(3, table.Average)
92+
t.SetColumnWidthMode(5, table.Average)
93+
94+
// Based on internal/cli/core/list.go
95+
for _, p := range ir.platforms {
96+
name := p.Name
97+
if p.Deprecated {
98+
name = fmt.Sprintf("[%s] %s", tr("DEPRECATED"), name)
99+
}
100+
t.AddRow(p.Id, name, p.Installed, p.Latest, "", "")
101+
}
102+
103+
// Based on internal/cli/lib/list.go
104+
sort.Slice(ir.installedLibs, func(i, j int) bool {
105+
return strings.ToLower(
106+
ir.installedLibs[i].Library.Name,
107+
) < strings.ToLower(
108+
ir.installedLibs[j].Library.Name,
109+
) ||
110+
strings.ToLower(
111+
ir.installedLibs[i].Library.ContainerPlatform,
112+
) < strings.ToLower(
113+
ir.installedLibs[j].Library.ContainerPlatform,
114+
)
115+
})
116+
lastName := ""
117+
for _, libMeta := range ir.installedLibs {
118+
lib := libMeta.GetLibrary()
119+
name := lib.Name
120+
if name == lastName {
121+
name = ` "`
122+
} else {
123+
lastName = name
124+
}
125+
126+
location := lib.GetLocation().String()
127+
if lib.ContainerPlatform != "" {
128+
location = lib.GetContainerPlatform()
129+
}
130+
131+
available := ""
132+
sentence := ""
133+
if libMeta.GetRelease() != nil {
134+
available = libMeta.GetRelease().GetVersion()
135+
sentence = lib.Sentence
136+
}
137+
138+
if available == "" {
139+
available = "-"
140+
}
141+
if sentence == "" {
142+
sentence = "-"
143+
} else if len(sentence) > 40 {
144+
sentence = sentence[:37] + "..."
145+
}
146+
t.AddRow("", name, lib.Version, available, location, sentence)
147+
}
148+
149+
return t.Render()
56150
}

0 commit comments

Comments
 (0)