Skip to content

Commit 223d3fa

Browse files
Added gRPC command SetSketchDefaults to change sketch attached board/port (#2217)
* Remove some direct access to sketch.Sketch * Moved `LoadSketch` command in the proper place * Removed some accesses to sketch.Sketch The required information are returned from LoadSketch. * Added SetSketchDefaults gRPC call This allows to finally remove wrong access to `sketch.Sketch` from `cli` package. * Updated docs * Fixed integration tests * Update rpc/cc/arduino/cli/commands/v1/commands.proto Co-authored-by: Alessio Perugini <[email protected]> --------- Co-authored-by: Alessio Perugini <[email protected]>
1 parent 82e6f5d commit 223d3fa

File tree

20 files changed

+1001
-550
lines changed

20 files changed

+1001
-550
lines changed

Diff for: arduino/errors.go

+13
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,19 @@ func (e *CantCreateSketchError) Unwrap() error {
516516
return e.Cause
517517
}
518518

519+
// CantUpdateSketchError is returned when the sketch cannot be updated
520+
type CantUpdateSketchError struct {
521+
Cause error
522+
}
523+
524+
func (e *CantUpdateSketchError) Error() string {
525+
return composeErrorMsg(tr("Can't update sketch"), e.Cause)
526+
}
527+
528+
func (e *CantUpdateSketchError) Unwrap() error {
529+
return e.Cause
530+
}
531+
519532
// CantOpenSketchError is returned when the sketch is not found or cannot be opened
520533
type CantOpenSketchError struct {
521534
Cause error

Diff for: commands/daemon/daemon.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,13 @@ func (s *ArduinoCoreServerImpl) NewSketch(ctx context.Context, req *rpc.NewSketc
198198

199199
// LoadSketch FIXMEDOC
200200
func (s *ArduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) {
201-
resp, err := commands.LoadSketch(ctx, req)
201+
resp, err := sketch.LoadSketch(ctx, req)
202+
return resp, convertErrorToRPCStatus(err)
203+
}
204+
205+
// SetSketchDefaults FIXMEDOC
206+
func (s *ArduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc.SetSketchDefaultsRequest) (*rpc.SetSketchDefaultsResponse, error) {
207+
resp, err := sketch.SetSketchDefaults(ctx, req)
202208
return resp, convertErrorToRPCStatus(err)
203209
}
204210

Diff for: commands/instances.go

-32
Original file line numberDiff line numberDiff line change
@@ -569,38 +569,6 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB rp
569569
return nil
570570
}
571571

572-
// LoadSketch collects and returns all files composing a sketch
573-
func LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) {
574-
// TODO: This should be a ToRpc function for the Sketch struct
575-
sk, err := sketch.New(paths.New(req.SketchPath))
576-
if err != nil {
577-
return nil, &arduino.CantOpenSketchError{Cause: err}
578-
}
579-
580-
otherSketchFiles := make([]string, sk.OtherSketchFiles.Len())
581-
for i, file := range sk.OtherSketchFiles {
582-
otherSketchFiles[i] = file.String()
583-
}
584-
585-
additionalFiles := make([]string, sk.AdditionalFiles.Len())
586-
for i, file := range sk.AdditionalFiles {
587-
additionalFiles[i] = file.String()
588-
}
589-
590-
rootFolderFiles := make([]string, sk.RootFolderFiles.Len())
591-
for i, file := range sk.RootFolderFiles {
592-
rootFolderFiles[i] = file.String()
593-
}
594-
595-
return &rpc.LoadSketchResponse{
596-
MainFile: sk.MainFile.String(),
597-
LocationPath: sk.FullPath.String(),
598-
OtherSketchFiles: otherSketchFiles,
599-
AdditionalFiles: additionalFiles,
600-
RootFolderFiles: rootFolderFiles,
601-
}, nil
602-
}
603-
604572
// firstUpdate downloads libraries and packages indexes if they don't exist.
605573
// This ideally is only executed the first time the CLI is run.
606574
func firstUpdate(ctx context.Context, instance *rpc.Instance, downloadCb func(msg *rpc.DownloadProgress), externalPackageIndexes []*url.URL) error {

Diff for: commands/sketch/load.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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 sketch
17+
18+
import (
19+
"context"
20+
21+
"github.com/arduino/arduino-cli/arduino"
22+
"github.com/arduino/arduino-cli/arduino/sketch"
23+
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
24+
paths "github.com/arduino/go-paths-helper"
25+
)
26+
27+
// LoadSketch collects and returns all files composing a sketch
28+
func LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) {
29+
// TODO: This should be a ToRpc function for the Sketch struct
30+
sk, err := sketch.New(paths.New(req.SketchPath))
31+
if err != nil {
32+
return nil, &arduino.CantOpenSketchError{Cause: err}
33+
}
34+
35+
otherSketchFiles := make([]string, sk.OtherSketchFiles.Len())
36+
for i, file := range sk.OtherSketchFiles {
37+
otherSketchFiles[i] = file.String()
38+
}
39+
40+
additionalFiles := make([]string, sk.AdditionalFiles.Len())
41+
for i, file := range sk.AdditionalFiles {
42+
additionalFiles[i] = file.String()
43+
}
44+
45+
rootFolderFiles := make([]string, sk.RootFolderFiles.Len())
46+
for i, file := range sk.RootFolderFiles {
47+
rootFolderFiles[i] = file.String()
48+
}
49+
50+
defaultPort, defaultProtocol := sk.GetDefaultPortAddressAndProtocol()
51+
return &rpc.LoadSketchResponse{
52+
MainFile: sk.MainFile.String(),
53+
LocationPath: sk.FullPath.String(),
54+
OtherSketchFiles: otherSketchFiles,
55+
AdditionalFiles: additionalFiles,
56+
RootFolderFiles: rootFolderFiles,
57+
DefaultFqbn: sk.GetDefaultFQBN(),
58+
DefaultPort: defaultPort,
59+
DefaultProtocol: defaultProtocol,
60+
}, nil
61+
}

Diff for: commands/sketch/set_defaults.go

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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 sketch
17+
18+
import (
19+
"context"
20+
21+
"github.com/arduino/arduino-cli/arduino"
22+
"github.com/arduino/arduino-cli/arduino/sketch"
23+
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
24+
paths "github.com/arduino/go-paths-helper"
25+
)
26+
27+
// SetSketchDefaults updates the sketch project file (sketch.yaml) with the given defaults
28+
// for the values `default_fqbn`, `default_port`, and `default_protocol`.
29+
func SetSketchDefaults(ctx context.Context, req *rpc.SetSketchDefaultsRequest) (*rpc.SetSketchDefaultsResponse, error) {
30+
sk, err := sketch.New(paths.New(req.SketchPath))
31+
if err != nil {
32+
return nil, &arduino.CantOpenSketchError{Cause: err}
33+
}
34+
35+
oldAddress, oldProtocol := sk.GetDefaultPortAddressAndProtocol()
36+
res := &rpc.SetSketchDefaultsResponse{
37+
DefaultFqbn: sk.GetDefaultFQBN(),
38+
DefaultPortAddress: oldAddress,
39+
DefaultPortProtocol: oldProtocol,
40+
}
41+
42+
if fqbn := req.GetDefaultFqbn(); fqbn != "" {
43+
if err := sk.SetDefaultFQBN(fqbn); err != nil {
44+
return nil, &arduino.CantUpdateSketchError{Cause: err}
45+
}
46+
res.DefaultFqbn = fqbn
47+
}
48+
if newAddress, newProtocol := req.GetDefaultPortAddress(), req.GetDefaultPortProtocol(); newAddress != "" {
49+
if err := sk.SetDefaultPort(newAddress, newProtocol); err != nil {
50+
return nil, &arduino.CantUpdateSketchError{Cause: err}
51+
}
52+
res.DefaultPortAddress = newAddress
53+
res.DefaultPortProtocol = newProtocol
54+
}
55+
56+
return res, nil
57+
}

Diff for: docs/UPGRADING.md

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
Here you can find a list of migration guides to handle breaking changes between releases of the CLI.
44

5+
## 0.34.0
6+
7+
### golang API: `LoadSketch` function has been moved
8+
9+
The function `github.com/arduino/arduino-cli/commands.LoadSketch` has been moved to package
10+
`github.com/arduino/arduino-cli/commands/sketch.LoadSketch`. You must change the import accordingly.
11+
512
## 0.33.0
613

714
### gRPC `cc.arduino.cli.commands.v1.Compile` command now return expanded build_properties by default.

Diff for: internal/cli/arguments/fqbn.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"strings"
2020

2121
"github.com/arduino/arduino-cli/arduino"
22-
"github.com/arduino/arduino-cli/arduino/sketch"
2322
"github.com/arduino/arduino-cli/internal/cli/feedback"
2423
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2524
"github.com/spf13/cobra"
@@ -70,12 +69,10 @@ func (f *Fqbn) Set(fqbn string) {
7069
// - the port is not found, in this case nil is returned
7170
// - the FQBN autodetection fail, in this case the function prints an error and
7271
// terminates the execution
73-
func CalculateFQBNAndPort(portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, sk *sketch.Sketch) (string, *rpc.Port) {
74-
// TODO: REMOVE sketch.Sketch from here
75-
72+
func CalculateFQBNAndPort(portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, defaultFQBN, defaultAddress, defaultProtocol string) (string, *rpc.Port) {
7673
fqbn := fqbnArg.String()
77-
if fqbn == "" && sk != nil {
78-
fqbn = sk.GetDefaultFQBN()
74+
if fqbn == "" {
75+
fqbn = defaultFQBN
7976
}
8077
if fqbn == "" {
8178
if portArgs == nil || portArgs.address == "" {
@@ -88,7 +85,7 @@ func CalculateFQBNAndPort(portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance,
8885
return fqbn, port
8986
}
9087

91-
port, err := portArgs.GetPort(instance, sk)
88+
port, err := portArgs.GetPort(instance, defaultAddress, defaultProtocol)
9289
if err != nil {
9390
feedback.Fatal(tr("Error getting port metadata: %v", err), feedback.ErrGeneric)
9491
}

Diff for: internal/cli/arguments/port.go

+6-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121

2222
"github.com/arduino/arduino-cli/arduino"
2323
"github.com/arduino/arduino-cli/arduino/discovery"
24-
"github.com/arduino/arduino-cli/arduino/sketch"
2524
"github.com/arduino/arduino-cli/commands"
2625
"github.com/arduino/arduino-cli/commands/board"
2726
"github.com/arduino/arduino-cli/internal/cli/feedback"
@@ -57,11 +56,12 @@ func (p *Port) AddToCommand(cmd *cobra.Command) {
5756
// This method allows will bypass the discoveries if:
5857
// - a nil instance is passed: in this case the plain port and protocol arguments are returned (even if empty)
5958
// - a protocol is specified: in this case the discoveries are not needed to autodetect the protocol.
60-
func (p *Port) GetPortAddressAndProtocol(instance *rpc.Instance, sk *sketch.Sketch) (string, string, error) {
59+
func (p *Port) GetPortAddressAndProtocol(instance *rpc.Instance, defaultAddress, defaultProtocol string) (string, string, error) {
6160
if p.protocol != "" || instance == nil {
6261
return p.address, p.protocol, nil
6362
}
64-
port, err := p.GetPort(instance, sk)
63+
64+
port, err := p.GetPort(instance, defaultAddress, defaultProtocol)
6565
if err != nil {
6666
return "", "", err
6767
}
@@ -70,15 +70,13 @@ func (p *Port) GetPortAddressAndProtocol(instance *rpc.Instance, sk *sketch.Sket
7070

7171
// GetPort returns the Port obtained by parsing command line arguments.
7272
// The extra metadata for the ports is obtained using the pluggable discoveries.
73-
func (p *Port) GetPort(instance *rpc.Instance, sk *sketch.Sketch) (*discovery.Port, error) {
74-
// TODO: REMOVE sketch.Sketch from here
73+
func (p *Port) GetPort(instance *rpc.Instance, defaultAddress, defaultProtocol string) (*discovery.Port, error) {
7574
// TODO: REMOVE discovery from here (use board.List instead)
7675

7776
address := p.address
7877
protocol := p.protocol
79-
80-
if address == "" && sk != nil {
81-
address, protocol = sk.GetDefaultPortAddressAndProtocol()
78+
if address == "" && (defaultAddress != "" || defaultProtocol != "") {
79+
address, protocol = defaultAddress, defaultProtocol
8280
}
8381
if address == "" {
8482
// If no address is provided we assume the user is trying to upload

Diff for: internal/cli/arguments/sketch.go

-9
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,6 @@ func InitSketchPath(path string) (sketchPath *paths.Path) {
4242
return sketchPath
4343
}
4444

45-
// NewSketch is a helper function useful to create a sketch instance
46-
func NewSketch(sketchPath *paths.Path) *sketch.Sketch {
47-
sketch, err := sketch.New(sketchPath)
48-
if err != nil {
49-
feedback.Fatal(tr("Error opening sketch: %v", err), feedback.ErrGeneric)
50-
}
51-
return sketch
52-
}
53-
5445
// WarnDeprecatedFiles warns the user that a type of sketch files are deprecated
5546
func WarnDeprecatedFiles(sketchPath *paths.Path) {
5647
// .pde files are still supported but deprecated, this warning urges the user to rename them

Diff for: internal/cli/board/attach.go

+20-26
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616
package board
1717

1818
import (
19+
"context"
1920
"fmt"
2021
"os"
2122

23+
"github.com/arduino/arduino-cli/commands/sketch"
2224
"github.com/arduino/arduino-cli/internal/cli/arguments"
2325
"github.com/arduino/arduino-cli/internal/cli/feedback"
26+
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2427
"github.com/spf13/cobra"
2528
)
2629

@@ -51,37 +54,28 @@ func initAttachCommand() *cobra.Command {
5154

5255
func runAttachCommand(path string, port *arguments.Port, fqbn string) {
5356
sketchPath := arguments.InitSketchPath(path)
54-
sk := arguments.NewSketch(sketchPath)
5557

56-
var currentPort *boardAttachPortResult
57-
if currentAddress, currentProtocol := sk.GetDefaultPortAddressAndProtocol(); currentAddress != "" {
58-
currentPort = &boardAttachPortResult{
59-
Address: currentAddress,
60-
Protocol: currentProtocol,
61-
}
62-
}
63-
current := &boardAttachResult{
64-
Port: currentPort,
65-
Fqbn: sk.GetDefaultFQBN(),
58+
portAddress, portProtocol, _ := port.GetPortAddressAndProtocol(nil, "", "")
59+
newDefaults, err := sketch.SetSketchDefaults(context.Background(), &rpc.SetSketchDefaultsRequest{
60+
SketchPath: sketchPath.String(),
61+
DefaultFqbn: fqbn,
62+
DefaultPortAddress: portAddress,
63+
DefaultPortProtocol: portProtocol,
64+
})
65+
if err != nil {
66+
feedback.FatalError(err, feedback.ErrGeneric)
6667
}
67-
address, protocol, _ := port.GetPortAddressAndProtocol(nil, sk)
68-
if address != "" {
69-
if err := sk.SetDefaultPort(address, protocol); err != nil {
70-
feedback.Fatal(fmt.Sprintf("%s: %s", tr("Error saving sketch metadata"), err), feedback.ErrGeneric)
71-
}
72-
current.Port = &boardAttachPortResult{
73-
Address: address,
74-
Protocol: protocol,
75-
}
68+
69+
res := &boardAttachResult{
70+
Fqbn: newDefaults.GetDefaultFqbn(),
7671
}
77-
if fqbn != "" {
78-
if err := sk.SetDefaultFQBN(fqbn); err != nil {
79-
feedback.Fatal(fmt.Sprintf("%s: %s", tr("Error saving sketch metadata"), err), feedback.ErrGeneric)
72+
if newDefaults.GetDefaultPortAddress() != "" {
73+
res.Port = &boardAttachPortResult{
74+
Address: newDefaults.GetDefaultPortAddress(),
75+
Protocol: newDefaults.GetDefaultPortProtocol(),
8076
}
81-
current.Fqbn = fqbn
8277
}
83-
84-
feedback.PrintResult(current)
78+
feedback.PrintResult(res)
8579
}
8680

8781
type boardAttachPortResult struct {

Diff for: internal/cli/burnbootloader/burnbootloader.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func runBootloaderCommand(command *cobra.Command, args []string) {
6767
logrus.Info("Executing `arduino-cli burn-bootloader`")
6868

6969
// We don't need a Sketch to upload a board's bootloader
70-
discoveryPort, err := port.GetPort(instance, nil)
70+
discoveryPort, err := port.GetPort(instance, "", "")
7171
if err != nil {
7272
feedback.Fatal(tr("Error during Upload: %v", err), feedback.ErrGeneric)
7373
}

0 commit comments

Comments
 (0)