Skip to content

Commit 01cef30

Browse files
committed
Ported Update command in cli-daemon
- Ported Update command in cli-daemon - Implemented stream out and stream err in daemon, maneged with two different go routine
1 parent 11483db commit 01cef30

File tree

10 files changed

+506
-134
lines changed

10 files changed

+506
-134
lines changed

cli/upload/upload.go

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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 upload
19+
20+
import (
21+
"context"
22+
"os"
23+
24+
"github.com/arduino/arduino-cli/cli"
25+
"github.com/arduino/arduino-cli/commands/upload"
26+
"github.com/arduino/arduino-cli/common/formatter"
27+
"github.com/arduino/arduino-cli/rpc"
28+
"github.com/spf13/cobra"
29+
)
30+
31+
// InitCommand prepares the command.
32+
func InitCommand() *cobra.Command {
33+
uploadCommand := &cobra.Command{
34+
Use: "upload",
35+
Short: "Upload Arduino sketches.",
36+
Long: "Upload Arduino sketches.",
37+
Example: " " + cli.AppName + " upload /home/user/Arduino/MySketch",
38+
Args: cobra.MaximumNArgs(1),
39+
Run: run,
40+
}
41+
uploadCommand.Flags().StringVarP(
42+
&flags.fqbn, "fqbn", "b", "",
43+
"Fully Qualified Board Name, e.g.: arduino:avr:uno")
44+
uploadCommand.Flags().StringVarP(
45+
&flags.port, "port", "p", "",
46+
"Upload port, e.g.: COM10 or /dev/ttyACM0")
47+
uploadCommand.Flags().StringVarP(
48+
&flags.importFile, "input", "i", "",
49+
"Input file to be uploaded.")
50+
uploadCommand.Flags().BoolVarP(
51+
&flags.verify, "verify", "t", false,
52+
"Verify uploaded binary after the upload.")
53+
uploadCommand.Flags().BoolVarP(
54+
&flags.verbose, "verbose", "v", false,
55+
"Optional, turns on verbose mode.")
56+
return uploadCommand
57+
}
58+
59+
var flags struct {
60+
fqbn string
61+
port string
62+
verbose bool
63+
verify bool
64+
importFile string
65+
}
66+
67+
func run(command *cobra.Command, args []string) {
68+
instance := cli.CreateInstance()
69+
path := ""
70+
71+
if len(args) > 0 {
72+
path = args[0]
73+
}
74+
75+
uploadRes, err := upload.Upload(context.Background(), &rpc.UploadReq{
76+
Instance: instance,
77+
Fqbn: flags.fqbn,
78+
SketchPath: path,
79+
Port: flags.port,
80+
Verbose: flags.verbose,
81+
Verify: flags.verify,
82+
ImportFile: flags.importFile,
83+
}, os.Stdout, os.Stderr)
84+
if err == nil {
85+
outputUploadResp(uploadRes)
86+
} else {
87+
formatter.PrintError(err, "Error during Upload")
88+
os.Exit(cli.ErrGeneric)
89+
}
90+
}
91+
92+
func outputUploadResp(details *rpc.UploadResp) {
93+
94+
}

commands/root/root.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ import (
2626
"github.com/arduino/arduino-cli/cli/compile"
2727
"github.com/arduino/arduino-cli/cli/core"
2828
"github.com/arduino/arduino-cli/cli/daemon"
29+
"github.com/arduino/arduino-cli/cli/upload"
2930
"github.com/arduino/arduino-cli/commands/config"
3031
"github.com/arduino/arduino-cli/commands/generatedocs"
3132
"github.com/arduino/arduino-cli/commands/lib"
3233
"github.com/arduino/arduino-cli/commands/sketch"
33-
"github.com/arduino/arduino-cli/commands/upload"
3434
"github.com/arduino/arduino-cli/commands/version"
3535
"github.com/arduino/arduino-cli/common/formatter"
3636
"github.com/arduino/arduino-cli/configs"

commands/upload/upload.go

+45-89
Original file line numberDiff line numberDiff line change
@@ -18,121 +18,80 @@
1818
package upload
1919

2020
import (
21+
"context"
2122
"fmt"
23+
"io"
2224
"os"
2325
"path/filepath"
2426
"strings"
2527
"time"
2628

2729
"github.com/arduino/arduino-cli/arduino/cores"
2830
"github.com/arduino/arduino-cli/cli"
31+
"github.com/arduino/arduino-cli/commands"
2932
"github.com/arduino/arduino-cli/common/formatter"
3033
"github.com/arduino/arduino-cli/executils"
34+
"github.com/arduino/arduino-cli/rpc"
3135
paths "github.com/arduino/go-paths-helper"
3236
properties "github.com/arduino/go-properties-orderedmap"
3337
"github.com/sirupsen/logrus"
34-
"github.com/spf13/cobra"
3538
serial "go.bug.st/serial.v1"
3639
)
3740

38-
// InitCommand prepares the command.
39-
func InitCommand() *cobra.Command {
40-
uploadCommand := &cobra.Command{
41-
Use: "upload",
42-
Short: "Upload Arduino sketches.",
43-
Long: "Upload Arduino sketches.",
44-
Example: " " + cli.AppName + " upload /home/user/Arduino/MySketch",
45-
Args: cobra.MaximumNArgs(1),
46-
Run: run,
47-
}
48-
uploadCommand.Flags().StringVarP(
49-
&flags.fqbn, "fqbn", "b", "",
50-
"Fully Qualified Board Name, e.g.: arduino:avr:uno")
51-
uploadCommand.Flags().StringVarP(
52-
&flags.port, "port", "p", "",
53-
"Upload port, e.g.: COM10 or /dev/ttyACM0")
54-
uploadCommand.Flags().StringVarP(
55-
&flags.importFile, "input", "i", "",
56-
"Input file to be uploaded.")
57-
uploadCommand.Flags().BoolVarP(
58-
&flags.verify, "verify", "t", false,
59-
"Verify uploaded binary after the upload.")
60-
uploadCommand.Flags().BoolVarP(
61-
&flags.verbose, "verbose", "v", false,
62-
"Optional, turns on verbose mode.")
63-
return uploadCommand
64-
}
65-
66-
var flags struct {
67-
fqbn string
68-
port string
69-
verbose bool
70-
verify bool
71-
importFile string
72-
}
73-
74-
func run(command *cobra.Command, args []string) {
41+
func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStream io.Writer) (*rpc.UploadResp, error) {
42+
logrus.Info("Executing `arduino upload`")
7543
var sketchPath *paths.Path
76-
if len(args) > 0 {
77-
sketchPath = paths.New(args[0])
44+
if req.GetSketchPath() != "" {
45+
sketchPath = paths.New(req.GetSketchPath())
7846
}
7947
sketch, err := cli.InitSketch(sketchPath)
8048
if err != nil {
81-
formatter.PrintError(err, "Error opening sketch.")
82-
os.Exit(cli.ErrGeneric)
49+
return nil, fmt.Errorf("opening sketch: %s", err)
8350
}
84-
8551
// FIXME: make a specification on how a port is specified via command line
86-
port := flags.port
52+
port := req.GetPort()
8753
if port == "" {
88-
formatter.PrintErrorMessage("No port provided.")
89-
os.Exit(cli.ErrBadCall)
54+
return nil, fmt.Errorf("No port provided.")
9055
}
9156

92-
if flags.fqbn == "" && sketch != nil {
93-
flags.fqbn = sketch.Metadata.CPU.Fqbn
57+
fqbnIn := req.GetFqbn()
58+
if fqbnIn == "" && sketch != nil && sketch.Metadata != nil {
59+
fqbnIn = sketch.Metadata.CPU.Fqbn
9460
}
95-
if flags.fqbn == "" {
96-
formatter.PrintErrorMessage("No Fully Qualified Board Name provided.")
97-
os.Exit(cli.ErrBadCall)
61+
if fqbnIn == "" {
62+
return nil, fmt.Errorf("No Fully Qualified Board Name provided")
9863
}
99-
fqbn, err := cores.ParseFQBN(flags.fqbn)
64+
fqbn, err := cores.ParseFQBN(fqbnIn)
10065
if err != nil {
101-
formatter.PrintError(err, "Invalid FQBN.")
102-
os.Exit(cli.ErrBadCall)
66+
return nil, fmt.Errorf("incorrect FQBN: %s", err)
10367
}
10468

105-
pm, _ := cli.InitPackageAndLibraryManager()
69+
pm := commands.GetPackageManager(req)
10670

10771
// Find target board and board properties
10872
_, _, board, boardProperties, _, err := pm.ResolveFQBN(fqbn)
10973
if err != nil {
110-
formatter.PrintError(err, "Invalid FQBN.")
111-
os.Exit(cli.ErrBadCall)
74+
return nil, fmt.Errorf("Invalid FQBN: %s", err)
11275
}
11376

11477
// Load programmer tool
11578
uploadToolPattern, have := boardProperties.GetOk("upload.tool")
11679
if !have || uploadToolPattern == "" {
117-
formatter.PrintErrorMessage("The board does not define an 'upload.tool' property.")
118-
os.Exit(cli.ErrGeneric)
80+
return nil, fmt.Errorf("The board does not define an 'upload.tool' property.")
11981
}
12082

12183
var referencedPlatformRelease *cores.PlatformRelease
12284
if split := strings.Split(uploadToolPattern, ":"); len(split) > 2 {
123-
formatter.PrintErrorMessage("The board defines an invalid 'upload.tool' property: " + uploadToolPattern)
124-
os.Exit(cli.ErrGeneric)
85+
return nil, fmt.Errorf("The board defines an invalid 'upload.tool' property: " + uploadToolPattern)
12586
} else if len(split) == 2 {
12687
referencedPackageName := split[0]
12788
uploadToolPattern = split[1]
12889
architecture := board.PlatformRelease.Platform.Architecture
12990

13091
if referencedPackage := pm.GetPackages().Packages[referencedPackageName]; referencedPackage == nil {
131-
formatter.PrintErrorMessage("The board requires platform '" + referencedPackageName + ":" + architecture + "' that is not installed.")
132-
os.Exit(cli.ErrGeneric)
92+
return nil, fmt.Errorf("The board requires platform '" + referencedPackageName + ":" + architecture + "' that is not installed.")
13393
} else if referencedPlatform := referencedPackage.Platforms[architecture]; referencedPlatform == nil {
134-
formatter.PrintErrorMessage("The board requires platform '" + referencedPackageName + ":" + architecture + "' that is not installed.")
135-
os.Exit(cli.ErrGeneric)
94+
return nil, fmt.Errorf("The board requires platform '" + referencedPackageName + ":" + architecture + "' that is not installed.")
13695
} else {
13796
referencedPlatformRelease = pm.GetInstalledPlatformRelease(referencedPlatform)
13897
}
@@ -157,7 +116,8 @@ func run(command *cobra.Command, args []string) {
157116
}
158117

159118
// Set properties for verbose upload
160-
if flags.verbose {
119+
Verbose := req.GetVerbose()
120+
if Verbose {
161121
if v, ok := uploadProperties.GetOk("upload.params.verbose"); ok {
162122
uploadProperties.Set("upload.verbose", v)
163123
}
@@ -168,7 +128,8 @@ func run(command *cobra.Command, args []string) {
168128
}
169129

170130
// Set properties for verify
171-
if flags.verify {
131+
Verify := req.GetVerify()
132+
if Verify {
172133
uploadProperties.Set("upload.verify", uploadProperties.Get("upload.params.verify"))
173134
} else {
174135
uploadProperties.Set("upload.verify", uploadProperties.Get("upload.params.noverify"))
@@ -181,19 +142,18 @@ func run(command *cobra.Command, args []string) {
181142

182143
var importPath *paths.Path
183144
var importFile string
184-
if flags.importFile == "" {
145+
if req.GetImportFile() == "" {
185146
importPath = sketch.FullPath
186147
importFile = sketch.Name + "." + fqbnSuffix
187148
} else {
188-
importPath = paths.New(flags.importFile).Parent()
189-
importFile = paths.New(flags.importFile).Base()
149+
importPath = paths.New(req.GetImportFile()).Parent()
150+
importFile = paths.New(req.GetImportFile()).Base()
190151
}
191152

192153
outputTmpFile, ok := uploadProperties.GetOk("recipe.output.tmp_file")
193154
outputTmpFile = uploadProperties.ExpandPropsInString(outputTmpFile)
194155
if !ok {
195-
formatter.PrintErrorMessage("The platform does not define the required property 'recipe.output.tmp_file'.")
196-
os.Exit(cli.ErrGeneric)
156+
return nil, fmt.Errorf("The platform does not define the required property 'recipe.output.tmp_file'.")
197157
}
198158
ext := filepath.Ext(outputTmpFile)
199159
if strings.HasSuffix(importFile, ext) {
@@ -205,25 +165,22 @@ func run(command *cobra.Command, args []string) {
205165
uploadFile := importPath.Join(importFile + ext)
206166
if _, err := uploadFile.Stat(); err != nil {
207167
if os.IsNotExist(err) {
208-
formatter.PrintErrorMessage("Compiled sketch not found: " + uploadFile.String() + ". Please compile first.")
168+
return nil, fmt.Errorf("Compiled sketch not found: "+uploadFile.String()+". Please compile first.", err)
209169
} else {
210-
formatter.PrintError(err, "Could not open compiled sketch.")
170+
return nil, fmt.Errorf("Could not open compiled sketch.", err)
211171
}
212-
os.Exit(cli.ErrGeneric)
213172
}
214173

215174
// Perform reset via 1200bps touch if requested
216175
if uploadProperties.GetBoolean("upload.use_1200bps_touch") {
217176
ports, err := serial.GetPortsList()
218177
if err != nil {
219-
formatter.PrintError(err, "Can't get serial port list")
220-
os.Exit(cli.ErrGeneric)
178+
return nil, fmt.Errorf("Can't get serial port list", err)
221179
}
222180
for _, p := range ports {
223181
if p == port {
224182
if err := touchSerialPortAt1200bps(p); err != nil {
225-
formatter.PrintError(err, "Can't perform reset via 1200bps-touch on serial port")
226-
os.Exit(cli.ErrGeneric)
183+
return nil, fmt.Errorf("Can't perform reset via 1200bps-touch on serial port", err)
227184
}
228185
break
229186
}
@@ -240,8 +197,7 @@ func run(command *cobra.Command, args []string) {
240197
actualPort := port // default
241198
if uploadProperties.GetBoolean("upload.wait_for_upload_port") {
242199
if p, err := waitForNewSerialPort(); err != nil {
243-
formatter.PrintError(err, "Could not detect serial ports")
244-
os.Exit(cli.ErrGeneric)
200+
return nil, fmt.Errorf("Could not detect serial ports", err)
245201
} else if p == "" {
246202
formatter.Print("No new serial port detected.")
247203
} else {
@@ -267,28 +223,28 @@ func run(command *cobra.Command, args []string) {
267223
cmdLine := uploadProperties.ExpandPropsInString(recipe)
268224
cmdArgs, err := properties.SplitQuotedString(cmdLine, `"'`, false)
269225
if err != nil {
270-
formatter.PrintError(err, "Invalid recipe in platform.")
271-
os.Exit(cli.ErrCoreConfig)
226+
return nil, fmt.Errorf("Invalid recipe in platform.", err)
272227
}
273228

274229
// Run Tool
275230
cmd, err := executils.Command(cmdArgs)
276231
if err != nil {
277-
formatter.PrintError(err, "Could not execute upload tool.")
278-
os.Exit(cli.ErrGeneric)
232+
return nil, fmt.Errorf("Could not execute upload tool.", err)
279233
}
280234

281235
executils.AttachStdoutListener(cmd, executils.PrintToStdout)
282236
executils.AttachStderrListener(cmd, executils.PrintToStderr)
237+
cmd.Stdout = outStream
238+
cmd.Stderr = errStream
283239

284240
if err := cmd.Start(); err != nil {
285-
formatter.PrintError(err, "Could not execute upload tool.")
286-
os.Exit(cli.ErrGeneric)
241+
return nil, fmt.Errorf("Could not execute upload tool.", err)
287242
}
243+
288244
if err := cmd.Wait(); err != nil {
289-
formatter.PrintError(err, "Error during upload.")
290-
os.Exit(cli.ErrGeneric)
245+
return nil, fmt.Errorf("Error during upload.", err)
291246
}
247+
return &rpc.UploadResp{}, nil
292248
}
293249

294250
func touchSerialPortAt1200bps(port string) error {

0 commit comments

Comments
 (0)