Пример #1
0
def fetch_portable_python(dst):
    url = get_portable_python_url()
    if not url:
        log.debug("Could not find portable Python for %s", util.get_systype())
        return None
    try:
        log.debug("Downloading portable python...")

        archive_path = util.download_file(
            url,
            os.path.join(os.path.join(dst, ".cache", "tmp"),
                         os.path.basename(url)))

        python_dir = os.path.join(dst, "python3")
        util.safe_remove_dir(python_dir)
        util.safe_create_dir(python_dir, raise_exception=True)

        log.debug("Unpacking portable python...")
        util.unpack_archive(archive_path, python_dir)
        if util.IS_WINDOWS:
            return os.path.join(python_dir, "python.exe")
        return os.path.join(python_dir, "bin", "python3")
    except:  # pylint:disable=bare-except
        log.debug("Could not download portable python")
    return None
Пример #2
0
def create_core_penv(penv_dir=None, ignore_pythons=None):
    penv_dir = penv_dir or get_penv_dir()

    click.echo("Creating a virtual environment at %s" % penv_dir)

    result_dir = None
    for python_exe in python.find_compatible_pythons(ignore_pythons):
        result_dir = create_virtualenv(python_exe, penv_dir)
        if result_dir:
            break

    if (not result_dir and util.get_systype() in python.PORTABLE_PYTHONS
            and not python.is_portable()):
        python_exe = python.fetch_portable_python(os.path.dirname(penv_dir))
        if python_exe:
            result_dir = create_virtualenv(python_exe, penv_dir)

    if not result_dir:
        raise exception.PIOInstallerException(
            "Could not create PIO Core Virtual Environment. Please report to "
            "https://github.com/platformio/platformio-core-installer/issues")

    python_exe = os.path.join(get_penv_bin_dir(penv_dir),
                              "python.exe" if util.IS_WINDOWS else "python")
    add_state_info(python_exe, penv_dir)
    install_pip(python_exe, penv_dir)
    click.echo("Virtual environment has been successfully created!")
    return result_dir
Пример #3
0
def test_install_pio_core(pio_installer_script, tmpdir, monkeypatch):
    monkeypatch.setattr(util, "get_installer_script", lambda: pio_installer_script)

    core_dir = tmpdir.mkdir(".pio")
    penv_dir = str(core_dir.mkdir("penv"))
    os.environ["PLATFORMIO_CORE_DIR"] = str(core_dir)

    assert core.install_platformio_core(shutdown_piohome=False)

    python_exe = os.path.join(
        penv.get_penv_bin_dir(penv_dir), "python.exe" if util.IS_WINDOWS else "python"
    )
    assert subprocess.check_call([python_exe, "-m", "platformio", "--version"]) == 0

    core_state_path = os.path.join(str(core_dir), "core-state.json")
    assert (
        subprocess.check_call(
            [
                "python",
                pio_installer_script,
                "check",
                "core",
                "--dump-state=%s" % core_state_path,
            ],
            stderr=subprocess.STDOUT,
        )
        == 0
    )
    with open(core_state_path) as fp:
        json_info = json.load(fp)
        assert json_info.get("core_dir") == str(core_dir)
        assert json_info.get("penv_dir") == penv_dir
        assert json_info.get("installer_version") == __version__
        assert json_info.get("system") == util.get_systype()

    assert os.path.isfile(
        os.path.join(
            penv.get_penv_bin_dir(penv_dir),
            "platformio.exe" if util.IS_WINDOWS else "platformio",
        )
    )
    assert os.path.isfile(
        os.path.join(str(core_dir), "packages", "contrib-piohome", "package.json")
    )
    assert os.path.isfile(
        os.path.join(str(core_dir), "packages", "contrib-pysite", "package.json")
    )
Пример #4
0
def get_portable_python_url():
    systype = util.get_systype()
    result = requests.get("https://api.registry.platformio.org/v3/packages/"
                          "platformio/tool/python-portable").json()
    versions = [
        version for version in result["versions"]
        if is_version_system_compatible(version, systype)
    ]
    best_version = None
    for version in versions:
        if not best_version or semantic_version.Version(
                version.name) > semantic_version.Version(best_version.name):
            best_version = version
    for item in (best_version or {}).get("files", []):
        if systype in item["system"]:
            return item["download_url"]
    return None
Пример #5
0
def check(dev=False, auto_upgrade=False, version_spec=None):
    # pylint: disable=bad-option-value, import-outside-toplevel, unused-import, import-error, unused-variable, cyclic-import
    from pioinstaller import penv

    platformio_exe = os.path.join(
        penv.get_penv_bin_dir(),
        "platformio.exe" if util.IS_WINDOWS else "platformio",
    )
    python_exe = os.path.join(penv.get_penv_bin_dir(),
                              "python.exe" if util.IS_WINDOWS else "python")
    result = {}

    if not os.path.isfile(platformio_exe):
        raise exception.InvalidPlatformIOCore(
            "PlatformIO executable not found in `%s`" %
            penv.get_penv_bin_dir())

    if not os.path.isfile(os.path.join(penv.get_penv_dir(), "state.json")):
        raise exception.InvalidPlatformIOCore(
            "Could not found state.json file in `%s`" %
            os.path.join(penv.get_penv_dir(), "state.json"))

    try:
        result.update(fetch_python_state(python_exe))
    except subprocess.CalledProcessError as e:
        error = e.output.decode()
        raise exception.InvalidPlatformIOCore(
            "Could not import PlatformIO module. Error: %s" % error)

    piocore_version = convert_version(result.get("core_version"))
    dev = dev or bool(piocore_version.prerelease if piocore_version else False)
    result.update({
        "core_dir": get_core_dir(),
        "cache_dir": get_cache_dir(),
        "penv_dir": penv.get_penv_dir(),
        "penv_bin_dir": penv.get_penv_bin_dir(),
        "platformio_exe": platformio_exe,
        "installer_version": __version__,
        "python_exe": python_exe,
        "system": util.get_systype(),
        "is_develop_core": dev,
    })

    if version_spec:
        try:
            if piocore_version not in semantic_version.Spec(version_spec):
                raise exception.InvalidPlatformIOCore(
                    "PlatformIO Core version %s does not match version requirements %s."
                    % (str(piocore_version), version_spec))
        except ValueError:
            click.secho("Invalid version requirements format: %s. "
                        "More about Semantic Versioning: https://semver.org/" %
                        version_spec)

    with open(os.path.join(penv.get_penv_dir(), "state.json")) as fp:
        penv_state = json.load(fp)
        if penv_state.get("platform") != platform.platform(terse=True):
            raise exception.InvalidPlatformIOCore(
                "PlatformIO Core was installed using another platform `%s`. "
                "Your current platform: %s" %
                (penv_state.get("platform"), platform.platform(terse=True)))

    try:
        subprocess.check_output([platformio_exe, "--version"],
                                stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError as e:
        error = e.output.decode()
        raise exception.InvalidPlatformIOCore(
            "Could not run `%s --version`.\nError: %s" %
            (platformio_exe, str(error)))

    if not auto_upgrade:
        return result

    time_now = int(round(time.time()))

    last_piocore_version_check = penv_state.get("last_piocore_version_check")

    if (last_piocore_version_check and
        (time_now - int(last_piocore_version_check)) < UPDATE_INTERVAL):
        return result

    with open(os.path.join(penv.get_penv_dir(), "state.json"), "w") as fp:
        penv_state["last_piocore_version_check"] = time_now
        json.dump(penv_state, fp)

    if not last_piocore_version_check:
        return result

    upgrade_core(platformio_exe, dev)

    try:
        result.update(fetch_python_state(python_exe))
    except:  # pylint:disable=bare-except
        raise exception.InvalidPlatformIOCore(
            "Could not import PlatformIO module")
    return result