diff --git a/cli/board/details.go b/cli/board/details.go index 40ff23aeeb8..f34e9b7a6db 100644 --- a/cli/board/details.go +++ b/cli/board/details.go @@ -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 diff --git a/cli/board/list.go b/cli/board/list.go index 8702e418a05..a8f73929cf8 100644 --- a/cli/board/list.go +++ b/cli/board/list.go @@ -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" @@ -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() @@ -123,5 +128,5 @@ func outputListResp(ports []*rpc.DetectedPort) { t.AddRow(address, protocol, board, fqbn, coreName) } } - feedback.Print(t.Render()) + return t.Render() } diff --git a/cli/board/listall.go b/cli/board/listall.go index 0034c6c6827..47472a69cc6 100644 --- a/cli/board/listall.go +++ b/cli/board/listall.go @@ -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" @@ -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() } diff --git a/cli/cli.go b/cli/cli.go index dfa7161c978..12450fa7ea0 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -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" @@ -52,9 +53,10 @@ var ( PersistentPreRun: preRun, } - verbose bool - logFile string - logFormat string + verbose bool + logFile string + logFormat string + outputFormat string ) const ( @@ -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.") } @@ -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? @@ -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) } @@ -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.") diff --git a/cli/config/dump.go b/cli/config/dump.go index a1f56e536e0..8b8787c8192 100644 --- a/cli/config/dump.go +++ b/cli/config/dump.go @@ -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`") @@ -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, @@ -98,8 +113,7 @@ func runDumpCommand(cmd *cobra.Command, args []string) { BoardsManager: &jsonBoardsManagerConfig{ AdditionalURLS: c.BoardManagerAdditionalUrls, }, - }) - } else { - feedback.Print(string(data)) - } + }, + plain: string(data), + }) } diff --git a/cli/config/init.go b/cli/config/init.go index 66998e02437..7d7efbc9eed 100644 --- a/cli/config/init.go +++ b/cli/config/init.go @@ -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 @@ -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() diff --git a/cli/core/list.go b/cli/core/list.go index d45f1835f38..c85fa4b290c 100644 --- a/cli/core/list.go +++ b/cli/core/list.go @@ -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" @@ -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() } diff --git a/cli/core/search.go b/cli/core/search.go index 419db357019..4d38e41a14b 100644 --- a/cli/core/search.go +++ b/cli/core/search.go @@ -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" @@ -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, @@ -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." } diff --git a/cli/feedback/exported.go b/cli/feedback/exported.go index a3cc2a6f23d..aee07535dbd 100644 --- a/cli/feedback/exported.go +++ b/cli/feedback/exported.go @@ -52,8 +52,8 @@ func Printf(format string, v ...interface{}) { } // Print behaves like fmt.Print but writes on the out writer and adds a newline. -func Print(v ...interface{}) { - fb.Print(v...) +func Print(v interface{}) { + fb.Print(v) } // Errorf behaves like fmt.Printf but writes on the error writer and adds a @@ -68,13 +68,9 @@ func Error(v ...interface{}) { fb.Error(v...) } -// PrintJSON is a convenient wrapper to provide feedback by printing the -// desired output in a pretty JSON format. It adds a newline to the output. -func PrintJSON(v interface{}) { - fb.PrintJSON(v) -} - -// PrintResult is a convenient wrapper... +// PrintResult is a convenient wrapper to provide feedback for complex data, +// where the contents can't be just serialized to JSON but requires more +// structure. func PrintResult(res Result) { fb.PrintResult(res) } diff --git a/cli/feedback/feedback.go b/cli/feedback/feedback.go index 1f355c9f869..9ccc5f4671d 100644 --- a/cli/feedback/feedback.go +++ b/cli/feedback/feedback.go @@ -86,8 +86,12 @@ func (fb *Feedback) Printf(format string, v ...interface{}) { } // Print behaves like fmt.Print but writes on the out writer and adds a newline. -func (fb *Feedback) Print(v ...interface{}) { - fmt.Fprintln(fb.out, v...) +func (fb *Feedback) Print(v interface{}) { + if fb.format == JSON { + fb.printJSON(v) + } else { + fmt.Fprintln(fb.out, v) + } } // Errorf behaves like fmt.Printf but writes on the error writer and adds a @@ -103,24 +107,22 @@ func (fb *Feedback) Error(v ...interface{}) { logrus.Error(fmt.Sprint(v...)) } -// PrintJSON is a convenient wrapper to provide feedback by printing the +// printJSON is a convenient wrapper to provide feedback by printing the // desired output in a pretty JSON format. It adds a newline to the output. -func (fb *Feedback) PrintJSON(v interface{}) { +func (fb *Feedback) printJSON(v interface{}) { if d, err := json.MarshalIndent(v, "", " "); err != nil { fb.Errorf("Error during JSON encoding of the output: %v", err) } else { - fb.Print(string(d)) + fmt.Fprint(fb.out, string(d)) } } -// PrintResult is a convenient wrapper... +// PrintResult is a convenient wrapper to provide feedback for complex data, +// where the contents can't be just serialized to JSON but requires more +// structure. func (fb *Feedback) PrintResult(res Result) { if fb.format == JSON { - if d, err := json.MarshalIndent(res.Data(), "", " "); err != nil { - fb.Errorf("Error during JSON encoding of the output: %v", err) - } else { - fb.Print(string(d)) - } + fb.printJSON(res.Data()) } else { fb.Print(fmt.Sprintf("%s", res)) } diff --git a/cli/globals/globals.go b/cli/globals/globals.go index ef718d4c696..fd46e0a6f09 100644 --- a/cli/globals/globals.go +++ b/cli/globals/globals.go @@ -29,8 +29,6 @@ import ( var ( // Debug determines whether to dump debug output to stderr or not Debug bool - // OutputFormat can be "text" or "json" - OutputFormat string // VersionInfo contains all info injected during build VersionInfo = version.NewInfo(filepath.Base(os.Args[0])) // Config FIXMEDOC diff --git a/cli/lib/list.go b/cli/lib/list.go index 0de750b4529..495174caf0f 100644 --- a/cli/lib/list.go +++ b/cli/lib/list.go @@ -22,7 +22,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/lib" rpc "github.com/arduino/arduino-cli/rpc/commands" @@ -66,27 +65,31 @@ func runListCommand(cmd *cobra.Command, args []string) { } libs := res.GetInstalledLibrary() - if libs != nil { - if globals.OutputFormat == "json" { - feedback.PrintJSON(libs) - } else { - outputListLibrary(libs) - } - } + feedback.PrintResult(installedResult{libs}) logrus.Info("Done") } -func outputListLibrary(il []*rpc.InstalledLibrary) { - if il == nil || len(il) == 0 { - return +// output from this command requires special formatting, let's create a dedicated +// feedback.Result implementation +type installedResult struct { + installedLibs []*rpc.InstalledLibrary +} + +func (ir installedResult) Data() interface{} { + return ir.installedLibs +} + +func (ir installedResult) String() string { + if ir.installedLibs == nil || len(ir.installedLibs) == 0 { + return "No libraries installed." } t := table.New() t.SetHeader("Name", "Installed", "Available", "Location") lastName := "" - for _, libMeta := range il { + for _, libMeta := range ir.installedLibs { lib := libMeta.GetLibrary() name := lib.Name if name == lastName { @@ -110,5 +113,5 @@ func outputListLibrary(il []*rpc.InstalledLibrary) { } } - feedback.Print(t.Render()) + return t.Render() } diff --git a/cli/lib/search.go b/cli/lib/search.go index 4014acc56fc..5c47df9019d 100644 --- a/cli/lib/search.go +++ b/cli/lib/search.go @@ -26,7 +26,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/lib" rpc "github.com/arduino/arduino-cli/rpc/commands" @@ -64,63 +63,76 @@ func runSearchCommand(cmd *cobra.Command, args []string) { os.Exit(errorcodes.ErrGeneric) } - if globals.OutputFormat == "json" { - if searchFlags.namesOnly { - type LibName struct { - Name string `json:"name,required"` - } - - type NamesOnly struct { - Libraries []LibName `json:"libraries,required"` - } - - names := []LibName{} - results := searchResp.GetLibraries() - for _, lsr := range results { - names = append(names, LibName{lsr.Name}) - } - feedback.PrintJSON(NamesOnly{ - names, - }) - } else { - feedback.PrintJSON(searchResp) + feedback.PrintResult(result{ + results: searchResp, + namesOnly: searchFlags.namesOnly, + }) + + logrus.Info("Done") +} + +// output from this command requires special formatting, let's create a dedicated +// feedback.Result implementation +type result struct { + results *rpc.LibrarySearchResp + namesOnly bool +} + +func (res result) Data() interface{} { + if res.namesOnly { + type LibName struct { + Name string `json:"name,required"` + } + + type NamesOnly struct { + Libraries []LibName `json:"libraries,required"` + } + + names := []LibName{} + results := res.results.GetLibraries() + for _, lsr := range results { + names = append(names, LibName{lsr.Name}) + } + + return NamesOnly{ + names, } - } else { - // get a sorted slice of results - results := searchResp.GetLibraries() - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) - - // print all the things - outputSearchedLibrary(results, searchFlags.namesOnly) } - logrus.Info("Done") + return res.results } -func outputSearchedLibrary(results []*rpc.SearchedLibrary, namesOnly bool) { +func (res result) String() string { + results := res.results.GetLibraries() if len(results) == 0 { - feedback.Print("No libraries matching your search.") - return + return "No libraries matching your search." } + // get a sorted slice of results + sort.Slice(results, func(i, j int) bool { + return results[i].Name < results[j].Name + }) + + var out strings.Builder + for _, lsr := range results { - feedback.Printf(`Name: "%s"`, lsr.Name) - if namesOnly { + out.WriteString(fmt.Sprintf("Name: \"%s\"\n", lsr.Name)) + if res.namesOnly { continue } - feedback.Printf(" Author: %s", lsr.GetLatest().Author) - feedback.Printf(" Maintainer: %s", lsr.GetLatest().Maintainer) - feedback.Printf(" Sentence: %s", lsr.GetLatest().Sentence) - feedback.Printf(" Paragraph: %s", lsr.GetLatest().Paragraph) - feedback.Printf(" Website: %s", lsr.GetLatest().Website) - feedback.Printf(" Category: %s", lsr.GetLatest().Category) - feedback.Printf(" Architecture: %s", strings.Join(lsr.GetLatest().Architectures, ", ")) - feedback.Printf(" Types: %s", strings.Join(lsr.GetLatest().Types, ", ")) - feedback.Printf(" Versions: %s", strings.Replace(fmt.Sprint(versionsFromSearchedLibrary(lsr)), " ", ", ", -1)) + out.WriteString(fmt.Sprintf(" Author: %s\n", lsr.GetLatest().Author)) + out.WriteString(fmt.Sprintf(" Maintainer: %s\n", lsr.GetLatest().Maintainer)) + out.WriteString(fmt.Sprintf(" Sentence: %s\n", lsr.GetLatest().Sentence)) + out.WriteString(fmt.Sprintf(" Paragraph: %s\n", lsr.GetLatest().Paragraph)) + out.WriteString(fmt.Sprintf(" Website: %s\n", lsr.GetLatest().Website)) + out.WriteString(fmt.Sprintf(" Category: %s\n", lsr.GetLatest().Category)) + out.WriteString(fmt.Sprintf(" Architecture: %s\n", strings.Join(lsr.GetLatest().Architectures, ", "))) + out.WriteString(fmt.Sprintf(" Types: %s\n", strings.Join(lsr.GetLatest().Types, ", "))) + out.WriteString(fmt.Sprintf(" Versions: %s\n", strings.Replace(fmt.Sprint(versionsFromSearchedLibrary(lsr)), " ", ", ", -1))) } + + return fmt.Sprintf("%s", out.String()) } func versionsFromSearchedLibrary(library *rpc.SearchedLibrary) []*semver.Version { diff --git a/cli/output/rpc_progress.go b/cli/output/rpc_progress.go index e6b61a2e1ea..ec47de305a3 100644 --- a/cli/output/rpc_progress.go +++ b/cli/output/rpc_progress.go @@ -20,16 +20,18 @@ package output import ( "fmt" - "github.com/arduino/arduino-cli/cli/globals" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/commands" "github.com/cmaglie/pb" ) +// OutputFormat can be "text" or "json" +var OutputFormat string + // ProgressBar returns a DownloadProgressCB that prints a progress bar. // If JSON output format has been selected, the callback outputs nothing. func ProgressBar() commands.DownloadProgressCB { - if globals.OutputFormat != "json" { + if OutputFormat != "json" { return NewDownloadProgressBarCB() } return func(curr *rpc.DownloadProgress) { @@ -40,7 +42,7 @@ func ProgressBar() commands.DownloadProgressCB { // TaskProgress returns a TaskProgressCB that prints the task progress. // If JSON output format has been selected, the callback outputs nothing. func TaskProgress() commands.TaskProgressCB { - if globals.OutputFormat != "json" { + if OutputFormat != "json" { return NewTaskProgressCB() } return func(curr *rpc.TaskProgress) { diff --git a/cli/version/version.go b/cli/version/version.go index 15c90054b2c..6c083c20ed1 100644 --- a/cli/version/version.go +++ b/cli/version/version.go @@ -38,9 +38,5 @@ func NewCommand() *cobra.Command { } func run(cmd *cobra.Command, args []string) { - if globals.OutputFormat == "json" { - feedback.PrintJSON(globals.VersionInfo) - } else { - feedback.Print(globals.VersionInfo) - } + feedback.Print(globals.VersionInfo) } diff --git a/test/test_lib.py b/test/test_lib.py index a899275a1ad..22f7fbff525 100644 --- a/test/test_lib.py +++ b/test/test_lib.py @@ -19,15 +19,15 @@ def test_list(run_command): # Init the environment explicitly assert run_command("core update-index") - # When ouput is empty, nothing is printed out, no matter the output format + # When output is empty, nothing is printed out, no matter the output format result = run_command("lib list") assert result.ok assert "" == result.stderr - assert "" == result.stdout + assert "No libraries installed." == result.stdout.strip() result = run_command("lib list --format json") assert result.ok assert "" == result.stderr - assert "" == result.stdout + assert "null" == result.stdout # Install something we can list at a version older than latest result = run_command("lib install ArduinoJson@6.11.0") @@ -83,7 +83,7 @@ def test_search(run_command): result = run_command("lib search --names") assert result.ok - out_lines = result.stdout.splitlines() + out_lines = result.stdout.strip().splitlines() # Create an array with just the name of the vars libs = [] for line in out_lines: