Better handling "clean" & "monitor" targets

This commit is contained in:
Ivan Kravets
2023-04-25 20:47:04 +03:00
parent 53cd43b676
commit c8eea40dd0
6 changed files with 123 additions and 105 deletions

View File

@ -168,7 +168,7 @@ env.SConsignFile(
env.SConscript(env.GetExtraScripts("pre"), exports="env")
if env.IsCleanTarget():
env.CleanProject("cleanall" in COMMAND_LINE_TARGETS)
env.CleanProject(fullclean=int(ARGUMENTS.get("FULLCLEAN", 0)))
env.Exit(0)
env.SConscript("$BUILD_SCRIPT")

View File

@ -16,7 +16,6 @@ import os
from SCons.Action import Action # pylint: disable=import-error
from SCons.Script import ARGUMENTS # pylint: disable=import-error
from SCons.Script import COMMAND_LINE_TARGETS # pylint: disable=import-error
from SCons.Script import AlwaysBuild # pylint: disable=import-error
from platformio import compat, fs
@ -29,10 +28,10 @@ def VerboseAction(_, act, actstr):
def IsCleanTarget(env):
return env.GetOption("clean") or ("cleanall" in COMMAND_LINE_TARGETS)
return env.GetOption("clean")
def CleanProject(env, clean_all=False):
def CleanProject(env, fullclean=False):
def _relpath(path):
if compat.IS_WINDOWS:
prefix = os.getcwd()[:2].lower()
@ -56,7 +55,7 @@ def CleanProject(env, clean_all=False):
else:
print("Build environment is clean")
if clean_all and os.path.isdir(libdeps_dir):
if fullclean and os.path.isdir(libdeps_dir):
_clean_dir(libdeps_dir)
print("Done cleaning")

View File

@ -25,6 +25,7 @@ from platformio import app, fs, proc, telemetry
from platformio.compat import hashlib_encode_data
from platformio.package.manager.core import get_core_package_dir
from platformio.platform.exception import BuildScriptNotFound
from platformio.run.helpers import KNOWN_CLEAN_TARGETS, KNOWN_FULLCLEAN_TARGETS
class PlatformRunMixin:
@ -56,9 +57,6 @@ class PlatformRunMixin:
self.silent = silent
self.verbose = verbose or app.get_setting("force_verbose")
if "clean" in targets:
targets = ["-c", "."]
variables["platform_manifest"] = self.manifest_path
if "build_script" not in variables:
@ -92,10 +90,18 @@ class PlatformRunMixin:
"--sconstruct",
os.path.join(fs.get_source_dir(), "builder", "main.py"),
]
args.append("PIOVERBOSE=%d" % (1 if self.verbose else 0))
args.append("PIOVERBOSE=%d" % int(self.verbose))
# pylint: disable=protected-access
args.append("ISATTY=%d" % (1 if click._compat.isatty(sys.stdout) else 0))
args += targets
args.append("ISATTY=%d" % int(click._compat.isatty(sys.stdout)))
if set(KNOWN_CLEAN_TARGETS + KNOWN_FULLCLEAN_TARGETS) & set(targets):
args.append("--clean")
args.append(
"FULLCLEAN=%d"
% (1 if set(KNOWN_FULLCLEAN_TARGETS) & set(targets) else 0)
)
elif targets:
args.extend(targets)
# encode and append variables
for key, value in variables.items():

View File

@ -26,7 +26,7 @@ from platformio.device.monitor.command import device_monitor_cmd
from platformio.project.config import ProjectConfig
from platformio.project.exception import ProjectError
from platformio.project.helpers import find_project_dir_above, load_build_metadata
from platformio.run.helpers import clean_build_dir, handle_legacy_libdeps
from platformio.run.helpers import clean_build_dir
from platformio.run.processor import EnvironmentProcessor
from platformio.test.runners.base import CTX_META_TEST_IS_RUNNING
@ -97,10 +97,12 @@ def cli(
if os.path.isfile(project_dir):
project_dir = find_project_dir_above(project_dir)
targets = list(target) if target else []
del target
only_monitor = targets == ["monitor"]
is_test_running = CTX_META_TEST_IS_RUNNING in ctx.meta
only_monitor = "monitor" in target and len(target) == 1
command_failed = False
with fs.cd(project_dir):
config = ProjectConfig.get_instance(project_conf)
config.validate(environment)
@ -108,59 +110,60 @@ def cli(
if list_targets:
return print_target_list(list(environment) or config.envs())
if not only_monitor:
# clean obsolete build dir
if not disable_auto_clean:
build_dir = config.get("platformio", "build_dir")
try:
clean_build_dir(build_dir, config)
except ProjectError as exc:
raise exc
except: # pylint: disable=bare-except
click.secho(
"Can not remove temporary directory `%s`. Please remove "
"it manually to avoid build issues" % build_dir,
fg="yellow",
)
default_envs = config.default_envs()
results = []
for env in config.envs():
skipenv = any(
[
environment and env not in environment,
not environment and default_envs and env not in default_envs,
]
# clean obsolete build dir
if not only_monitor and not disable_auto_clean:
build_dir = config.get("platformio", "build_dir")
try:
clean_build_dir(build_dir, config)
except ProjectError as exc:
raise exc
except: # pylint: disable=bare-except
click.secho(
"Can not remove temporary directory `%s`. Please remove "
"it manually to avoid build issues" % build_dir,
fg="yellow",
)
if skipenv:
results.append({"env": env})
continue
# print empty line between multi environment project
if not silent and any(r.get("succeeded") is not None for r in results):
click.echo()
default_envs = config.default_envs()
results = []
for env in config.envs():
skipenv = any(
[
environment and env not in environment,
not environment and default_envs and env not in default_envs,
]
)
if skipenv:
results.append({"env": env})
continue
results.append(
process_env(
ctx,
env,
config,
target,
upload_port,
jobs,
program_args,
is_test_running,
silent,
verbose,
)
# print empty line between multi environment project
if not silent and any(r.get("succeeded") is not None for r in results):
click.echo()
results.append(
process_env(
ctx,
env,
config,
targets,
upload_port,
monitor_port,
jobs,
program_args,
is_test_running,
silent,
verbose,
)
command_failed = any(r.get("succeeded") is False for r in results)
if (
not is_test_running
and (command_failed or not silent)
and len(results) > 1
):
print_processing_summary(results, verbose)
)
command_failed = any(r.get("succeeded") is False for r in results)
if (
not is_test_running
and not only_monitor
and (command_failed or not silent)
and len(results) > 1
):
print_processing_summary(results, verbose)
# Reset custom project config
app.set_session_var("custom_project_conf", None)
@ -168,14 +171,6 @@ def cli(
if command_failed:
raise exception.ReturnErrorCode(1)
if "monitor" in target and "nobuild" not in target:
ctx.invoke(
device_monitor_cmd,
project_dir=project_dir,
port=monitor_port,
environment=environment[0] if environment else None,
)
return True
@ -185,6 +180,7 @@ def process_env(
config,
targets,
upload_port,
monitor_port,
jobs,
program_args,
is_test_running,
@ -194,22 +190,38 @@ def process_env(
if not is_test_running and not silent:
print_processing_header(name, config, verbose)
ep = EnvironmentProcessor(
ctx,
name,
config,
targets,
upload_port,
jobs,
program_args,
silent,
verbose,
)
result = {"env": name, "duration": time(), "succeeded": ep.process()}
targets = targets or config.get(f"env:{name}", "targets", [])
only_monitor = targets == ["monitor"]
result = {"env": name, "duration": time(), "succeeded": True}
if not only_monitor:
result["succeeded"] = EnvironmentProcessor(
ctx,
name,
config,
[t for t in targets if t != "monitor"],
upload_port,
jobs,
program_args,
silent,
verbose,
).process()
if "monitor" in targets and "nobuild" not in targets:
ctx.invoke(
device_monitor_cmd,
port=monitor_port,
environment=name,
)
result["duration"] = time() - result["duration"]
# print footer on error or when is not unit testing
if not is_test_running and (not silent or not result["succeeded"]):
if (
not is_test_running
and not only_monitor
and (not silent or not result["succeeded"])
):
print_processing_footer(result)
return result

View File

@ -18,6 +18,10 @@ from os.path import isdir, isfile, join
from platformio import fs
from platformio.project.helpers import compute_project_checksum, get_project_dir
KNOWN_CLEAN_TARGETS = ("clean",)
KNOWN_FULLCLEAN_TARGETS = ("cleanall", "fullclean")
KNOWN_ALLCLEAN_TARGETS = KNOWN_CLEAN_TARGETS + KNOWN_FULLCLEAN_TARGETS
def clean_build_dir(build_dir, config):
# remove legacy ".pioenvs" folder

View File

@ -15,6 +15,7 @@
from platformio.package.commands.install import install_project_env_dependencies
from platformio.platform.factory import PlatformFactory
from platformio.project.exception import UndefinedEnvPlatformError
from platformio.run.helpers import KNOWN_ALLCLEAN_TARGETS
from platformio.test.runners.base import CTX_META_TEST_RUNNING_NAME
# pylint: disable=too-many-instance-attributes
@ -36,7 +37,7 @@ class EnvironmentProcessor:
self.cmd_ctx = cmd_ctx
self.name = name
self.config = config
self.targets = [str(t) for t in targets]
self.targets = targets
self.upload_port = upload_port
self.jobs = jobs
self.program_args = program_args
@ -61,33 +62,29 @@ class EnvironmentProcessor:
variables["upload_port"] = self.upload_port
return variables
def get_build_targets(self):
return (
self.targets
if self.targets
else self.config.get("env:" + self.name, "targets", [])
)
def process(self):
if "platform" not in self.options:
raise UndefinedEnvPlatformError(self.name)
build_vars = self.get_build_variables()
build_targets = list(self.get_build_targets())
is_clean = set(KNOWN_ALLCLEAN_TARGETS) & set(self.targets)
build_targets = list(set(self.targets) - set(KNOWN_ALLCLEAN_TARGETS))
# skip monitor target, we call it above
if "monitor" in build_targets:
build_targets.remove("monitor")
if not set(["clean", "cleanall"]) & set(build_targets):
install_project_env_dependencies(
self.name,
{
"project_targets": build_targets,
"piotest_running_name": build_vars.get("piotest_running_name"),
},
)
# pre-clean
if is_clean:
result = PlatformFactory.new(
self.options["platform"], autoinstall=True
).run(build_vars, self.targets, self.silent, self.verbose, self.jobs)
if not build_targets:
return result["returncode"] == 0
install_project_env_dependencies(
self.name,
{
"project_targets": self.targets,
"piotest_running_name": build_vars.get("piotest_running_name"),
},
)
result = PlatformFactory.new(self.options["platform"], autoinstall=True).run(
build_vars, build_targets, self.silent, self.verbose, self.jobs
)