Skip to content

Commit 6bb9425

Browse files
committed
Porting attach command(WIP)
1 parent 6f90002 commit 6bb9425

File tree

9 files changed

+455
-238
lines changed

9 files changed

+455
-238
lines changed

arduino/sketches/sketches.go

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func NewSketchFromPath(path *paths.Path) (*Sketch, error) {
6969
sketch := &Sketch{
7070
FullPath: path,
7171
Name: path.Base(),
72+
Metadata: &Metadata{},
7273
}
7374
sketch.ImportMetadata()
7475
return sketch, nil

cli/board/attach.go

+14-132
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,13 @@
1818
package board
1919

2020
import (
21-
"fmt"
22-
"net/url"
21+
"context"
2322
"os"
24-
"strings"
25-
"time"
2623

27-
"github.com/arduino/arduino-cli/arduino/cores"
28-
"github.com/arduino/arduino-cli/arduino/cores/packagemanager"
29-
"github.com/arduino/arduino-cli/arduino/sketches"
3024
"github.com/arduino/arduino-cli/cli"
25+
"github.com/arduino/arduino-cli/commands/board"
3126
"github.com/arduino/arduino-cli/common/formatter"
32-
discovery "github.com/arduino/board-discovery"
33-
paths "github.com/arduino/go-paths-helper"
34-
"github.com/sirupsen/logrus"
27+
"github.com/arduino/arduino-cli/rpc"
3528
"github.com/spf13/cobra"
3629
)
3730

@@ -59,131 +52,20 @@ var attachFlags struct {
5952
}
6053

6154
func runAttachCommand(cmd *cobra.Command, args []string) {
62-
boardURI := args[0]
63-
64-
var path *paths.Path
55+
instance := cli.CreateInstance()
56+
var path string
6557
if len(args) > 0 {
66-
path = paths.New(args[0])
58+
path = args[1]
6759
}
68-
sketchPath := cli.InitSketchPath(path)
69-
70-
sketch, err := sketches.NewSketchFromPath(sketchPath)
60+
_, err := board.BoardAttach(context.Background(), &rpc.BoardAttachReq{
61+
Instance: instance,
62+
BoardURI: args[0],
63+
SketchPath: path,
64+
BoardFlavour: attachFlags.boardFlavour,
65+
SearchTimeout: attachFlags.searchTimeout,
66+
})
7167
if err != nil {
72-
formatter.PrintError(err, "Error opening sketch.")
68+
formatter.PrintError(err, "attach board error")
7369
os.Exit(cli.ErrGeneric)
7470
}
75-
76-
logrus.WithField("fqbn", boardURI).Print("Parsing FQBN")
77-
fqbn, err := cores.ParseFQBN(boardURI)
78-
if err != nil && !strings.HasPrefix(boardURI, "serial") {
79-
boardURI = "serial://" + boardURI
80-
}
81-
82-
pm, _ := cli.InitPackageAndLibraryManager()
83-
84-
if fqbn != nil {
85-
sketch.Metadata.CPU = sketches.BoardMetadata{
86-
Fqbn: fqbn.String(),
87-
}
88-
} else {
89-
deviceURI, err := url.Parse(boardURI)
90-
if err != nil {
91-
formatter.PrintError(err, "The provided Device URL is not in a valid format.")
92-
os.Exit(cli.ErrBadCall)
93-
}
94-
95-
var findBoardFunc func(*packagemanager.PackageManager, *discovery.Monitor, *url.URL) *cores.Board
96-
switch deviceURI.Scheme {
97-
case "serial", "tty":
98-
findBoardFunc = findSerialConnectedBoard
99-
case "http", "https", "tcp", "udp":
100-
findBoardFunc = findNetworkConnectedBoard
101-
default:
102-
formatter.PrintErrorMessage("Invalid device port type provided. Accepted types are: serial://, tty://, http://, https://, tcp://, udp://.")
103-
os.Exit(cli.ErrBadCall)
104-
}
105-
106-
duration, err := time.ParseDuration(attachFlags.searchTimeout)
107-
if err != nil {
108-
logrus.WithError(err).Warnf("Invalid interval `%s` provided, using default (5s).", attachFlags.searchTimeout)
109-
duration = time.Second * 5
110-
}
111-
112-
monitor := discovery.New(time.Second)
113-
monitor.Start()
114-
115-
time.Sleep(duration)
116-
117-
// TODO: Handle the case when no board is found.
118-
board := findBoardFunc(pm, monitor, deviceURI)
119-
if board == nil {
120-
formatter.PrintErrorMessage("No supported board has been found at " + deviceURI.String() + ", try either install new cores or check your board URI.")
121-
os.Exit(cli.ErrGeneric)
122-
}
123-
formatter.Print("Board found: " + board.Name())
124-
125-
sketch.Metadata.CPU = sketches.BoardMetadata{
126-
Fqbn: board.FQBN(),
127-
Name: board.Name(),
128-
}
129-
}
130-
131-
err = sketch.ExportMetadata()
132-
if err != nil {
133-
formatter.PrintError(err, "Cannot export sketch metadata.")
134-
}
135-
formatter.PrintResult("Selected fqbn: " + sketch.Metadata.CPU.Fqbn)
136-
}
137-
138-
// FIXME: Those should probably go in a "BoardManager" pkg or something
139-
// findSerialConnectedBoard find the board which is connected to the specified URI via serial port, using a monitor and a set of Boards
140-
// for the matching.
141-
func findSerialConnectedBoard(pm *packagemanager.PackageManager, monitor *discovery.Monitor, deviceURI *url.URL) *cores.Board {
142-
found := false
143-
location := deviceURI.Path
144-
var serialDevice discovery.SerialDevice
145-
for _, device := range monitor.Serial() {
146-
if device.Port == location {
147-
// Found the device !
148-
found = true
149-
serialDevice = *device
150-
}
151-
}
152-
if !found {
153-
return nil
154-
}
155-
156-
boards := pm.FindBoardsWithVidPid(serialDevice.VendorID, serialDevice.ProductID)
157-
if len(boards) == 0 {
158-
os.Exit(cli.ErrGeneric)
159-
}
160-
161-
return boards[0]
162-
}
163-
164-
// findNetworkConnectedBoard find the board which is connected to the specified URI on the network, using a monitor and a set of Boards
165-
// for the matching.
166-
func findNetworkConnectedBoard(pm *packagemanager.PackageManager, monitor *discovery.Monitor, deviceURI *url.URL) *cores.Board {
167-
found := false
168-
169-
var networkDevice discovery.NetworkDevice
170-
171-
for _, device := range monitor.Network() {
172-
if device.Address == deviceURI.Host &&
173-
fmt.Sprint(device.Port) == deviceURI.Port() {
174-
// Found the device !
175-
found = true
176-
networkDevice = *device
177-
}
178-
}
179-
if !found {
180-
return nil
181-
}
182-
183-
boards := pm.FindBoardsWithID(networkDevice.Name)
184-
if len(boards) == 0 {
185-
return nil
186-
}
187-
188-
return boards[0]
18971
}

commands/board/attach.go

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/*
2+
* This file is part of arduino-cli.
3+
*
4+
* Copyright 2018 ARDUINO SA (http://www.arduino.cc/)
5+
*
6+
* This software is released under the GNU General Public License version 3,
7+
* which covers the main part of arduino-cli.
8+
* The terms of this license can be found at:
9+
* https://www.gnu.org/licenses/gpl-3.0.en.html
10+
*
11+
* You can be released from the requirements of the above licenses by purchasing
12+
* a commercial license. Buying such a license is mandatory if you want to modify or
13+
* otherwise use the software for commercial activities involving the Arduino
14+
* software without disclosing the source code of your own applications. To purchase
15+
* a commercial license, send an email to license@arduino.cc.
16+
*/
17+
18+
package board
19+
20+
import (
21+
"context"
22+
"errors"
23+
"fmt"
24+
"net/url"
25+
"strings"
26+
"time"
27+
28+
"github.com/arduino/arduino-cli/arduino/cores"
29+
"github.com/arduino/arduino-cli/arduino/cores/packagemanager"
30+
"github.com/arduino/arduino-cli/arduino/sketches"
31+
"github.com/arduino/arduino-cli/commands"
32+
"github.com/arduino/arduino-cli/common/formatter"
33+
"github.com/arduino/arduino-cli/rpc"
34+
discovery "github.com/arduino/board-discovery"
35+
paths "github.com/arduino/go-paths-helper"
36+
)
37+
38+
func BoardAttach(ctx context.Context, req *rpc.BoardAttachReq) (*rpc.BoardAttachResp, error) {
39+
40+
pm := commands.GetPackageManager(req)
41+
if pm == nil {
42+
return nil, errors.New("invalid instance")
43+
}
44+
var sketchPath *paths.Path
45+
if req.GetSketchPath() != "" {
46+
sketchPath = paths.New(req.GetSketchPath())
47+
}
48+
sketch, err := sketches.NewSketchFromPath(sketchPath)
49+
if err != nil {
50+
return nil, fmt.Errorf("opening sketch: %s", err)
51+
}
52+
if sketch.Metadata == nil {
53+
formatter.Print("sketch errrorrrerereererer")
54+
}
55+
boardURI := req.GetBoardURI()
56+
fqbn, err := cores.ParseFQBN(boardURI)
57+
if err != nil && !strings.HasPrefix(boardURI, "serial") {
58+
boardURI = "serial://" + boardURI
59+
}
60+
61+
if fqbn != nil {
62+
sketch.Metadata.CPU = sketches.BoardMetadata{
63+
Fqbn: fqbn.String(),
64+
}
65+
} else {
66+
deviceURI, err := url.Parse(boardURI)
67+
if err != nil {
68+
return nil, fmt.Errorf("invalid Device URL format: %s", err)
69+
}
70+
71+
var findBoardFunc func(*packagemanager.PackageManager, *discovery.Monitor, *url.URL) *cores.Board
72+
switch deviceURI.Scheme {
73+
case "serial", "tty":
74+
findBoardFunc = findSerialConnectedBoard
75+
case "http", "https", "tcp", "udp":
76+
findBoardFunc = findNetworkConnectedBoard
77+
default:
78+
return nil, fmt.Errorf("invalid device port type provided")
79+
}
80+
81+
duration, err := time.ParseDuration(req.GetSearchTimeout())
82+
if err != nil {
83+
//logrus.WithError(err).Warnf("Invalid interval `%s` provided, using default (5s).", req.GetSearchTimeout())
84+
duration = time.Second * 5
85+
}
86+
87+
monitor := discovery.New(time.Second)
88+
monitor.Start()
89+
90+
time.Sleep(duration)
91+
92+
// TODO: Handle the case when no board is found.
93+
board := findBoardFunc(pm, monitor, deviceURI)
94+
if board == nil {
95+
return nil, fmt.Errorf("no supported board found at %s", deviceURI.String())
96+
}
97+
formatter.Print("Board found: " + board.Name())
98+
99+
sketch.Metadata.CPU = sketches.BoardMetadata{
100+
Fqbn: board.FQBN(),
101+
Name: board.Name(),
102+
}
103+
}
104+
105+
err = sketch.ExportMetadata()
106+
if err != nil {
107+
return nil, fmt.Errorf("cannot export sketch metadata: %s", err)
108+
}
109+
formatter.PrintResult("Selected fqbn: " + sketch.Metadata.CPU.Fqbn)
110+
return &rpc.BoardAttachResp{}, nil
111+
}
112+
113+
// FIXME: Those should probably go in a "BoardManager" pkg or something
114+
// findSerialConnectedBoard find the board which is connected to the specified URI via serial port, using a monitor and a set of Boards
115+
// for the matching.
116+
func findSerialConnectedBoard(pm *packagemanager.PackageManager, monitor *discovery.Monitor, deviceURI *url.URL) *cores.Board {
117+
found := false
118+
location := deviceURI.Path
119+
var serialDevice discovery.SerialDevice
120+
for _, device := range monitor.Serial() {
121+
if device.Port == location {
122+
// Found the device !
123+
found = true
124+
serialDevice = *device
125+
}
126+
}
127+
if !found {
128+
return nil
129+
}
130+
131+
boards := pm.FindBoardsWithVidPid(serialDevice.VendorID, serialDevice.ProductID)
132+
if len(boards) == 0 {
133+
return nil
134+
}
135+
136+
return boards[0]
137+
}
138+
139+
// findNetworkConnectedBoard find the board which is connected to the specified URI on the network, using a monitor and a set of Boards
140+
// for the matching.
141+
func findNetworkConnectedBoard(pm *packagemanager.PackageManager, monitor *discovery.Monitor, deviceURI *url.URL) *cores.Board {
142+
found := false
143+
144+
var networkDevice discovery.NetworkDevice
145+
146+
for _, device := range monitor.Network() {
147+
if device.Address == deviceURI.Host &&
148+
fmt.Sprint(device.Port) == deviceURI.Port() {
149+
// Found the device !
150+
found = true
151+
networkDevice = *device
152+
}
153+
}
154+
if !found {
155+
return nil
156+
}
157+
158+
boards := pm.FindBoardsWithID(networkDevice.Name)
159+
if len(boards) == 0 {
160+
return nil
161+
}
162+
163+
return boards[0]
164+
}

daemon/client/client.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ func main() {
8585
}
8686

8787
// PLATFORM SEARCH
88-
fmt.Println("=== calling PlatformSearch(uno)")
88+
fmt.Println("=== calling PlatformSearch(samd)")
8989
searchResp, err := client.PlatformSearch(context.Background(), &rpc.PlatformSearchReq{
9090
Instance: instance,
91-
SearchArgs: "uno",
91+
SearchArgs: "samd",
9292
})
9393
if err != nil {
9494
fmt.Printf("Search error: %s\n", err)
@@ -194,6 +194,18 @@ func main() {
194194
fmt.Printf("---> %+v\n", details)
195195
fmt.Println()
196196

197+
// BOARDS ATTACH
198+
fmt.Println("=== calling BoardAttach(serial:///dev/ttyACM0)")
199+
_, err = client.BoardAttach(context.Background(), &rpc.BoardAttachReq{
200+
Instance: instance,
201+
BoardURI: "serial:///dev/ttyACM0",
202+
SketchPath: "/home/riccardo/Arduino/MyFirstSketch",
203+
})
204+
if err != nil {
205+
fmt.Printf("attach error : %s\n", err)
206+
os.Exit(1)
207+
}
208+
197209
// COMPILE
198210
fmt.Println("=== calling Compile(arduino:samd:mkr1000, VERBOSE, " + os.Args[2] + ")")
199211
compRespStream, err := client.Compile(context.Background(), &rpc.CompileReq{
@@ -265,12 +277,12 @@ func main() {
265277
}
266278

267279
// PLATFORM UNINSTALL
268-
fmt.Println("=== calling PlatformUninstall(arduino:samd@1.6.21)")
280+
fmt.Println("=== calling PlatformUninstall(arduino:samd@1.6.19)")
269281
uninstallRespStream, err := client.PlatformUninstall(context.Background(), &rpc.PlatformUninstallReq{
270282
Instance: instance,
271283
PlatformPackage: "arduino",
272284
Architecture: "samd",
273-
Version: "1.6.21",
285+
Version: "1.6.19",
274286
})
275287
if err != nil {
276288
fmt.Printf("Uninstall error: %s\n", err)

daemon/daemon.go

+4
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ func (s *ArduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.Board
6060
return board.BoardDetails(ctx, req)
6161
}
6262

63+
func (s *ArduinoCoreServerImpl) BoardAttach(ctx context.Context, req *rpc.BoardAttachReq) (*rpc.BoardAttachResp, error) {
64+
return board.BoardAttach(ctx, req)
65+
}
66+
6367
func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyReq) (*rpc.DestroyResp, error) {
6468
return commands.Destroy(ctx, req)
6569
}

0 commit comments

Comments
 (0)