Skip to content

Commit 35722fd

Browse files
author
Maurizio Branca
authored
Create a compile+upload combo command (#326)
* Add an optional upload step in compile (CLI-35) * Add few integration tests for compile command
1 parent 4d36bac commit 35722fd

File tree

2 files changed

+155
-11
lines changed

2 files changed

+155
-11
lines changed

Diff for: cli/compile/compile.go

+35-11
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/arduino/arduino-cli/cli/errorcodes"
2727
"github.com/arduino/arduino-cli/cli/instance"
2828
"github.com/arduino/arduino-cli/commands/compile"
29+
"github.com/arduino/arduino-cli/commands/upload"
2930
"github.com/arduino/arduino-cli/common/formatter"
3031
rpc "github.com/arduino/arduino-cli/rpc/commands"
3132
"github.com/arduino/go-paths-helper"
@@ -34,17 +35,20 @@ import (
3435
)
3536

3637
var (
37-
fqbn string // Fully Qualified Board Name, e.g.: arduino:avr:uno.
38-
showProperties bool // Show all build preferences used instead of compiling.
39-
preprocess bool // Print preprocessed code to stdout.
40-
buildCachePath string // Builds of 'core.a' are saved into this path to be cached and reused.
41-
buildPath string // Path where to save compiled files.
42-
buildProperties []string // List of custom build properties separated by commas. Or can be used multiple times for multiple properties.
43-
warnings string // Used to tell gcc which warning level to use.
44-
verbose bool // Turns on verbose mode.
45-
quiet bool // Suppresses almost every output.
46-
vidPid string // VID/PID specific build properties.
47-
exportFile string // The compiled binary is written to this file
38+
fqbn string // Fully Qualified Board Name, e.g.: arduino:avr:uno.
39+
showProperties bool // Show all build preferences used instead of compiling.
40+
preprocess bool // Print preprocessed code to stdout.
41+
buildCachePath string // Builds of 'core.a' are saved into this path to be cached and reused.
42+
buildPath string // Path where to save compiled files.
43+
buildProperties []string // List of custom build properties separated by commas. Or can be used multiple times for multiple properties.
44+
warnings string // Used to tell gcc which warning level to use.
45+
verbose bool // Turns on verbose mode.
46+
quiet bool // Suppresses almost every output.
47+
vidPid string // VID/PID specific build properties.
48+
uploadAfterCompile bool // Upload the binary after the compilation.
49+
port string // Upload port, e.g.: COM10 or /dev/ttyACM0.
50+
verify bool // Upload, verify uploaded binary after the upload.
51+
exportFile string // The compiled binary is written to this file
4852
)
4953

5054
// NewCommand created a new `compile` command
@@ -71,6 +75,9 @@ func NewCommand() *cobra.Command {
7175
`Optional, can be "none", "default", "more" and "all". Defaults to "none". Used to tell gcc which warning level to use (-W flag).`)
7276
command.Flags().BoolVarP(&verbose, "verbose", "v", false, "Optional, turns on verbose mode.")
7377
command.Flags().BoolVar(&quiet, "quiet", false, "Optional, supresses almost every output.")
78+
command.Flags().BoolVarP(&uploadAfterCompile, "upload", "u", false, "Upload the binary after the compilation.")
79+
command.Flags().StringVarP(&port, "port", "p", "", "Upload port, e.g.: COM10 or /dev/ttyACM0")
80+
command.Flags().BoolVarP(&verify, "verify", "t", false, "Verify uploaded binary after the upload.")
7481
command.Flags().StringVar(&vidPid, "vid-pid", "", "When specified, VID/PID specific build properties are used, if boards supports them.")
7582

7683
return command
@@ -106,6 +113,23 @@ func run(cmd *cobra.Command, args []string) {
106113
formatter.PrintError(err, "Error during build")
107114
os.Exit(errorcodes.ErrGeneric)
108115
}
116+
117+
if uploadAfterCompile {
118+
_, err := upload.Upload(context.Background(), &rpc.UploadReq{
119+
Instance: instance,
120+
Fqbn: fqbn,
121+
SketchPath: sketchPath.String(),
122+
Port: port,
123+
Verbose: verbose,
124+
Verify: verify,
125+
ImportFile: exportFile,
126+
}, os.Stdout, os.Stderr)
127+
128+
if err != nil {
129+
formatter.PrintError(err, "Error during Upload")
130+
os.Exit(errorcodes.ErrGeneric)
131+
}
132+
}
109133
}
110134

111135
// initSketchPath returns the current working directory

Diff for: test/test_compile.py

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# This file is part of arduino-cli.
2+
3+
# Copyright 2019 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 modify or
12+
# otherwise use the software for commercial activities involving the Arduino
13+
# software without disclosing the source code of your own applications. To purchase
14+
# a commercial license, send an email to [email protected].
15+
import pytest
16+
import json
17+
import os
18+
19+
from .common import running_on_ci
20+
21+
22+
def test_compile_without_fqbn(run_command):
23+
# Init the environment explicitly
24+
result = run_command("core update-index")
25+
assert result.ok
26+
27+
# Download latest AVR
28+
result = run_command("core install arduino:avr")
29+
assert result.ok
30+
31+
# Build sketch without FQBN
32+
result = run_command("compile")
33+
assert result.failed
34+
35+
36+
def test_compile_with_simple_sketch(run_command, data_dir):
37+
# Init the environment explicitly
38+
result = run_command("core update-index")
39+
assert result.ok
40+
41+
# # Download latest AVR
42+
result = run_command("core install arduino:avr")
43+
assert result.ok
44+
45+
sketch_path = os.path.join(data_dir, "CompileIntegrationTest")
46+
47+
# Create a test sketch
48+
result = run_command("sketch new CompileIntegrationTest")
49+
assert result.ok
50+
assert "Sketch created in: {}".format(sketch_path) in result.stdout
51+
52+
# Build sketch for arduino:avr:uno
53+
result = run_command("compile -b arduino:avr:uno {}".format(sketch_path))
54+
assert result.ok
55+
assert "Sketch uses" in result.stdout
56+
57+
58+
@pytest.mark.skipif(running_on_ci(), reason="VMs have no serial ports")
59+
def test_compile_and_compile_combo(run_command, data_dir):
60+
61+
# Init the environment explicitly
62+
result = run_command("core update-index")
63+
assert result.ok
64+
65+
# Install required core(s)
66+
result = run_command("core install arduino:avr")
67+
# result = run_command("core install arduino:samd")
68+
assert result.ok
69+
70+
# Create a test sketch
71+
sketch_path = os.path.join(data_dir, "CompileAndUploadIntegrationTest")
72+
result = run_command("sketch new CompileAndUploadIntegrationTest")
73+
assert result.ok
74+
assert "Sketch created in: {}".format(sketch_path) in result.stdout
75+
76+
#
77+
# Build a list of detected boards to test, if any.
78+
#
79+
result = run_command("board list --format json")
80+
assert result.ok
81+
82+
#
83+
# The `board list --format json` returns a JSON that looks like to the following:
84+
#
85+
# [
86+
# {
87+
# "address": "/dev/cu.usbmodem14201",
88+
# "protocol": "serial",
89+
# "protocol_label": "Serial Port (USB)",
90+
# "boards": [
91+
# {
92+
# "name": "Arduino NANO 33 IoT",
93+
# "FQBN": "arduino:samd:nano_33_iot"
94+
# }
95+
# ]
96+
# }
97+
# ]
98+
99+
detected_boards = []
100+
101+
ports = json.loads(result.stdout)
102+
assert isinstance(ports, list)
103+
for port in ports:
104+
boards = port.get('boards')
105+
assert isinstance(boards, list)
106+
for board in boards:
107+
detected_boards.append(dict(address=port.get('address'), fqbn=board.get('FQBN')))
108+
109+
assert len(detected_boards) >= 1, "There are no boards available for testing"
110+
111+
# Build sketch for each detected board
112+
for board in detected_boards:
113+
result = run_command(
114+
"compile -b {fqbn} --upload -p {address} {sketch_path}".format(
115+
fqbn=board.get('fqbn'),
116+
address=board.get('address'),
117+
sketch_path=sketch_path)
118+
)
119+
assert result.ok
120+
assert "Verify successful" in result.stdout

0 commit comments

Comments
 (0)