From 3989979ca3b30cbd5b13c31f1081e4f07d0d2ed9 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 7 May 2022 16:22:05 +0300 Subject: [PATCH] Pass extra arguments to the native program with a new "pio run --program-arg" option // Resolve #4246 --- HISTORY.rst | 1 + docs | 2 +- platformio/builder/main.py | 1 + platformio/commands/run/command.py | 36 +++++++++++++++++++++------- platformio/commands/run/processor.py | 20 +++++++++++++--- platformio/platform/_run.py | 14 +++++++---- 6 files changed, 56 insertions(+), 18 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 8930b255..4c98db7b 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -95,6 +95,7 @@ Please check `Migration guide from 5.x to 6.0 `__ program with a new `pio run --program-arg `__ option (`issue #4246 `_) - Improved PIO Remote setup on credit-card sized computers (Raspberry Pi, BeagleBon, etc) (`issue #3865 `_) - Finally removed all tracks to the Python 2.7, the Python 3.6 is the minimum supported version. diff --git a/docs b/docs index 7ea8af92..a035ea48 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 7ea8af9265f7fac72e9a116f14d9915526ddaa49 +Subproject commit a035ea48bb3e75a95931679455d2e21d63d80f78 diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 190bcbea..2a48c3ab 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -44,6 +44,7 @@ clivars.AddVariables( ("PIOENV",), ("PIOTEST_RUNNING_NAME",), ("UPLOAD_PORT",), + ("PROGRAM_ARGS",), ) DEFAULT_ENV_OPTIONS = dict( diff --git a/platformio/commands/run/command.py b/platformio/commands/run/command.py index 5eef20d6..add43a9a 100644 --- a/platformio/commands/run/command.py +++ b/platformio/commands/run/command.py @@ -66,10 +66,17 @@ except NotImplementedError: "Default is a number of CPUs in a system (N=%d)" % DEFAULT_JOB_NUMS ), ) -@click.option("-s", "--silent", is_flag=True) -@click.option("-v", "--verbose", is_flag=True) +@click.option( + "-a", + "--program-arg", + "program_args", + multiple=True, + help="A program argument (multiple are allowed)", +) @click.option("--disable-auto-clean", is_flag=True) @click.option("--list-targets", is_flag=True) +@click.option("-s", "--silent", is_flag=True) +@click.option("-v", "--verbose", is_flag=True) @click.pass_context def cli( ctx, @@ -79,10 +86,11 @@ def cli( project_dir, project_conf, jobs, - silent, - verbose, + program_args, disable_auto_clean, list_targets, + silent, + verbose, ): app.set_session_var("custom_project_conf", project_conf) @@ -138,10 +146,11 @@ def cli( environment, target, upload_port, + jobs, + program_args, + is_test_running, silent, verbose, - jobs, - is_test_running, ) ) @@ -165,16 +174,25 @@ def process_env( environments, targets, upload_port, + jobs, + program_args, + is_test_running, silent, verbose, - jobs, - is_test_running, ): if not is_test_running and not silent: print_processing_header(name, config, verbose) ep = EnvironmentProcessor( - ctx, name, config, targets, upload_port, silent, verbose, jobs + ctx, + name, + config, + targets, + upload_port, + jobs, + program_args, + silent, + verbose, ) result = {"env": name, "duration": time(), "succeeded": ep.process()} result["duration"] = time() - result["duration"] diff --git a/platformio/commands/run/processor.py b/platformio/commands/run/processor.py index dbeea442..4751d352 100644 --- a/platformio/commands/run/processor.py +++ b/platformio/commands/run/processor.py @@ -22,20 +22,34 @@ from platformio.test.runners.base import CTX_META_TEST_RUNNING_NAME class EnvironmentProcessor(object): def __init__( # pylint: disable=too-many-arguments - self, cmd_ctx, name, config, targets, upload_port, silent, verbose, jobs + self, + cmd_ctx, + name, + config, + targets, + upload_port, + jobs, + program_args, + silent, + verbose, ): self.cmd_ctx = cmd_ctx self.name = name self.config = config self.targets = [str(t) for t in targets] self.upload_port = upload_port + self.jobs = jobs + self.program_args = program_args self.silent = silent self.verbose = verbose - self.jobs = jobs self.options = config.items(env=name, as_dict=True) def get_build_variables(self): - variables = {"pioenv": self.name, "project_config": self.config.path} + variables = dict( + pioenv=self.name, + project_config=self.config.path, + program_args=self.program_args, + ) if CTX_META_TEST_RUNNING_NAME in self.cmd_ctx.meta: variables["piotest_running_name"] = self.cmd_ctx.meta[ diff --git a/platformio/platform/_run.py b/platformio/platform/_run.py index b389b56f..5bac13ae 100644 --- a/platformio/platform/_run.py +++ b/platformio/platform/_run.py @@ -13,6 +13,7 @@ # limitations under the License. import base64 +import json import os import re import sys @@ -21,7 +22,7 @@ from urllib.parse import quote import click from platformio import app, fs, proc, telemetry -from platformio.compat import hashlib_encode_data, is_bytes +from platformio.compat import hashlib_encode_data from platformio.package.manager.core import get_core_package_dir from platformio.platform.exception import BuildScriptNotFound @@ -32,13 +33,16 @@ class PlatformRunMixin(object): @staticmethod def encode_scons_arg(value): - data = base64.urlsafe_b64encode(hashlib_encode_data(value)) - return data.decode() if is_bytes(data) else data + if isinstance(value, (list, tuple, dict)): + value = json.dumps(value) + return base64.urlsafe_b64encode(hashlib_encode_data(value)).decode() @staticmethod def decode_scons_arg(data): - value = base64.urlsafe_b64decode(data) - return value.decode() if is_bytes(value) else value + value = base64.urlsafe_b64decode(data).decode() + if value.startswith(("[", "{")): + value = json.loads(value) + return value def run( # pylint: disable=too-many-arguments self, variables, targets, silent, verbose, jobs