Ejemplo n.º 1
0
    def handle(self):
        from poetry.layouts import layout

        layout_ = layout('standard')

        path = Path.cwd() / Path(self.argument('path'))
        name = self.option('name')
        if not name:
            name = path.name

        if path.exists():
            if list(path.glob('*')):
                # Directory is not empty. Aborting.
                raise RuntimeError(
                    'Destination <fg=yellow;bg=red>{}</> '
                    'exists and is not empty'.format(
                        path
                    )
                )

        readme_format = 'rst'

        layout_ = layout_(name, '0.1.0', readme_format=readme_format)
        layout_.create(path)

        self.line(
            'Created package <info>{}</> in <fg=blue>{}</>'
            .format(name, path.relative_to(Path.cwd()))
        )
Ejemplo n.º 2
0
    def handle(self):
        from poetry.core.semver import parse_constraint
        from poetry.core.vcs.git import GitConfig
        from poetry.layouts import layout
        from poetry.utils._compat import Path
        from poetry.utils.env import SystemEnv, InterpreterLookup

        if self.option("src"):
            layout_ = layout("src")
        else:
            layout_ = layout("standard")

        path = Path.cwd() / Path(self.argument("path"))
        name = self.option("name")
        if not name:
            name = path.name

        if path.exists():
            if list(path.glob("*")):
                # Directory is not empty. Aborting.
                raise RuntimeError("Destination <fg=yellow>{}</> "
                                   "exists and is not empty".format(path))

        readme_format = "rst"

        config = GitConfig()
        author = None
        if config.get("user.name"):
            author = config["user.name"]
            author_email = config.get("user.email")
            if author_email:
                author += " <{}>".format(author_email)

        executable, py_minor, py_patch = InterpreterLookup.find()
        current_env = SystemEnv(executable)
        default_python = "^{}".format(".".join(
            str(v) for v in current_env.version_info[:2]))

        dev_dependencies = {}
        python_constraint = parse_constraint(default_python)
        if parse_constraint("<3.5").allows_any(python_constraint):
            dev_dependencies["pytest"] = "^4.6"
        if parse_constraint(">=3.5").allows_all(python_constraint):
            dev_dependencies["pytest"] = "^5.2"

        layout_ = layout_(
            name,
            "0.1.0",
            author=author,
            readme_format=readme_format,
            python=default_python,
            dev_dependencies=dev_dependencies,
        )
        layout_.create(path)

        self.line("Created package <info>{}</> in <fg=blue>{}</>".format(
            module_name(name), path.relative_to(Path.cwd())))
Ejemplo n.º 3
0
    def handle(self):
        from poetry.layouts import layout
        from poetry.utils._compat import Path
        from poetry.utils.env import SystemEnv
        from poetry.vcs.git import GitConfig

        if self.option("src"):
            layout_ = layout("src")
        else:
            layout_ = layout("standard")

        path = Path.cwd() / Path(self.argument("path"))
        name = self.option("name")
        if not name:
            name = path.name

        if path.exists():
            if list(path.glob("*")):
                # Directory is not empty. Aborting.
                raise RuntimeError(
                    "Destination <fg=yellow>{}</> "
                    "exists and is not empty".format(path)
                )

        readme_format = "rst"

        config = GitConfig()
        author = None
        if config.get("user.name"):
            author = config["user.name"]
            author_email = config.get("user.email")
            if author_email:
                author += " <{}>".format(author_email)

        current_env = SystemEnv(Path(sys.executable))
        default_python = "^{}".format(
            ".".join(str(v) for v in current_env.version_info[:2])
        )
        layout_ = layout_(
            name,
            "0.1.0",
            author=author,
            readme_format=readme_format,
            python=default_python,
        )
        layout_.create(path)

        self.line(
            "Created package <info>{}</> in <fg=blue>{}</>".format(
                name, path.relative_to(Path.cwd())
            )
        )
Ejemplo n.º 4
0
def test_get_cached_archive_for_link(config, mocker):
    chef = Chef(
        config,
        MockEnv(
            version_info=(3, 8, 3),
            marker_env={
                "interpreter_name": "cpython",
                "interpreter_version": "3.8.3"
            },
            supported_tags=[
                Tag("cp38", "cp38", "macosx_10_15_x86_64"),
                Tag("py3", "none", "any"),
            ],
        ),
    )

    cwd = Path.cwd() / ".pypoetrycache"

    mocker.patch.object(
        chef,
        "get_cached_archives_for_link",
        return_value=[
            Link(f"file:///{cwd}demo-0.1.0-py2.py3-none-any"),
            Link(f"file:///{cwd}demo-0.1.0.tar.gz"),
            Link(f"file:///{cwd}demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl"),
            Link(f"file:///{cwd}demo-0.1.0-cp37-cp37-macosx_10_15_x86_64.whl"),
        ],
    )

    archive = chef.get_cached_archive_for_link(
        Link("https://files.python-poetry.org/demo-0.1.0.tar.gz"))

    assert Link(f"file:///{cwd}demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl"
                ) == archive
Ejemplo n.º 5
0
    def poetry(self):
        from poetry.factory import Factory
        from poetry.utils._compat import Path

        if self._poetry is not None:
            return self._poetry

        self._poetry = Factory().create_poetry(Path.cwd())

        return self._poetry
Ejemplo n.º 6
0
    def handle(self):
        from poetry.layouts import layout
        from poetry.utils._compat import Path
        from poetry.vcs.git import GitConfig

        if self.option('src'):
            layout_ = layout('src')
        else:
            layout_ = layout('standard')

        path = Path.cwd() / Path(self.argument('path'))
        name = self.option('name')
        if not name:
            name = path.name

        if path.exists():
            if list(path.glob('*')):
                # Directory is not empty. Aborting.
                raise RuntimeError(
                    'Destination <fg=yellow>{}</> '
                    'exists and is not empty'.format(
                        path
                    )
                )

        readme_format = 'rst'

        config = GitConfig()
        author = None
        if config.get('user.name'):
            author = config['user.name']
            author_email = config.get('user.email')
            if author_email:
                author += ' <{}>'.format(author_email)

        layout_ = layout_(name, '0.1.0', author=author, readme_format=readme_format)
        layout_.create(path)

        self.line(
            'Created package <info>{}</> in <fg=blue>{}</>'
            .format(name, path.relative_to(Path.cwd()))
        )
Ejemplo n.º 7
0
    def handle(self):
        from poetry.layouts import layout
        from poetry.utils._compat import Path
        from poetry.vcs.git import GitConfig

        if self.option("src"):
            layout_ = layout("src")
        else:
            layout_ = layout("standard")

        path = Path.cwd() / Path(self.argument("path"))
        name = self.option("name")
        if not name:
            name = path.name

        if path.exists():
            if list(path.glob("*")):
                # Directory is not empty. Aborting.
                raise RuntimeError(
                    "Destination <fg=yellow>{}</> "
                    "exists and is not empty".format(path)
                )

        readme_format = "rst"

        config = GitConfig()
        author = None
        if config.get("user.name"):
            author = config["user.name"]
            author_email = config.get("user.email")
            if author_email:
                author += " <{}>".format(author_email)

        layout_ = layout_(name, "0.1.0", author=author, readme_format=readme_format)
        layout_.create(path)

        self.line(
            "Created package <info>{}</> in <fg=blue>{}</>".format(
                name, path.relative_to(Path.cwd())
            )
        )
Ejemplo n.º 8
0
    def get(cls, reload=False, cwd=None):  # type: (IO, bool) -> Env
        if cls._env is not None and not reload:
            return cls._env

        # Check if we are inside a virtualenv or not
        in_venv = (os.environ.get("VIRTUAL_ENV") is not None
                   or hasattr(sys, "real_prefix")
                   or (hasattr(sys, "base_prefix")
                       and sys.base_prefix != sys.prefix))

        if not in_venv:
            # Checking if a local virtualenv exists
            if cwd and (cwd / ".venv").exists():
                venv = cwd / ".venv"

                return VirtualEnv(Path(venv))

            config = Config.create("config.toml")
            create_venv = config.setting("settings.virtualenvs.create", True)

            if not create_venv:
                return SystemEnv(Path(sys.prefix))

            venv_path = config.setting("settings.virtualenvs.path")
            if venv_path is None:
                venv_path = Path(CACHE_DIR) / "virtualenvs"
            else:
                venv_path = Path(venv_path)

            if cwd is None:
                cwd = Path.cwd()

            name = cwd.name
            name = "{}-py{}".format(
                name, ".".join([str(v) for v in sys.version_info[:2]]))

            venv = venv_path / name

            if not venv.exists():
                return SystemEnv(Path(sys.prefix))

            return VirtualEnv(venv)

        if os.environ.get("VIRTUAL_ENV") is not None:
            prefix = Path(os.environ["VIRTUAL_ENV"])
            base_prefix = None
        else:
            prefix = Path(sys.prefix)
            base_prefix = cls.get_base_prefix()

        return VirtualEnv(prefix, base_prefix)
Ejemplo n.º 9
0
def get_vcs(directory):  # type: (Path) -> Git
    working_dir = Path.cwd()
    os.chdir(str(directory.resolve()))

    try:
        git_dir = decode(
            subprocess.check_output(["git", "rev-parse", "--show-toplevel"],
                                    stderr=subprocess.STDOUT)).strip()

        vcs = Git(Path(git_dir))

    except (subprocess.CalledProcessError, OSError):
        vcs = None
    finally:
        os.chdir(str(working_dir))

    return vcs
Ejemplo n.º 10
0
    def handle(self):
        # Load poetry config and display errors, if any
        poetry_file = Poetry.locate(Path.cwd())
        config = TomlFile(str(poetry_file)).read()["tool"]["poetry"]
        check_result = Poetry.check(config, strict=True)
        if not check_result["errors"] and not check_result["warnings"]:
            self.info("All set!")

            return 0

        for error in check_result["errors"]:
            self.line("<error>Error: {}</error>".format(error))

        for error in check_result["warnings"]:
            self.line("<warning>Warning: {}</warning>".format(error))

        return 1
Ejemplo n.º 11
0
    def handle(self):
        # Load poetry config and display errors, if any
        poetry_file = Factory.locate(Path.cwd())
        config = PyProjectTOML(poetry_file).poetry_config
        check_result = Factory.validate(config, strict=True)
        if not check_result["errors"] and not check_result["warnings"]:
            self.info("All set!")

            return 0

        for error in check_result["errors"]:
            self.line("<error>Error: {}</error>".format(error))

        for error in check_result["warnings"]:
            self.line("<warning>Warning: {}</warning>".format(error))

        return 1
Ejemplo n.º 12
0
def test_get_cache_directory_for_link(config):
    chef = Chef(
        config,
        MockEnv(marker_env={
            "interpreter_name": "cpython",
            "interpreter_version": "3.8.3"
        }),
    )

    cwd = Path.cwd() / ".pypoetrycache"

    directory = chef.get_cache_directory_for_link(
        Link("https://files.python-poetry.org/poetry-1.1.0.tar.gz"))
    expected = Path(
        f"{cwd}/artifacts/ba/63/13/283a3b3b7f95f05e9e6f84182d276f7bb0951d5b0cc24422b33f7a4648"
    )

    assert expected == directory
Ejemplo n.º 13
0
def main(print_content_hash: bool) -> None:
    """Merge the lock file of a Poetry project.

    This is a tool for resolving merge conflicts in the lock file of
    Poetry, a packaging and dependency manager for Python. If the merge
    conflicts cannot be resolved by this tool, you can use the
    --print-content-hash option to compute the content hash for the
    metadata.content-hash entry, and resolve the conflicts manually.
    \f

    Args:
        print_content_hash: Print the content hash.
    """
    poetry = Factory().create_poetry(Path.cwd())

    if print_content_hash:
        click.echo(poetry.locker._content_hash)
    else:
        merge_lock(poetry)
Ejemplo n.º 14
0
    def create(cls, io, name=None, cwd=None):  # type: (...) -> Venv
        if "VIRTUAL_ENV" not in os.environ:
            # Not in a virtualenv
            # Checking if we need to create one

            # First we check if there is a .venv
            # at the root of the project.
            if cwd and (cwd / ".venv").exists():
                venv = cwd / ".venv"
            else:
                config = Config.create("config.toml")

                create_venv = config.setting("settings.virtualenvs.create")
                root_venv = config.setting("settings.virtualenvs.in-project")

                venv_path = config.setting("settings.virtualenvs.path")
                if root_venv:
                    if not cwd:
                        raise RuntimeError(
                            "Unable to determine the project's directory"
                        )

                    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 = Path.cwd().name

                name = "{}-py{}".format(
                    name, ".".join([str(v) for v in sys.version_info[:2]])
                )

                if root_venv:
                    venv = venv_path
                else:
                    venv = venv_path / name

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

                        return cls()

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

                    cls.build(str(venv))
                else:
                    if io.is_very_verbose():
                        io.writeln(
                            "Virtualenv <info>{}</> already exists.".format(name)
                        )

            os.environ["VIRTUAL_ENV"] = str(venv)

        # 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(os.environ["VIRTUAL_ENV"])
        if any(p.startswith(p_venv) for p in paths):
            # Running properly in the virtualenv, don't need to do anything
            return cls()

        venv = os.environ["VIRTUAL_ENV"]

        return cls(venv)
Ejemplo n.º 15
0
    def create(cls, io, name=None, cwd=None):  # type: (...) -> Venv
        if 'VIRTUAL_ENV' not in os.environ:
            # Not in a virtualenv
            # Checking if we need to create one

            # First we check if there is a .venv
            # at the root of the project.
            if cwd and (cwd / '.venv').exists():
                venv = cwd / '.venv'
            else:
                config = Config.create('config.toml')

                create_venv = config.setting('settings.virtualenvs.create')
                root_venv = config.setting('settings.virtualenvs.in-project')

                venv_path = config.setting('settings.virtualenvs.path')
                if root_venv:
                    if not cwd:
                        raise RuntimeError('Unbale to determine the project\'s directory')

                    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 = Path.cwd().name

                name = '{}-py{}'.format(
                    name, '.'.join([str(v) for v in sys.version_info[:2]])
                )

                if root_venv:
                    venv = venv_path
                else:
                    venv = venv_path / name

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

                        return cls()

                    io.writeln(
                        'Creating virtualenv <info>{}</> in {}'.format(
                            name, str(venv_path)
                        )
                    )

                    cls.build(str(venv))
                else:
                    if io.is_very_verbose():
                        io.writeln(
                            'Virtualenv <info>{}</> already exists.'.format(name)
                        )

            os.environ['VIRTUAL_ENV'] = str(venv)

        # 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(os.environ['VIRTUAL_ENV'])
        if any(p.startswith(p_venv) for p in paths):
            # Running properly in the virtualenv, don't need to do anything
            return cls()

        venv = os.environ['VIRTUAL_ENV']

        return cls(venv)
Ejemplo n.º 16
0
    def handle(self):
        from poetry.layouts import layout
        from poetry.utils._compat import Path
        from poetry.utils.env import SystemEnv
        from poetry.core.vcs.git import GitConfig

        if (Path.cwd() / "pyproject.toml").exists():
            self.line("<error>A pyproject.toml file already exists.</error>")
            return 1

        vcs_config = GitConfig()

        self.line("")
        self.line(
            "This command will guide you through creating your <info>pyproject.toml</> config."
        )
        self.line("")

        name = self.option("name")
        if not name:
            name = Path.cwd().name.lower()

            question = self.create_question(
                "Package name [<comment>{}</comment>]: ".format(name),
                default=name)
            name = self.ask(question)

        version = "0.1.0"
        question = self.create_question(
            "Version [<comment>{}</comment>]: ".format(version),
            default=version)
        version = self.ask(question)

        description = self.option("description") or ""
        question = self.create_question(
            "Description [<comment>{}</comment>]: ".format(description),
            default=description,
        )
        description = self.ask(question)

        author = self.option("author")
        if not author and vcs_config and vcs_config.get("user.name"):
            author = vcs_config["user.name"]
            author_email = vcs_config.get("user.email")
            if author_email:
                author += " <{}>".format(author_email)

        question = self.create_question(
            "Author [<comment>{}</comment>, n to skip]: ".format(author),
            default=author)
        question.set_validator(lambda v: self._validate_author(v, author))
        author = self.ask(question)

        if not author:
            authors = []
        else:
            authors = [author]

        license = self.option("license") or ""

        question = self.create_question(
            "License [<comment>{}</comment>]: ".format(license),
            default=license)
        question.set_validator(self._validate_license)
        license = self.ask(question)

        python = self.option("python")
        if not python:
            current_env = SystemEnv(Path(sys.executable))
            default_python = "^{}".format(".".join(
                str(v) for v in current_env.version_info[:2]))
            question = self.create_question(
                "Compatible Python versions [<comment>{}</comment>]: ".format(
                    default_python),
                default=default_python,
            )
            python = self.ask(question)

        self.line("")

        requirements = {}

        question = "Would you like to define your main dependencies interactively?"
        help_message = (
            "You can specify a package in the following forms:\n"
            "  - A single name (<b>requests</b>)\n"
            "  - A name and a constraint (<b>requests@^2.23.0</b>)\n"
            "  - A git url (<b>git+https://github.com/python-poetry/poetry.git</b>)\n"
            "  - A git url with a revision (<b>git+https://github.com/python-poetry/poetry.git#develop</b>)\n"
            "  - A file path (<b>../my-package/my-package.whl</b>)\n"
            "  - A directory (<b>../my-package/</b>)\n"
            "  - A url (<b>https://example.com/packages/my-package-0.1.0.tar.gz</b>)\n"
        )
        help_displayed = False
        if self.confirm(question, True):
            self.line(help_message)
            help_displayed = True
            requirements = self._format_requirements(
                self._determine_requirements(self.option("dependency")))
            self.line("")

        dev_requirements = {}

        question = (
            "Would you like to define your development dependencies interactively?"
        )
        if self.confirm(question, True):
            if not help_displayed:
                self.line(help_message)

            dev_requirements = self._format_requirements(
                self._determine_requirements(self.option("dev-dependency")))
            self.line("")

        layout_ = layout("standard")(
            name,
            version,
            description=description,
            author=authors[0] if authors else None,
            license=license,
            python=python,
            dependencies=requirements,
            dev_dependencies=dev_requirements,
        )

        content = layout_.generate_poetry_content()
        if self.io.is_interactive():
            self.line("<info>Generated file</info>")
            self.line("")
            self.line(content)
            self.line("")

        if not self.confirm("Do you confirm generation?", True):
            self.line("<error>Command aborted</error>")

            return 1

        with (Path.cwd() / "pyproject.toml").open("w", encoding="utf-8") as f:
            f.write(content)
Ejemplo n.º 17
0
    def _parse_requirements(
            self, requirements):  # type: (List[str]) -> List[Dict[str, str]]
        from poetry.puzzle.provider import Provider

        result = []

        try:
            cwd = self.poetry.file.parent
        except RuntimeError:
            cwd = Path.cwd()

        for requirement in requirements:
            requirement = requirement.strip()
            extras = []
            extras_m = re.search(r"\[([\w\d,-_]+)\]$", requirement)
            if extras_m:
                extras = [e.strip() for e in extras_m.group(1).split(",")]
                requirement, _ = requirement.split("[")

            url_parsed = urlparse.urlparse(requirement)
            if url_parsed.scheme and url_parsed.netloc:
                # Url
                if url_parsed.scheme in ["git+https", "git+ssh"]:
                    from poetry.core.vcs.git import Git
                    from poetry.core.vcs.git import ParsedUrl

                    parsed = ParsedUrl.parse(requirement)
                    url = Git.normalize_url(requirement)

                    pair = OrderedDict([("name", parsed.name),
                                        ("git", url.url)])
                    if parsed.rev:
                        pair["rev"] = url.revision

                    if extras:
                        pair["extras"] = extras

                    package = Provider.get_package_from_vcs(
                        "git", url.url, reference=pair.get("rev"))
                    pair["name"] = package.name
                    result.append(pair)

                    continue
                elif url_parsed.scheme in ["http", "https"]:
                    package = Provider.get_package_from_url(requirement)

                    pair = OrderedDict([("name", package.name),
                                        ("url", package.source_url)])
                    if extras:
                        pair["extras"] = extras

                    result.append(pair)
                    continue
            elif (os.path.sep in requirement or "/"
                  in requirement) and cwd.joinpath(requirement).exists():
                path = cwd.joinpath(requirement)
                if path.is_file():
                    package = Provider.get_package_from_file(path.resolve())
                else:
                    package = Provider.get_package_from_directory(path)

                result.append(
                    OrderedDict([
                        ("name", package.name),
                        ("path", path.relative_to(cwd).as_posix()),
                    ] + ([("extras", extras)] if extras else [])))

                continue

            pair = re.sub("^([^@=: ]+)(?:@|==|(?<![<>~!])=|:| )(.*)$",
                          "\\1 \\2", requirement)
            pair = pair.strip()

            require = OrderedDict()
            if " " in pair:
                name, version = pair.split(" ", 2)
                extras_m = re.search(r"\[([\w\d,-_]+)\]$", name)
                if extras_m:
                    extras = [e.strip() for e in extras_m.group(1).split(",")]
                    name, _ = name.split("[")

                require["name"] = name
                if version != "latest":
                    require["version"] = version
            else:
                m = re.match(r"^([^><=!: ]+)((?:>=|<=|>|<|!=|~=|~|\^).*)$",
                             requirement.strip())
                if m:
                    name, constraint = m.group(1), m.group(2)
                    extras_m = re.search(r"\[([\w\d,-_]+)\]$", name)
                    if extras_m:
                        extras = [
                            e.strip() for e in extras_m.group(1).split(",")
                        ]
                        name, _ = name.split("[")

                    require["name"] = name
                    require["version"] = constraint
                else:
                    extras_m = re.search(r"\[([\w\d,-_]+)\]$", pair)
                    if extras_m:
                        extras = [
                            e.strip() for e in extras_m.group(1).split(",")
                        ]
                        pair, _ = pair.split("[")

                    require["name"] = pair

            if extras:
                require["extras"] = extras

            result.append(require)

        return result
Ejemplo n.º 18
0
    def handle(self):
        from poetry.config.file_config_source import FileConfigSource
        from poetry.locations import CONFIG_DIR
        from poetry.utils._compat import Path
        from poetry.utils._compat import basestring
        from poetry.utils.toml_file import TomlFile

        config = Factory.create_config(self.io)
        config_file = TomlFile(Path(CONFIG_DIR) / "config.toml")

        try:
            local_config_file = TomlFile(self.poetry.file.parent /
                                         "poetry.toml")
            if local_config_file.exists():
                config.merge(local_config_file.read())
        except RuntimeError:
            local_config_file = TomlFile(Path.cwd() / "poetry.toml")

        if self.option("local"):
            config.set_config_source(FileConfigSource(local_config_file))

        if not config_file.exists():
            config_file.path.parent.mkdir(parents=True, exist_ok=True)
            config_file.touch(mode=0o0600)

        if self.option("list"):
            self._list_configuration(config.all(), config.raw())

            return 0

        setting_key = self.argument("key")
        if not setting_key:
            return 0

        if self.argument("value") and self.option("unset"):
            raise RuntimeError(
                "You can not combine a setting value with --unset")

        # show the value if no value is provided
        if not self.argument("value") and not self.option("unset"):
            m = re.match(r"^repos?(?:itories)?(?:\.(.+))?",
                         self.argument("key"))
            if m:
                if not m.group(1):
                    value = {}
                    if config.get("repositories") is not None:
                        value = config.get("repositories")
                else:
                    repo = config.get("repositories.{}".format(m.group(1)))
                    if repo is None:
                        raise ValueError(
                            "There is no {} repository defined".format(
                                m.group(1)))

                    value = repo

                self.line(str(value))
            else:
                values = self.unique_config_values
                if setting_key not in values:
                    raise ValueError(
                        "There is no {} setting.".format(setting_key))

                value = config.get(setting_key)

                if not isinstance(value, basestring):
                    value = json.dumps(value)

                self.line(value)

            return 0

        values = self.argument("value")

        unique_config_values = self.unique_config_values
        if setting_key in unique_config_values:
            if self.option("unset"):
                return config.config_source.remove_property(setting_key)

            return self._handle_single_value(
                config.config_source,
                setting_key,
                unique_config_values[setting_key],
                values,
            )

        # handle repositories
        m = re.match(r"^repos?(?:itories)?(?:\.(.+))?", self.argument("key"))
        if m:
            if not m.group(1):
                raise ValueError(
                    "You cannot remove the [repositories] section")

            if self.option("unset"):
                repo = config.get("repositories.{}".format(m.group(1)))
                if repo is None:
                    raise ValueError(
                        "There is no {} repository defined".format(m.group(1)))

                config.config_source.remove_property("repositories.{}".format(
                    m.group(1)))

                return 0

            if len(values) == 1:
                url = values[0]

                config.config_source.add_property(
                    "repositories.{}.url".format(m.group(1)), url)

                return 0

            raise ValueError(
                "You must pass the url. "
                "Example: poetry config repositories.foo https://bar.com")

        # handle auth
        m = re.match(r"^(http-basic|pypi-token)\.(.+)", self.argument("key"))
        if m:
            if self.option("unset"):
                keyring_repository_password_del(config, m.group(2))
                config.auth_config_source.remove_property("{}.{}".format(
                    m.group(1), m.group(2)))

                return 0

            if m.group(1) == "http-basic":
                if len(values) == 1:
                    username = values[0]
                    # Only username, so we prompt for password
                    password = self.secret("Password:"******"Expected one or two arguments "
                                     "(username, password), got {}".format(
                                         len(values)))
                else:
                    username = values[0]
                    password = values[1]

                property_value = dict(username=username)
                try:
                    keyring_repository_password_set(m.group(2), username,
                                                    password)
                except RuntimeError:
                    property_value.update(password=password)

                config.auth_config_source.add_property(
                    "{}.{}".format(m.group(1), m.group(2)), property_value)
            elif m.group(1) == "pypi-token":
                if len(values) != 1:
                    raise ValueError(
                        "Expected only one argument (token), got {}".format(
                            len(values)))

                token = values[0]

                config.auth_config_source.add_property(
                    "{}.{}".format(m.group(1), m.group(2)), token)

            return 0

        # handle certs
        m = re.match(r"(?:certificates)\.([^.]+)\.(cert|client-cert)",
                     self.argument("key"))
        if m:
            if self.option("unset"):
                config.auth_config_source.remove_property(
                    "certificates.{}.{}".format(m.group(1), m.group(2)))

                return 0

            if len(values) == 1:
                config.auth_config_source.add_property(
                    "certificates.{}.{}".format(m.group(1), m.group(2)),
                    values[0])
            else:
                raise ValueError("You must pass exactly 1 value")

            return 0

        raise ValueError("Setting {} does not exist".format(
            self.argument("key")))
Ejemplo n.º 19
0
def package():
    p = ProjectPackage("root", "1.0")
    p.root_dir = Path.cwd()

    return p
Ejemplo n.º 20
0
    def create_venv(cls,
                    io,
                    name=None,
                    cwd=None):  # type: (IO, bool, Path) -> Env
        if cls._env is not None:
            return cls._env

        env = cls.get(cwd=cwd)
        if env.is_venv():
            # Already inside a virtualenv.
            return env

        config = Config.create("config.toml")

        create_venv = config.setting("settings.virtualenvs.create")
        root_venv = config.setting("settings.virtualenvs.in-project")

        venv_path = config.setting("settings.virtualenvs.path")
        if root_venv:
            if not cwd:
                raise RuntimeError(
                    "Unable to determine the project's directory")

            venv_path = cwd / ".venv"
        elif venv_path is None:
            venv_path = Path(CACHE_DIR) / "virtualenvs"
        else:
            venv_path = Path(venv_path)

        if not name:
            if not cwd:
                cwd = Path.cwd()

            name = cwd.name

        name = "{}-py{}".format(
            name, ".".join([str(v) for v in sys.version_info[:2]]))

        if root_venv:
            venv = venv_path
        else:
            venv = venv_path / name

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

                return SystemEnv(Path(sys.prefix))

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

            cls.build_venv(str(venv))
        else:
            if io.is_very_verbose():
                io.writeln(
                    "Virtualenv <info>{}</> 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), cls.get_base_prefix())

        return VirtualEnv(venv)
Ejemplo n.º 21
0
    def handle(self):
        from poetry.layouts import layout
        from poetry.utils._compat import Path
        from poetry.utils.env import Env
        from poetry.vcs.git import GitConfig

        if (Path.cwd() / "pyproject.toml").exists():
            self.error("A pyproject.toml file already exists.")
            return 1

        vcs_config = GitConfig()

        self.line([
            "",
            "This command will guide you through creating your <info>pyproject.toml</> config.",
            "",
        ])

        name = self.option("name")
        if not name:
            name = Path.cwd().name.lower()

            question = self.create_question(
                "Package name [<comment>{}</comment>]: ".format(name),
                default=name)
            name = self.ask(question)

        version = "0.1.0"
        question = self.create_question(
            "Version [<comment>{}</comment>]: ".format(version),
            default=version)
        version = self.ask(question)

        description = self.option("description") or ""
        question = self.create_question(
            "Description [<comment>{}</comment>]: ".format(description),
            default=description,
        )
        description = self.ask(question)

        author = self.option("author")
        if not author and vcs_config and vcs_config.get("user.name"):
            author = vcs_config["user.name"]
            author_email = vcs_config.get("user.email")
            if author_email:
                author += " <{}>".format(author_email)

        question = self.create_question(
            "Author [<comment>{}</comment>, n to skip]: ".format(author),
            default=author)
        question.validator = lambda v: self._validate_author(v, author)
        author = self.ask(question)

        if not author:
            authors = []
        else:
            authors = [author]

        license = self.option("license") or ""

        question = self.create_question(
            "License [<comment>{}</comment>]: ".format(license),
            default=license)
        question.validator = self._validate_license
        license = self.ask(question)

        current_env = Env.get()
        default_python = "^{}".format(".".join(
            str(v) for v in current_env.version_info[:2]))
        question = self.create_question(
            "Compatible Python versions [<comment>{}</comment>]: ".format(
                default_python),
            default=default_python,
        )
        python = self.ask(question)

        self.line("")

        requirements = {}

        question = ("Would you like to define your dependencies"
                    " (require) interactively?")
        if self.confirm(question, True):
            requirements = self._format_requirements(
                self._determine_requirements(self.option("dependency")))

        dev_requirements = {}

        question = ("Would you like to define your dev dependencies"
                    " (require-dev) interactively")
        if self.confirm(question, True):
            dev_requirements = self._format_requirements(
                self._determine_requirements(self.option("dev-dependency")))

        layout_ = layout("standard")(
            name,
            version,
            description=description,
            author=authors[0] if authors else None,
            license=license,
            python=python,
            dependencies=requirements,
            dev_dependencies=dev_requirements,
        )

        content = layout_.generate_poetry_content()
        if self.input.is_interactive():
            self.line("<info>Generated file</info>")
            self.line(["", content, ""])

        if not self.confirm("Do you confirm generation?", True):
            self.line("<error>Command aborted</error>")

            return 1

        with (Path.cwd() / "pyproject.toml").open("w") as f:
            f.write(content)
Ejemplo n.º 22
0
    def handle(self):
        from poetry.layouts import layout
        from poetry.utils._compat import Path
        from poetry.vcs.git import GitConfig

        if (Path.cwd() / "pyproject.toml").exists():
            self.error("A pyproject.toml file already exists.")
            return 1

        vcs_config = GitConfig()

        self.line(
            [
                "",
                "This command will guide you through creating your <info>pyproject.toml</> config.",
                "",
            ]
        )

        name = self.option("name")
        if not name:
            name = Path.cwd().name.lower()

            question = self.create_question(
                "Package name [<comment>{}</comment>]: ".format(name), default=name
            )
            name = self.ask(question)

        version = "0.1.0"
        question = self.create_question(
            "Version [<comment>{}</comment>]: ".format(version), default=version
        )
        version = self.ask(question)

        description = self.option("description") or ""
        question = self.create_question(
            "Description [<comment>{}</comment>]: ".format(description),
            default=description,
        )
        description = self.ask(question)

        author = self.option("author")
        if not author and vcs_config and vcs_config.get("user.name"):
            author = vcs_config["user.name"]
            author_email = vcs_config.get("user.email")
            if author_email:
                author += " <{}>".format(author_email)

        question = self.create_question(
            "Author [<comment>{}</comment>, n to skip]: ".format(author), default=author
        )
        question.validator = lambda v: self._validate_author(v, author)
        author = self.ask(question)

        if not author:
            authors = []
        else:
            authors = [author]

        license = self.option("license") or ""

        question = self.create_question(
            "License [<comment>{}</comment>]: ".format(license), default=license
        )
        question.validator = self._validate_license
        license = self.ask(question)

        question = self.create_question("Compatible Python versions [*]: ", default="*")
        python = self.ask(question)

        self.line("")

        requirements = {}

        question = "Would you like to define your dependencies" " (require) interactively?"
        if self.confirm(question, True):
            requirements = self._format_requirements(
                self._determine_requirements(self.option("dependency"))
            )

        dev_requirements = {}

        question = "Would you like to define your dev dependencies" " (require-dev) interactively"
        if self.confirm(question, True):
            dev_requirements = self._format_requirements(
                self._determine_requirements(self.option("dev-dependency"))
            )

        layout_ = layout("standard")(
            name,
            version,
            description=description,
            author=authors[0] if authors else None,
            license=license,
            python=python,
            dependencies=requirements,
            dev_dependencies=dev_requirements,
        )

        content = layout_.generate_poetry_content()
        if self.input.is_interactive():
            self.line("<info>Generated file</info>")
            self.line(["", content, ""])

        if not self.confirm("Do you confirm generation?", True):
            self.line("<error>Command aborted</error>")

            return 1

        with (Path.cwd() / "pyproject.toml").open("w") as f:
            f.write(content)
Ejemplo n.º 23
0
 def __init__(self):
     self._lock = TOMLFile(Path.cwd().joinpath("poetry.lock"))
     self._locked = True
     self._content_hash = self._get_content_hash()
Ejemplo n.º 24
0
    def handle(self):
        from poetry.layouts import layout
        from poetry.utils._compat import Path
        from poetry.vcs.git import GitConfig

        if (Path.cwd() / 'pyproject.toml').exists():
            self.error('A pyproject.toml file already exists.')
            return 1

        vcs_config = GitConfig()

        self.line([
            '',
            'This command will guide you through creating your <info>poetry.toml</> config.',
            ''
        ])

        name = self.option('name')
        if not name:
            name = Path.cwd().name.lower()

            question = self.create_question(
                'Package name [<comment>{}</comment>]: '.format(name),
                default=name
            )
            name = self.ask(question)

        version = '0.1.0'
        question = self.create_question(
            'Version [<comment>{}</comment>]: '.format(version),
            default=version
        )
        version = self.ask(question)

        description = self.option('description') or ''
        question = self.create_question(
            'Description [<comment>{}</comment>]: '.format(description),
            default=description
        )
        description = self.ask(question)

        author = self.option('author')
        if not author and vcs_config and vcs_config.get('user.name'):
            author = vcs_config['user.name']
            author_email = vcs_config.get('user.email')
            if author_email:
                author += ' <{}>'.format(author_email)

        question = self.create_question(
            'Author [<comment>{}</comment>, n to skip]: '.format(author),
            default=author
        )
        question.validator = lambda v: self._validate_author(v, author)
        author = self.ask(question)

        if not author:
            authors = []
        else:
            authors = [author]

        license = self.option('license') or ''

        question = self.create_question(
            'License [<comment>{}</comment>]: '.format(license),
            default=license
        )

        license = self.ask(question)

        question = self.create_question(
            'Compatible Python versions [*]: ',
            default='*'
        )
        python = self.ask(question)

        self.line('')

        requirements = []

        question = 'Would you like to define your dependencies' \
                   ' (require) interactively?'
        if self.confirm(question, True):
            requirements = self._format_requirements(
                self._determine_requirements(self.option('dependency'))
            )

        dev_requirements = []

        question = 'Would you like to define your dev dependencies' \
                   ' (require-dev) interactively'
        if self.confirm(question, True):
            dev_requirements = self._format_requirements(
                self._determine_requirements(self.option('dev-dependency'))
            )

        layout_ = layout('standard')(
            name,
            version,
            description=description,
            author=authors[0] if authors else None,
            license=license,
            python=python,
            dependencies=requirements,
            dev_dependencies=dev_requirements
        )

        content = layout_.generate_poetry_content()
        if self.input.is_interactive():
            self.line('<info>Generated file</info>')
            self.line(['', content, ''])

        if not self.confirm('Do you confirm generation?', True):
            self.line('<error>Command aborted</error>')

            return 1

        with (Path.cwd() / 'pyproject.toml').open('w') as f:
            f.write(content)