From cbbab96dd62ad7d9d5b6432c9160a5670eeaa3cf Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Tue, 24 May 2022 15:42:45 +0200 Subject: [PATCH 1/2] repos: ensure pypi names are consistent with checks --- src/poetry/repositories/pypi_repository.py | 2 +- tests/test_factory.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/poetry/repositories/pypi_repository.py b/src/poetry/repositories/pypi_repository.py index 37e539ec2b8..018178cb24d 100644 --- a/src/poetry/repositories/pypi_repository.py +++ b/src/poetry/repositories/pypi_repository.py @@ -36,7 +36,7 @@ def __init__( fallback: bool = True, ) -> None: super().__init__( - "PyPI", url.rstrip("/") + "/simple/", disable_cache=disable_cache + "pypi", url.rstrip("/") + "/simple/", disable_cache=disable_cache ) self._base_url = url diff --git a/tests/test_factory.py b/tests/test_factory.py index a281ef78b4d..2ac3f320736 100644 --- a/tests/test_factory.py +++ b/tests/test_factory.py @@ -211,7 +211,7 @@ def test_poetry_with_non_default_source(with_simple_keyring: None): assert poetry.pool.repositories[0].name == "foo" assert isinstance(poetry.pool.repositories[0], LegacyRepository) - assert poetry.pool.repositories[1].name == "PyPI" + assert poetry.pool.repositories[1].name == "pypi" assert isinstance(poetry.pool.repositories[1], PyPiRepository) @@ -223,7 +223,7 @@ def test_poetry_with_non_default_secondary_source(with_simple_keyring: None): assert poetry.pool.has_default() repository = poetry.pool.repositories[0] - assert repository.name == "PyPI" + assert repository.name == "pypi" assert isinstance(repository, PyPiRepository) repository = poetry.pool.repositories[1] @@ -241,7 +241,7 @@ def test_poetry_with_non_default_multiple_secondary_sources(with_simple_keyring: assert poetry.pool.has_default() repository = poetry.pool.repositories[0] - assert repository.name == "PyPI" + assert repository.name == "pypi" assert isinstance(repository, PyPiRepository) repository = poetry.pool.repositories[1] @@ -269,7 +269,7 @@ def test_poetry_with_non_default_multiple_sources(with_simple_keyring: None): assert isinstance(repository, LegacyRepository) repository = poetry.pool.repositories[2] - assert repository.name == "PyPI" + assert repository.name == "pypi" assert isinstance(repository, PyPiRepository) @@ -280,7 +280,7 @@ def test_poetry_with_no_default_source(): assert poetry.pool.has_default() - assert poetry.pool.repositories[0].name == "PyPI" + assert poetry.pool.repositories[0].name == "pypi" assert isinstance(poetry.pool.repositories[0], PyPiRepository) From 586919400988791dd682e6cc69a7887ee623f259 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Tue, 24 May 2022 15:43:58 +0200 Subject: [PATCH 2/2] cmd/source/show: incl. pypi and add additional info --- docs/cli.md | 4 +- src/poetry/console/commands/source/show.py | 102 +++++++++++++++------ src/poetry/repositories/pool.py | 20 ++++ tests/console/commands/source/test_show.py | 5 + 4 files changed, 102 insertions(+), 29 deletions(-) diff --git a/docs/cli.md b/docs/cli.md index d95615a21d6..d4c2c40c38a 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -797,7 +797,9 @@ poetry source show pypi-test ``` {{% note %}} -This command will only show sources configured via the `pyproject.toml` and does not include PyPI. +When used with the `-v` (verbose) global option, this command will provide additional +information about the sources configured for your project, if more than one is +available. {{% /note %}} ### `source remove` diff --git a/src/poetry/console/commands/source/show.py b/src/poetry/console/commands/source/show.py index 1d5b3044f18..90133bf6167 100644 --- a/src/poetry/console/commands/source/show.py +++ b/src/poetry/console/commands/source/show.py @@ -2,6 +2,7 @@ from cleo.helpers import argument +from poetry.config.source import Source from poetry.console.commands.command import Command @@ -18,42 +19,87 @@ class SourceShowCommand(Command): ), ] + def render_source(self, source: Source) -> None: + bool_string = { + True: "yes", + False: "no", + } + + table = self.table(style="compact") + rows = [ + ["name", f" : {source.name}"], + ["url", f" : {source.url}"], + [ + "default", + f" : {bool_string.get(source.default, False)}", + ], + [ + "secondary", + f" : {bool_string.get(source.secondary, False)}", + ], + ] + table.add_rows(rows) + table.render() + self.line("") + def handle(self) -> int | None: sources = self.poetry.get_sources() names = self.argument("source") - if not sources: - self.line("No sources configured for this project.") - return 0 - - if names and not any(s.name in names for s in sources): + if names and "pypi" not in names and not any(s.name in names for s in sources): self.line_error(f"No source found with name(s): {', '.join(names)}") return 1 - bool_string = { - True: "yes", - False: "no", - } + for repositories, secondary in [ + (self.poetry.pool.primary_repositories, False), + (self.poetry.pool.secondary_repositories, True), + ]: + for repository in repositories: + if names and repository.name not in names: + continue + + self.render_source( + Source( + name=repository.name or "-", + url=getattr(repository, "url", "-"), + default=repository is self.poetry.pool.default_repository, + secondary=secondary, + ) + ) + + if names or not self.io.is_verbose(): + return 0 + + self.write( + "Poetry will search all of the above package sources when " + "searching for packages.\n" + ) + + if len(self.poetry.pool.repositories) <= 1: + return 0 + + self.line("") + + first = self.poetry.pool.repositories[0].name or "" + last = self.poetry.pool.repositories[-1].name or "" + + if first and last: + self.write( + "All other things equal, for a give package that is available from" + " multiple sources, it will be preferred in the order listed" + " above.\n\nFor example, if a package foo is" + f" available in both {first} and {last}, Poetry will" + f" select {first}.\n\nYou can override this, by explicitly" + " specify the source when adding the package.\n\n $ poetry add" + f" --source {last} foo\n\n" + ) + + if first.lower() != "pypi": + self.write( + "Alternatively, you can set all your custom sources" + " as secondary.\n" + ) - for source in sources: - if names and source.name not in names: - continue - - table = self.table(style="compact") - rows = [ - ["name", f" : {source.name}"], - ["url", f" : {source.url}"], - [ - "default", - f" : {bool_string.get(source.default, False)}", - ], - [ - "secondary", - f" : {bool_string.get(source.secondary, False)}", - ], - ] - table.add_rows(rows) - table.render() self.line("") return 0 diff --git a/src/poetry/repositories/pool.py b/src/poetry/repositories/pool.py index 1167ab4b44f..f21252a03d1 100644 --- a/src/poetry/repositories/pool.py +++ b/src/poetry/repositories/pool.py @@ -57,6 +57,26 @@ def repository(self, name: str) -> Repository: raise ValueError(f'Repository "{name}" does not exist.') + @property + def default_repository(self) -> Repository | None: + if self.has_default() and self._repositories: + return self._repositories[0] + return None + + @property + def primary_repositories(self) -> list[Repository]: + if self._secondary_start_idx is None: + return self.repositories + + return self._repositories[: self._secondary_start_idx] + + @property + def secondary_repositories(self) -> list[Repository]: + if self._secondary_start_idx is None: + return [] + + return self._repositories[self._secondary_start_idx :] + def add_repository( self, repository: Repository, default: bool = False, secondary: bool = False ) -> Pool: diff --git a/tests/console/commands/source/test_show.py b/tests/console/commands/source/test_show.py index 8b975cf4b92..0a934907d10 100644 --- a/tests/console/commands/source/test_show.py +++ b/tests/console/commands/source/test_show.py @@ -40,6 +40,11 @@ def test_source_show_simple(tester: CommandTester): url : https://two.com default : no secondary : no + +name : pypi +url : https://pypi.org/simple/ +default : no +secondary : yes """.splitlines() assert [ line.strip() for line in tester.io.fetch_output().strip().splitlines()