Beispiel #1
0
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)
Beispiel #2
0
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",
            )
Beispiel #3
0
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",
            )
Beispiel #4
0
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
Beispiel #5
0
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)
Beispiel #6
0
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
Beispiel #7
0
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()
Beispiel #8
0
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)))
Beispiel #9
0
 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}")
Beispiel #10
0
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
Beispiel #11
0
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"])
Beispiel #12
0
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()]))
Beispiel #13
0
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
Beispiel #14
0
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")
Beispiel #15
0
    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"])
Beispiel #16
0
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
Beispiel #17
0
    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))
Beispiel #19
0
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("")
Beispiel #21
0
def _get_boards(installed=False):
    pm = PlatformPackageManager()
    return pm.get_installed_boards() if installed else pm.get_all_boards()
Beispiel #22
0
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
Beispiel #24
0
    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