Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
102 changes: 74 additions & 28 deletions src/poetry/console/commands/source/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from cleo.helpers import argument

from poetry.config.source import Source
from poetry.console.commands.command import Command


Expand All @@ -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 = [
["<info>name</>", f" : <c1>{source.name}</>"],
["<info>url</>", f" : {source.url}"],
[
"<info>default</>",
f" : {bool_string.get(source.default, False)}",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this False be "no"? And the same in line 38?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False is the default value if source.default is None.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, but if I understand this right, we want to display default: yes or default: no. With False, it will be default: False.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, fair point... bool_string.get(bool(source.default)) might lead to the desired behavior.

],
[
"<info>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(
"<c2>Poetry will search <warning>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(
"<c2>All other things equal, for a give package that is available from"
" multiple sources, it will be preferred in the order listed"
" above.</>\n\n<warning>For example, if a package <c2>foo</> is"
f" available in both <c1>{first}</> and <c1>{last}</>, Poetry will"
f" select <c1>{first}</>.\n\nYou can override this, by explicitly"
" specify the source when adding the package.\n\n $ <c2>poetry add"
f" --source {last} foo</>\n\n</>"
)

if first.lower() != "pypi":
self.write(
"<warning>Alternatively, you can set <c2>all</> your custom sources"
" as <c2>secondary</>.</>\n"
)

for source in sources:
if names and source.name not in names:
continue

table = self.table(style="compact")
rows = [
["<info>name</>", f" : <c1>{source.name}</>"],
["<info>url</>", f" : {source.url}"],
[
"<info>default</>",
f" : {bool_string.get(source.default, False)}",
],
[
"<info>secondary</>",
f" : {bool_string.get(source.secondary, False)}",
],
]
table.add_rows(rows)
table.render()
self.line("")

return 0
20 changes: 20 additions & 0 deletions src/poetry/repositories/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion src/poetry/repositories/pypi_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions tests/console/commands/source/test_show.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
10 changes: 5 additions & 5 deletions tests/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand All @@ -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]
Expand All @@ -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]
Expand Down Expand Up @@ -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)


Expand All @@ -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)


Expand Down