@@ -42,11 +42,13 @@ type commander struct {
42
42
// programmatically call arduino-cli commands.
43
43
// It directly imports the golang packages of the arduino-cli.
44
44
func NewCommander () (arduino.Commander , error ) {
45
- // Discard arduino-cli log info messages
45
+ // Discard arduino-cli log info messages.
46
46
logrus .SetLevel (logrus .PanicLevel )
47
- // Initialize arduino-cli configuration
47
+
48
+ // Initialize arduino-cli configuration.
48
49
configuration .Settings = configuration .Init (configuration .FindConfigFileInArgsOrWorkingDirectory (os .Args ))
49
- // Create arduino-cli instance, needed to execute arduino-cli commands
50
+
51
+ // Create and init an arduino-cli instance, needed to execute arduino-cli commands.
50
52
inst , err := instance .Create ()
51
53
if err != nil {
52
54
err = fmt .Errorf ("creating arduino-cli instance: %w" , err )
@@ -56,7 +58,7 @@ func NewCommander() (arduino.Commander, error) {
56
58
if len (errs ) > 0 {
57
59
err = errors .New ("initializing arduino-cli instance: received errors: " )
58
60
for _ , e := range errs {
59
- err = fmt .Errorf ("%w %v; " , err , e )
61
+ err = fmt .Errorf ("%v: %v; " , err , e )
60
62
}
61
63
return nil , err
62
64
}
@@ -69,22 +71,40 @@ func NewCommander() (arduino.Commander, error) {
69
71
70
72
// BoardList executes the 'arduino-cli board list' command
71
73
// and returns its result.
72
- func (c * commander ) BoardList () ([]* rpc.DetectedPort , error ) {
74
+ func (c * commander ) BoardList (ctx context. Context ) ([]* rpc.DetectedPort , error ) {
73
75
req := & rpc.BoardListRequest {
74
76
Instance : c .Instance ,
75
77
Timeout : time .Second .Milliseconds (),
76
78
}
77
- ports , err := board .List (req )
78
- if err != nil {
79
- err = fmt .Errorf ("%s: %w" , "detecting boards" , err )
80
- return nil , err
79
+
80
+ // There is no obvious way to cancel the execution of this command.
81
+ // So, we execute it in a goroutine and leave it running alone if ctx gets cancelled.
82
+ type resp struct {
83
+ err error
84
+ ports []* rpc.DetectedPort
85
+ }
86
+ quit := make (chan resp , 1 )
87
+ go func () {
88
+ ports , err := board .List (req )
89
+ quit <- resp {err : err , ports : ports }
90
+ close (quit )
91
+ }()
92
+
93
+ // Wait for the command to complete or the context to be terminated.
94
+ select {
95
+ case <- ctx .Done ():
96
+ return nil , errors .New ("board list command cancelled" )
97
+ case r := <- quit :
98
+ if r .err != nil {
99
+ return nil , fmt .Errorf ("executing board list command: %w" , r .err )
100
+ }
101
+ return r .ports , nil
81
102
}
82
- return ports , nil
83
103
}
84
104
85
105
// UploadBin executes the 'arduino-cli upload -i' command
86
106
// and returns its result.
87
- func (c * commander ) UploadBin (fqbn , bin , address , protocol string ) error {
107
+ func (c * commander ) UploadBin (ctx context. Context , fqbn , bin , address , protocol string ) error {
88
108
req := & rpc.UploadRequest {
89
109
Instance : c .Instance ,
90
110
Fqbn : fqbn ,
@@ -93,11 +113,25 @@ func (c *commander) UploadBin(fqbn, bin, address, protocol string) error {
93
113
Port : & rpc.Port {Address : address , Protocol : protocol },
94
114
Verbose : false ,
95
115
}
96
-
97
116
l := logrus .StandardLogger ().WithField ("source" , "arduino-cli" ).Writer ()
98
- if _ , err := upload .Upload (context .Background (), req , l , l ); err != nil {
99
- err = fmt .Errorf ("%s: %w" , "uploading binary" , err )
100
- return err
117
+
118
+ // There is no obvious way to cancel the execution of this command.
119
+ // So, we execute it in a goroutine and leave it running if ctx gets cancelled.
120
+ quit := make (chan error , 1 )
121
+ go func () {
122
+ _ , err := upload .Upload (ctx , req , l , l )
123
+ quit <- err
124
+ close (quit )
125
+ }()
126
+
127
+ // Wait for the upload to complete or the context to be terminated.
128
+ select {
129
+ case <- ctx .Done ():
130
+ return errors .New ("upload cancelled" )
131
+ case err := <- quit :
132
+ if err != nil {
133
+ return fmt .Errorf ("uploading binary: %w" , err )
134
+ }
135
+ return nil
101
136
}
102
- return nil
103
137
}
0 commit comments