Skip to content

Commit dbdc1ef

Browse files
committed
Add generic Port argument
1 parent 4404dc3 commit dbdc1ef

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

cli/arguments/port.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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 license@arduino.cc.
15+
16+
package arguments
17+
18+
import (
19+
"fmt"
20+
"net/url"
21+
22+
"github.com/arduino/arduino-cli/arduino/discovery"
23+
"github.com/arduino/arduino-cli/arduino/sketch"
24+
"github.com/arduino/arduino-cli/commands"
25+
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
26+
"github.com/pkg/errors"
27+
"github.com/sirupsen/logrus"
28+
"github.com/spf13/cobra"
29+
)
30+
31+
// Port contains the port arguments result.
32+
// This is useful so all flags used by commands that need
33+
// this information are consistent with each other.
34+
type Port struct {
35+
address string
36+
protocol string
37+
}
38+
39+
// AddToCommand adds the flags used to set port and protocol to the specified Command
40+
func (p *Port) AddToCommand(cmd *cobra.Command) {
41+
cmd.Flags().StringVarP(&p.address, "port", "p", "", "Upload port address, e.g.: COM3 or /dev/ttyACM2")
42+
cmd.Flags().StringVarP(&p.protocol, "protocol", "l", "", "Upload port protocol, e.g: serial")
43+
}
44+
45+
// GetPort returns the Port obtained by parsing command line arguments.
46+
// The extra metadata for the ports is obtained using the pluggable discoveries.
47+
func (p *Port) GetPort(instance *rpc.Instance, sk *sketch.Sketch) (*discovery.Port, error) {
48+
address := p.address
49+
protocol := p.protocol
50+
if address != "" && protocol != "" {
51+
return &discovery.Port{
52+
Address: address,
53+
Protocol: protocol,
54+
}, nil
55+
}
56+
57+
if address == "" && sk != nil && sk.Metadata != nil {
58+
deviceURI, err := url.Parse(sk.Metadata.CPU.Port)
59+
if err != nil {
60+
return nil, errors.Errorf("invalid Device URL format: %s", err)
61+
}
62+
if deviceURI.Scheme == "serial" {
63+
address = deviceURI.Host + deviceURI.Path
64+
}
65+
}
66+
if address == "" {
67+
return nil, nil
68+
}
69+
logrus.WithField("port", address).Tracef("Upload port")
70+
71+
pm := commands.GetPackageManager(instance.Id)
72+
if pm == nil {
73+
return nil, errors.New("invalid instance")
74+
}
75+
76+
if err := pm.DiscoveryManager().RunAll(); err != nil {
77+
return nil, err
78+
}
79+
if err := pm.DiscoveryManager().StartAll(); err != nil {
80+
return nil, err
81+
}
82+
83+
defer func() {
84+
// Quit all discoveries at the end.
85+
err := pm.DiscoveryManager().QuitAll()
86+
if err != nil {
87+
logrus.Errorf("quitting discoveries when getting port metadata: %s", err)
88+
}
89+
}()
90+
91+
ports := pm.DiscoveryManager().List()
92+
93+
matchingPorts := []*discovery.Port{}
94+
for _, port := range ports {
95+
if address == port.Address {
96+
matchingPorts = append(matchingPorts, port)
97+
if len(matchingPorts) > 1 {
98+
// Too many matching ports found, can't handle this case.
99+
// This must never happen.
100+
return nil, fmt.Errorf("multiple ports found matching address %s", address)
101+
}
102+
}
103+
}
104+
105+
if len(matchingPorts) == 1 {
106+
// Only one matching port found, use it
107+
return matchingPorts[0], nil
108+
}
109+
110+
// In case no matching port is found assume the address refers to a serial port
111+
return &discovery.Port{
112+
Address: address,
113+
Protocol: "serial",
114+
}, nil
115+
}

0 commit comments

Comments
 (0)