From 18aada402e36e5e4c5440e32de16ab56808ec568 Mon Sep 17 00:00:00 2001 From: Zachary Vonler Date: Fri, 22 Sep 2023 12:06:24 -0500 Subject: [PATCH 1/3] Added --timestamp option to monitor command to fix #2316. --- internal/cli/monitor/monitor.go | 55 ++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index 65b5c599a76..45b4895145c 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -24,6 +24,7 @@ import ( "os" "sort" "strings" + "time" "github.com/arduino/arduino-cli/commands/monitor" "github.com/arduino/arduino-cli/configuration" @@ -44,12 +45,13 @@ var tr = i18n.Tr // NewCommand created a new `monitor` command func NewCommand() *cobra.Command { var ( - raw bool - portArgs arguments.Port - describe bool - configs []string - quiet bool - fqbn arguments.Fqbn + raw bool + portArgs arguments.Port + describe bool + configs []string + quiet bool + timestamp bool + fqbn arguments.Fqbn ) monitorCommand := &cobra.Command{ Use: "monitor", @@ -59,7 +61,7 @@ func NewCommand() *cobra.Command { " " + os.Args[0] + " monitor -p /dev/ttyACM0\n" + " " + os.Args[0] + " monitor -p /dev/ttyACM0 --describe", Run: func(cmd *cobra.Command, args []string) { - runMonitorCmd(&portArgs, &fqbn, configs, describe, quiet, raw) + runMonitorCmd(&portArgs, &fqbn, configs, describe, timestamp, quiet, raw) }, } portArgs.AddToCommand(monitorCommand) @@ -67,12 +69,13 @@ func NewCommand() *cobra.Command { monitorCommand.Flags().BoolVar(&describe, "describe", false, tr("Show all the settings of the communication port.")) monitorCommand.Flags().StringSliceVarP(&configs, "config", "c", []string{}, tr("Configure communication port settings. The format is =[,=]...")) monitorCommand.Flags().BoolVarP(&quiet, "quiet", "q", false, tr("Run in silent mode, show only monitor input and output.")) + monitorCommand.Flags().BoolVar(×tamp, "timestamp", false, tr("Timestamp each incoming line.")) fqbn.AddToCommand(monitorCommand) monitorCommand.MarkFlagRequired("port") return monitorCommand } -func runMonitorCmd(portArgs *arguments.Port, fqbn *arguments.Fqbn, configs []string, describe, quiet, raw bool) { +func runMonitorCmd(portArgs *arguments.Port, fqbn *arguments.Fqbn, configs []string, describe, timestamp, quiet, raw bool) { instance := instance.CreateAndInit() logrus.Info("Executing `arduino-cli monitor`") @@ -160,6 +163,10 @@ func runMonitorCmd(portArgs *arguments.Port, fqbn *arguments.Fqbn, configs []str feedback.FatalError(err, feedback.ErrGeneric) } + if timestamp { + ttyOut = newTimeStampWriter(ttyOut) + } + ctx, cancel := cleanup.InterruptableContext(context.Background()) if raw { feedback.SetRawModeStdin() @@ -241,3 +248,35 @@ func contains(s []string, searchterm string) bool { } return false } + +type timeStampWriter struct { + writer io.Writer + sendTimeStampNext bool +} + +func newTimeStampWriter(writer io.Writer) *timeStampWriter { + return &timeStampWriter{ + writer: writer, + sendTimeStampNext: true, + } +} + +func (t *timeStampWriter) Write(p []byte) (int, error) { + written := 0 + for _, b := range p { + if (t.sendTimeStampNext) { + _, err := t.writer.Write([]byte(time.Now().Format("[2006-01-02 15:04:05] "))) + if err != nil { + return written, err + } + t.sendTimeStampNext = false; + } + n, err := t.writer.Write([]byte{b}) + written += n + if err != nil { + return written, err + } + t.sendTimeStampNext = b == '\n'; + } + return written, nil +} From a30a15899a566f848fce89699fd5129f7a95f316 Mon Sep 17 00:00:00 2001 From: Zachary Vonler Date: Fri, 22 Sep 2023 17:45:34 -0500 Subject: [PATCH 2/3] Added test and fixed formatting. --- internal/cli/monitor/monitor.go | 12 ++++----- internal/cli/monitor/monitor_test.go | 37 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 internal/cli/monitor/monitor_test.go diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index 45b4895145c..b15cd5bb436 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -24,7 +24,7 @@ import ( "os" "sort" "strings" - "time" + "time" "github.com/arduino/arduino-cli/commands/monitor" "github.com/arduino/arduino-cli/configuration" @@ -250,13 +250,13 @@ func contains(s []string, searchterm string) bool { } type timeStampWriter struct { - writer io.Writer + writer io.Writer sendTimeStampNext bool } func newTimeStampWriter(writer io.Writer) *timeStampWriter { return &timeStampWriter{ - writer: writer, + writer: writer, sendTimeStampNext: true, } } @@ -264,19 +264,19 @@ func newTimeStampWriter(writer io.Writer) *timeStampWriter { func (t *timeStampWriter) Write(p []byte) (int, error) { written := 0 for _, b := range p { - if (t.sendTimeStampNext) { + if t.sendTimeStampNext { _, err := t.writer.Write([]byte(time.Now().Format("[2006-01-02 15:04:05] "))) if err != nil { return written, err } - t.sendTimeStampNext = false; + t.sendTimeStampNext = false } n, err := t.writer.Write([]byte{b}) written += n if err != nil { return written, err } - t.sendTimeStampNext = b == '\n'; + t.sendTimeStampNext = b == '\n' } return written, nil } diff --git a/internal/cli/monitor/monitor_test.go b/internal/cli/monitor/monitor_test.go new file mode 100644 index 00000000000..818c4ee41d1 --- /dev/null +++ b/internal/cli/monitor/monitor_test.go @@ -0,0 +1,37 @@ +// This file is part of arduino-cli. +// +// Copyright 2023 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 monitor + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestTimeStampWriter(t *testing.T) { + buf := &bytes.Buffer{} + writer := newTimeStampWriter(buf) + + writer.Write([]byte("foo")) + // The first received bytes get a timestamp prepended + require.Regexp(t, `^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] foo$`, buf) + + buf.Reset() + writer.Write([]byte("\nbar\n")) + // A timestamp should be inserted before the first char of the next line + require.Regexp(t, "^\n"+`\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] bar` + "\n$", buf) +} From a664c2db410a1c95edbd9cbd2943efd43bfd64b7 Mon Sep 17 00:00:00 2001 From: Zachary Vonler Date: Fri, 22 Sep 2023 18:44:42 -0500 Subject: [PATCH 3/3] One more format change. --- internal/cli/monitor/monitor_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cli/monitor/monitor_test.go b/internal/cli/monitor/monitor_test.go index 818c4ee41d1..7909e2a3365 100644 --- a/internal/cli/monitor/monitor_test.go +++ b/internal/cli/monitor/monitor_test.go @@ -33,5 +33,5 @@ func TestTimeStampWriter(t *testing.T) { buf.Reset() writer.Write([]byte("\nbar\n")) // A timestamp should be inserted before the first char of the next line - require.Regexp(t, "^\n"+`\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] bar` + "\n$", buf) + require.Regexp(t, "^\n"+`\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] bar`+"\n$", buf) }