def platform_frameworks(query, json_output): regclient = PlatformPackageManager().get_registry_client_instance() frameworks = [] for framework in regclient.fetch_json_data("get", "/v2/frameworks", cache_valid="1d"): if query == "all": query = "" search_data = dump_json_to_unicode(framework) if query and query.lower() not in search_data.lower(): continue framework[ "homepage"] = "https://platformio.org/frameworks/" + framework[ "name"] framework["platforms"] = [ platform["name"] for platform in _get_registry_platforms() if framework["name"] in platform["frameworks"] ] frameworks.append(framework) frameworks = sorted(frameworks, key=lambda manifest: manifest["name"]) if json_output: click.echo(dump_json_to_unicode(frameworks)) else: _print_platforms(frameworks)
def platform_install( # pylint: disable=too-many-arguments platforms, with_package, without_package, skip_default_package, with_all_packages, silent, force, ): pm = PlatformPackageManager() for platform in platforms: pkg = pm.install( spec=platform, with_packages=with_package, without_packages=without_package, skip_default_package=skip_default_package, with_all_packages=with_all_packages, silent=silent, force=force, ) if pkg and not silent: click.secho( "The platform '%s' has been successfully installed!\n" "The rest of the packages will be installed later " "depending on your build environment." % platform, fg="green", )
def platform_uninstall(platforms): pm = PlatformPackageManager() for platform in platforms: if pm.uninstall(platform): click.secho( "The platform '%s' has been successfully removed!" % platform, fg="green", )
def validate_boards(ctx, param, value): # pylint: disable=W0613 pm = PlatformPackageManager() for id_ in value: try: pm.board_config(id_) except UnknownBoard: raise click.BadParameter( "`%s`. Please search for board ID using `platformio boards` " "command" % id_) return value
def platform_list(json_output): platforms = [] pm = PlatformPackageManager() for pkg in pm.get_installed(): platforms.append( _get_installed_platform_data(pkg, with_boards=False, expose_packages=False)) platforms = sorted(platforms, key=lambda manifest: manifest["name"]) if json_output: click.echo(dump_json_to_unicode(platforms)) else: _print_platforms(platforms)
def test_build_metadata(isolated_pio_core, tmpdir_factory): pm = PlatformPackageManager() vcs_revision = "a2ebfd7c0f" pkg_dir = tmpdir_factory.mktemp("package") # test package without manifest with pytest.raises(MissingPackageManifestError): pm.load_manifest(str(pkg_dir)) with pytest.raises(MissingPackageManifestError): pm.build_metadata(str(pkg_dir), PackageSpec("MyLib")) # with manifest pkg_dir.join("platform.json").write( '{"name": "Dev-Platform", "version": "1.2.3-alpha.1"}') metadata = pm.build_metadata(str(pkg_dir), PackageSpec("owner/platform-name")) assert metadata.name == "Dev-Platform" assert str(metadata.version) == "1.2.3-alpha.1" # with vcs metadata = pm.build_metadata(str(pkg_dir), PackageSpec("owner/platform-name"), vcs_revision) assert str(metadata.version) == ("1.2.3-alpha.1+sha." + vcs_revision) assert metadata.version.build[1] == vcs_revision
def update_board_envs(ctx, project_dir, board_ids, project_option, env_prefix, force_download): config = ProjectConfig(os.path.join(project_dir, "platformio.ini"), parse_extra=False) used_boards = [] for section in config.sections(): cond = [ section.startswith("env:"), config.has_option(section, "board") ] if all(cond): used_boards.append(config.get(section, "board")) pm = PlatformPackageManager() used_platforms = [] modified = False for id_ in board_ids: board_config = pm.board_config(id_) used_platforms.append(board_config["platform"]) if id_ in used_boards: continue used_boards.append(id_) modified = True envopts = {"platform": board_config["platform"], "board": id_} # find default framework for board frameworks = board_config.get("frameworks") if frameworks: envopts["framework"] = frameworks[0] for item in project_option: if "=" not in item: continue _name, _value = item.split("=", 1) envopts[_name.strip()] = _value.strip() section = "env:%s%s" % (env_prefix, id_) config.add_section(section) for option, value in envopts.items(): config.set(section, option, value) if force_download and used_platforms: _install_dependent_platforms(ctx, used_platforms) if modified: config.save()
def _install_dependent_platforms(ctx, platforms): installed_platforms = [ pkg.metadata.name for pkg in PlatformPackageManager().get_installed() ] if set(platforms) <= set(installed_platforms): return ctx.invoke(cli_platform_install, platforms=list(set(platforms) - set(installed_platforms)))
def setup(self): self._old_dir = os.getcwd() os.chdir(self.path) self.project_config = ProjectConfig( self.path.joinpath("platformio.ini")) self.package_manager = PlatformPackageManager() if not self.check_env(): raise BuilderError(f"Environment doesn't exist: {self.build.env}")
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 test_find_pkg_root(isolated_pio_core, tmpdir_factory): # has manifest pkg_dir = tmpdir_factory.mktemp("package-has-manifest") root_dir = pkg_dir.join("nested").mkdir().join("folder").mkdir() root_dir.join("platform.json").write("") pm = PlatformPackageManager() found_dir = pm.find_pkg_root(str(pkg_dir), spec=None) assert os.path.realpath(str(root_dir)) == os.path.realpath(found_dir) # does not have manifest pkg_dir = tmpdir_factory.mktemp("package-does-not-have-manifest") pkg_dir.join("nested").mkdir().join("folder").mkdir().join( "readme.txt").write("") pm = PlatformPackageManager() with pytest.raises(MissingPackageManifestError): pm.find_pkg_root(str(pkg_dir), spec=None) # library package without manifest, should find source root pkg_dir = tmpdir_factory.mktemp("library-package-without-manifest") root_dir = pkg_dir.join("nested").mkdir().join("folder").mkdir() root_dir.join("src").mkdir().join("main.cpp").write("") root_dir.join("include").mkdir().join("main.h").write("") assert os.path.realpath(str(root_dir)) == os.path.realpath( LibraryPackageManager.find_library_root(str(pkg_dir))) # library manager should create "library.json" lm = LibraryPackageManager() spec = PackageSpec("[email protected]") pkg_root = lm.find_pkg_root(str(pkg_dir), spec) manifest_path = os.path.join(pkg_root, "library.json") assert os.path.realpath(str(root_dir)) == os.path.realpath(pkg_root) assert os.path.isfile(manifest_path) manifest = lm.load_manifest(pkg_root) assert manifest["name"] == "custom-name" assert "0.0.0" in str(manifest["version"])
def system_info(json_output): project_config = ProjectConfig() data = {} data["core_version"] = {"title": "PlatformIO Core", "value": __version__} data["python_version"] = { "title": "Python", "value": "{0}.{1}.{2}-{3}.{4}".format(*list(sys.version_info)), } data["system"] = {"title": "System Type", "value": util.get_systype()} data["platform"] = { "title": "Platform", "value": platform.platform(terse=True) } data["filesystem_encoding"] = { "title": "File System Encoding", "value": compat.get_filesystem_encoding(), } data["locale_encoding"] = { "title": "Locale Encoding", "value": compat.get_locale_encoding(), } data["core_dir"] = { "title": "PlatformIO Core Directory", "value": project_config.get_optional_dir("core"), } data["platformio_exe"] = { "title": "PlatformIO Core Executable", "value": proc.where_is_program( "platformio.exe" if proc.WINDOWS else "platformio"), } data["python_exe"] = { "title": "Python Executable", "value": proc.get_pythonexe_path(), } data["global_lib_nums"] = { "title": "Global Libraries", "value": len(LibraryPackageManager().get_installed()), } data["dev_platform_nums"] = { "title": "Development Platforms", "value": len(PlatformPackageManager().get_installed()), } data["package_tool_nums"] = { "title": "Tools & Toolchains", "value": len( ToolPackageManager( project_config.get_optional_dir("packages")).get_installed()), } click.echo( json.dumps(data) if json_output else tabulate([( item["title"], item["value"]) for item in data.values()]))
def get_builtin_libs(storage_names=None): # pylint: disable=import-outside-toplevel from platformio.package.manager.library import LibraryPackageManager items = [] storage_names = storage_names or [] pm = PlatformPackageManager() for pkg in pm.get_installed(): p = PlatformFactory.new(pkg) for storage in p.get_lib_storages(): if storage_names and storage["name"] not in storage_names: continue lm = LibraryPackageManager(storage["path"]) items.append({ "name": storage["name"], "path": storage["path"], "items": lm.legacy_get_installed(), }) return items
def test_build_legacy_spec(isolated_pio_core, tmpdir_factory): storage_dir = tmpdir_factory.mktemp("storage") pm = PlatformPackageManager(str(storage_dir)) # test src manifest pkg1_dir = storage_dir.join("pkg-1").mkdir() pkg1_dir.join(".pio").mkdir().join(".piopkgmanager.json").write(""" { "name": "StreamSpy-0.0.1.tar", "url": "https://dl.platformio.org/e8936b7/StreamSpy-0.0.1.tar.gz", "requirements": null } """) assert pm.build_legacy_spec(str(pkg1_dir)) == PackageSpec( name="StreamSpy-0.0.1.tar", url="https://dl.platformio.org/e8936b7/StreamSpy-0.0.1.tar.gz", ) # without src manifest pkg2_dir = storage_dir.join("pkg-2").mkdir() pkg2_dir.join("main.cpp").write("") with pytest.raises(MissingPackageManifestError): pm.build_legacy_spec(str(pkg2_dir)) # with package manifest pkg3_dir = storage_dir.join("pkg-3").mkdir() pkg3_dir.join("platform.json").write( '{"name": "pkg3", "version": "1.2.0"}') assert pm.build_legacy_spec(str(pkg3_dir)) == PackageSpec(name="pkg3")
def get_project_examples(): result = [] pm = PlatformPackageManager() for pkg in pm.get_installed(): examples_dir = os.path.join(pkg.path, "examples") if not os.path.isdir(examples_dir): continue items = [] for project_dir, _, __ in os.walk(examples_dir): project_description = None try: config = ProjectConfig( os.path.join(project_dir, "platformio.ini")) config.validate(silent=True) project_description = config.get("platformio", "description") except ProjectError: continue path_tokens = project_dir.split(os.path.sep) items.append({ "name": "/".join(path_tokens[path_tokens.index("examples") + 1:]), "path": project_dir, "description": project_description, }) manifest = pm.load_manifest(pkg) result.append({ "platform": { "title": manifest["title"], "version": manifest["version"], }, "items": sorted(items, key=lambda item: item["name"]), }) return sorted(result, key=lambda data: data["platform"]["title"])
def platform_update( # pylint: disable=too-many-locals, too-many-arguments platforms, only_packages, only_check, dry_run, silent, json_output): pm = PlatformPackageManager() platforms = platforms or pm.get_installed() only_check = dry_run or only_check if only_check and json_output: result = [] for platform in platforms: spec = None pkg = None if isinstance(platform, PackageItem): pkg = platform else: spec = PackageSpec(platform) pkg = pm.get_package(spec) if not pkg: continue outdated = pm.outdated(pkg, spec) if (not outdated.is_outdated(allow_incompatible=True) and not PlatformFactory.new(pkg).are_outdated_packages()): continue data = _get_installed_platform_data(pkg, with_boards=False, expose_packages=False) if outdated.is_outdated(allow_incompatible=True): data["versionLatest"] = (str(outdated.latest) if outdated.latest else None) result.append(data) return click.echo(dump_json_to_unicode(result)) # cleanup cached board and platform lists cleanup_content_cache("http") for platform in platforms: click.echo("Platform %s" % click.style( platform.metadata.name if isinstance(platform, PackageItem) else platform, fg="cyan", )) click.echo("--------") pm.update(platform, only_packages=only_packages, only_check=only_check, silent=silent) click.echo() return True
def new(cls, pkg_or_spec): platform_dir = None platform_name = None if isinstance(pkg_or_spec, PackageItem): platform_dir = pkg_or_spec.path platform_name = pkg_or_spec.metadata.name elif os.path.isdir(pkg_or_spec): platform_dir = pkg_or_spec else: from platformio.package.manager.platform import ( # pylint: disable=import-outside-toplevel PlatformPackageManager, ) pkg = PlatformPackageManager().get_package(pkg_or_spec) if not pkg: raise UnknownPlatform(pkg_or_spec) platform_dir = pkg.path platform_name = pkg.metadata.name if not platform_dir or not os.path.isfile( os.path.join(platform_dir, "platform.json")): raise UnknownPlatform(pkg_or_spec) if not platform_name: platform_name = fs.load_json( os.path.join(platform_dir, "platform.json"))["name"] platform_cls = None if os.path.isfile(os.path.join(platform_dir, "platform.py")): platform_cls = getattr( cls.load_module(platform_name, os.path.join(platform_dir, "platform.py")), cls.get_clsname(platform_name), ) else: platform_cls = type(str(cls.get_clsname(platform_name)), (PlatformBase, ), {}) _instance = platform_cls(os.path.join(platform_dir, "platform.json")) assert isinstance(_instance, PlatformBase) return _instance
def pytest_generate_tests(metafunc): if "pioproject_dir" not in metafunc.fixturenames: return examples_dirs = [] # repo examples examples_dirs.append( os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "examples")) ) # dev/platforms for pkg in PlatformPackageManager().get_installed(): p = PlatformFactory.new(pkg) examples_dir = os.path.join(p.get_dir(), "examples") if os.path.isdir(examples_dir): examples_dirs.append(examples_dir) project_dirs = [] for examples_dir in examples_dirs: candidates = {} for root, _, files in os.walk(examples_dir): if "platformio.ini" not in files or ".skiptest" in files: continue if "zephyr-" in root and PY2: continue group = os.path.basename(root) if "-" in group: group = group.split("-", 1)[0] if group not in candidates: candidates[group] = [] candidates[group].append(root) project_dirs.extend( [random.choice(examples) for examples in candidates.values() if examples] ) metafunc.parametrize("pioproject_dir", sorted(project_dirs))
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
def check_internal_updates(ctx, what): # pylint: disable=too-many-branches last_check = app.get_state_item("last_check", {}) interval = int(app.get_setting("check_%s_interval" % what)) * 3600 * 24 if (time() - interval) < last_check.get(what + "_update", 0): return last_check[what + "_update"] = int(time()) app.set_state_item("last_check", last_check) http.ensure_internet_on(raise_exception=True) outdated_items = [] pm = PlatformPackageManager() if what == "platforms" else LibraryPackageManager() for pkg in pm.get_installed(): if pkg.metadata.name in outdated_items: continue conds = [ pm.outdated(pkg).is_outdated(), what == "platforms" and PlatformFactory.new(pkg).are_outdated_packages(), ] if any(conds): outdated_items.append(pkg.metadata.name) if not outdated_items: return terminal_width, _ = click.get_terminal_size() click.echo("") click.echo("*" * terminal_width) click.secho( "There are the new updates for %s (%s)" % (what, ", ".join(outdated_items)), fg="yellow", ) if not app.get_setting("auto_update_" + what): click.secho("Please update them via ", fg="yellow", nl=False) click.secho( "`platformio %s update`" % ("lib --global" if what == "libraries" else "platform"), fg="cyan", nl=False, ) click.secho(" command.\n", fg="yellow") click.secho( "If you want to manually check for the new versions " "without updating, please use ", fg="yellow", nl=False, ) click.secho( "`platformio %s update --dry-run`" % ("lib --global" if what == "libraries" else "platform"), fg="cyan", nl=False, ) click.secho(" command.", fg="yellow") else: click.secho("Please wait while updating %s ..." % what, fg="yellow") if what == "platforms": ctx.invoke(cmd_platform_update, platforms=outdated_items) elif what == "libraries": ctx.meta[CTX_META_STORAGE_DIRS_KEY] = [pm.package_dir] ctx.invoke(cmd_lib_update, libraries=outdated_items) click.echo() telemetry.send_event(category="Auto", action="Update", label=what.title()) click.echo("*" * terminal_width) click.echo("")
def _get_boards(installed=False): pm = PlatformPackageManager() return pm.get_installed_boards() if installed else pm.get_all_boards()
def _get_registry_platforms(): regclient = PlatformPackageManager().get_registry_client_instance() return regclient.fetch_json_data("get", "/v2/platforms", cache_valid="1d")
except ImportError: from urllib.parse import ParseResult, urlparse, urlunparse RST_COPYRIGHT = """.. Copyright (c) 2014-present PlatformIO <*****@*****.**> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ REGCLIENT = regclient = PlatformPackageManager().get_registry_client_instance() API_PACKAGES = regclient.fetch_json_data("get", "/v2/packages") API_FRAMEWORKS = regclient.fetch_json_data("get", "/v2/frameworks") BOARDS = PlatformPackageManager().get_installed_boards() PLATFORM_MANIFESTS = PlatformPackageManager().legacy_get_installed() DOCS_ROOT_DIR = realpath(join(dirname(realpath(__file__)), "..", "docs")) def is_compat_platform_and_framework(platform, framework): p = PlatformFactory.new(platform) return framework in (p.frameworks or {}).keys() def campaign_url(url, source="platformio.org", medium="docs"): data = urlparse(url) query = data.query
def get_projects(): def _get_project_data(): data = {"boards": [], "envLibdepsDirs": [], "libExtraDirs": []} config = ProjectConfig() data["envs"] = config.envs() data["description"] = config.get("platformio", "description") data["libExtraDirs"].extend( config.get("platformio", "lib_extra_dirs", [])) libdeps_dir = config.get_optional_dir("libdeps") for section in config.sections(): if not section.startswith("env:"): continue data["envLibdepsDirs"].append( os.path.join(libdeps_dir, section[4:])) if config.has_option(section, "board"): data["boards"].append(config.get(section, "board")) data["libExtraDirs"].extend( config.get(section, "lib_extra_dirs", [])) # skip non existing folders and resolve full path for key in ("envLibdepsDirs", "libExtraDirs"): data[key] = [ fs.expanduser(d) if d.startswith("~") else os.path.realpath(d) for d in data[key] if os.path.isdir(d) ] return data def _path_to_name(path): return (os.path.sep).join(path.split(os.path.sep)[-2:]) result = [] pm = PlatformPackageManager() for project_dir in AppRPC.load_state()["storage"]["recentProjects"]: if not os.path.isdir(project_dir): continue data = {} boards = [] try: with fs.cd(project_dir): data = _get_project_data() except ProjectError: continue for board_id in data.get("boards", []): name = board_id try: name = pm.board_config(board_id)["name"] except exception.PlatformioException: pass boards.append({"id": board_id, "name": name}) result.append({ "path": project_dir, "name": _path_to_name(project_dir), "modified": int(os.path.getmtime(project_dir)), "boards": boards, "description": data.get("description"), "envs": data.get("envs", []), "envLibStorages": [{ "name": os.path.basename(d), "path": d } for d in data.get("envLibdepsDirs", [])], "extraLibStorages": [{ "name": _path_to_name(d), "path": d } for d in data.get("libExtraDirs", [])], }) return result