Skip to content

Commit 728847c

Browse files
Implementation of CLI 'monitor' command (#1495)
* Implementation of Monitor business logic * Implementation of 'monitor' command of the CLI * fix i18n * Update commands/monitor/monitor.go Co-authored-by: Silvano Cerza <[email protected]> Co-authored-by: Silvano Cerza <[email protected]>
1 parent 73b8aa0 commit 728847c

File tree

5 files changed

+173
-14
lines changed

5 files changed

+173
-14
lines changed

Diff for: cli/monitor/monitor.go

+40-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ package monitor
1717

1818
import (
1919
"context"
20+
"errors"
21+
"io"
2022
"os"
2123
"sort"
2224
"strings"
@@ -78,8 +80,44 @@ func runMonitorCmd(cmd *cobra.Command, args []string) {
7880
return
7981
}
8082

81-
feedback.Error("Monitor functionality not yet implemented")
82-
os.Exit(errorcodes.ErrGeneric)
83+
tty, err := newStdInOutTerminal()
84+
if err != nil {
85+
feedback.Error(err)
86+
os.Exit(errorcodes.ErrGeneric)
87+
}
88+
defer tty.Close()
89+
90+
portProxy, _, err := monitor.Monitor(context.Background(), &rpc.MonitorRequest{
91+
Instance: instance,
92+
Port: port.ToRPC(),
93+
Fqbn: "",
94+
})
95+
if err != nil {
96+
feedback.Error(err)
97+
os.Exit(errorcodes.ErrGeneric)
98+
}
99+
defer portProxy.Close()
100+
101+
ctx, cancel := context.WithCancel(context.Background())
102+
go func() {
103+
_, err := io.Copy(tty, portProxy)
104+
if err != nil && !errors.Is(err, io.EOF) {
105+
feedback.Error(tr("Port closed:"), err)
106+
}
107+
cancel()
108+
}()
109+
go func() {
110+
_, err := io.Copy(portProxy, tty)
111+
if err != nil && !errors.Is(err, io.EOF) {
112+
feedback.Error(tr("Port closed:"), err)
113+
}
114+
cancel()
115+
}()
116+
117+
feedback.Print(tr("Connected to %s! Press CTRL-C to exit.", port.String()))
118+
119+
// Wait for port closed
120+
<-ctx.Done()
83121
}
84122

85123
type detailsResult struct {

Diff for: cli/monitor/term.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2020 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to [email protected].
15+
16+
package monitor
17+
18+
import (
19+
"os"
20+
)
21+
22+
type stdInOut struct {
23+
}
24+
25+
func newStdInOutTerminal() (*stdInOut, error) {
26+
return &stdInOut{}, nil
27+
}
28+
29+
func (n *stdInOut) Close() error {
30+
return nil
31+
}
32+
33+
func (n *stdInOut) Read(buff []byte) (int, error) {
34+
return os.Stdin.Read(buff)
35+
}
36+
37+
func (n *stdInOut) Write(buff []byte) (int, error) {
38+
return os.Stdout.Write(buff)
39+
}

Diff for: commands/monitor/monitor.go

+73
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,85 @@
1616
package monitor
1717

1818
import (
19+
"context"
20+
"io"
21+
1922
"github.com/arduino/arduino-cli/arduino/cores"
2023
"github.com/arduino/arduino-cli/arduino/cores/packagemanager"
24+
pluggableMonitor "github.com/arduino/arduino-cli/arduino/monitor"
2125
"github.com/arduino/arduino-cli/commands"
2226
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2327
)
2428

29+
// PortProxy is an io.ReadWriteCloser that maps into the monitor port of the board
30+
type PortProxy struct {
31+
rw io.ReadWriter
32+
changeSettingsCB func(setting, value string) error
33+
closeCB func() error
34+
}
35+
36+
func (p *PortProxy) Read(buff []byte) (int, error) {
37+
return p.rw.Read(buff)
38+
}
39+
40+
func (p *PortProxy) Write(buff []byte) (int, error) {
41+
return p.rw.Write(buff)
42+
}
43+
44+
// Config sets the port configuration setting to the specified value
45+
func (p *PortProxy) Config(setting, value string) error {
46+
return p.changeSettingsCB(setting, value)
47+
}
48+
49+
// Close the port
50+
func (p *PortProxy) Close() error {
51+
return p.closeCB()
52+
}
53+
54+
// Monitor opens a communication port. It returns a PortProxy to communicate with the port and a PortDescriptor
55+
// that describes the available configuration settings.
56+
func Monitor(ctx context.Context, req *rpc.MonitorRequest) (*PortProxy, *pluggableMonitor.PortDescriptor, error) {
57+
pm := commands.GetPackageManager(req.GetInstance().GetId())
58+
if pm == nil {
59+
return nil, nil, &commands.InvalidInstanceError{}
60+
}
61+
62+
monitorRef, err := findMonitorForProtocolAndBoard(pm, req.GetPort(), req.GetFqbn())
63+
if err != nil {
64+
return nil, nil, err
65+
}
66+
67+
tool := pm.FindMonitorDependency(monitorRef)
68+
if tool == nil {
69+
return nil, nil, &commands.MonitorNotFoundError{Monitor: monitorRef.String()}
70+
}
71+
72+
m := pluggableMonitor.New(monitorRef.Name, tool.InstallDir.Join(monitorRef.Name).String())
73+
74+
if err := m.Run(); err != nil {
75+
return nil, nil, &commands.FailedMonitorError{Cause: err}
76+
}
77+
78+
descriptor, err := m.Describe()
79+
if err != nil {
80+
return nil, nil, &commands.FailedMonitorError{Cause: err}
81+
}
82+
83+
monIO, err := m.Open(req.GetPort())
84+
if err != nil {
85+
return nil, nil, &commands.FailedMonitorError{Cause: err}
86+
}
87+
88+
return &PortProxy{
89+
rw: monIO,
90+
changeSettingsCB: m.Configure(setting, value),
91+
closeCB: func() error {
92+
m.Close()
93+
return m.Quit()
94+
},
95+
}, descriptor, nil
96+
}
97+
2598
func findMonitorForProtocolAndBoard(pm *packagemanager.PackageManager, port *rpc.Port, fqbn string) (*cores.MonitorDependency, error) {
2699
if port == nil {
27100
return nil, &commands.MissingPortError{}

Diff for: i18n/data/en.po

+17-8
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,10 @@ msgstr "Configuring platform."
423423
msgid "Connected"
424424
msgstr "Connected"
425425

426+
#: cli/monitor/monitor.go:117
427+
msgid "Connected to %s! Press CTRL-C to exit."
428+
msgstr "Connected to %s! Press CTRL-C to exit."
429+
426430
#: cli/board/list.go:87
427431
#: cli/board/list.go:125
428432
msgid "Core"
@@ -496,7 +500,7 @@ msgstr "Debugging not supported for board %s"
496500
msgid "Debugging supported:"
497501
msgstr "Debugging supported:"
498502

499-
#: cli/monitor/monitor.go:96
503+
#: cli/monitor/monitor.go:134
500504
msgid "Default"
501505
msgstr "Default"
502506

@@ -782,7 +786,7 @@ msgstr "Error getting information for library %s"
782786
msgid "Error getting libraries info: %v"
783787
msgstr "Error getting libraries info: %v"
784788

785-
#: cli/monitor/monitor.go:74
789+
#: cli/monitor/monitor.go:76
786790
msgid "Error getting port settings details: %s"
787791
msgstr "Error getting port settings details: %s"
788792

@@ -1130,7 +1134,7 @@ msgstr "Global variables use {0} bytes of dynamic memory."
11301134

11311135
#: cli/core/list.go:84
11321136
#: cli/core/search.go:114
1133-
#: cli/monitor/monitor.go:96
1137+
#: cli/monitor/monitor.go:134
11341138
#: cli/outdated/outdated.go:62
11351139
msgid "ID"
11361140
msgstr "ID"
@@ -1568,8 +1572,8 @@ msgstr "OS:"
15681572
msgid "Official Arduino board:"
15691573
msgstr "Official Arduino board:"
15701574

1571-
#: cli/monitor/monitor.go:45
1572-
#: cli/monitor/monitor.go:46
1575+
#: cli/monitor/monitor.go:47
1576+
#: cli/monitor/monitor.go:48
15731577
msgid "Open a communication port with a board."
15741578
msgstr "Open a communication port with a board."
15751579

@@ -1719,6 +1723,11 @@ msgstr "Platform size (bytes):"
17191723
msgid "Port"
17201724
msgstr "Port"
17211725

1726+
#: cli/monitor/monitor.go:105
1727+
#: cli/monitor/monitor.go:112
1728+
msgid "Port closed:"
1729+
msgstr "Port closed:"
1730+
17221731
#: commands/errors.go:508
17231732
msgid "Port monitor error"
17241733
msgstr "Port monitor error"
@@ -1852,7 +1861,7 @@ msgstr "Sets a setting value."
18521861
msgid "Sets where to save the configuration file."
18531862
msgstr "Sets where to save the configuration file."
18541863

1855-
#: cli/monitor/monitor.go:96
1864+
#: cli/monitor/monitor.go:134
18561865
msgid "Setting"
18571866
msgstr "Setting"
18581867

@@ -1869,7 +1878,7 @@ msgstr "Show all available core versions."
18691878
msgid "Show all build properties used instead of compiling."
18701879
msgstr "Show all build properties used instead of compiling."
18711880

1872-
#: cli/monitor/monitor.go:53
1881+
#: cli/monitor/monitor.go:55
18731882
msgid "Show all the settings of the communication port."
18741883
msgstr "Show all the settings of the communication port."
18751884

@@ -2327,7 +2336,7 @@ msgstr "VERSION"
23272336
msgid "VERSION_NUMBER"
23282337
msgstr "VERSION_NUMBER"
23292338

2330-
#: cli/monitor/monitor.go:96
2339+
#: cli/monitor/monitor.go:134
23312340
msgid "Values"
23322341
msgstr "Values"
23332342

Diff for: i18n/rice-box.go

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)