Skip to content

Commit 68e82ba

Browse files
authored
Rewrite the output system (arduino#345)
* change the logging setup * proper handle colors in logs * use feedback API instead of formatter * removed unused formatter * add PrintJSON to the feedback api * add newline to messages * remove JSONOrElse * fix config dump json format * re-add table in a dedicated package * do not pollute stdout when json format is selected * restore output format, make --names work with json too * fix integration tests * move output format decision outside command
1 parent cada486 commit 68e82ba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+812
-1260
lines changed

Diff for: cli/board/attach.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ import (
2222
"os"
2323

2424
"github.com/arduino/arduino-cli/cli/errorcodes"
25+
"github.com/arduino/arduino-cli/cli/feedback"
2526
"github.com/arduino/arduino-cli/cli/instance"
2627
"github.com/arduino/arduino-cli/cli/output"
2728
"github.com/arduino/arduino-cli/commands/board"
28-
"github.com/arduino/arduino-cli/common/formatter"
2929
rpc "github.com/arduino/arduino-cli/rpc/commands"
3030
"github.com/spf13/cobra"
3131
)
@@ -63,7 +63,7 @@ func runAttachCommand(cmd *cobra.Command, args []string) {
6363
SearchTimeout: attachFlags.searchTimeout,
6464
}, output.TaskProgress())
6565
if err != nil {
66-
formatter.PrintError(err, "attach board error")
66+
feedback.Errorf("Attach board error: %v", err)
6767
os.Exit(errorcodes.ErrGeneric)
6868
}
6969
}

Diff for: cli/board/details.go

+51-25
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ package board
1919

2020
import (
2121
"context"
22-
"fmt"
2322
"os"
2423

2524
"github.com/arduino/arduino-cli/cli/errorcodes"
25+
"github.com/arduino/arduino-cli/cli/feedback"
2626
"github.com/arduino/arduino-cli/cli/instance"
27-
"github.com/arduino/arduino-cli/cli/output"
2827
"github.com/arduino/arduino-cli/commands/board"
29-
"github.com/arduino/arduino-cli/common/formatter"
3028
rpc "github.com/arduino/arduino-cli/rpc/commands"
29+
"github.com/arduino/arduino-cli/table"
30+
"github.com/fatih/color"
3131
"github.com/spf13/cobra"
3232
)
3333

@@ -47,42 +47,68 @@ func runDetailsCommand(cmd *cobra.Command, args []string) {
4747
})
4848

4949
if err != nil {
50-
formatter.PrintError(err, "Error getting board details")
50+
feedback.Errorf("Error getting board details: %v", err)
5151
os.Exit(errorcodes.ErrGeneric)
5252
}
53-
if output.JSONOrElse(res) {
54-
outputDetailsResp(res)
55-
}
53+
54+
feedback.PrintResult(detailsResult{details: res})
5655
}
5756

58-
func outputDetailsResp(details *rpc.BoardDetailsResp) {
59-
table := output.NewTable()
60-
table.SetColumnWidthMode(1, output.Average)
61-
table.AddRow("Board name:", details.Name)
57+
// ouput from this command requires special formatting, let's create a dedicated
58+
// feedback.Result implementation
59+
type detailsResult struct {
60+
details *rpc.BoardDetailsResp
61+
}
62+
63+
func (dr detailsResult) Data() interface{} {
64+
return dr.details
65+
}
66+
67+
func (dr detailsResult) String() string {
68+
details := dr.details
69+
// Table is 4 columns wide:
70+
// | | | | |
71+
// Board name: Arduino Nano
72+
//
73+
// Required tools: arduino:avr-gcc 5.4.0-atmel3.6.1-arduino2
74+
// arduino:avrdude 6.3.0-arduino14
75+
// arduino:arduinoOTA 1.2.1
76+
//
77+
// Option: Processor cpu
78+
// ATmega328P ✔ cpu=atmega328
79+
// ATmega328P (Old Bootloader) cpu=atmega328old
80+
// ATmega168 cpu=atmega168
81+
t := table.New()
82+
t.SetColumnWidthMode(1, table.Average)
83+
t.AddRow("Board name:", details.Name)
84+
6285
for i, tool := range details.RequiredTools {
63-
head := ""
6486
if i == 0 {
65-
table.AddRow()
66-
head = "Required tools:"
87+
t.AddRow() // get some space from above
88+
t.AddRow("Required tools:", tool.Packager+":"+tool.Name, "", tool.Version)
89+
continue
6790
}
68-
table.AddRow(head, tool.Packager+":"+tool.Name, "", tool.Version)
91+
t.AddRow("", tool.Packager+":"+tool.Name, "", tool.Version)
6992
}
93+
7094
for _, option := range details.ConfigOptions {
71-
table.AddRow()
72-
table.AddRow("Option:",
73-
option.OptionLabel,
74-
"", option.Option)
95+
t.AddRow() // get some space from above
96+
t.AddRow("Option:", option.OptionLabel, "", option.Option)
7597
for _, value := range option.Values {
98+
green := color.New(color.FgGreen)
7699
if value.Selected {
77-
table.AddRow("",
78-
output.Green(value.ValueLabel),
79-
output.Green("✔"), output.Green(option.Option+"="+value.Value))
100+
t.AddRow("",
101+
table.NewCell(value.ValueLabel, green),
102+
table.NewCell("✔", green),
103+
table.NewCell(option.Option+"="+value.Value, green))
80104
} else {
81-
table.AddRow("",
105+
t.AddRow("",
82106
value.ValueLabel,
83-
"", option.Option+"="+value.Value)
107+
"",
108+
option.Option+"="+value.Value)
84109
}
85110
}
86111
}
87-
fmt.Print(table.Render())
112+
113+
return t.Render()
88114
}

Diff for: cli/board/list.go

+15-12
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@
1818
package board
1919

2020
import (
21-
"fmt"
2221
"os"
2322
"sort"
2423
"time"
2524

2625
"github.com/arduino/arduino-cli/cli/errorcodes"
26+
"github.com/arduino/arduino-cli/cli/feedback"
27+
"github.com/arduino/arduino-cli/cli/globals"
2728
"github.com/arduino/arduino-cli/cli/instance"
28-
"github.com/arduino/arduino-cli/cli/output"
2929
"github.com/arduino/arduino-cli/commands/board"
30-
"github.com/arduino/arduino-cli/common/formatter"
3130
rpc "github.com/arduino/arduino-cli/rpc/commands"
31+
"github.com/arduino/arduino-cli/table"
3232
"github.com/spf13/cobra"
3333
)
3434

@@ -54,35 +54,38 @@ var listFlags struct {
5454
// runListCommand detects and lists the connected arduino boards
5555
func runListCommand(cmd *cobra.Command, args []string) {
5656
if timeout, err := time.ParseDuration(listFlags.timeout); err != nil {
57-
formatter.PrintError(err, "Invalid timeout.")
57+
feedback.Errorf("Invalid timeout: %v", err)
5858
os.Exit(errorcodes.ErrBadArgument)
5959
} else {
6060
time.Sleep(timeout)
6161
}
6262

6363
ports, err := board.List(instance.CreateInstance().GetId())
6464
if err != nil {
65-
formatter.PrintError(err, "Error detecting boards")
65+
feedback.Errorf("Error detecting boards: %v", err)
6666
os.Exit(errorcodes.ErrNetwork)
6767
}
6868

69-
if output.JSONOrElse(ports) {
69+
if globals.OutputFormat == "json" {
70+
feedback.PrintJSON(ports)
71+
} else {
7072
outputListResp(ports)
7173
}
7274
}
7375

7476
func outputListResp(ports []*rpc.DetectedPort) {
7577
if len(ports) == 0 {
76-
formatter.Print("No boards found.")
78+
feedback.Print("No boards found.")
7779
return
7880
}
7981
sort.Slice(ports, func(i, j int) bool {
8082
x, y := ports[i], ports[j]
8183
return x.GetProtocol() < y.GetProtocol() ||
8284
(x.GetProtocol() == y.GetProtocol() && x.GetAddress() < y.GetAddress())
8385
})
84-
table := output.NewTable()
85-
table.SetHeader("Port", "Type", "Board Name", "FQBN")
86+
87+
t := table.New()
88+
t.SetHeader("Port", "Type", "Board Name", "FQBN")
8689
for _, port := range ports {
8790
address := port.GetProtocol() + "://" + port.GetAddress()
8891
if port.GetProtocol() == "serial" {
@@ -97,16 +100,16 @@ func outputListResp(ports []*rpc.DetectedPort) {
97100
for _, b := range boards {
98101
board := b.GetName()
99102
fqbn := b.GetFQBN()
100-
table.AddRow(address, protocol, board, fqbn)
103+
t.AddRow(address, protocol, board, fqbn)
101104
// show address and protocol only on the first row
102105
address = ""
103106
protocol = ""
104107
}
105108
} else {
106109
board := "Unknown"
107110
fqbn := ""
108-
table.AddRow(address, protocol, board, fqbn)
111+
t.AddRow(address, protocol, board, fqbn)
109112
}
110113
}
111-
fmt.Print(table.Render())
114+
feedback.Print(t.Render())
112115
}

Diff for: cli/board/listall.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ package board
1919

2020
import (
2121
"context"
22-
"fmt"
2322
"os"
2423
"sort"
2524

2625
"github.com/arduino/arduino-cli/cli/errorcodes"
26+
"github.com/arduino/arduino-cli/cli/feedback"
27+
"github.com/arduino/arduino-cli/cli/globals"
2728
"github.com/arduino/arduino-cli/cli/instance"
28-
"github.com/arduino/arduino-cli/cli/output"
2929
"github.com/arduino/arduino-cli/commands/board"
30-
"github.com/arduino/arduino-cli/common/formatter"
3130
rpc "github.com/arduino/arduino-cli/rpc/commands"
31+
"github.com/arduino/arduino-cli/table"
3232
"github.com/spf13/cobra"
3333
)
3434

@@ -54,11 +54,13 @@ func runListAllCommand(cmd *cobra.Command, args []string) {
5454
SearchArgs: args,
5555
})
5656
if err != nil {
57-
formatter.PrintError(err, "Error listing boards")
57+
feedback.Errorf("Error listing boards: %v", err)
5858
os.Exit(errorcodes.ErrGeneric)
5959
}
6060

61-
if output.JSONOrElse(list) {
61+
if globals.OutputFormat == "json" {
62+
feedback.PrintJSON(list)
63+
} else {
6264
outputBoardListAll(list)
6365
}
6466
}
@@ -68,10 +70,10 @@ func outputBoardListAll(list *rpc.BoardListAllResp) {
6870
return list.Boards[i].GetName() < list.Boards[j].GetName()
6971
})
7072

71-
table := output.NewTable()
72-
table.SetHeader("Board Name", "FQBN")
73+
t := table.New()
74+
t.SetHeader("Board Name", "FQBN")
7375
for _, item := range list.GetBoards() {
74-
table.AddRow(item.GetName(), item.GetFQBN())
76+
t.AddRow(item.GetName(), item.GetFQBN())
7577
}
76-
fmt.Print(table.Render())
78+
feedback.Print(t.Render())
7779
}

0 commit comments

Comments
 (0)