From e3fd70c379178570a2ad4d6b7b4c48c7db350b0b Mon Sep 17 00:00:00 2001 From: Maurizio Branca Date: Tue, 6 Aug 2019 15:01:49 +0200 Subject: [PATCH 1/2] Add an optional upload step in compile (CLI-35) --- cli/compile/compile.go | 46 ++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 885edaecbd6..91b5d66dedb 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -26,6 +26,7 @@ import ( "github.com/arduino/arduino-cli/cli/errorcodes" "github.com/arduino/arduino-cli/cli/instance" "github.com/arduino/arduino-cli/commands/compile" + "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/common/formatter" rpc "github.com/arduino/arduino-cli/rpc/commands" "github.com/arduino/go-paths-helper" @@ -34,17 +35,20 @@ import ( ) var ( - fqbn string // Fully Qualified Board Name, e.g.: arduino:avr:uno. - showProperties bool // Show all build preferences used instead of compiling. - preprocess bool // Print preprocessed code to stdout. - buildCachePath string // Builds of 'core.a' are saved into this path to be cached and reused. - buildPath string // Path where to save compiled files. - buildProperties []string // List of custom build properties separated by commas. Or can be used multiple times for multiple properties. - warnings string // Used to tell gcc which warning level to use. - verbose bool // Turns on verbose mode. - quiet bool // Suppresses almost every output. - vidPid string // VID/PID specific build properties. - exportFile string // The compiled binary is written to this file + fqbn string // Fully Qualified Board Name, e.g.: arduino:avr:uno. + showProperties bool // Show all build preferences used instead of compiling. + preprocess bool // Print preprocessed code to stdout. + buildCachePath string // Builds of 'core.a' are saved into this path to be cached and reused. + buildPath string // Path where to save compiled files. + buildProperties []string // List of custom build properties separated by commas. Or can be used multiple times for multiple properties. + warnings string // Used to tell gcc which warning level to use. + verbose bool // Turns on verbose mode. + quiet bool // Suppresses almost every output. + vidPid string // VID/PID specific build properties. + uploadAfterCompile bool // Upload the binary after the compilation. + port string // Upload port, e.g.: COM10 or /dev/ttyACM0. + verify bool // Upload, verify uploaded binary after the upload. + exportFile string // The compiled binary is written to this file ) // NewCommand created a new `compile` command @@ -71,6 +75,9 @@ func NewCommand() *cobra.Command { `Optional, can be "none", "default", "more" and "all". Defaults to "none". Used to tell gcc which warning level to use (-W flag).`) command.Flags().BoolVarP(&verbose, "verbose", "v", false, "Optional, turns on verbose mode.") command.Flags().BoolVar(&quiet, "quiet", false, "Optional, supresses almost every output.") + command.Flags().BoolVarP(&uploadAfterCompile, "upload", "u", false, "Upload the binary after the compilation.") + command.Flags().StringVarP(&port, "port", "p", "", "Upload port, e.g.: COM10 or /dev/ttyACM0") + command.Flags().BoolVarP(&verify, "verify", "t", false, "Verify uploaded binary after the upload.") command.Flags().StringVar(&vidPid, "vid-pid", "", "When specified, VID/PID specific build properties are used, if boards supports them.") return command @@ -106,6 +113,23 @@ func run(cmd *cobra.Command, args []string) { formatter.PrintError(err, "Error during build") os.Exit(errorcodes.ErrGeneric) } + + if uploadAfterCompile { + _, err := upload.Upload(context.Background(), &rpc.UploadReq{ + Instance: instance, + Fqbn: fqbn, + SketchPath: sketchPath.String(), + Port: port, + Verbose: verbose, + Verify: verify, + ImportFile: exportFile, + }, os.Stdout, os.Stderr) + + if err != nil { + formatter.PrintError(err, "Error during Upload") + os.Exit(errorcodes.ErrGeneric) + } + } } // initSketchPath returns the current working directory From 7abe0d5bff69096c9acdf78bb0494532f5490ab1 Mon Sep 17 00:00:00 2001 From: Maurizio Branca Date: Mon, 19 Aug 2019 12:18:05 +0200 Subject: [PATCH 2/2] Add few integration tests for compile command --- test/test_compile.py | 120 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 test/test_compile.py diff --git a/test/test_compile.py b/test/test_compile.py new file mode 100644 index 00000000000..4034b40718d --- /dev/null +++ b/test/test_compile.py @@ -0,0 +1,120 @@ +# This file is part of arduino-cli. + +# Copyright 2019 ARDUINO SA (http://www.arduino.cc/) + +# This software is released under the GNU General Public License version 3, +# which covers the main part of arduino-cli. +# The terms of this license can be found at: +# https://www.gnu.org/licenses/gpl-3.0.en.html + +# You can be released from the requirements of the above licenses by purchasing +# a commercial license. Buying such a license is mandatory if you want to modify or +# otherwise use the software for commercial activities involving the Arduino +# software without disclosing the source code of your own applications. To purchase +# a commercial license, send an email to license@arduino.cc. +import pytest +import json +import os + +from .common import running_on_ci + + +def test_compile_without_fqbn(run_command): + # Init the environment explicitly + result = run_command("core update-index") + assert result.ok + + # Download latest AVR + result = run_command("core install arduino:avr") + assert result.ok + + # Build sketch without FQBN + result = run_command("compile") + assert result.failed + + +def test_compile_with_simple_sketch(run_command, data_dir): + # Init the environment explicitly + result = run_command("core update-index") + assert result.ok + + # # Download latest AVR + result = run_command("core install arduino:avr") + assert result.ok + + sketch_path = os.path.join(data_dir, "CompileIntegrationTest") + + # Create a test sketch + result = run_command("sketch new CompileIntegrationTest") + assert result.ok + assert "Sketch created in: {}".format(sketch_path) in result.stdout + + # Build sketch for arduino:avr:uno + result = run_command("compile -b arduino:avr:uno {}".format(sketch_path)) + assert result.ok + assert "Sketch uses" in result.stdout + + +@pytest.mark.skipif(running_on_ci(), reason="VMs have no serial ports") +def test_compile_and_compile_combo(run_command, data_dir): + + # Init the environment explicitly + result = run_command("core update-index") + assert result.ok + + # Install required core(s) + result = run_command("core install arduino:avr") + # result = run_command("core install arduino:samd") + assert result.ok + + # Create a test sketch + sketch_path = os.path.join(data_dir, "CompileAndUploadIntegrationTest") + result = run_command("sketch new CompileAndUploadIntegrationTest") + assert result.ok + assert "Sketch created in: {}".format(sketch_path) in result.stdout + + # + # Build a list of detected boards to test, if any. + # + result = run_command("board list --format json") + assert result.ok + + # + # The `board list --format json` returns a JSON that looks like to the following: + # + # [ + # { + # "address": "/dev/cu.usbmodem14201", + # "protocol": "serial", + # "protocol_label": "Serial Port (USB)", + # "boards": [ + # { + # "name": "Arduino NANO 33 IoT", + # "FQBN": "arduino:samd:nano_33_iot" + # } + # ] + # } + # ] + + detected_boards = [] + + ports = json.loads(result.stdout) + assert isinstance(ports, list) + for port in ports: + boards = port.get('boards') + assert isinstance(boards, list) + for board in boards: + detected_boards.append(dict(address=port.get('address'), fqbn=board.get('FQBN'))) + + assert len(detected_boards) >= 1, "There are no boards available for testing" + + # Build sketch for each detected board + for board in detected_boards: + result = run_command( + "compile -b {fqbn} --upload -p {address} {sketch_path}".format( + fqbn=board.get('fqbn'), + address=board.get('address'), + sketch_path=sketch_path) + ) + assert result.ok + assert "Verify successful" in result.stdout