From 96ea15d70c52af3b2fa2c458c1a0b64e9cf1ed56 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Thu, 5 Nov 2020 10:32:43 +0100 Subject: [PATCH 1/5] Add support for definitions containing quotes in compile --build-properties flag --- cli/compile/compile.go | 4 +- go.mod | 1 + legacy/builder/types/context.go | 16 --- test/conftest.py | 13 +- test/test_compile.py | 127 ++++++++++++++++++ test/test_sketch.py | 77 ++++++++--- .../sketch_with_multiple_defines.ino | 9 ++ .../sketch_with_single_define.ino | 8 ++ 8 files changed, 210 insertions(+), 45 deletions(-) create mode 100644 test/testdata/sketch_with_multiple_defines/sketch_with_multiple_defines.ino create mode 100644 test/testdata/sketch_with_single_define/sketch_with_single_define.ino diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 64a4f418ff0..d6119ec416a 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -72,8 +72,8 @@ func NewCommand() *cobra.Command { command.Flags().StringVarP(&exportDir, "output-dir", "", "", "Save build artifacts in this directory.") command.Flags().StringVar(&buildPath, "build-path", "", "Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS.") - command.Flags().StringSliceVar(&buildProperties, "build-properties", []string{}, - "List of custom build properties separated by commas. Or can be used multiple times for multiple properties.") + command.Flags().StringArrayVar(&buildProperties, "build-properties", []string{}, + "List of custom build properties separated by spaces. Or can be used multiple times for multiple properties.") command.Flags().StringVar(&warnings, "warnings", "none", `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.") diff --git a/go.mod b/go.mod index 020a4206274..4d1e5caa6f5 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/sirupsen/logrus v1.4.2 github.com/spf13/cobra v1.0.1-0.20200710201246-675ae5f5a98c github.com/spf13/jwalterweatherman v1.0.0 + github.com/spf13/pflag v1.0.3 github.com/spf13/viper v1.6.2 github.com/stretchr/testify v1.6.1 go.bug.st/cleanup v1.0.0 diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go index cd5510e1897..df913350842 100644 --- a/legacy/builder/types/context.go +++ b/legacy/builder/types/context.go @@ -187,22 +187,6 @@ func (ctx *Context) ExtractBuildOptions() *properties.Map { return opts } -func (ctx *Context) InjectBuildOptions(opts *properties.Map) { - ctx.HardwareDirs = paths.NewPathList(strings.Split(opts.Get("hardwareFolders"), ",")...) - ctx.BuiltInToolsDirs = paths.NewPathList(strings.Split(opts.Get("builtInToolsFolders"), ",")...) - ctx.BuiltInLibrariesDirs = paths.NewPathList(strings.Split(opts.Get("builtInLibrariesFolders"), ",")...) - ctx.OtherLibrariesDirs = paths.NewPathList(strings.Split(opts.Get("otherLibrariesFolders"), ",")...) - ctx.SketchLocation = opts.GetPath("sketchLocation") - fqbn, err := cores.ParseFQBN(opts.Get("fqbn")) - if err != nil { - i18n.ErrorfWithLogger(ctx.GetLogger(), "Error in FQBN: %s", err) - } - ctx.FQBN = fqbn - ctx.ArduinoAPIVersion = opts.Get("runtime.ide.version") - ctx.CustomBuildProperties = strings.Split(opts.Get("customBuildProperties"), ",") - ctx.OptimizationFlags = opts.Get("compiler.optimization_flags") -} - func (ctx *Context) GetLogger() i18n.Logger { if ctx.logger == nil { return &i18n.HumanLogger{} diff --git a/test/conftest.py b/test/conftest.py index ae60b74ab21..6f0c511462a 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -212,11 +212,14 @@ def detected_boards(run_command): @pytest.fixture(scope="function") def copy_sketch(working_dir): - # Copies sketch for testing - sketch_path = Path(__file__).parent / "testdata" / "sketch_simple" - test_sketch_path = Path(working_dir) / "sketch_simple" - shutil.copytree(sketch_path, test_sketch_path) - yield str(test_sketch_path) + def _copy(sketch_name): + # Copies sketch to working directory for testing + sketch_path = Path(__file__).parent / "testdata" / sketch_name + test_sketch_path = Path(working_dir, sketch_name) + shutil.copytree(sketch_path, test_sketch_path) + return str(test_sketch_path) + + return _copy @pytest.fixture(scope="function") diff --git a/test/test_compile.py b/test/test_compile.py index 5c714a9aca3..bf24273f6d2 100644 --- a/test/test_compile.py +++ b/test/test_compile.py @@ -233,6 +233,133 @@ def test_compile_without_precompiled_libraries(run_command, data_dir): assert result.ok +def test_compile_with_build_properties_flag(run_command, data_dir, copy_sketch): + # Init the environment explicitly + assert run_command("core update-index") + + # Install Arduino AVR Boards + assert run_command("core install arduino:avr@1.8.3") + + sketch_path = copy_sketch("sketch_with_single_string_define") + fqbn = "arduino:avr:uno" + + # Compile using a build property with quotes + res = run_command( + f"compile -b {fqbn} " + + '--build-properties="build.extra_flags=\\"-DMY_DEFINE=\\"hello world\\"\\"" ' + + f"{sketch_path} --verbose --clean" + ) + assert res.failed + assert "Flag --build-properties has been deprecated, please use --build-property instead." not in res.stderr + + # Try again with quotes + res = run_command( + f"compile -b {fqbn} " + + '--build-properties="build.extra_flags=-DMY_DEFINE=\\"hello\\"" ' + + f"{sketch_path} --verbose --clean" + ) + assert res.failed + assert "Flag --build-properties has been deprecated, please use --build-property instead." not in res.stderr + + # Try without quotes + sketch_path = copy_sketch("sketch_with_single_int_define") + res = run_command( + f"compile -b {fqbn} " + + '--build-properties="build.extra_flags=-DMY_DEFINE=1" ' + + f"{sketch_path} --verbose --clean" + ) + assert res.ok + assert "Flag --build-properties has been deprecated, please use --build-property instead." in res.stderr + assert "-DMY_DEFINE=1" in res.stdout + + sketch_path = copy_sketch("sketch_with_multiple_int_defines") + res = run_command( + f"compile -b {fqbn} " + + '--build-properties="build.extra_flags=-DFIRST_PIN=1,compiler.cpp.extra_flags=-DSECOND_PIN=2" ' + + f"{sketch_path} --verbose --clean" + ) + assert res.ok + assert "Flag --build-properties has been deprecated, please use --build-property instead." in res.stderr + assert "-DFIRST_PIN=1" in res.stdout + assert "-DSECOND_PIN=2" in res.stdout + + +def test_compile_with_build_property_containing_quotes(run_command, data_dir, copy_sketch): + # Init the environment explicitly + assert run_command("core update-index") + + # Install Arduino AVR Boards + assert run_command("core install arduino:avr@1.8.3") + + sketch_path = copy_sketch("sketch_with_single_string_define") + fqbn = "arduino:avr:uno" + + # Compile using a build property with quotes + res = run_command( + f"compile -b {fqbn} " + + '--build-property="build.extra_flags=\\"-DMY_DEFINE=\\"hello world\\"\\"" ' + + f"{sketch_path} --verbose" + ) + assert res.ok + assert '-DMY_DEFINE=\\"hello world\\"' in res.stdout + + +def test_compile_with_multiple_build_property_flags(run_command, data_dir, copy_sketch, working_dir): + # Init the environment explicitly + assert run_command("core update-index") + + # Install Arduino AVR Boards + assert run_command("core install arduino:avr@1.8.3") + + sketch_path = copy_sketch("sketch_with_multiple_defines") + fqbn = "arduino:avr:uno" + + # Compile using multiple build properties separated by a space + res = run_command( + f"compile -b {fqbn} " + + '--build-property="compiler.cpp.extra_flags=\\"-DPIN=2 -DSSID=\\"This is a String\\"\\"" ' + + f"{sketch_path} --verbose --clean" + ) + assert res.failed + + # Compile using multiple build properties separated by a space and properly quoted + res = run_command( + f"compile -b {fqbn} " + + '--build-property="compiler.cpp.extra_flags=-DPIN=2 \\"-DSSID=\\"This is a String\\"\\"" ' + + f"{sketch_path} --verbose --clean" + ) + assert res.ok + assert '-DPIN=2 "-DSSID=\\"This is a String\\""' in res.stdout + + # Tries compilation using multiple build properties separated by a comma + res = run_command( + f"compile -b {fqbn} " + + '--build-property="compiler.cpp.extra_flags=\\"-DPIN=2,-DSSID=\\"This is a String\\"\\"\\" ' + + f"{sketch_path} --verbose --clean" + ) + assert res.failed + + res = run_command( + f"compile -b {fqbn} " + + '--build-property="compiler.cpp.extra_flags=\\"-DPIN=2\\"" ' + + '--build-property="compiler.cpp.extra_flags=\\"-DSSID=\\"This is a String\\"\\"" ' + + f"{sketch_path} --verbose --clean" + ) + assert res.failed + assert "-DPIN=2" not in res.stdout + assert '-DSSID=\\"This is a String\\"' in res.stdout + + res = run_command( + f"compile -b {fqbn} " + + '--build-property="compiler.cpp.extra_flags=\\"-DPIN=2\\"" ' + + '--build-property="build.extra_flags=\\"-DSSID=\\"hello world\\"\\"" ' + + f"{sketch_path} --verbose --clean" + ) + assert res.ok + assert "-DPIN=2" in res.stdout + assert '-DSSID=\\"hello world\\"' in res.stdout + + def test_compile_with_output_dir_flag(run_command, data_dir): # Init the environment explicitly run_command("core update-index") diff --git a/test/test_sketch.py b/test/test_sketch.py index 036cead5083..99abda64fb6 100644 --- a/test/test_sketch.py +++ b/test/test_sketch.py @@ -95,7 +95,7 @@ def verify_zip_contains_sketch_including_build_dir(files): def test_sketch_archive_no_args(run_command, copy_sketch, working_dir): - result = run_command("sketch archive", copy_sketch) + result = run_command("sketch archive", copy_sketch("sketch_simple")) print(result.stderr) assert result.ok @@ -108,7 +108,7 @@ def test_sketch_archive_no_args(run_command, copy_sketch, working_dir): def test_sketch_archive_dot_arg(run_command, copy_sketch, working_dir): - result = run_command("sketch archive .", copy_sketch) + result = run_command("sketch archive .", copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{working_dir}/sketch_simple.zip") @@ -124,7 +124,7 @@ def test_sketch_archive_dot_arg_relative_zip_path(run_command, copy_sketch, work archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command("sketch archive . ../my_archives", copy_sketch) + result = run_command("sketch archive . ../my_archives", copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{working_dir}/my_archives/sketch_simple.zip") @@ -140,7 +140,7 @@ def test_sketch_archive_dot_arg_absolute_zip_path(run_command, copy_sketch, work archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command(f'sketch archive . "{archives_folder}"', copy_sketch) + result = run_command(f'sketch archive . "{archives_folder}"', copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{archives_folder}/sketch_simple.zip") @@ -156,7 +156,7 @@ def test_sketch_archive_dot_arg_relative_zip_path_and_name_without_extension(run archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command("sketch archive . ../my_archives/my_custom_sketch", copy_sketch) + result = run_command("sketch archive . ../my_archives/my_custom_sketch", copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{working_dir}/my_archives/my_custom_sketch.zip") @@ -172,7 +172,7 @@ def test_sketch_archive_dot_arg_absolute_zip_path_and_name_without_extension(run archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command(f'sketch archive . "{archives_folder}/my_custom_sketch"', copy_sketch) + result = run_command(f'sketch archive . "{archives_folder}/my_custom_sketch"', copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{archives_folder}/my_custom_sketch.zip") @@ -188,7 +188,7 @@ def test_sketch_archive_dot_arg_custom_zip_path_and_name_with_extension(run_comm archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command(f'sketch archive . "{archives_folder}/my_custom_sketch.zip"', copy_sketch) + result = run_command(f'sketch archive . "{archives_folder}/my_custom_sketch.zip"', copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{archives_folder}/my_custom_sketch.zip") @@ -200,6 +200,7 @@ def test_sketch_archive_dot_arg_custom_zip_path_and_name_with_extension(run_comm def test_sketch_archive_relative_sketch_path(run_command, copy_sketch, working_dir): + copy_sketch("sketch_simple") result = run_command("sketch archive ./sketch_simple") assert result.ok @@ -212,7 +213,7 @@ def test_sketch_archive_relative_sketch_path(run_command, copy_sketch, working_d def test_sketch_archive_absolute_sketch_path(run_command, copy_sketch, working_dir): - result = run_command(f'sketch archive "{working_dir}/sketch_simple"', copy_sketch) + result = run_command(f'sketch archive "{working_dir}/sketch_simple"', copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{working_dir}/sketch_simple.zip") @@ -224,6 +225,7 @@ def test_sketch_archive_absolute_sketch_path(run_command, copy_sketch, working_d def test_sketch_archive_relative_sketch_path_with_relative_zip_path(run_command, copy_sketch, working_dir): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -240,6 +242,7 @@ def test_sketch_archive_relative_sketch_path_with_relative_zip_path(run_command, def test_sketch_archive_relative_sketch_path_with_absolute_zip_path(run_command, copy_sketch, working_dir): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -258,6 +261,7 @@ def test_sketch_archive_relative_sketch_path_with_absolute_zip_path(run_command, def test_sketch_archive_relative_sketch_path_with_relative_zip_path_and_name_without_extension( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -276,6 +280,7 @@ def test_sketch_archive_relative_sketch_path_with_relative_zip_path_and_name_wit def test_sketch_archive_relative_sketch_path_with_relative_zip_path_and_name_with_extension( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -294,6 +299,7 @@ def test_sketch_archive_relative_sketch_path_with_relative_zip_path_and_name_wit def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_and_name_without_extension( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -312,6 +318,7 @@ def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_and_name_wit def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_and_name_with_extension( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -328,6 +335,7 @@ def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_and_name_wit def test_sketch_archive_absolute_sketch_path_with_relative_zip_path(run_command, copy_sketch, working_dir): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -348,7 +356,9 @@ def test_sketch_archive_absolute_sketch_path_with_absolute_zip_path(run_command, archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command(f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}"', copy_sketch) + result = run_command( + f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}"', copy_sketch("sketch_simple") + ) assert result.ok archive = zipfile.ZipFile(f"{archives_folder}/sketch_simple.zip") @@ -362,6 +372,7 @@ def test_sketch_archive_absolute_sketch_path_with_absolute_zip_path(run_command, def test_sketch_archive_absolute_sketch_path_with_relative_zip_path_and_name_without_extension( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -380,6 +391,7 @@ def test_sketch_archive_absolute_sketch_path_with_relative_zip_path_and_name_wit def test_sketch_archive_absolute_sketch_path_with_relative_zip_path_and_name_with_extension( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -403,7 +415,8 @@ def test_sketch_archive_absolute_sketch_path_with_absolute_zip_path_and_name_wit Path(archives_folder).mkdir() result = run_command( - f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}/my_custom_sketch"', copy_sketch + f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}/my_custom_sketch"', + copy_sketch("sketch_simple"), ) assert result.ok @@ -423,7 +436,8 @@ def test_sketch_archive_absolute_sketch_path_with_absolute_zip_path_and_name_wit Path(archives_folder).mkdir() result = run_command( - f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}/my_custom_sketch.zip"', copy_sketch + f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}/my_custom_sketch.zip"', + copy_sketch("sketch_simple"), ) assert result.ok @@ -436,7 +450,7 @@ def test_sketch_archive_absolute_sketch_path_with_absolute_zip_path_and_name_wit def test_sketch_archive_no_args_with_include_build_dir_flag(run_command, copy_sketch, working_dir): - result = run_command("sketch archive --include-build-dir", copy_sketch) + result = run_command("sketch archive --include-build-dir", copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{working_dir}/sketch_simple.zip") @@ -448,7 +462,7 @@ def test_sketch_archive_no_args_with_include_build_dir_flag(run_command, copy_sk def test_sketch_archive_dot_arg_with_include_build_dir_flag(run_command, copy_sketch, working_dir): - result = run_command("sketch archive . --include-build-dir", copy_sketch) + result = run_command("sketch archive . --include-build-dir", copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{working_dir}/sketch_simple.zip") @@ -464,7 +478,7 @@ def test_sketch_archive_dot_arg_relative_zip_path_with_include_build_dir_flag(ru archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command("sketch archive . ../my_archives --include-build-dir", copy_sketch) + result = run_command("sketch archive . ../my_archives --include-build-dir", copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{working_dir}/my_archives/sketch_simple.zip") @@ -480,7 +494,7 @@ def test_sketch_archive_dot_arg_absolute_zip_path_with_include_build_dir_flag(ru archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command(f'sketch archive . "{archives_folder}" --include-build-dir', copy_sketch) + result = run_command(f'sketch archive . "{archives_folder}" --include-build-dir', copy_sketch("sketch_simple")) assert result.ok archive = zipfile.ZipFile(f"{archives_folder}/sketch_simple.zip") @@ -498,7 +512,9 @@ def test_sketch_archive_dot_arg_relative_zip_path_and_name_without_extension_wit archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command("sketch archive . ../my_archives/my_custom_sketch --include-build-dir", copy_sketch) + result = run_command( + "sketch archive . ../my_archives/my_custom_sketch --include-build-dir", copy_sketch("sketch_simple") + ) assert result.ok archive = zipfile.ZipFile(f"{working_dir}/my_archives/my_custom_sketch.zip") @@ -516,7 +532,9 @@ def test_sketch_archive_dot_arg_absolute_zip_path_and_name_without_extension_wit archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command(f'sketch archive . "{archives_folder}/my_custom_sketch" --include-build-dir', copy_sketch) + result = run_command( + f'sketch archive . "{archives_folder}/my_custom_sketch" --include-build-dir', copy_sketch("sketch_simple") + ) assert result.ok archive = zipfile.ZipFile(f"{archives_folder}/my_custom_sketch.zip") @@ -534,7 +552,9 @@ def test_sketch_archive_dot_arg_custom_zip_path_and_name_with_extension_with_inc archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() - result = run_command(f'sketch archive . "{archives_folder}/my_custom_sketch.zip" --include-build-dir', copy_sketch) + result = run_command( + f'sketch archive . "{archives_folder}/my_custom_sketch.zip" --include-build-dir', copy_sketch("sketch_simple") + ) assert result.ok archive = zipfile.ZipFile(f"{archives_folder}/my_custom_sketch.zip") @@ -546,6 +566,7 @@ def test_sketch_archive_dot_arg_custom_zip_path_and_name_with_extension_with_inc def test_sketch_archive_relative_sketch_path_with_include_build_dir_flag(run_command, copy_sketch, working_dir): + copy_sketch("sketch_simple") result = run_command("sketch archive ./sketch_simple --include-build-dir") assert result.ok @@ -558,7 +579,9 @@ def test_sketch_archive_relative_sketch_path_with_include_build_dir_flag(run_com def test_sketch_archive_absolute_sketch_path_with_include_build_dir_flag(run_command, copy_sketch, working_dir): - result = run_command(f'sketch archive "{working_dir}/sketch_simple" --include-build-dir', copy_sketch) + result = run_command( + f'sketch archive "{working_dir}/sketch_simple" --include-build-dir', copy_sketch("sketch_simple") + ) assert result.ok archive = zipfile.ZipFile(f"{working_dir}/sketch_simple.zip") @@ -572,6 +595,7 @@ def test_sketch_archive_absolute_sketch_path_with_include_build_dir_flag(run_com def test_sketch_archive_relative_sketch_path_with_relative_zip_path_with_include_build_dir_flag( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -590,6 +614,7 @@ def test_sketch_archive_relative_sketch_path_with_relative_zip_path_with_include def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_with_include_build_dir_flag( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -608,6 +633,7 @@ def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_with_include def test_sketch_archive_relative_sketch_path_with_relative_zip_path_and_name_without_extension_with_include_build_dir_flag( # noqa run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -626,6 +652,7 @@ def test_sketch_archive_relative_sketch_path_with_relative_zip_path_and_name_wit def test_sketch_archive_relative_sketch_path_with_relative_zip_path_and_name_with_extension_with_include_build_dir_flag( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -644,6 +671,7 @@ def test_sketch_archive_relative_sketch_path_with_relative_zip_path_and_name_wit def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_and_name_without_extension_with_include_build_dir_flag( # noqa run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -662,6 +690,7 @@ def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_and_name_wit def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_and_name_with_extension_with_include_build_dir_flag( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -680,6 +709,7 @@ def test_sketch_archive_relative_sketch_path_with_absolute_zip_path_and_name_wit def test_sketch_archive_absolute_sketch_path_with_relative_zip_path_with_include_build_dir_flag( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -703,7 +733,8 @@ def test_sketch_archive_absolute_sketch_path_with_absolute_zip_path_with_include Path(archives_folder).mkdir() result = run_command( - f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}" --include-build-dir', copy_sketch + f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}" --include-build-dir', + copy_sketch("sketch_simple"), ) assert result.ok @@ -718,6 +749,7 @@ def test_sketch_archive_absolute_sketch_path_with_absolute_zip_path_with_include def test_sketch_archive_absolute_sketch_path_with_relative_zip_path_and_name_without_extension_with_include_build_dir_flag( # noqa run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -738,6 +770,7 @@ def test_sketch_archive_absolute_sketch_path_with_relative_zip_path_and_name_wit def test_sketch_archive_absolute_sketch_path_with_relative_zip_path_and_name_with_extension_with_include_build_dir_flag( run_command, copy_sketch, working_dir ): + copy_sketch("sketch_simple") # Creates a folder where to save the zip archives_folder = f"{working_dir}/my_archives/" Path(archives_folder).mkdir() @@ -764,7 +797,7 @@ def test_sketch_archive_absolute_sketch_path_with_absolute_zip_path_and_name_wit result = run_command( f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}/my_custom_sketch" --include-build-dir', - copy_sketch, + copy_sketch("sketch_simple"), ) assert result.ok @@ -785,7 +818,7 @@ def test_sketch_archive_absolute_sketch_path_with_absolute_zip_path_and_name_wit result = run_command( f'sketch archive "{working_dir}/sketch_simple" "{archives_folder}/my_custom_sketch.zip" --include-build-dir', - copy_sketch, + copy_sketch("sketch_simple"), ) assert result.ok diff --git a/test/testdata/sketch_with_multiple_defines/sketch_with_multiple_defines.ino b/test/testdata/sketch_with_multiple_defines/sketch_with_multiple_defines.ino new file mode 100644 index 00000000000..ed5f9eeba44 --- /dev/null +++ b/test/testdata/sketch_with_multiple_defines/sketch_with_multiple_defines.ino @@ -0,0 +1,9 @@ + +const int DEFAULT_PIN = PIN; +const String DEFAULT_SSID = SSID; + +void setup() { +} + +void loop() { +} diff --git a/test/testdata/sketch_with_single_define/sketch_with_single_define.ino b/test/testdata/sketch_with_single_define/sketch_with_single_define.ino new file mode 100644 index 00000000000..75a6d4ffe1a --- /dev/null +++ b/test/testdata/sketch_with_single_define/sketch_with_single_define.ino @@ -0,0 +1,8 @@ + +const String FOO = MY_DEFINE; + +void setup() { +} + +void loop() { +} From 32e0d95b1af76388a3f244d94c30e4bd0530cc17 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Fri, 23 Oct 2020 12:24:11 +0200 Subject: [PATCH 2/5] Revert back a function --- legacy/builder/types/context.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go index df913350842..cd5510e1897 100644 --- a/legacy/builder/types/context.go +++ b/legacy/builder/types/context.go @@ -187,6 +187,22 @@ func (ctx *Context) ExtractBuildOptions() *properties.Map { return opts } +func (ctx *Context) InjectBuildOptions(opts *properties.Map) { + ctx.HardwareDirs = paths.NewPathList(strings.Split(opts.Get("hardwareFolders"), ",")...) + ctx.BuiltInToolsDirs = paths.NewPathList(strings.Split(opts.Get("builtInToolsFolders"), ",")...) + ctx.BuiltInLibrariesDirs = paths.NewPathList(strings.Split(opts.Get("builtInLibrariesFolders"), ",")...) + ctx.OtherLibrariesDirs = paths.NewPathList(strings.Split(opts.Get("otherLibrariesFolders"), ",")...) + ctx.SketchLocation = opts.GetPath("sketchLocation") + fqbn, err := cores.ParseFQBN(opts.Get("fqbn")) + if err != nil { + i18n.ErrorfWithLogger(ctx.GetLogger(), "Error in FQBN: %s", err) + } + ctx.FQBN = fqbn + ctx.ArduinoAPIVersion = opts.Get("runtime.ide.version") + ctx.CustomBuildProperties = strings.Split(opts.Get("customBuildProperties"), ",") + ctx.OptimizationFlags = opts.Get("compiler.optimization_flags") +} + func (ctx *Context) GetLogger() i18n.Logger { if ctx.logger == nil { return &i18n.HumanLogger{} From 1f7d7f8a9d1835d82c742c9960fadb2b51d2c3cc Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Mon, 26 Oct 2020 17:15:32 +0100 Subject: [PATCH 3/5] Deprecate --build-properties flag in favor of --build-property --- cli/compile/compile.go | 24 ++++++++++++------- .../sketch_with_multiple_defines.ino | 3 +++ .../sketch_with_multiple_int_defines.ino | 12 ++++++++++ .../sketch_with_single_int_define.ino | 10 ++++++++ .../sketch_with_single_string_define.ino} | 2 ++ 5 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 test/testdata/sketch_with_multiple_int_defines/sketch_with_multiple_int_defines.ino create mode 100644 test/testdata/sketch_with_single_int_define/sketch_with_single_int_define.ino rename test/testdata/{sketch_with_single_define/sketch_with_single_define.ino => sketch_with_single_string_define/sketch_with_single_string_define.ino} (57%) diff --git a/cli/compile/compile.go b/cli/compile/compile.go index d6119ec416a..2b199894b0f 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -57,12 +57,16 @@ var ( // NewCommand created a new `compile` command func NewCommand() *cobra.Command { command := &cobra.Command{ - Use: "compile", - Short: "Compiles Arduino sketches.", - Long: "Compiles Arduino sketches.", - Example: " " + os.Args[0] + " compile -b arduino:avr:uno /home/user/Arduino/MySketch", - Args: cobra.MaximumNArgs(1), - Run: run, + Use: "compile", + Short: "Compiles Arduino sketches.", + Long: "Compiles Arduino sketches.", + Example: "" + + " " + os.Args[0] + " compile -b arduino:avr:uno /home/user/Arduino/MySketch\n" + + " " + os.Args[0] + " compile -b arduino:avr:uno --build-property='build.extra_flags=\"-DMY_DEFINE=\"hello world\"\"' /home/user/Arduino/MySketch\n" + + " " + os.Args[0] + " compile -b arduino:avr:uno --build-property='build.extra_flags=-DPIN=2 \"-DMY_DEFINE=\"hello world\"\"' /home/user/Arduino/MySketch\n" + + " " + os.Args[0] + " compile -b arduino:avr:uno --build-property=build.extra_flags=-DPIN=2 --build-property='compiler.cpp.extra_flags=\"-DSSID=\"hello world\"\"'-DMY_DEFINE=\"hello world\"' /home/user/Arduino/MySketch\n", + Args: cobra.MaximumNArgs(1), + Run: run, } command.Flags().StringVarP(&fqbn, "fqbn", "b", "", "Fully Qualified Board Name, e.g.: arduino:avr:uno") @@ -72,8 +76,10 @@ func NewCommand() *cobra.Command { command.Flags().StringVarP(&exportDir, "output-dir", "", "", "Save build artifacts in this directory.") command.Flags().StringVar(&buildPath, "build-path", "", "Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS.") - command.Flags().StringArrayVar(&buildProperties, "build-properties", []string{}, - "List of custom build properties separated by spaces. Or can be used multiple times for multiple properties.") + command.Flags().StringSliceVar(&buildProperties, "build-properties", []string{}, + "List of custom build properties separated by commas. Or can be used multiple times for multiple properties.") + command.Flags().StringArrayVar(&buildProperties, "build-property", []string{}, + "Override a build property with a custom value. Can be used multiple times for multiple properties.") command.Flags().StringVar(&warnings, "warnings", "none", `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.") @@ -95,6 +101,8 @@ func NewCommand() *cobra.Command { configuration.Settings.BindPFlag("sketch.always_export_binaries", command.Flags().Lookup("export-binaries")) + command.Flags().MarkDeprecated("build-properties", "please use --build-property instead.") + return command } diff --git a/test/testdata/sketch_with_multiple_defines/sketch_with_multiple_defines.ino b/test/testdata/sketch_with_multiple_defines/sketch_with_multiple_defines.ino index ed5f9eeba44..140baaa885a 100644 --- a/test/testdata/sketch_with_multiple_defines/sketch_with_multiple_defines.ino +++ b/test/testdata/sketch_with_multiple_defines/sketch_with_multiple_defines.ino @@ -3,6 +3,9 @@ const int DEFAULT_PIN = PIN; const String DEFAULT_SSID = SSID; void setup() { + Serial.begin(9600); + Serial.println(DEFAULT_PIN); + Serial.println(DEFAULT_SSID); } void loop() { diff --git a/test/testdata/sketch_with_multiple_int_defines/sketch_with_multiple_int_defines.ino b/test/testdata/sketch_with_multiple_int_defines/sketch_with_multiple_int_defines.ino new file mode 100644 index 00000000000..070784f33ed --- /dev/null +++ b/test/testdata/sketch_with_multiple_int_defines/sketch_with_multiple_int_defines.ino @@ -0,0 +1,12 @@ + +const int MY_FIRST_PIN = FIRST_PIN; +const int MY_SECOND_PIN = SECOND_PIN; + +void setup() { + Serial.begin(9600); + Serial.println(MY_FIRST_PIN); + Serial.println(MY_SECOND_PIN); +} + +void loop() { +} diff --git a/test/testdata/sketch_with_single_int_define/sketch_with_single_int_define.ino b/test/testdata/sketch_with_single_int_define/sketch_with_single_int_define.ino new file mode 100644 index 00000000000..fee3ca10a1f --- /dev/null +++ b/test/testdata/sketch_with_single_int_define/sketch_with_single_int_define.ino @@ -0,0 +1,10 @@ + +const int FOO = MY_DEFINE; + +void setup() { + Serial.begin(9600); + Serial.println(FOO); +} + +void loop() { +} diff --git a/test/testdata/sketch_with_single_define/sketch_with_single_define.ino b/test/testdata/sketch_with_single_string_define/sketch_with_single_string_define.ino similarity index 57% rename from test/testdata/sketch_with_single_define/sketch_with_single_define.ino rename to test/testdata/sketch_with_single_string_define/sketch_with_single_string_define.ino index 75a6d4ffe1a..919ba848ab9 100644 --- a/test/testdata/sketch_with_single_define/sketch_with_single_define.ino +++ b/test/testdata/sketch_with_single_string_define/sketch_with_single_string_define.ino @@ -2,6 +2,8 @@ const String FOO = MY_DEFINE; void setup() { + Serial.begin(9600); + Serial.println(FOO); } void loop() { From 64930c7f417361b0560556da8e66f10629eb131c Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Mon, 26 Oct 2020 18:27:24 +0100 Subject: [PATCH 4/5] Fix some escaping issues on Windows --- cli/compile/compile.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 2b199894b0f..6257510f9e9 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -62,9 +62,9 @@ func NewCommand() *cobra.Command { Long: "Compiles Arduino sketches.", Example: "" + " " + os.Args[0] + " compile -b arduino:avr:uno /home/user/Arduino/MySketch\n" + - " " + os.Args[0] + " compile -b arduino:avr:uno --build-property='build.extra_flags=\"-DMY_DEFINE=\"hello world\"\"' /home/user/Arduino/MySketch\n" + - " " + os.Args[0] + " compile -b arduino:avr:uno --build-property='build.extra_flags=-DPIN=2 \"-DMY_DEFINE=\"hello world\"\"' /home/user/Arduino/MySketch\n" + - " " + os.Args[0] + " compile -b arduino:avr:uno --build-property=build.extra_flags=-DPIN=2 --build-property='compiler.cpp.extra_flags=\"-DSSID=\"hello world\"\"'-DMY_DEFINE=\"hello world\"' /home/user/Arduino/MySketch\n", + " " + os.Args[0] + " compile -b arduino:avr:uno --build-property=\"build.extra_flags=\\\"-DMY_DEFINE=\\\"hello world\\\"\\\"\" /home/user/Arduino/MySketch\n" + + " " + os.Args[0] + " compile -b arduino:avr:uno --build-property=\"build.extra_flags=-DPIN=2 \\\"-DMY_DEFINE=\\\"hello world\\\"\\\"\" /home/user/Arduino/MySketch\n" + + " " + os.Args[0] + " compile -b arduino:avr:uno --build-property=build.extra_flags=-DPIN=2 --build-property=\"compiler.cpp.extra_flags=\\\"-DSSID=\\\"hello world\\\"\\\"\"-DMY_DEFINE=\"hello world\"' /home/user/Arduino/MySketch\n", Args: cobra.MaximumNArgs(1), Run: run, } From e3507b4f90e768e36eaa61411bce8793b01314b0 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Wed, 28 Oct 2020 16:18:54 +0100 Subject: [PATCH 5/5] Simplify compile examples --- cli/compile/compile.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 6257510f9e9..23e65758e7b 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -62,9 +62,9 @@ func NewCommand() *cobra.Command { Long: "Compiles Arduino sketches.", Example: "" + " " + os.Args[0] + " compile -b arduino:avr:uno /home/user/Arduino/MySketch\n" + - " " + os.Args[0] + " compile -b arduino:avr:uno --build-property=\"build.extra_flags=\\\"-DMY_DEFINE=\\\"hello world\\\"\\\"\" /home/user/Arduino/MySketch\n" + - " " + os.Args[0] + " compile -b arduino:avr:uno --build-property=\"build.extra_flags=-DPIN=2 \\\"-DMY_DEFINE=\\\"hello world\\\"\\\"\" /home/user/Arduino/MySketch\n" + - " " + os.Args[0] + " compile -b arduino:avr:uno --build-property=build.extra_flags=-DPIN=2 --build-property=\"compiler.cpp.extra_flags=\\\"-DSSID=\\\"hello world\\\"\\\"\"-DMY_DEFINE=\"hello world\"' /home/user/Arduino/MySketch\n", + " " + os.Args[0] + ` compile -b arduino:avr:uno --build-property "build.extra_flags=\"-DMY_DEFINE=\"hello world\"\"" /home/user/Arduino/MySketch` + "\n" + + " " + os.Args[0] + ` compile -b arduino:avr:uno --build-property "build.extra_flags=-DPIN=2 \"-DMY_DEFINE=\"hello world\"\"" /home/user/Arduino/MySketch` + "\n" + + " " + os.Args[0] + ` compile -b arduino:avr:uno --build-property build.extra_flags=-DPIN=2 --build-property "compiler.cpp.extra_flags=\"-DSSID=\"hello world\"\"" /home/user/Arduino/MySketch` + "\n", Args: cobra.MaximumNArgs(1), Run: run, }