mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-30 18:17:13 +02:00
Add verbosity option for "run" and "ci" commands
This commit is contained in:
15
HISTORY.rst
15
HISTORY.rst
@ -11,26 +11,27 @@ Release History
|
|||||||
(`issue #108 <https://github.com/platformio/platformio/issues/108>`_)
|
(`issue #108 <https://github.com/platformio/platformio/issues/108>`_)
|
||||||
* Created `PlatformIO gitter.im <https://gitter.im/platformio/platformio>`_ room
|
* Created `PlatformIO gitter.im <https://gitter.im/platformio/platformio>`_ room
|
||||||
(`issue #174 <https://github.com/platformio/platformio/issues/174>`_)
|
(`issue #174 <https://github.com/platformio/platformio/issues/174>`_)
|
||||||
* Added global ``-f, --force`` option which will force to accept any
|
* Global ``-f, --force`` option which will force to accept any
|
||||||
confirmation prompts (`issue #152 <https://github.com/platformio/platformio/issues/152>`_)
|
confirmation prompts (`issue #152 <https://github.com/platformio/platformio/issues/152>`_)
|
||||||
* Allowed to run project with `platformio run --project-dir <http://docs.platformio.org/en/latest/userguide/cmd_run.html#cmdoption--project-dir>`_ option without changing the current working
|
* Run project with `platformio run --project-dir <http://docs.platformio.org/en/latest/userguide/cmd_run.html#cmdoption--project-dir>`_ option without changing the current working
|
||||||
directory
|
directory
|
||||||
(`issue #192 <https://github.com/platformio/platformio/issues/192>`_)
|
(`issue #192 <https://github.com/platformio/platformio/issues/192>`_)
|
||||||
* Allowed to add library dependencies for build environment using
|
* Control verbosity of `platformio run <http://docs.platformio.org/en/latest/userguide/cmd_run.html#cmdoption-platformio-run-v>`_ command via ``-v/--verbose`` option
|
||||||
|
* Add library dependencies for build environment using
|
||||||
`install_libs <http://docs.platformio.org/en/latest/projectconf.html#install-libs>`_
|
`install_libs <http://docs.platformio.org/en/latest/projectconf.html#install-libs>`_
|
||||||
option in ``platformio.ini``
|
option in ``platformio.ini``
|
||||||
(`issue #134 <https://github.com/platformio/platformio/issues/134>`_)
|
(`issue #134 <https://github.com/platformio/platformio/issues/134>`_)
|
||||||
* Allowed to specify libraries which are compatible with build environment using
|
* Specify libraries which are compatible with build environment using
|
||||||
`use_libs <http://docs.platformio.org/en/latest/projectconf.html#use-libs>`_
|
`use_libs <http://docs.platformio.org/en/latest/projectconf.html#use-libs>`_
|
||||||
option in ``platformio.ini``
|
option in ``platformio.ini``
|
||||||
(`issue #148 <https://github.com/platformio/platformio/issues/148>`_)
|
(`issue #148 <https://github.com/platformio/platformio/issues/148>`_)
|
||||||
* Allowed to add more boards to PlatformIO project with
|
* Add more boards to PlatformIO project with
|
||||||
`platformio init --board <http://docs.platformio.org/en/latest/userguide/cmd_init.html#cmdoption--board>`__
|
`platformio init --board <http://docs.platformio.org/en/latest/userguide/cmd_init.html#cmdoption--board>`__
|
||||||
command
|
command
|
||||||
(`issue #167 <https://github.com/platformio/platformio/issues/167>`_)
|
(`issue #167 <https://github.com/platformio/platformio/issues/167>`_)
|
||||||
* Allowed to choose which library to update
|
* Choose which library to update
|
||||||
(`issue #168 <https://github.com/platformio/platformio/issues/168>`_)
|
(`issue #168 <https://github.com/platformio/platformio/issues/168>`_)
|
||||||
* Allowed to specify `platformio init --env-prefix <http://docs.platformio.org/en/latest/userguide/cmd_init.html#cmdoption--env-prefix>`__ when initialise/update project
|
* Specify `platformio init --env-prefix <http://docs.platformio.org/en/latest/userguide/cmd_init.html#cmdoption--env-prefix>`__ when initialise/update project
|
||||||
(`issue #182 <https://github.com/platformio/platformio/issues/182>`_)
|
(`issue #182 <https://github.com/platformio/platformio/issues/182>`_)
|
||||||
* Disabled automatic updates by default for platforms, packages and libraries
|
* Disabled automatic updates by default for platforms, packages and libraries
|
||||||
(`issue #171 <https://github.com/platformio/platformio/issues/171>`_)
|
(`issue #171 <https://github.com/platformio/platformio/issues/171>`_)
|
||||||
|
@ -106,6 +106,14 @@ Don't remove :option:`platformio ci --build-dir` after build process.
|
|||||||
|
|
||||||
Buid project using pre-configured :ref:`projectconf`.
|
Buid project using pre-configured :ref:`projectconf`.
|
||||||
|
|
||||||
|
.. option::
|
||||||
|
-v, --verbose
|
||||||
|
|
||||||
|
Shows details about the results of processing environments. More details
|
||||||
|
:option:`platformio run --verbose`
|
||||||
|
|
||||||
|
By default, verbosity level is set to 1 (only errors will be printed).
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -47,6 +47,21 @@ Upload port of embedded board. To print all available ports use
|
|||||||
Specify the path to project directory. By default, ``--build-dir`` is equal to
|
Specify the path to project directory. By default, ``--build-dir`` is equal to
|
||||||
current working directory (``CWD``).
|
current working directory (``CWD``).
|
||||||
|
|
||||||
|
.. option::
|
||||||
|
-v, --verbose
|
||||||
|
|
||||||
|
Shows details about the results of processing environments. Each instance of
|
||||||
|
``--verbose`` on the command line increases the verbosity level by one, so if
|
||||||
|
you need more details on the output, specify it twice.
|
||||||
|
|
||||||
|
There 3 levels of verbosity:
|
||||||
|
|
||||||
|
1. ``-v`` - output errors only
|
||||||
|
2. ``-vv`` - output errors and warnings
|
||||||
|
3. ``-vvv`` - output errors, warnings and additional information
|
||||||
|
|
||||||
|
By default, verbosity level is set to 3 (maximum information).
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -52,9 +52,10 @@ def validate_boards(ctx, param, value): # pylint: disable=W0613
|
|||||||
@click.option("--project-conf",
|
@click.option("--project-conf",
|
||||||
type=click.Path(exists=True, file_okay=True, dir_okay=False,
|
type=click.Path(exists=True, file_okay=True, dir_okay=False,
|
||||||
readable=True, resolve_path=True))
|
readable=True, resolve_path=True))
|
||||||
|
@click.option("--verbose", "-v", count=True, default=1)
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def cli(ctx, src, lib, exclude, board, # pylint: disable=R0913
|
def cli(ctx, src, lib, exclude, board, # pylint: disable=R0913
|
||||||
build_dir, keep_build_dir, project_conf):
|
build_dir, keep_build_dir, project_conf, verbose):
|
||||||
|
|
||||||
if not src:
|
if not src:
|
||||||
src = environ.get("PLATFORMIO_CI_SRC", "").split(":")
|
src = environ.get("PLATFORMIO_CI_SRC", "").split(":")
|
||||||
@ -86,7 +87,7 @@ def cli(ctx, src, lib, exclude, board, # pylint: disable=R0913
|
|||||||
disable_auto_uploading=True)
|
disable_auto_uploading=True)
|
||||||
|
|
||||||
# process project
|
# process project
|
||||||
ctx.invoke(cmd_run, project_dir=build_dir)
|
ctx.invoke(cmd_run, project_dir=build_dir, verbose=verbose)
|
||||||
finally:
|
finally:
|
||||||
if not keep_build_dir:
|
if not keep_build_dir:
|
||||||
rmtree(build_dir)
|
rmtree(build_dir)
|
||||||
|
@ -24,8 +24,10 @@ from platformio.platforms.base import PlatformFactory
|
|||||||
@click.option("--project-dir", default=getcwd,
|
@click.option("--project-dir", default=getcwd,
|
||||||
type=click.Path(exists=True, file_okay=False, dir_okay=True,
|
type=click.Path(exists=True, file_okay=False, dir_okay=True,
|
||||||
writable=True, resolve_path=True))
|
writable=True, resolve_path=True))
|
||||||
|
@click.option("--verbose", "-v", count=True, default=3)
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def cli(ctx, environment, target, upload_port, project_dir):
|
def cli(ctx, environment, target, upload_port, # pylint: disable=R0913,R0914
|
||||||
|
project_dir, verbose):
|
||||||
initial_cwd = getcwd()
|
initial_cwd = getcwd()
|
||||||
chdir(project_dir)
|
chdir(project_dir)
|
||||||
try:
|
try:
|
||||||
@ -47,51 +49,58 @@ def cli(ctx, environment, target, upload_port, project_dir):
|
|||||||
|
|
||||||
results = []
|
results = []
|
||||||
for section in config.sections():
|
for section in config.sections():
|
||||||
if results and results[-1] is not None:
|
|
||||||
click.echo()
|
|
||||||
|
|
||||||
results.append(_process_conf_section(
|
|
||||||
ctx, config, section, environment, target, upload_port))
|
|
||||||
|
|
||||||
if not all([r for r in results if r is not None]):
|
|
||||||
raise exception.ReturnErrorCode()
|
|
||||||
finally:
|
|
||||||
chdir(initial_cwd)
|
|
||||||
|
|
||||||
|
|
||||||
def _process_conf_section(ctx, config, section, # pylint: disable=R0913
|
|
||||||
environment, target, upload_port):
|
|
||||||
# skip main configuration section
|
# skip main configuration section
|
||||||
if section == "platformio":
|
if section == "platformio":
|
||||||
return None
|
continue
|
||||||
|
|
||||||
if section[:4] != "env:":
|
if not section.startswith("env:"):
|
||||||
raise exception.InvalidEnvName(section)
|
raise exception.InvalidEnvName(section)
|
||||||
|
|
||||||
envname = section[4:]
|
envname = section[4:]
|
||||||
if environment and envname not in environment:
|
if environment and envname not in environment:
|
||||||
# echo("Skipped %s environment" % style(envname, fg="yellow"))
|
# echo("Skipped %s environment" % style(envname, fg="yellow"))
|
||||||
return None
|
continue
|
||||||
|
|
||||||
|
if results:
|
||||||
|
click.echo()
|
||||||
|
|
||||||
options = {}
|
options = {}
|
||||||
for k, v in config.items(section):
|
for k, v in config.items(section):
|
||||||
options[k] = v
|
options[k] = v
|
||||||
|
|
||||||
return _process_environment(ctx, envname, options, target, upload_port)
|
ep = EnvironmentProcessor(
|
||||||
|
ctx, envname, options, target, upload_port, verbose)
|
||||||
|
results.append(ep.process())
|
||||||
|
|
||||||
|
if not all(results):
|
||||||
|
raise exception.ReturnErrorCode()
|
||||||
|
finally:
|
||||||
|
chdir(initial_cwd)
|
||||||
|
|
||||||
|
|
||||||
def _process_environment(ctx, name, options, targets, upload_port):
|
class EnvironmentProcessor(object):
|
||||||
|
|
||||||
|
def __init__(self, cmd_ctx, name, options, # pylint: disable=R0913
|
||||||
|
targets, upload_port, verbose):
|
||||||
|
self.cmd_ctx = cmd_ctx
|
||||||
|
self.name = name
|
||||||
|
self.options = options
|
||||||
|
self.targets = targets
|
||||||
|
self.upload_port = upload_port
|
||||||
|
self.verbose_level = int(verbose)
|
||||||
|
|
||||||
|
def process(self):
|
||||||
terminal_width, _ = click.get_terminal_size()
|
terminal_width, _ = click.get_terminal_size()
|
||||||
start_time = time()
|
start_time = time()
|
||||||
|
|
||||||
click.echo("[%s] Processing %s (%s)" % (
|
click.echo("[%s] Processing %s (%s)" % (
|
||||||
datetime.now().strftime("%c"),
|
datetime.now().strftime("%c"),
|
||||||
click.style(name, fg="cyan", bold=True),
|
click.style(self.name, fg="cyan", bold=True),
|
||||||
", ".join(["%s: %s" % (k, v) for k, v in options.iteritems()])
|
", ".join(["%s: %s" % (k, v) for k, v in self.options.iteritems()])
|
||||||
))
|
))
|
||||||
click.secho("-" * terminal_width, bold=True)
|
click.secho("-" * terminal_width, bold=True)
|
||||||
|
|
||||||
result = _run_environment(ctx, name, options, targets, upload_port)
|
result = self._run()
|
||||||
|
|
||||||
is_error = result['returncode'] != 0
|
is_error = result['returncode'] != 0
|
||||||
summary_text = " Took %.2f seconds " % (time() - start_time)
|
summary_text = " Took %.2f seconds " % (time() - start_time)
|
||||||
@ -106,39 +115,45 @@ def _process_environment(ctx, name, options, targets, upload_port):
|
|||||||
|
|
||||||
return not is_error
|
return not is_error
|
||||||
|
|
||||||
|
def _get_build_variables(self):
|
||||||
def _run_environment(ctx, name, options, targets, upload_port):
|
variables = ["PIOENV=" + self.name]
|
||||||
variables = ["PIOENV=" + name]
|
if self.upload_port:
|
||||||
if upload_port:
|
variables.append("UPLOAD_PORT=%s" % self.upload_port)
|
||||||
variables.append("UPLOAD_PORT=%s" % upload_port)
|
for k, v in self.options.items():
|
||||||
for k, v in options.items():
|
|
||||||
k = k.upper()
|
k = k.upper()
|
||||||
if k == "TARGETS" or (k == "UPLOAD_PORT" and upload_port):
|
if k == "TARGETS" or (k == "UPLOAD_PORT" and self.upload_port):
|
||||||
continue
|
continue
|
||||||
variables.append("%s=%s" % (k.upper(), v))
|
variables.append("%s=%s" % (k.upper(), v))
|
||||||
|
return variables
|
||||||
|
|
||||||
envtargets = []
|
def _get_build_targets(self):
|
||||||
if targets:
|
targets = []
|
||||||
envtargets = [t for t in targets]
|
if self.targets:
|
||||||
elif "targets" in options:
|
targets = [t for t in self.targets]
|
||||||
envtargets = options['targets'].split()
|
elif "targets" in self.options:
|
||||||
|
targets = self.options['targets'].split()
|
||||||
|
return targets
|
||||||
|
|
||||||
if "platform" not in options:
|
def _run(self):
|
||||||
raise exception.UndefinedEnvPlatform(name)
|
if "platform" not in self.options:
|
||||||
platform = options['platform']
|
raise exception.UndefinedEnvPlatform(self.name)
|
||||||
|
|
||||||
telemetry.on_run_environment(options, envtargets)
|
platform = self.options['platform']
|
||||||
|
build_vars = self._get_build_variables()
|
||||||
|
build_targets = self._get_build_targets()
|
||||||
|
|
||||||
|
telemetry.on_run_environment(self.options, build_targets)
|
||||||
|
|
||||||
# install platform and libs dependencies
|
# install platform and libs dependencies
|
||||||
_autoinstall_env_platform(ctx, platform)
|
_autoinstall_platform(self.cmd_ctx, platform)
|
||||||
if "install_libs" in options:
|
if "install_libs" in self.options:
|
||||||
_autoinstall_env_libs(ctx, options['install_libs'])
|
_autoinstall_libs(self.cmd_ctx, self.options['install_libs'])
|
||||||
|
|
||||||
p = PlatformFactory.newPlatform(platform)
|
p = PlatformFactory.newPlatform(platform)
|
||||||
return p.run(variables, envtargets)
|
return p.run(build_vars, build_targets, self.verbose_level)
|
||||||
|
|
||||||
|
|
||||||
def _autoinstall_env_platform(ctx, platform):
|
def _autoinstall_platform(ctx, platform):
|
||||||
installed_platforms = PlatformFactory.get_platforms(
|
installed_platforms = PlatformFactory.get_platforms(
|
||||||
installed=True).keys()
|
installed=True).keys()
|
||||||
if (platform not in installed_platforms and (
|
if (platform not in installed_platforms and (
|
||||||
@ -148,7 +163,7 @@ def _autoinstall_env_platform(ctx, platform):
|
|||||||
ctx.invoke(cmd_platforms_install, platforms=[platform])
|
ctx.invoke(cmd_platforms_install, platforms=[platform])
|
||||||
|
|
||||||
|
|
||||||
def _autoinstall_env_libs(ctx, libids_list):
|
def _autoinstall_libs(ctx, libids_list):
|
||||||
require_libs = [int(l.strip()) for l in libids_list.split(",")]
|
require_libs = [int(l.strip()) for l in libids_list.split(",")]
|
||||||
installed_libs = [
|
installed_libs = [
|
||||||
l['id'] for l in LibraryManager().get_installed().values()
|
l['id'] for l in LibraryManager().get_installed().values()
|
||||||
|
@ -47,7 +47,7 @@ class AtmelavrPlatform(BasePlatform):
|
|||||||
else:
|
else:
|
||||||
BasePlatform.on_run_err(self, line)
|
BasePlatform.on_run_err(self, line)
|
||||||
|
|
||||||
def run(self, variables, targets):
|
def run(self, variables, targets, verbose):
|
||||||
for v in variables:
|
for v in variables:
|
||||||
if "BOARD=" not in v:
|
if "BOARD=" not in v:
|
||||||
continue
|
continue
|
||||||
@ -58,4 +58,4 @@ class AtmelavrPlatform(BasePlatform):
|
|||||||
tuploader = "tool-micronucleus"
|
tuploader = "tool-micronucleus"
|
||||||
self.PACKAGES[tuploader]['alias'] = "uploader"
|
self.PACKAGES[tuploader]['alias'] = "uploader"
|
||||||
break
|
break
|
||||||
return BasePlatform.run(self, variables, targets)
|
return BasePlatform.run(self, variables, targets, verbose)
|
||||||
|
@ -190,6 +190,12 @@ class BasePlatform(object):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._found_error = False
|
self._found_error = False
|
||||||
|
self._last_echo_line = None
|
||||||
|
|
||||||
|
# 1 = errors
|
||||||
|
# 2 = 1 + warnings
|
||||||
|
# 3 = 2 + others
|
||||||
|
self._verbose_level = 3
|
||||||
|
|
||||||
def get_type(self):
|
def get_type(self):
|
||||||
return self.__class__.__name__[:-8].lower()
|
return self.__class__.__name__[:-8].lower()
|
||||||
@ -306,10 +312,12 @@ class BasePlatform(object):
|
|||||||
obsolated = pm.get_outdated()
|
obsolated = pm.get_outdated()
|
||||||
return not set(self.get_packages().keys()).isdisjoint(set(obsolated))
|
return not set(self.get_packages().keys()).isdisjoint(set(obsolated))
|
||||||
|
|
||||||
def run(self, variables, targets):
|
def run(self, variables, targets, verbose):
|
||||||
assert isinstance(variables, list)
|
assert isinstance(variables, list)
|
||||||
assert isinstance(targets, list)
|
assert isinstance(targets, list)
|
||||||
|
|
||||||
|
self._verbose_level = int(verbose)
|
||||||
|
|
||||||
installed_platforms = PlatformFactory.get_platforms(
|
installed_platforms = PlatformFactory.get_platforms(
|
||||||
installed=True).keys()
|
installed=True).keys()
|
||||||
installed_packages = PackageManager.get_installed()
|
installed_packages = PackageManager.get_installed()
|
||||||
@ -356,16 +364,34 @@ class BasePlatform(object):
|
|||||||
if self._found_error:
|
if self._found_error:
|
||||||
result['returncode'] = 1
|
result['returncode'] = 1
|
||||||
|
|
||||||
|
if self._last_echo_line == ".":
|
||||||
|
click.echo("")
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def on_run_out(self, line): # pylint: disable=R0201
|
def on_run_out(self, line):
|
||||||
fg = None
|
self._echo_line(line, level=3)
|
||||||
if "is up to date" in line:
|
|
||||||
fg = "green"
|
|
||||||
click.secho(line, fg=fg)
|
|
||||||
|
|
||||||
def on_run_err(self, line): # pylint: disable=R0201
|
def on_run_err(self, line):
|
||||||
is_error = self.LINE_ERROR_RE.search(line) is not None
|
is_error = self.LINE_ERROR_RE.search(line) is not None
|
||||||
if is_error:
|
if is_error:
|
||||||
self._found_error = True
|
self._found_error = True
|
||||||
click.secho(line, err=True, fg="red" if is_error else "yellow")
|
self._echo_line(line, level=1 if is_error else 2)
|
||||||
|
|
||||||
|
def _echo_line(self, line, level):
|
||||||
|
assert 1 <= level <= 3
|
||||||
|
|
||||||
|
fg = ("red", "yellow", None)[level - 1]
|
||||||
|
if level == 3 and "is up to date" in line:
|
||||||
|
fg = "green"
|
||||||
|
|
||||||
|
if level > self._verbose_level:
|
||||||
|
click.secho(".", fg=fg, err=level < 3, nl=False)
|
||||||
|
self._last_echo_line = "."
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._last_echo_line == ".":
|
||||||
|
click.echo("")
|
||||||
|
self._last_echo_line = line
|
||||||
|
|
||||||
|
click.secho(line, fg=fg, err=level < 3)
|
||||||
|
@ -44,7 +44,7 @@ class TeensyPlatform(BasePlatform):
|
|||||||
def get_name(self):
|
def get_name(self):
|
||||||
return "Teensy"
|
return "Teensy"
|
||||||
|
|
||||||
def run(self, variables, targets):
|
def run(self, variables, targets, verbose):
|
||||||
for v in variables:
|
for v in variables:
|
||||||
if "BOARD=" not in v:
|
if "BOARD=" not in v:
|
||||||
continue
|
continue
|
||||||
@ -56,4 +56,4 @@ class TeensyPlatform(BasePlatform):
|
|||||||
tpackage = "toolchain-gccarmnoneeabi"
|
tpackage = "toolchain-gccarmnoneeabi"
|
||||||
self.PACKAGES[tpackage]['alias'] = "toolchain"
|
self.PACKAGES[tpackage]['alias'] = "toolchain"
|
||||||
break
|
break
|
||||||
return BasePlatform.run(self, variables, targets)
|
return BasePlatform.run(self, variables, targets, verbose)
|
||||||
|
Reference in New Issue
Block a user