Skip to content
2 changes: 1 addition & 1 deletion cli/board/details.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func runDetailsCommand(cmd *cobra.Command, args []string) {
feedback.PrintResult(detailsResult{details: res})
}

// ouput from this command requires special formatting, let's create a dedicated
// output from this command requires special formatting, let's create a dedicated
// feedback.Result implementation
type detailsResult struct {
details *rpc.BoardDetailsResp
Expand Down
33 changes: 19 additions & 14 deletions cli/board/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/arduino/arduino-cli/arduino/cores"
"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/cli/globals"
"github.com/arduino/arduino-cli/cli/instance"
"github.com/arduino/arduino-cli/commands/board"
rpc "github.com/arduino/arduino-cli/rpc/commands"
Expand Down Expand Up @@ -68,27 +67,33 @@ func runListCommand(cmd *cobra.Command, args []string) {
os.Exit(errorcodes.ErrNetwork)
}

if globals.OutputFormat == "json" {
feedback.PrintJSON(ports)
} else {
outputListResp(ports)
}
feedback.PrintResult(result{ports})
}

// output from this command requires special formatting, let's create a dedicated
// feedback.Result implementation
type result struct {
ports []*rpc.DetectedPort
}

func outputListResp(ports []*rpc.DetectedPort) {
if len(ports) == 0 {
feedback.Print("No boards found.")
return
func (dr result) Data() interface{} {
return dr.ports
}

func (dr result) String() string {
if len(dr.ports) == 0 {
return "No boards found."
}
sort.Slice(ports, func(i, j int) bool {
x, y := ports[i], ports[j]

sort.Slice(dr.ports, func(i, j int) bool {
x, y := dr.ports[i], dr.ports[j]
return x.GetProtocol() < y.GetProtocol() ||
(x.GetProtocol() == y.GetProtocol() && x.GetAddress() < y.GetAddress())
})

t := table.New()
t.SetHeader("Port", "Type", "Board Name", "FQBN", "Core")
for _, port := range ports {
for _, port := range dr.ports {
address := port.GetProtocol() + "://" + port.GetAddress()
if port.GetProtocol() == "serial" {
address = port.GetAddress()
Expand Down Expand Up @@ -123,5 +128,5 @@ func outputListResp(ports []*rpc.DetectedPort) {
t.AddRow(address, protocol, board, fqbn, coreName)
}
}
feedback.Print(t.Render())
return t.Render()
}
27 changes: 16 additions & 11 deletions cli/board/listall.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (

"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/cli/globals"
"github.com/arduino/arduino-cli/cli/instance"
"github.com/arduino/arduino-cli/commands/board"
rpc "github.com/arduino/arduino-cli/rpc/commands"
Expand Down Expand Up @@ -58,22 +57,28 @@ func runListAllCommand(cmd *cobra.Command, args []string) {
os.Exit(errorcodes.ErrGeneric)
}

if globals.OutputFormat == "json" {
feedback.PrintJSON(list)
} else {
outputBoardListAll(list)
}
feedback.PrintResult(resultAll{list})
}

// output from this command requires special formatting, let's create a dedicated
// feedback.Result implementation
type resultAll struct {
list *rpc.BoardListAllResp
}

func (dr resultAll) Data() interface{} {
return dr.list
}

func outputBoardListAll(list *rpc.BoardListAllResp) {
sort.Slice(list.Boards, func(i, j int) bool {
return list.Boards[i].GetName() < list.Boards[j].GetName()
func (dr resultAll) String() string {
sort.Slice(dr.list.Boards, func(i, j int) bool {
return dr.list.Boards[i].GetName() < dr.list.Boards[j].GetName()
})

t := table.New()
t.SetHeader("Board Name", "FQBN")
for _, item := range list.GetBoards() {
for _, item := range dr.list.GetBoards() {
t.AddRow(item.GetName(), item.GetFQBN())
}
feedback.Print(t.Render())
return t.Render()
}
20 changes: 12 additions & 8 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/arduino/arduino-cli/cli/generatedocs"
"github.com/arduino/arduino-cli/cli/globals"
"github.com/arduino/arduino-cli/cli/lib"
"github.com/arduino/arduino-cli/cli/output"
"github.com/arduino/arduino-cli/cli/sketch"
"github.com/arduino/arduino-cli/cli/upload"
"github.com/arduino/arduino-cli/cli/version"
Expand All @@ -52,9 +53,10 @@ var (
PersistentPreRun: preRun,
}

verbose bool
logFile string
logFormat string
verbose bool
logFile string
logFormat string
outputFormat string
)

const (
Expand Down Expand Up @@ -83,7 +85,7 @@ func createCliCommandTree(cmd *cobra.Command) {
cmd.PersistentFlags().StringVar(&globals.LogLevel, "log-level", defaultLogLevel, "Messages with this level and above will be logged.")
cmd.PersistentFlags().StringVar(&logFile, "log-file", "", "Path to the file where logs will be written.")
cmd.PersistentFlags().StringVar(&logFormat, "log-format", "text", "The output format for the logs, can be [text|json].")
cmd.PersistentFlags().StringVar(&globals.OutputFormat, "format", "text", "The output format, can be [text|json].")
cmd.PersistentFlags().StringVar(&outputFormat, "format", "text", "The output format, can be [text|json].")
cmd.PersistentFlags().StringVar(&globals.YAMLConfigFile, "config-file", "", "The custom config file (if not specified the default will be used).")
cmd.PersistentFlags().StringSliceVar(&globals.AdditionalUrls, "additional-urls", []string{}, "Additional URLs for the board manager.")
}
Expand Down Expand Up @@ -115,7 +117,9 @@ func parseFormatString(arg string) (feedback.OutputFormat, bool) {

func preRun(cmd *cobra.Command, args []string) {
// normalize the format strings
globals.OutputFormat = strings.ToLower(globals.OutputFormat)
outputFormat = strings.ToLower(outputFormat)
// configure the output package
output.OutputFormat = outputFormat
logFormat = strings.ToLower(logFormat)

// should we log to file?
Expand Down Expand Up @@ -159,9 +163,9 @@ func preRun(cmd *cobra.Command, args []string) {
}

// check the right output format was passed
format, found := parseFormatString(globals.OutputFormat)
format, found := parseFormatString(outputFormat)
if !found {
feedback.Error("Invalid output format: " + globals.OutputFormat)
feedback.Error("Invalid output format: " + outputFormat)
os.Exit(errorcodes.ErrBadCall)
}

Expand All @@ -174,7 +178,7 @@ func preRun(cmd *cobra.Command, args []string) {
logrus.Info("Starting root command preparation (`arduino`)")

logrus.Info("Formatter set")
if globals.OutputFormat != "text" {
if outputFormat != "text" {
cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
logrus.Warn("Calling help on JSON format")
feedback.Error("Invalid Call : should show Help, but it is available only in TEXT mode.")
Expand Down
50 changes: 32 additions & 18 deletions cli/config/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ var dumpCmd = &cobra.Command{
Run: runDumpCommand,
}

// output from this command requires special formatting, let's create a dedicated
// feedback.Result implementation
type dumpResult struct {
structured *jsonConfig
plain string
}

func (dr dumpResult) Data() interface{} {
return dr.structured
}

func (dr dumpResult) String() string {
return dr.plain
}

func runDumpCommand(cmd *cobra.Command, args []string) {
logrus.Info("Executing `arduino config dump`")

Expand All @@ -69,23 +84,23 @@ func runDumpCommand(cmd *cobra.Command, args []string) {

c := globals.Config

if globals.OutputFormat == "json" {
sketchbookDir := ""
if c.SketchbookDir != nil {
sketchbookDir = c.SketchbookDir.String()
}
sketchbookDir := ""
if c.SketchbookDir != nil {
sketchbookDir = c.SketchbookDir.String()
}

arduinoDataDir := ""
if c.DataDir != nil {
arduinoDataDir = c.DataDir.String()
}
arduinoDataDir := ""
if c.DataDir != nil {
arduinoDataDir = c.DataDir.String()
}

arduinoDownloadsDir := ""
if c.ArduinoDownloadsDir != nil {
arduinoDownloadsDir = c.ArduinoDownloadsDir.String()
}
arduinoDownloadsDir := ""
if c.ArduinoDownloadsDir != nil {
arduinoDownloadsDir = c.ArduinoDownloadsDir.String()
}

feedback.PrintJSON(jsonConfig{
feedback.PrintResult(&dumpResult{
structured: &jsonConfig{
ProxyType: c.ProxyType,
ProxyManualConfig: &jsonProxyConfig{
Hostname: c.ProxyHostname,
Expand All @@ -98,8 +113,7 @@ func runDumpCommand(cmd *cobra.Command, args []string) {
BoardsManager: &jsonBoardsManagerConfig{
AdditionalURLS: c.BoardManagerAdditionalUrls,
},
})
} else {
feedback.Print(string(data))
}
},
plain: string(data),
})
}
9 changes: 0 additions & 9 deletions cli/config/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ func initInitCommand() *cobra.Command {
Args: cobra.NoArgs,
Run: runInitCommand,
}
initCommand.Flags().BoolVar(&initFlags._default, "default", false,
"If omitted, ask questions to the user about setting configuration properties, otherwise use default configuration.")
initCommand.Flags().StringVar(&initFlags.location, "save-as", "",
"Sets where to save the configuration file [default is ./arduino-cli.yaml].")
return initCommand
Expand All @@ -55,13 +53,6 @@ var initFlags struct {
func runInitCommand(cmd *cobra.Command, args []string) {
logrus.Info("Executing `arduino config init`")

if !initFlags._default {
if globals.OutputFormat != "text" {
feedback.Error("The interactive mode is supported only in text mode.")
os.Exit(errorcodes.ErrBadCall)
}
}

filepath := initFlags.location
if filepath == "" {
filepath = globals.Config.ConfigFile.String()
Expand Down
31 changes: 18 additions & 13 deletions cli/core/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"github.com/arduino/arduino-cli/arduino/cores"
"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/cli/globals"
"github.com/arduino/arduino-cli/cli/instance"
"github.com/arduino/arduino-cli/commands/core"
"github.com/arduino/arduino-cli/table"
Expand Down Expand Up @@ -59,26 +58,32 @@ func runListCommand(cmd *cobra.Command, args []string) {
os.Exit(errorcodes.ErrGeneric)
}

if globals.OutputFormat == "json" {
feedback.PrintJSON(platforms)
} else {
outputInstalledCores(platforms)
}
feedback.PrintResult(installedResult{platforms})
}

// output from this command requires special formatting, let's create a dedicated
// feedback.Result implementation
type installedResult struct {
platforms []*cores.PlatformRelease
}

func (ir installedResult) Data() interface{} {
return ir.platforms
}

func outputInstalledCores(platforms []*cores.PlatformRelease) {
if platforms == nil || len(platforms) == 0 {
return
func (ir installedResult) String() string {
if ir.platforms == nil || len(ir.platforms) == 0 {
return ""
}

t := table.New()
t.SetHeader("ID", "Installed", "Latest", "Name")
sort.Slice(platforms, func(i, j int) bool {
return platforms[i].Platform.String() < platforms[j].Platform.String()
sort.Slice(ir.platforms, func(i, j int) bool {
return ir.platforms[i].Platform.String() < ir.platforms[j].Platform.String()
})
for _, p := range platforms {
for _, p := range ir.platforms {
t.AddRow(p.Platform.String(), p.Version.String(), p.Platform.GetLatestRelease().Version.String(), p.Platform.Name)
}

feedback.Print(t.Render())
return t.Render()
}
37 changes: 18 additions & 19 deletions cli/core/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (

"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/cli/globals"
"github.com/arduino/arduino-cli/cli/instance"
"github.com/arduino/arduino-cli/commands/core"
rpc "github.com/arduino/arduino-cli/rpc/commands"
Expand All @@ -51,11 +50,6 @@ func runSearchCommand(cmd *cobra.Command, args []string) {
logrus.Info("Executing `arduino core search`")

arguments := strings.ToLower(strings.Join(args, " "))

if globals.OutputFormat != "json" {
feedback.Printf("Searching for platforms matching '%s'", arguments)
}

resp, err := core.PlatformSearch(context.Background(), &rpc.PlatformSearchReq{
Instance: instance,
SearchArgs: arguments,
Expand All @@ -66,25 +60,30 @@ func runSearchCommand(cmd *cobra.Command, args []string) {
}

coreslist := resp.GetSearchOutput()
if globals.OutputFormat == "json" {
feedback.PrintJSON(coreslist)
} else {
outputSearchCores(coreslist)
}
feedback.PrintResult(searchResults{coreslist})
}

// output from this command requires special formatting, let's create a dedicated
// feedback.Result implementation
type searchResults struct {
platforms []*rpc.Platform
}

func (sr searchResults) Data() interface{} {
return sr.platforms
}

func outputSearchCores(cores []*rpc.Platform) {
if len(cores) > 0 {
func (sr searchResults) String() string {
if len(sr.platforms) > 0 {
t := table.New()
t.SetHeader("ID", "Version", "Name")
sort.Slice(cores, func(i, j int) bool {
return cores[i].ID < cores[j].ID
sort.Slice(sr.platforms, func(i, j int) bool {
return sr.platforms[i].ID < sr.platforms[j].ID
})
for _, item := range cores {
for _, item := range sr.platforms {
t.AddRow(item.GetID(), item.GetLatest(), item.GetName())
}
feedback.Print(t.Render())
} else {
feedback.Print("No platforms matching your search.")
return t.Render()
}
return "No platforms matching your search."
}
Loading