mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-30 10:07:14 +02:00
Fix bug with invalid process's "return code" when PlatformIO has internal error
This commit is contained in:
@ -31,6 +31,8 @@ Release History
|
|||||||
* Fixed compiling error if space is in user's folder (`issue #56 <https://github.com/ivankravets/platformio/issues/56>`_)
|
* Fixed compiling error if space is in user's folder (`issue #56 <https://github.com/ivankravets/platformio/issues/56>`_)
|
||||||
* Fixed `AttributeError: 'module' object has no attribute 'disable_warnings'`
|
* Fixed `AttributeError: 'module' object has no attribute 'disable_warnings'`
|
||||||
when a version of `requests` package is less then 2.4.0
|
when a version of `requests` package is less then 2.4.0
|
||||||
|
* Fixed bug with invalid process's "return code" when PlatformIO has internal
|
||||||
|
error (`issue #81 <https://github.com/ivankravets/platformio/issues/81>`_)
|
||||||
|
|
||||||
|
|
||||||
0.10.2 (2015-01-06)
|
0.10.2 (2015-01-06)
|
||||||
|
@ -8,8 +8,7 @@ from traceback import format_exc
|
|||||||
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
from platformio import __version__, maintenance
|
from platformio import __version__, exception, maintenance
|
||||||
from platformio.exception import PlatformioException, UnknownCLICommand
|
|
||||||
from platformio.util import get_source_dir
|
from platformio.util import get_source_dir
|
||||||
|
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ class PlatformioCLI(click.MultiCommand): # pylint: disable=R0904
|
|||||||
mod = __import__("platformio.commands." + name,
|
mod = __import__("platformio.commands." + name,
|
||||||
None, None, ["cli"])
|
None, None, ["cli"])
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise UnknownCLICommand(name)
|
raise exception.UnknownCLICommand(name)
|
||||||
return mod.cli
|
return mod.cli
|
||||||
|
|
||||||
|
|
||||||
@ -52,12 +51,13 @@ def main():
|
|||||||
try:
|
try:
|
||||||
cli(None)
|
cli(None)
|
||||||
except Exception as e: # pylint: disable=W0703
|
except Exception as e: # pylint: disable=W0703
|
||||||
maintenance.on_platformio_exception(e)
|
if not isinstance(e, exception.ReturnErrorCode):
|
||||||
if isinstance(e, PlatformioException):
|
maintenance.on_platformio_exception(e)
|
||||||
click.echo("Error: " + str(e), err=True)
|
if isinstance(e, exception.PlatformioException):
|
||||||
sys_exit(1)
|
click.echo("Error: " + str(e), err=True)
|
||||||
else:
|
else:
|
||||||
print format_exc()
|
click.echo(format_exc(), err=True)
|
||||||
|
sys_exit(1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -36,6 +36,7 @@ def cli(ctx, environment, target, upload_port):
|
|||||||
getmtime(_pioenvs_dir)):
|
getmtime(_pioenvs_dir)):
|
||||||
rmtree(_pioenvs_dir)
|
rmtree(_pioenvs_dir)
|
||||||
|
|
||||||
|
found_error = False
|
||||||
_first_done = False
|
_first_done = False
|
||||||
for section in config.sections():
|
for section in config.sections():
|
||||||
# skip main configuration section
|
# skip main configuration section
|
||||||
@ -56,9 +57,13 @@ def cli(ctx, environment, target, upload_port):
|
|||||||
if _first_done:
|
if _first_done:
|
||||||
click.echo()
|
click.echo()
|
||||||
|
|
||||||
process_environment(ctx, envname, options, target, upload_port)
|
if not process_environment(ctx, envname, options, target, upload_port):
|
||||||
|
found_error = True
|
||||||
_first_done = True
|
_first_done = True
|
||||||
|
|
||||||
|
if found_error:
|
||||||
|
raise exception.ReturnErrorCode()
|
||||||
|
|
||||||
|
|
||||||
def process_environment(ctx, name, options, targets, upload_port):
|
def process_environment(ctx, name, options, targets, upload_port):
|
||||||
terminal_width, _ = click.get_terminal_size()
|
terminal_width, _ = click.get_terminal_size()
|
||||||
@ -72,8 +77,8 @@ def process_environment(ctx, name, options, targets, upload_port):
|
|||||||
click.secho("-" * terminal_width, bold=True)
|
click.secho("-" * terminal_width, bold=True)
|
||||||
|
|
||||||
result = _run_environment(ctx, name, options, targets, upload_port)
|
result = _run_environment(ctx, name, options, targets, upload_port)
|
||||||
is_error = "error" in result['err'].lower()
|
|
||||||
|
|
||||||
|
is_error = result['returncode'] != 0
|
||||||
summary_text = " Took %.2f seconds " % (time() - start_time)
|
summary_text = " Took %.2f seconds " % (time() - start_time)
|
||||||
half_line = "=" * ((terminal_width - len(summary_text) - 10) / 2)
|
half_line = "=" * ((terminal_width - len(summary_text) - 10) / 2)
|
||||||
click.echo("%s [%s]%s%s" % (
|
click.echo("%s [%s]%s%s" % (
|
||||||
@ -84,6 +89,8 @@ def process_environment(ctx, name, options, targets, upload_port):
|
|||||||
half_line
|
half_line
|
||||||
), err=is_error)
|
), err=is_error)
|
||||||
|
|
||||||
|
return not is_error
|
||||||
|
|
||||||
|
|
||||||
def _run_environment(ctx, name, options, targets, upload_port):
|
def _run_environment(ctx, name, options, targets, upload_port):
|
||||||
variables = ["PIOENV=" + name]
|
variables = ["PIOENV=" + name]
|
||||||
|
@ -13,6 +13,10 @@ class PlatformioException(Exception):
|
|||||||
return Exception.__str__(self)
|
return Exception.__str__(self)
|
||||||
|
|
||||||
|
|
||||||
|
class ReturnErrorCode(PlatformioException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AbortedByUser(PlatformioException):
|
class AbortedByUser(PlatformioException):
|
||||||
|
|
||||||
MESSAGE = "Aborted by user"
|
MESSAGE = "Aborted by user"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Copyright (C) Ivan Kravets <me@ikravets.com>
|
# Copyright (C) Ivan Kravets <me@ikravets.com>
|
||||||
# See LICENSE for details.
|
# See LICENSE for details.
|
||||||
|
|
||||||
|
import re
|
||||||
from imp import load_source
|
from imp import load_source
|
||||||
from os import listdir
|
from os import listdir
|
||||||
from os.path import isdir, isfile, join
|
from os.path import isdir, isfile, join
|
||||||
@ -76,6 +77,10 @@ class PlatformFactory(object):
|
|||||||
class BasePlatform(object):
|
class BasePlatform(object):
|
||||||
|
|
||||||
PACKAGES = {}
|
PACKAGES = {}
|
||||||
|
LINE_ERROR_RE = re.compile(r"(\s+error|error[:\s]+)", re.I)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._found_error = False
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
return self.__class__.__name__[:-8].lower()
|
return self.__class__.__name__[:-8].lower()
|
||||||
@ -214,6 +219,7 @@ class BasePlatform(object):
|
|||||||
variables.append(
|
variables.append(
|
||||||
"PIOPACKAGE_%s=%s" % (options['alias'].upper(), name))
|
"PIOPACKAGE_%s=%s" % (options['alias'].upper(), name))
|
||||||
|
|
||||||
|
self._found_error = False
|
||||||
try:
|
try:
|
||||||
result = util.exec_command(
|
result = util.exec_command(
|
||||||
[
|
[
|
||||||
@ -227,9 +233,10 @@ class BasePlatform(object):
|
|||||||
except OSError:
|
except OSError:
|
||||||
raise exception.SConsNotInstalled()
|
raise exception.SConsNotInstalled()
|
||||||
|
|
||||||
return self.after_run(result)
|
assert "returncode" in result
|
||||||
|
if self._found_error:
|
||||||
|
result['returncode'] = 1
|
||||||
|
|
||||||
def after_run(self, result): # pylint: disable=R0201
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def on_run_out(self, line): # pylint: disable=R0201
|
def on_run_out(self, line): # pylint: disable=R0201
|
||||||
@ -239,5 +246,7 @@ class BasePlatform(object):
|
|||||||
click.secho(line, fg=fg)
|
click.secho(line, fg=fg)
|
||||||
|
|
||||||
def on_run_err(self, line): # pylint: disable=R0201
|
def on_run_err(self, line): # pylint: disable=R0201
|
||||||
click.secho(line, err=True,
|
is_error = self.LINE_ERROR_RE.search(line) is not None
|
||||||
fg="red" if "error" in line.lower() else "yellow")
|
if is_error:
|
||||||
|
self._found_error = True
|
||||||
|
click.secho(line, err=True, fg="red" if is_error else "yellow")
|
||||||
|
@ -117,7 +117,12 @@ def change_filemtime(path, time):
|
|||||||
|
|
||||||
|
|
||||||
def exec_command(*args, **kwargs):
|
def exec_command(*args, **kwargs):
|
||||||
result = {"out": None, "err": None}
|
result = {
|
||||||
|
"out": None,
|
||||||
|
"err": None,
|
||||||
|
"returncode": None
|
||||||
|
}
|
||||||
|
|
||||||
default = dict(
|
default = dict(
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
@ -129,6 +134,7 @@ def exec_command(*args, **kwargs):
|
|||||||
p = subprocess.Popen(*args, **kwargs)
|
p = subprocess.Popen(*args, **kwargs)
|
||||||
try:
|
try:
|
||||||
result['out'], result['err'] = p.communicate()
|
result['out'], result['err'] = p.communicate()
|
||||||
|
result['returncode'] = p.returncode
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
for s in ("stdout", "stderr"):
|
for s in ("stdout", "stderr"):
|
||||||
if isinstance(kwargs[s], AsyncPipe):
|
if isinstance(kwargs[s], AsyncPipe):
|
||||||
@ -141,9 +147,8 @@ def exec_command(*args, **kwargs):
|
|||||||
result[s[3:]] = "\n".join(kwargs[s].get_buffer())
|
result[s[3:]] = "\n".join(kwargs[s].get_buffer())
|
||||||
|
|
||||||
for k, v in result.iteritems():
|
for k, v in result.iteritems():
|
||||||
if not v:
|
if v and isinstance(v, basestring):
|
||||||
continue
|
result[k].strip()
|
||||||
result[k].strip()
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -30,9 +30,8 @@ def test_run(platformio_setup, pioproject_dir):
|
|||||||
["platformio", "run"],
|
["platformio", "run"],
|
||||||
cwd=pioproject_dir
|
cwd=pioproject_dir
|
||||||
)
|
)
|
||||||
output = "%s\n%s" % (result['out'], result['err'])
|
if result['returncode'] != 0:
|
||||||
if "error" in output.lower():
|
pytest.fail(result)
|
||||||
pytest.fail(output)
|
|
||||||
|
|
||||||
# check .elf file
|
# check .elf file
|
||||||
pioenvs_dir = join(pioproject_dir, ".pioenvs")
|
pioenvs_dir = join(pioproject_dir, ".pioenvs")
|
||||||
|
Reference in New Issue
Block a user