Ejemplo n.º 1
0
    def configure_sources(cls, poetry: Poetry, sources: list[dict[str, str]],
                          config: Config, io: IO) -> None:
        for source in sources:
            repository = cls.create_legacy_repository(source, config)
            is_default = bool(source.get("default", False))
            is_secondary = bool(source.get("secondary", False))
            if io.is_debug():
                message = f"Adding repository {repository.name} ({repository.url})"
                if is_default:
                    message += " and setting it as the default one"
                elif is_secondary:
                    message += " and setting it as secondary"

                io.write_line(message)

            poetry.pool.add_repository(repository,
                                       is_default,
                                       secondary=is_secondary)

        # Put PyPI last to prefer private repositories
        # unless we have no default source AND no primary sources
        # (default = false, secondary = false)
        if poetry.pool.has_default():
            if io.is_debug():
                io.write_line("Deactivating the PyPI repository")
        else:
            from poetry.repositories.pypi_repository import PyPiRepository

            default = not poetry.pool.has_primary_repositories()
            poetry.pool.add_repository(PyPiRepository(), default, not default)
Ejemplo n.º 2
0
    def _download(self, destination: pathlib.Path,
                  io: cleo_io.IO) -> pathlib.Path:
        req = requests.get(self.url, stream=True)
        length = int(req.headers.get("content-length", 0))

        progress = progress_bar.ProgressBar(io, max=length)
        io.write_line(f"Downloading <info>{self.url}</>")
        if req.status_code < 200 or req.status_code >= 300:
            raise RuntimeError(f"download failed: {req.status_code}")

        progress.start(length)

        try:
            with open(destination, "wb") as f:
                for chunk in req.iter_content(chunk_size=4096):
                    if chunk:
                        progress.advance(len(chunk))
                        f.write(chunk)
        except BaseException:
            if destination.exists():
                destination.unlink()
        finally:
            progress.finish()
            io.write_line("")

        try:
            self.verify(destination)
        except Exception:
            destination.unlink()
            raise

        return destination
Ejemplo n.º 3
0
    def display_package_tree(self, io: IO, package: Package,
                             installed_repo: Repository) -> None:
        io.write(f"<c1>{package.pretty_name}</c1>")
        description = ""
        if package.description:
            description = " " + package.description

        io.write_line(f" <b>{package.pretty_version}</b>{description}")

        dependencies = package.requires
        dependencies = sorted(dependencies, key=lambda x: x.name)
        tree_bar = "├"
        total = len(dependencies)
        for i, dependency in enumerate(dependencies, 1):
            if i == total:
                tree_bar = "└"

            level = 1
            color = self.colors[level]
            info = (f"{tree_bar}── <{color}>{dependency.name}</{color}>"
                    f" {dependency.pretty_constraint}")
            self._write_tree_line(io, info)

            tree_bar = tree_bar.replace("└", " ")
            packages_in_tree = [package.name, dependency.name]

            self._display_tree(io, dependency, installed_repo,
                               packages_in_tree, tree_bar, level + 1)
Ejemplo n.º 4
0
    def _write_tree_line(self, io: IO, line: str) -> None:
        if not io.output.supports_utf8():
            line = line.replace("└", "`-")
            line = line.replace("├", "|-")
            line = line.replace("──", "-")
            line = line.replace("│", "|")

        io.write_line(line)
Ejemplo n.º 5
0
    def download(self, io: cleo_io.IO) -> pathlib.Path:
        destination_dir = cache.cachedir() / "distfiles"
        if not destination_dir.exists():
            destination_dir.mkdir()

        destination = destination_dir / self.name
        if destination.exists():
            try:
                self.verify(destination)
            except Exception:
                io.write_line(
                    f"<warning>Cached {self.name} exists, but does pass "
                    f"verification.  Downloading anew.")
            else:
                return destination

        return self._download(destination, io)
Ejemplo n.º 6
0
    def deactivate(self, io: IO) -> None:
        venv_path = self._poetry.config.get("virtualenvs.path")
        if venv_path is None:
            venv_path = Path(CACHE_DIR) / "virtualenvs"
        else:
            venv_path = Path(venv_path)

        name = self._poetry.package.name
        name = self.generate_env_name(name, str(self._poetry.file.parent))

        envs_file = TOMLFile(venv_path / self.ENVS_FILE)
        if envs_file.exists():
            envs = envs_file.read()
            env = envs.get(name)
            if env is not None:
                io.write_line(
                    "Deactivating virtualenv: <comment>{}</comment>".format(
                        venv_path / (name + "-py{}".format(env["minor"]))))
                del envs[name]

                envs_file.write(envs)
Ejemplo n.º 7
0
    def create_venv(
        self,
        io: IO,
        name: Optional[str] = None,
        executable: Optional[str] = None,
        force: bool = False,
    ) -> Union["SystemEnv", "VirtualEnv"]:
        if self._env is not None and not force:
            return self._env

        cwd = self._poetry.file.parent
        env = self.get(reload=True)

        if not env.is_sane():
            force = True

        if env.is_venv() and not force:
            # Already inside a virtualenv.
            return env

        create_venv = self._poetry.config.get("virtualenvs.create")
        root_venv = self._poetry.config.get("virtualenvs.in-project")

        venv_path = self._poetry.config.get("virtualenvs.path")
        if root_venv:
            venv_path = cwd / ".venv"
        elif venv_path is None:
            venv_path = Path(CACHE_DIR) / "virtualenvs"
        else:
            venv_path = Path(venv_path)

        if not name:
            name = self._poetry.package.name

        python_patch = ".".join([str(v) for v in sys.version_info[:3]])
        python_minor = ".".join([str(v) for v in sys.version_info[:2]])
        if executable:
            python_patch = decode(
                subprocess.check_output(
                    list_to_shell_command([
                        executable,
                        "-c",
                        "\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"",
                    ]),
                    shell=True,
                ).strip())
            python_minor = ".".join(python_patch.split(".")[:2])

        supported_python = self._poetry.package.python_constraint
        if not supported_python.allows(Version.parse(python_patch)):
            # The currently activated or chosen Python version
            # is not compatible with the Python constraint specified
            # for the project.
            # If an executable has been specified, we stop there
            # and notify the user of the incompatibility.
            # Otherwise, we try to find a compatible Python version.
            if executable:
                raise NoCompatiblePythonVersionFound(
                    self._poetry.package.python_versions, python_patch)

            io.write_line(
                "<warning>The currently activated Python version {} "
                "is not supported by the project ({}).\n"
                "Trying to find and use a compatible version.</warning> ".
                format(python_patch, self._poetry.package.python_versions))

            for python_to_try in reversed(
                    sorted(
                        self._poetry.package.AVAILABLE_PYTHONS,
                        key=lambda v: (v.startswith("3"), -len(v), v),
                    )):
                if len(python_to_try) == 1:
                    if not parse_constraint("^{}.0".format(
                            python_to_try)).allows_any(supported_python):
                        continue
                elif not supported_python.allows_all(
                        parse_constraint(python_to_try + ".*")):
                    continue

                python = "python" + python_to_try

                if io.is_debug():
                    io.write_line("<debug>Trying {}</debug>".format(python))

                try:
                    python_patch = decode(
                        subprocess.check_output(
                            list_to_shell_command([
                                python,
                                "-c",
                                "\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"",
                            ]),
                            stderr=subprocess.STDOUT,
                            shell=True,
                        ).strip())
                except CalledProcessError:
                    continue

                if not python_patch:
                    continue

                if supported_python.allows(Version.parse(python_patch)):
                    io.write_line("Using <c1>{}</c1> ({})".format(
                        python, python_patch))
                    executable = python
                    python_minor = ".".join(python_patch.split(".")[:2])
                    break

            if not executable:
                raise NoCompatiblePythonVersionFound(
                    self._poetry.package.python_versions)

        if root_venv:
            venv = venv_path
        else:
            name = self.generate_env_name(name, str(cwd))
            name = "{}-py{}".format(name, python_minor.strip())
            venv = venv_path / name

        if not venv.exists():
            if create_venv is False:
                io.write_line("<fg=black;bg=yellow>"
                              "Skipping virtualenv creation, "
                              "as specified in config file."
                              "</>")

                return SystemEnv(Path(sys.prefix))

            io.write_line("Creating virtualenv <c1>{}</> in {}".format(
                name, str(venv_path)))

            self.build_venv(
                venv,
                executable=executable,
                flags=self._poetry.config.get("virtualenvs.options"),
            )
        else:
            if force:
                if not env.is_sane():
                    io.write_line(
                        "<warning>The virtual environment found in {} seems to be broken.</warning>"
                        .format(env.path))
                io.write_line("Recreating virtualenv <c1>{}</> in {}".format(
                    name, str(venv)))
                self.remove_venv(venv)
                self.build_venv(
                    venv,
                    executable=executable,
                    flags=self._poetry.config.get("virtualenvs.options"),
                )
            elif io.is_very_verbose():
                io.write_line(
                    "Virtualenv <c1>{}</> already exists.".format(name))

        # venv detection:
        # stdlib venv may symlink sys.executable, so we can't use realpath.
        # but others can symlink *to* the venv Python,
        # so we can't just use sys.executable.
        # So we just check every item in the symlink tree (generally <= 3)
        p = os.path.normcase(sys.executable)
        paths = [p]
        while os.path.islink(p):
            p = os.path.normcase(
                os.path.join(os.path.dirname(p), os.readlink(p)))
            paths.append(p)

        p_venv = os.path.normcase(str(venv))
        if any(p.startswith(p_venv) for p in paths):
            # Running properly in the virtualenv, don't need to do anything
            return SystemEnv(Path(sys.prefix), self.get_base_prefix())

        return VirtualEnv(venv)
Ejemplo n.º 8
0
 def activate(self, poetry: Poetry, io: IO) -> None:
     io.write_line("Updating version")
     poetry.package.set_version("9.9.9")
Ejemplo n.º 9
0
 def activate(self, poetry: Poetry, io: IO) -> None:
     io.write_line("Setting readmes")
     poetry.package.readmes = ("README.md", )
Ejemplo n.º 10
0
 def interact(self, io: IO) -> None:
     io.write_line("interact called")