Skip to content

Commit abc717a

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 183d5e9 commit abc717a

File tree

6 files changed

+130
-10
lines changed

6 files changed

+130
-10
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
}

Diff for: internal/integrationtest/outdated/outdated_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func TestOutdated(t *testing.T) {
5353
lines[i] = strings.TrimSpace(lines[i])
5454
}
5555
require.Contains(t, lines[1], "Arduino AVR Boards")
56-
require.Contains(t, lines[4], "USBHost")
56+
require.Contains(t, lines[2], "USBHost")
5757
}
5858

5959
func TestOutdatedUsingLibraryWithInvalidVersion(t *testing.T) {

Diff for: internal/integrationtest/update/update_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func TestUpdateShowingOutdated(t *testing.T) {
6767
require.Contains(t, lines[0], "Downloading index: library_index.tar.bz2 downloaded")
6868
require.Contains(t, lines[1], "Downloading index: package_index.tar.bz2 downloaded")
6969
require.Contains(t, lines[3], "Arduino AVR Boards")
70-
require.Contains(t, lines[6], "USBHost")
70+
require.Contains(t, lines[4], "USBHost")
7171
}
7272

7373
func TestUpdateWithUrlNotFound(t *testing.T) {

Diff for: internal/integrationtest/upgrade/upgrade_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ func TestUpgrade(t *testing.T) {
5050
require.NoError(t, err)
5151
lines := strings.Split(string(stdout), "\n")
5252
require.Contains(t, lines[1], "Arduino AVR Boards")
53-
require.Contains(t, lines[4], "USBHost")
53+
require.Contains(t, lines[2], "USBHost")
5454

5555
_, _, err = cli.Run("upgrade")
5656
require.NoError(t, err)
5757

5858
// Verifies cores and libraries have been updated
5959
stdout, _, err = cli.Run("outdated")
6060
require.NoError(t, err)
61-
require.Contains(t, string(stdout), "No libraries update is available.")
61+
require.Contains(t, string(stdout), "No outdated platforms or libraries found.")
6262
}
6363

6464
func TestUpgradeUsingLibraryWithInvalidVersion(t *testing.T) {

0 commit comments

Comments
 (0)