forked from platformio/platformio-core
Automatically install missed development platform for run command
This commit is contained in:
@ -203,10 +203,10 @@ class EnvironmentProcessor(object):
|
|||||||
platform, version = platform.rsplit("@", 1)
|
platform, version = platform.rsplit("@", 1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
p = PlatformFactory.newPlatform(platform)
|
p = PlatformFactory.newPlatform(platform, version)
|
||||||
except exception.UnknownPlatform:
|
except exception.UnknownPlatform:
|
||||||
self.cmd_ctx.invoke(cmd_platform_install, platforms=[platform])
|
self.cmd_ctx.invoke(cmd_platform_install, platforms=[platform])
|
||||||
p = PlatformFactory.newPlatform(platform)
|
p = PlatformFactory.newPlatform(platform, version)
|
||||||
|
|
||||||
return p.run(build_vars, build_targets, self.verbose_level)
|
return p.run(build_vars, build_targets, self.verbose_level)
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ class PackageManager(object):
|
|||||||
continue
|
continue
|
||||||
if (not current or semantic_version.compare(
|
if (not current or semantic_version.compare(
|
||||||
manifest['version'], current['version']) == 1):
|
manifest['version'], current['version']) == 1):
|
||||||
current = manifest
|
current = manifest
|
||||||
|
|
||||||
if current is None:
|
if current is None:
|
||||||
return
|
return
|
||||||
|
@ -33,7 +33,7 @@ class PlatformManager(PackageManager):
|
|||||||
PackageManager.__init__(
|
PackageManager.__init__(
|
||||||
self,
|
self,
|
||||||
join(util.get_home_dir(), "platforms"),
|
join(util.get_home_dir(), "platforms"),
|
||||||
["http://dl.platformio.org/misc/platforms_manifest.json"]
|
["http://dl.platformio.org/platforms/manifest.json"]
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -68,7 +68,8 @@ class PlatformManager(PackageManager):
|
|||||||
return PackageManager.uninstall(self, name, requirements)
|
return PackageManager.uninstall(self, name, requirements)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def update(self, name, version):
|
def update(self, # pylint: disable=arguments-differ
|
||||||
|
name, version):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def is_outdated(self, name, version):
|
def is_outdated(self, name, version):
|
||||||
@ -235,12 +236,111 @@ class PlatformPackagesMixin(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class BasePlatform(PlatformPackagesMixin):
|
class PlatformRunMixin(object):
|
||||||
|
|
||||||
_BOARDS_CACHE = {}
|
|
||||||
|
|
||||||
LINE_ERROR_RE = re.compile(r"(\s+error|error[:\s]+)", re.I)
|
LINE_ERROR_RE = re.compile(r"(\s+error|error[:\s]+)", re.I)
|
||||||
|
|
||||||
|
def run(self, variables, targets, verbose):
|
||||||
|
assert isinstance(variables, dict)
|
||||||
|
assert isinstance(targets, list)
|
||||||
|
|
||||||
|
self.configure_default_packages(variables, targets)
|
||||||
|
self.install_packages(silent=True)
|
||||||
|
|
||||||
|
self._verbose_level = int(verbose)
|
||||||
|
|
||||||
|
if "clean" in targets:
|
||||||
|
targets.remove("clean")
|
||||||
|
targets.append("-c")
|
||||||
|
|
||||||
|
variables['platform_manifest'] = self.manifest_path
|
||||||
|
|
||||||
|
if "build_script" not in variables:
|
||||||
|
variables['build_script'] = self.get_build_script()
|
||||||
|
if not isfile(variables['build_script']):
|
||||||
|
raise exception.BuildScriptNotFound(variables['build_script'])
|
||||||
|
|
||||||
|
self._found_error = False
|
||||||
|
result = self._run_scons(variables, targets)
|
||||||
|
assert "returncode" in result
|
||||||
|
# if self._found_error:
|
||||||
|
# result['returncode'] = 1
|
||||||
|
|
||||||
|
if self._last_echo_line == ".":
|
||||||
|
click.echo("")
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _run_scons(self, variables, targets):
|
||||||
|
# pass current PYTHONPATH to SCons
|
||||||
|
if "PYTHONPATH" in os.environ:
|
||||||
|
_PYTHONPATH = os.environ.get("PYTHONPATH").split(os.pathsep)
|
||||||
|
else:
|
||||||
|
_PYTHONPATH = []
|
||||||
|
for p in os.sys.path:
|
||||||
|
if p not in _PYTHONPATH:
|
||||||
|
_PYTHONPATH.append(p)
|
||||||
|
os.environ['PYTHONPATH'] = os.pathsep.join(_PYTHONPATH)
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
os.path.normpath(sys.executable),
|
||||||
|
join(self.get_package_dir("tool-scons"), "script", "scons"),
|
||||||
|
"-Q",
|
||||||
|
"-j %d" % self.get_job_nums(),
|
||||||
|
"--warn=no-no-parallel-support",
|
||||||
|
"-f", join(util.get_source_dir(), "builder", "main.py")
|
||||||
|
] + targets
|
||||||
|
|
||||||
|
# encode and append variables
|
||||||
|
for key, value in variables.items():
|
||||||
|
cmd.append("%s=%s" % (key.upper(), base64.b64encode(value)))
|
||||||
|
|
||||||
|
result = util.exec_command(
|
||||||
|
cmd,
|
||||||
|
stdout=util.AsyncPipe(self.on_run_out),
|
||||||
|
stderr=util.AsyncPipe(self.on_run_err)
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def on_run_out(self, line):
|
||||||
|
self._echo_line(line, level=3)
|
||||||
|
|
||||||
|
def on_run_err(self, line):
|
||||||
|
is_error = self.LINE_ERROR_RE.search(line) is not None
|
||||||
|
if is_error:
|
||||||
|
self._found_error = True
|
||||||
|
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)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_job_nums():
|
||||||
|
try:
|
||||||
|
return cpu_count()
|
||||||
|
except NotImplementedError:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
class BasePlatform(PlatformPackagesMixin, PlatformRunMixin):
|
||||||
|
|
||||||
|
_BOARDS_CACHE = {}
|
||||||
|
|
||||||
def __init__(self, manifest_path):
|
def __init__(self, manifest_path):
|
||||||
self._BOARDS_CACHE = {}
|
self._BOARDS_CACHE = {}
|
||||||
self.manifest_path = manifest_path
|
self.manifest_path = manifest_path
|
||||||
@ -370,102 +470,6 @@ class BasePlatform(PlatformPackagesMixin):
|
|||||||
# skip all packages, allow only upload tools
|
# skip all packages, allow only upload tools
|
||||||
self.get_packages()[_name]['optional'] = True
|
self.get_packages()[_name]['optional'] = True
|
||||||
|
|
||||||
def run(self, variables, targets, verbose):
|
|
||||||
assert isinstance(variables, dict)
|
|
||||||
assert isinstance(targets, list)
|
|
||||||
|
|
||||||
self.configure_default_packages(variables, targets)
|
|
||||||
self.install_packages(silent=True)
|
|
||||||
|
|
||||||
self._verbose_level = int(verbose)
|
|
||||||
|
|
||||||
if "clean" in targets:
|
|
||||||
targets.remove("clean")
|
|
||||||
targets.append("-c")
|
|
||||||
|
|
||||||
variables['platform_manifest'] = self.manifest_path
|
|
||||||
|
|
||||||
if "build_script" not in variables:
|
|
||||||
variables['build_script'] = self.get_build_script()
|
|
||||||
if not isfile(variables['build_script']):
|
|
||||||
raise exception.BuildScriptNotFound(variables['build_script'])
|
|
||||||
|
|
||||||
self._found_error = False
|
|
||||||
result = self._run_scons(variables, targets)
|
|
||||||
assert "returncode" in result
|
|
||||||
# if self._found_error:
|
|
||||||
# result['returncode'] = 1
|
|
||||||
|
|
||||||
if self._last_echo_line == ".":
|
|
||||||
click.echo("")
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _run_scons(self, variables, targets):
|
|
||||||
# pass current PYTHONPATH to SCons
|
|
||||||
if "PYTHONPATH" in os.environ:
|
|
||||||
_PYTHONPATH = os.environ.get("PYTHONPATH").split(os.pathsep)
|
|
||||||
else:
|
|
||||||
_PYTHONPATH = []
|
|
||||||
for p in os.sys.path:
|
|
||||||
if p not in _PYTHONPATH:
|
|
||||||
_PYTHONPATH.append(p)
|
|
||||||
os.environ['PYTHONPATH'] = os.pathsep.join(_PYTHONPATH)
|
|
||||||
|
|
||||||
cmd = [
|
|
||||||
os.path.normpath(sys.executable),
|
|
||||||
join(self.get_package_dir("tool-scons"), "script", "scons"),
|
|
||||||
"-Q",
|
|
||||||
"-j %d" % self.get_job_nums(),
|
|
||||||
"--warn=no-no-parallel-support",
|
|
||||||
"-f", join(util.get_source_dir(), "builder", "main.py")
|
|
||||||
] + targets
|
|
||||||
|
|
||||||
# encode and append variables
|
|
||||||
for key, value in variables.items():
|
|
||||||
cmd.append("%s=%s" % (key.upper(), base64.b64encode(value)))
|
|
||||||
|
|
||||||
result = util.exec_command(
|
|
||||||
cmd,
|
|
||||||
stdout=util.AsyncPipe(self.on_run_out),
|
|
||||||
stderr=util.AsyncPipe(self.on_run_err)
|
|
||||||
)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def on_run_out(self, line):
|
|
||||||
self._echo_line(line, level=3)
|
|
||||||
|
|
||||||
def on_run_err(self, line):
|
|
||||||
is_error = self.LINE_ERROR_RE.search(line) is not None
|
|
||||||
if is_error:
|
|
||||||
self._found_error = True
|
|
||||||
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)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_job_nums():
|
|
||||||
try:
|
|
||||||
return cpu_count()
|
|
||||||
except NotImplementedError:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
class PlatformBoardConfig(object):
|
class PlatformBoardConfig(object):
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user