From 048415c5e6334f8435ffc4216df0b03e306c3e35 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 31 Aug 2023 12:49:05 +0200 Subject: [PATCH 1/2] Upload port detector improvements (#2288) * If the upload port-detector fails detection, fallback to the user-provided port This will ensure that a port is always returned. * Increased debug level * Extend timeout if candidate port is lost in any case Even if `waitForUploadPort` is true, we should extend the timeout to allow USB enumeration to complete. In this case we extend by only 1 second instead of 5. * Revert "Extend timeout if candidate port is lost in any case" This reverts commit 7c77ed242383e416ff8748884a64474f73932911. The latest commit is not necessary since the detector has already 5 seconds of timeout. --- commands/upload/upload.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/commands/upload/upload.go b/commands/upload/upload.go index 75f8aae9238..5fe21089848 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -514,7 +514,8 @@ func runProgramAction(pme *packagemanager.Explorer, updatedPort := updatedUploadPort.Await() if updatedPort == nil { - return nil, nil + // If the algorithms can not detect the new port, fallback to the user-provided port. + return userPort, nil } return updatedPort.ToRPC(), nil } @@ -526,7 +527,7 @@ func detectUploadPort( result f.Future[*discovery.Port], ) { log := logrus.WithField("task", "port_detection") - log.Tracef("Detecting new board port after upload") + log.Debugf("Detecting new board port after upload") candidate := uploadPort.Clone() defer func() { @@ -542,11 +543,11 @@ func detectUploadPort( return } if candidate != nil && ev.Type == "remove" && ev.Port.Equals(candidate) { - log.WithField("event", ev).Trace("User-specified port has been disconnected, forcing wait for upload port") + log.WithField("event", ev).Debug("User-specified port has been disconnected, forcing wait for upload port") waitForUploadPort = true candidate = nil } else { - log.WithField("event", ev).Trace("Ignored watcher event before upload") + log.WithField("event", ev).Debug("Ignored watcher event before upload") } continue case <-uploadCtx.Done(): @@ -568,17 +569,17 @@ func detectUploadPort( return } if candidate != nil && ev.Type == "remove" && candidate.Equals(ev.Port) { - log.WithField("event", ev).Trace("Candidate port is no longer available") + log.WithField("event", ev).Debug("Candidate port is no longer available") candidate = nil if !waitForUploadPort { waitForUploadPort = true timeout = time.After(5 * time.Second) - log.Trace("User-specified port has been disconnected, now waiting for upload port, timeout extended by 5 seconds") + log.Debug("User-specified port has been disconnected, now waiting for upload port, timeout extended by 5 seconds") } continue } if ev.Type != "add" { - log.WithField("event", ev).Trace("Ignored non-add event") + log.WithField("event", ev).Debug("Ignored non-add event") continue } @@ -601,21 +602,21 @@ func detectUploadPort( evPortPriority := portPriority(ev.Port) candidatePriority := portPriority(candidate) if evPortPriority <= candidatePriority { - log.WithField("event", ev).Tracef("New upload port candidate is worse than the current one (prio=%d)", evPortPriority) + log.WithField("event", ev).Debugf("New upload port candidate is worse than the current one (prio=%d)", evPortPriority) continue } - log.WithField("event", ev).Tracef("Found new upload port candidate (prio=%d)", evPortPriority) + log.WithField("event", ev).Debugf("Found new upload port candidate (prio=%d)", evPortPriority) candidate = ev.Port // If the current candidate have the desired HW-ID return it quickly. if candidate.HardwareID == ev.Port.HardwareID { timeout = time.After(time.Second) - log.Trace("New candidate port match the desired HW ID, timeout reduced to 1 second.") + log.Debug("New candidate port match the desired HW ID, timeout reduced to 1 second.") continue } case <-timeout: - log.WithField("selected_port", candidate).Trace("Timeout waiting for candidate port") + log.WithField("selected_port", candidate).Debug("Timeout waiting for candidate port") return } } From 590b9df98e0fab1100638ed66119fbd5477208fe Mon Sep 17 00:00:00 2001 From: ardnew Date: Sat, 9 Sep 2023 23:11:34 -0500 Subject: [PATCH 2/2] add "config get" command to print settings values --- internal/cli/config/config.go | 1 + internal/cli/config/get.go | 88 +++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 internal/cli/config/get.go diff --git a/internal/cli/config/config.go b/internal/cli/config/config.go index ee0e8922852..f4c62b8e4f7 100644 --- a/internal/cli/config/config.go +++ b/internal/cli/config/config.go @@ -37,6 +37,7 @@ func NewCommand() *cobra.Command { configCommand.AddCommand(initAddCommand()) configCommand.AddCommand(initDeleteCommand()) configCommand.AddCommand(initDumpCommand()) + configCommand.AddCommand(initGetCommand()) configCommand.AddCommand(initInitCommand()) configCommand.AddCommand(initRemoveCommand()) configCommand.AddCommand(initSetCommand()) diff --git a/internal/cli/config/get.go b/internal/cli/config/get.go new file mode 100644 index 00000000000..e9cc9ba497d --- /dev/null +++ b/internal/cli/config/get.go @@ -0,0 +1,88 @@ +// This file is part of arduino-cli. +// +// Copyright 2020 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package config + +import ( + "os" + "reflect" + + "github.com/arduino/arduino-cli/configuration" + "github.com/arduino/arduino-cli/internal/cli/feedback" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "gopkg.in/yaml.v2" +) + +func initGetCommand() *cobra.Command { + getCommand := &cobra.Command{ + Use: "get", + Short: tr("Gets a setting value."), + Long: tr("Gets a setting value."), + Example: "" + + " " + os.Args[0] + " config get logging.level\n" + + " " + os.Args[0] + " config get logging.file\n" + + " " + os.Args[0] + " config get sketch.always_export_binaries\n" + + " " + os.Args[0] + " config get board_manager.additional_urls", + Args: cobra.MinimumNArgs(1), + Run: runGetCommand, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return configuration.Settings.AllKeys(), cobra.ShellCompDirectiveDefault + }, + } + return getCommand +} + +func runGetCommand(cmd *cobra.Command, args []string) { + logrus.Info("Executing `arduino-cli config get`") + key := args[0] + kind := validateKey(key) + + if kind != reflect.Slice && len(args) > 1 { + feedback.Fatal(tr("Can't get multiple key values"), feedback.ErrGeneric) + } + + var value interface{} + switch kind { + case reflect.Slice: + value = configuration.Settings.GetStringSlice(key) + case reflect.String: + value = configuration.Settings.GetString(key) + case reflect.Bool: + value = configuration.Settings.GetBool(key) + } + + feedback.PrintResult(getResult{value}) +} + +// output from this command may require special formatting. +// create a dedicated feedback.Result implementation to safely handle +// any changes to the configuration.Settings struct. +type getResult struct { + data interface{} +} + +func (gr getResult) Data() interface{} { + return gr.data +} + +func (gr getResult) String() string { + gs, err := yaml.Marshal(gr.data) + if err != nil { + // Should never happen + panic(tr("unable to marshal config to YAML: %v", err)) + } + return string(gs) +}