Fixed an error "Unknown development platform" when running unit tests on a clean machine // Resolve #3901

This commit is contained in:
Ivan Kravets
2021-04-01 21:15:14 +03:00
parent 32e1cbe2a3
commit ee7ea77fc3
5 changed files with 180 additions and 167 deletions

View File

@ -30,6 +30,7 @@ PlatformIO Core 5
* **Miscellaneous** * **Miscellaneous**
- Ensure that a serial port is ready before running unit tests on a remote target (`issue #3742 <https://github.com/platformio/platformio-core/issues/3742>`_) - Ensure that a serial port is ready before running unit tests on a remote target (`issue #3742 <https://github.com/platformio/platformio-core/issues/3742>`_)
- Fixed an error "Unknown development platform" when running unit tests on a clean machine (`issue #3901 <https://github.com/platformio/platformio-core/issues/3901>`_)
5.1.1 (2021-03-17) 5.1.1 (2021-03-17)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~

View File

@ -22,14 +22,12 @@ import subprocess
import click import click
from platformio import app, exception, fs, proc from platformio import app, exception, fs, proc
from platformio.commands.platform import platform_install as cmd_platform_install from platformio.commands.platform import init_platform
from platformio.compat import IS_WINDOWS from platformio.compat import IS_WINDOWS
from platformio.debug import helpers from platformio.debug import helpers
from platformio.debug.config.factory import DebugConfigFactory from platformio.debug.config.factory import DebugConfigFactory
from platformio.debug.exception import DebugInvalidOptionsError from platformio.debug.exception import DebugInvalidOptionsError
from platformio.debug.process.gdb import GDBClientProcess from platformio.debug.process.gdb import GDBClientProcess
from platformio.platform.exception import UnknownPlatform
from platformio.platform.factory import PlatformFactory
from platformio.project.config import ProjectConfig from platformio.project.config import ProjectConfig
from platformio.project.exception import ProjectEnvsNotAvailableError from platformio.project.exception import ProjectEnvsNotAvailableError
from platformio.project.helpers import is_platformio_project from platformio.project.helpers import is_platformio_project
@ -84,17 +82,9 @@ def cli(ctx, project_dir, project_conf, environment, verbose, interface, __unpro
if "platform" not in env_options: if "platform" not in env_options:
raise ProjectEnvsNotAvailableError() raise ProjectEnvsNotAvailableError()
try: debug_config = DebugConfigFactory.new(
platform = PlatformFactory.new(env_options["platform"]) init_platform(env_options["platform"]), project_config, env_name
except UnknownPlatform: )
ctx.invoke(
cmd_platform_install,
platforms=[env_options["platform"]],
skip_default_package=True,
)
platform = PlatformFactory.new(env_options["platform"])
debug_config = DebugConfigFactory.new(platform, project_config, env_name)
if "--version" in __unprocessed: if "--version" in __unprocessed:
return subprocess.run( return subprocess.run(

View File

@ -31,139 +31,6 @@ def cli():
pass pass
def _print_platforms(platforms):
for platform in platforms:
click.echo(
"{name} ~ {title}".format(
name=click.style(platform["name"], fg="cyan"), title=platform["title"]
)
)
click.echo("=" * (3 + len(platform["name"] + platform["title"])))
click.echo(platform["description"])
click.echo()
if "homepage" in platform:
click.echo("Home: %s" % platform["homepage"])
if "frameworks" in platform and platform["frameworks"]:
click.echo("Frameworks: %s" % ", ".join(platform["frameworks"]))
if "packages" in platform:
click.echo("Packages: %s" % ", ".join(platform["packages"]))
if "version" in platform:
if "__src_url" in platform:
click.echo(
"Version: %s (%s)" % (platform["version"], platform["__src_url"])
)
else:
click.echo("Version: " + platform["version"])
click.echo()
def _get_registry_platforms():
regclient = PlatformPackageManager().get_registry_client_instance()
return regclient.fetch_json_data("get", "/v2/platforms", cache_valid="1d")
def _get_platform_data(*args, **kwargs):
try:
return _get_installed_platform_data(*args, **kwargs)
except UnknownPlatform:
return _get_registry_platform_data(*args, **kwargs)
def _get_installed_platform_data(platform, with_boards=True, expose_packages=True):
p = PlatformFactory.new(platform)
data = dict(
name=p.name,
title=p.title,
description=p.description,
version=p.version,
homepage=p.homepage,
url=p.homepage,
repository=p.repository_url,
license=p.license,
forDesktop=not p.is_embedded(),
frameworks=sorted(list(p.frameworks) if p.frameworks else []),
packages=list(p.packages) if p.packages else [],
)
# if dump to API
# del data['version']
# return data
# overwrite VCS version and add extra fields
manifest = PlatformPackageManager().legacy_load_manifest(
os.path.dirname(p.manifest_path)
)
assert manifest
for key in manifest:
if key == "version" or key.startswith("__"):
data[key] = manifest[key]
if with_boards:
data["boards"] = [c.get_brief_data() for c in p.get_boards().values()]
if not data["packages"] or not expose_packages:
return data
data["packages"] = []
installed_pkgs = {
pkg.metadata.name: p.pm.load_manifest(pkg) for pkg in p.get_installed_packages()
}
for name, options in p.packages.items():
item = dict(
name=name,
type=p.get_package_type(name),
requirements=options.get("version"),
optional=options.get("optional") is True,
)
if name in installed_pkgs:
for key, value in installed_pkgs[name].items():
if key not in ("url", "version", "description"):
continue
item[key] = value
if key == "version":
item["originalVersion"] = get_original_version(value)
data["packages"].append(item)
return data
def _get_registry_platform_data( # pylint: disable=unused-argument
platform, with_boards=True, expose_packages=True
):
_data = None
for p in _get_registry_platforms():
if p["name"] == platform:
_data = p
break
if not _data:
return None
data = dict(
ownername=_data.get("ownername"),
name=_data["name"],
title=_data["title"],
description=_data["description"],
homepage=_data["homepage"],
repository=_data["repository"],
url=_data["url"],
license=_data["license"],
forDesktop=_data["forDesktop"],
frameworks=_data["frameworks"],
packages=_data["packages"],
versions=_data.get("versions"),
)
if with_boards:
data["boards"] = [
board
for board in PlatformPackageManager().get_registered_boards()
if board["platform"] == _data["name"]
]
return data
@cli.command("search", short_help="Search for development platform") @cli.command("search", short_help="Search for development platform")
@click.argument("query", required=False) @click.argument("query", required=False)
@click.option("--json-output", is_flag=True) @click.option("--json-output", is_flag=True)
@ -319,13 +186,33 @@ def platform_install( # pylint: disable=too-many-arguments
with_all_packages, with_all_packages,
silent, silent,
force, force,
):
return _platform_install(
platforms,
with_package,
without_package,
skip_default_package,
with_all_packages,
silent,
force,
)
def _platform_install( # pylint: disable=too-many-arguments
platforms,
with_package=None,
without_package=None,
skip_default_package=False,
with_all_packages=False,
silent=False,
force=False,
): ):
pm = PlatformPackageManager() pm = PlatformPackageManager()
for platform in platforms: for platform in platforms:
pkg = pm.install( pkg = pm.install(
spec=platform, spec=platform,
with_packages=with_package, with_packages=with_package or [],
without_packages=without_package, without_packages=without_package or [],
skip_default_package=skip_default_package, skip_default_package=skip_default_package,
with_all_packages=with_all_packages, with_all_packages=with_all_packages,
silent=silent, silent=silent,
@ -423,3 +310,150 @@ def platform_update( # pylint: disable=too-many-locals, too-many-arguments
click.echo() click.echo()
return True return True
#
# Helpers
#
def init_platform(name, skip_default_package=True, auto_install=True):
try:
return PlatformFactory.new(name)
except UnknownPlatform:
if auto_install:
_platform_install([name], skip_default_package=skip_default_package)
return PlatformFactory.new(name)
def _print_platforms(platforms):
for platform in platforms:
click.echo(
"{name} ~ {title}".format(
name=click.style(platform["name"], fg="cyan"), title=platform["title"]
)
)
click.echo("=" * (3 + len(platform["name"] + platform["title"])))
click.echo(platform["description"])
click.echo()
if "homepage" in platform:
click.echo("Home: %s" % platform["homepage"])
if "frameworks" in platform and platform["frameworks"]:
click.echo("Frameworks: %s" % ", ".join(platform["frameworks"]))
if "packages" in platform:
click.echo("Packages: %s" % ", ".join(platform["packages"]))
if "version" in platform:
if "__src_url" in platform:
click.echo(
"Version: %s (%s)" % (platform["version"], platform["__src_url"])
)
else:
click.echo("Version: " + platform["version"])
click.echo()
def _get_registry_platforms():
regclient = PlatformPackageManager().get_registry_client_instance()
return regclient.fetch_json_data("get", "/v2/platforms", cache_valid="1d")
def _get_platform_data(*args, **kwargs):
try:
return _get_installed_platform_data(*args, **kwargs)
except UnknownPlatform:
return _get_registry_platform_data(*args, **kwargs)
def _get_installed_platform_data(platform, with_boards=True, expose_packages=True):
p = PlatformFactory.new(platform)
data = dict(
name=p.name,
title=p.title,
description=p.description,
version=p.version,
homepage=p.homepage,
url=p.homepage,
repository=p.repository_url,
license=p.license,
forDesktop=not p.is_embedded(),
frameworks=sorted(list(p.frameworks) if p.frameworks else []),
packages=list(p.packages) if p.packages else [],
)
# if dump to API
# del data['version']
# return data
# overwrite VCS version and add extra fields
manifest = PlatformPackageManager().legacy_load_manifest(
os.path.dirname(p.manifest_path)
)
assert manifest
for key in manifest:
if key == "version" or key.startswith("__"):
data[key] = manifest[key]
if with_boards:
data["boards"] = [c.get_brief_data() for c in p.get_boards().values()]
if not data["packages"] or not expose_packages:
return data
data["packages"] = []
installed_pkgs = {
pkg.metadata.name: p.pm.load_manifest(pkg) for pkg in p.get_installed_packages()
}
for name, options in p.packages.items():
item = dict(
name=name,
type=p.get_package_type(name),
requirements=options.get("version"),
optional=options.get("optional") is True,
)
if name in installed_pkgs:
for key, value in installed_pkgs[name].items():
if key not in ("url", "version", "description"):
continue
item[key] = value
if key == "version":
item["originalVersion"] = get_original_version(value)
data["packages"].append(item)
return data
def _get_registry_platform_data( # pylint: disable=unused-argument
platform, with_boards=True, expose_packages=True
):
_data = None
for p in _get_registry_platforms():
if p["name"] == platform:
_data = p
break
if not _data:
return None
data = dict(
ownername=_data.get("ownername"),
name=_data["name"],
title=_data["title"],
description=_data["description"],
homepage=_data["homepage"],
repository=_data["repository"],
url=_data["url"],
license=_data["license"],
forDesktop=_data["forDesktop"],
frameworks=_data["frameworks"],
packages=_data["packages"],
versions=_data.get("versions"),
)
if with_boards:
data["boards"] = [
board
for board in PlatformPackageManager().get_registered_boards()
if board["platform"] == _data["name"]
]
return data

View File

@ -12,10 +12,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from platformio.commands.platform import platform_install as cmd_platform_install from platformio.commands.platform import init_platform
from platformio.commands.test.processor import CTX_META_TEST_RUNNING_NAME from platformio.commands.test.processor import CTX_META_TEST_RUNNING_NAME
from platformio.platform.exception import UnknownPlatform
from platformio.platform.factory import PlatformFactory
from platformio.project.exception import UndefinedEnvPlatformError from platformio.project.exception import UndefinedEnvPlatformError
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
@ -66,15 +64,7 @@ class EnvironmentProcessor(object):
if "monitor" in build_targets: if "monitor" in build_targets:
build_targets.remove("monitor") build_targets.remove("monitor")
try: result = init_platform(self.options["platform"]).run(
p = PlatformFactory.new(self.options["platform"]) build_vars, build_targets, self.silent, self.verbose, self.jobs
except UnknownPlatform: )
self.cmd_ctx.invoke(
cmd_platform_install,
platforms=[self.options["platform"]],
skip_default_package=True,
)
p = PlatformFactory.new(self.options["platform"])
result = p.run(build_vars, build_targets, self.silent, self.verbose, self.jobs)
return result["returncode"] == 0 return result["returncode"] == 0

View File

@ -22,10 +22,10 @@ import click
from tabulate import tabulate from tabulate import tabulate
from platformio import app, exception, fs, util from platformio import app, exception, fs, util
from platformio.commands.platform import init_platform
from platformio.commands.test.embedded import EmbeddedTestProcessor from platformio.commands.test.embedded import EmbeddedTestProcessor
from platformio.commands.test.helpers import get_test_names from platformio.commands.test.helpers import get_test_names
from platformio.commands.test.native import NativeTestProcessor from platformio.commands.test.native import NativeTestProcessor
from platformio.platform.factory import PlatformFactory
from platformio.project.config import ProjectConfig from platformio.project.config import ProjectConfig
@ -141,9 +141,7 @@ def cli( # pylint: disable=redefined-builtin
cls = ( cls = (
EmbeddedTestProcessor EmbeddedTestProcessor
if config.get(section, "platform") if config.get(section, "platform")
and PlatformFactory.new( and init_platform(config.get(section, "platform")).is_embedded()
config.get(section, "platform")
).is_embedded()
else NativeTestProcessor else NativeTestProcessor
) )
tp = cls( tp = cls(