Unverified Commit 6ebfb1dc authored by Zach Vonler's avatar Zach Vonler Committed by GitHub

Added `--timestamp` option to monitor command. (#2336)

parent 8b36949f
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"os" "os"
"sort" "sort"
"strings" "strings"
"time"
"github.com/arduino/arduino-cli/commands/monitor" "github.com/arduino/arduino-cli/commands/monitor"
"github.com/arduino/arduino-cli/configuration" "github.com/arduino/arduino-cli/configuration"
...@@ -49,6 +50,7 @@ func NewCommand() *cobra.Command { ...@@ -49,6 +50,7 @@ func NewCommand() *cobra.Command {
describe bool describe bool
configs []string configs []string
quiet bool quiet bool
timestamp bool
fqbn arguments.Fqbn fqbn arguments.Fqbn
) )
monitorCommand := &cobra.Command{ monitorCommand := &cobra.Command{
...@@ -59,7 +61,7 @@ func NewCommand() *cobra.Command { ...@@ -59,7 +61,7 @@ func NewCommand() *cobra.Command {
" " + os.Args[0] + " monitor -p /dev/ttyACM0\n" + " " + os.Args[0] + " monitor -p /dev/ttyACM0\n" +
" " + os.Args[0] + " monitor -p /dev/ttyACM0 --describe", " " + os.Args[0] + " monitor -p /dev/ttyACM0 --describe",
Run: func(cmd *cobra.Command, args []string) { 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) portArgs.AddToCommand(monitorCommand)
...@@ -67,12 +69,13 @@ func NewCommand() *cobra.Command { ...@@ -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().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 <ID>=<value>[,<ID>=<value>]...")) monitorCommand.Flags().StringSliceVarP(&configs, "config", "c", []string{}, tr("Configure communication port settings. The format is <ID>=<value>[,<ID>=<value>]..."))
monitorCommand.Flags().BoolVarP(&quiet, "quiet", "q", false, tr("Run in silent mode, show only monitor input and output.")) monitorCommand.Flags().BoolVarP(&quiet, "quiet", "q", false, tr("Run in silent mode, show only monitor input and output."))
monitorCommand.Flags().BoolVar(&timestamp, "timestamp", false, tr("Timestamp each incoming line."))
fqbn.AddToCommand(monitorCommand) fqbn.AddToCommand(monitorCommand)
monitorCommand.MarkFlagRequired("port") monitorCommand.MarkFlagRequired("port")
return monitorCommand 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() instance := instance.CreateAndInit()
logrus.Info("Executing `arduino-cli monitor`") logrus.Info("Executing `arduino-cli monitor`")
...@@ -160,6 +163,10 @@ func runMonitorCmd(portArgs *arguments.Port, fqbn *arguments.Fqbn, configs []str ...@@ -160,6 +163,10 @@ func runMonitorCmd(portArgs *arguments.Port, fqbn *arguments.Fqbn, configs []str
feedback.FatalError(err, feedback.ErrGeneric) feedback.FatalError(err, feedback.ErrGeneric)
} }
if timestamp {
ttyOut = newTimeStampWriter(ttyOut)
}
ctx, cancel := cleanup.InterruptableContext(context.Background()) ctx, cancel := cleanup.InterruptableContext(context.Background())
if raw { if raw {
feedback.SetRawModeStdin() feedback.SetRawModeStdin()
...@@ -241,3 +248,35 @@ func contains(s []string, searchterm string) bool { ...@@ -241,3 +248,35 @@ func contains(s []string, searchterm string) bool {
} }
return false 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
}
// 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)
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment