From ba5e0e4300c6453c5579c795dbb17ce63dfb62b0 Mon Sep 17 00:00:00 2001 From: Gabriel Dugny Date: Sun, 15 Jan 2023 14:23:40 +0100 Subject: [PATCH 01/12] doc: fix wrong configuration key --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a0446e348c..9f957e2da6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,7 +53,7 @@ python -m pip install -e . ``` You are free to create a virtualenv with either `venv` module or `virtualenv` tool for the development. If you are doing -so, you may also need to set `pdm config use_venv true` after installation is done. +so, you may also need to set `pdm config python.use_venv true` after installation is done. Now, all dependencies are installed into the Python environment you choose, which will be used for development after this point. From d0c08081b3d06e97c04556047ed13eefd2eea48a Mon Sep 17 00:00:00 2001 From: Gabriel Dugny Date: Sun, 15 Jan 2023 14:43:42 +0100 Subject: [PATCH 02/12] fix: display extra Pypi indexes config --- src/pdm/cli/commands/config.py | 30 +++++++++++++++++++-- src/pdm/project/config.py | 48 ++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/pdm/cli/commands/config.py b/src/pdm/cli/commands/config.py index f51c6bb058..e2b9c010bd 100644 --- a/src/pdm/cli/commands/config.py +++ b/src/pdm/cli/commands/config.py @@ -4,7 +4,7 @@ from pdm import termui from pdm.cli.commands.base import BaseCommand from pdm.project import Project -from pdm.project.config import Config +from pdm.project.config import Config, RegistryConfig, RepositoryConfig, REPOSITORY class Command(BaseCommand): @@ -74,10 +74,36 @@ def _show_config( if canonical_key in supersedes: superseded = True deprecated = f"[error](deprecating: {key})[/]" - elif key not in Config._config_map: + elif key not in Config._config_map and not ( + key.startswith("pypi.") or key.startswith(REPOSITORY) + ): continue extra_style = "dim" if superseded else None if canonical_key not in Config._config_map: + if key.startswith("pypi."): + index_name = key.split(".")[1] + self.ui.echo( + f"[warning]# Configuration of non-default Pypi index `{index_name}`", + style=extra_style, + verbosity=termui.Verbosity.DETAIL, + ) + self.ui.echo( + RegistryConfig(**config[key], config_prefix=key).__rich__() + ) + continue + if key.startswith(REPOSITORY): + for item in config[key]: + self.ui.echo( + f"[warning]# Configuration of custom repository `{item}`", + style=extra_style, + verbosity=termui.Verbosity.DETAIL, + ) + self.ui.echo( + RepositoryConfig( + **config[key][item], config_prefix=f"{key}.{item}" + ).__rich__() + ) + continue continue config_item = Config._config_map[canonical_key] self.ui.echo( diff --git a/src/pdm/project/config.py b/src/pdm/project/config.py index 8bbd0bb8c4..fed5640677 100644 --- a/src/pdm/project/config.py +++ b/src/pdm/project/config.py @@ -26,14 +26,46 @@ class RepositoryConfig: password: str | None = None ca_certs: str | None = None + config_prefix: str | None = None + def __rich__(self) -> str: - lines = [f"[primary]url[/] = {self.url}"] + config_prefix = ( + f"{self.config_prefix}." if self.config_prefix is not None else "" + ) + lines = [f"[primary]{config_prefix}url[/] = {self.url}"] if self.username: - lines.append(f"[primary]username[/] = {self.username}") + lines.append(f"[primary]{config_prefix}username[/] = {self.username}") if self.password: - lines.append("[primary]password[/] = ") + lines.append(f"[primary]{config_prefix}password[/] = [i][/]") if self.ca_certs: - lines.append(f"[primary]ca_certs[/] = {self.ca_certs}") + lines.append(f"[primary]{config_prefix}ca_certs[/] = {self.ca_certs}") + return "\n".join(lines) + + +@dataclasses.dataclass +class RegistryConfig: + + url: str + username: str | None = None + password: str | None = None + verify_ssl: bool | None = None + type: str | None = None + + config_prefix: str | None = None + + def __rich__(self) -> str: + config_prefix = ( + f"{self.config_prefix}." if self.config_prefix is not None else "" + ) + lines = [f"[primary]{config_prefix}url[/] = {self.url}"] + if self.username: + lines.append(f"[primary]{config_prefix}username[/] = {self.username}") + if self.password: + lines.append(f"[primary]{config_prefix}password[/] = [i][/]") + if self.verify_ssl: + lines.append(f"[primary]{config_prefix}verify_ssl[/] = {self.verify_ssl}") + if self.type: + lines.append(f"[primary]{config_prefix}type[/] = {self.type}") return "\n".join(lines) @@ -338,7 +370,13 @@ def __getitem__(self, key: str) -> Any: if index_key not in self._data: raise KeyError(f"No PyPI index named {parts[1]}") source = self._data[index_key] - return source[parts[2]] if len(parts) >= 3 else source + if len(parts) >= 3 and parts[2] == "password": + return "" + return ( + source[parts[2]] + if len(parts) >= 3 + else RegistryConfig(**self._data[index_key]) + ) if key not in self._config_map and key not in self.deprecated: raise NoConfigError(key) From 271122720d0a2713545c4cf8a5361d3f6dce03b9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 13:58:06 +0000 Subject: [PATCH 03/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/pdm/cli/commands/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pdm/cli/commands/config.py b/src/pdm/cli/commands/config.py index e2b9c010bd..f752d94f87 100644 --- a/src/pdm/cli/commands/config.py +++ b/src/pdm/cli/commands/config.py @@ -4,7 +4,7 @@ from pdm import termui from pdm.cli.commands.base import BaseCommand from pdm.project import Project -from pdm.project.config import Config, RegistryConfig, RepositoryConfig, REPOSITORY +from pdm.project.config import REPOSITORY, Config, RegistryConfig, RepositoryConfig class Command(BaseCommand): From aece7278638569a0b8696f8e0df8ae7f260eb631 Mon Sep 17 00:00:00 2001 From: Gabriel Dugny Date: Wed, 18 Jan 2023 10:10:38 +0100 Subject: [PATCH 04/12] fix: hide passwords --- src/pdm/cli/commands/config.py | 3 ++- src/pdm/project/config.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pdm/cli/commands/config.py b/src/pdm/cli/commands/config.py index f752d94f87..9c371e5385 100644 --- a/src/pdm/cli/commands/config.py +++ b/src/pdm/cli/commands/config.py @@ -111,8 +111,9 @@ def _show_config( style=extra_style, verbosity=termui.Verbosity.DETAIL, ) + value = "[i][/]" if key.endswith("password") else config[key] self.ui.echo( - f"[primary]{canonical_key}[/]{deprecated} = {config[key]}", + f"[primary]{canonical_key}[/]{deprecated} = {value}", style=extra_style, ) diff --git a/src/pdm/project/config.py b/src/pdm/project/config.py index fed5640677..23c8b309d0 100644 --- a/src/pdm/project/config.py +++ b/src/pdm/project/config.py @@ -377,6 +377,8 @@ def __getitem__(self, key: str) -> Any: if len(parts) >= 3 else RegistryConfig(**self._data[index_key]) ) + elif key == "pypi.password": + return "" if key not in self._config_map and key not in self.deprecated: raise NoConfigError(key) From 47509d950bffeb4548408ea5632e3cea78934c55 Mon Sep 17 00:00:00 2001 From: Gabriel Dugny Date: Wed, 18 Jan 2023 10:10:47 +0100 Subject: [PATCH 05/12] chore: add tests --- tests/cli/test_config.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/cli/test_config.py b/tests/cli/test_config.py index 9381ad744a..0f18fc69c6 100644 --- a/tests/cli/test_config.py +++ b/tests/cli/test_config.py @@ -129,7 +129,7 @@ def test_repository_overwrite_default(project): assert repository.url == "https://example.pypi.org/legacy/" -def test_hide_password_in_output(project, invoke): +def test_hide_password_in_output_repository(project, invoke): assert project.global_config["repository.pypi.password"] is None project.global_config["repository.pypi.username"] = "testuser" project.global_config["repository.pypi.password"] = "secret" @@ -138,6 +138,20 @@ def test_hide_password_in_output(project, invoke): result = invoke(["config", "repository.pypi.password"], obj=project, strict=True) assert "" == result.output.strip() +def test_hide_password_in_output_pypi(project, invoke): + with pytest.raises( KeyError): + assert project.global_config["pypi.extra.password"] is None + project.global_config["pypi.extra.username"] = "testuser" + project.global_config["pypi.extra.password"] = "secret" + project.global_config["pypi.extra.url"] = "https://test/simple" + result = invoke(["config", "pypi.extra"], obj=project, strict=True) + assert "password = " in result.output + result = invoke(["config", "pypi.extra.password"], obj=project, strict=True) + assert "" == result.output.strip() + result = invoke(["config"], obj=project) + assert "pypi.extra.password" in result.output + assert "" in result.output + def test_config_get_repository(project, invoke): config = project.global_config["repository.pypi"] From 1ba7cde512c039ea9f9a2c1068c9b60d7ce5285b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 09:11:28 +0000 Subject: [PATCH 06/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/cli/test_config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cli/test_config.py b/tests/cli/test_config.py index 0f18fc69c6..cd6b278bc7 100644 --- a/tests/cli/test_config.py +++ b/tests/cli/test_config.py @@ -138,8 +138,9 @@ def test_hide_password_in_output_repository(project, invoke): result = invoke(["config", "repository.pypi.password"], obj=project, strict=True) assert "" == result.output.strip() + def test_hide_password_in_output_pypi(project, invoke): - with pytest.raises( KeyError): + with pytest.raises(KeyError): assert project.global_config["pypi.extra.password"] is None project.global_config["pypi.extra.username"] = "testuser" project.global_config["pypi.extra.password"] = "secret" From aa49e3944c64b39c560a6794f53567c222bac2b2 Mon Sep 17 00:00:00 2001 From: Gabriel Dugny Date: Sun, 22 Jan 2023 16:16:59 +0100 Subject: [PATCH 07/12] fix: remove call to __rich__ --- src/pdm/cli/commands/config.py | 4 ++-- src/pdm/termui.py | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/pdm/cli/commands/config.py b/src/pdm/cli/commands/config.py index 9c371e5385..47a7eac6fe 100644 --- a/src/pdm/cli/commands/config.py +++ b/src/pdm/cli/commands/config.py @@ -88,7 +88,7 @@ def _show_config( verbosity=termui.Verbosity.DETAIL, ) self.ui.echo( - RegistryConfig(**config[key], config_prefix=key).__rich__() + RegistryConfig(**config[key], config_prefix=key) ) continue if key.startswith(REPOSITORY): @@ -101,7 +101,7 @@ def _show_config( self.ui.echo( RepositoryConfig( **config[key][item], config_prefix=f"{key}.{item}" - ).__rich__() + ) ) continue continue diff --git a/src/pdm/termui.py b/src/pdm/termui.py index 755a1fb4ad..0606733aad 100644 --- a/src/pdm/termui.py +++ b/src/pdm/termui.py @@ -6,7 +6,7 @@ import logging import os from tempfile import mktemp -from typing import Any, Iterator, Sequence +from typing import Any, Iterator, Protocol, Sequence from rich.box import ROUNDED from rich.console import Console @@ -35,6 +35,11 @@ _err_console = Console(stderr=True, theme=Theme(DEFAULT_THEME)) +class RichProtocol(Protocol): + def __rich__(self) -> str: + ... + + def is_interactive(console: Console | None = None) -> bool: """Check if the terminal is run under interactive mode""" if console is None: @@ -167,7 +172,7 @@ def set_theme(self, theme: Theme) -> None: def echo( self, - message: str = "", + message: str | RichProtocol = "", err: bool = False, verbosity: Verbosity = Verbosity.NORMAL, **kwargs: Any, From 9ca0ff8688750668295e42aa332b484b7c61dcc9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 15:17:35 +0000 Subject: [PATCH 08/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/pdm/cli/commands/config.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pdm/cli/commands/config.py b/src/pdm/cli/commands/config.py index 47a7eac6fe..f21dde90d1 100644 --- a/src/pdm/cli/commands/config.py +++ b/src/pdm/cli/commands/config.py @@ -87,9 +87,7 @@ def _show_config( style=extra_style, verbosity=termui.Verbosity.DETAIL, ) - self.ui.echo( - RegistryConfig(**config[key], config_prefix=key) - ) + self.ui.echo(RegistryConfig(**config[key], config_prefix=key)) continue if key.startswith(REPOSITORY): for item in config[key]: From 885c76e716e2f872936d8672d2e1763b7a0a7266 Mon Sep 17 00:00:00 2001 From: Gabriel Dugny Date: Sun, 22 Jan 2023 16:19:36 +0100 Subject: [PATCH 09/12] chore: move to types --- src/pdm/_types.py | 5 +++++ src/pdm/termui.py | 7 ++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pdm/_types.py b/src/pdm/_types.py index cf3a322d78..e8ed27a40b 100644 --- a/src/pdm/_types.py +++ b/src/pdm/_types.py @@ -43,4 +43,9 @@ def __exit__(self, *args: Any) -> None: ... +class RichProtocol(Protocol): + def __rich__(self) -> str: + ... + + SearchResult = List[Package] diff --git a/src/pdm/termui.py b/src/pdm/termui.py index 0606733aad..b08a7a2712 100644 --- a/src/pdm/termui.py +++ b/src/pdm/termui.py @@ -6,7 +6,7 @@ import logging import os from tempfile import mktemp -from typing import Any, Iterator, Protocol, Sequence +from typing import Any, Iterator, Sequence from rich.box import ROUNDED from rich.console import Console @@ -15,7 +15,7 @@ from rich.table import Table from rich.theme import Theme -from pdm._types import Spinner, SpinnerT +from pdm._types import Spinner, SpinnerT, RichProtocol logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) @@ -35,9 +35,6 @@ _err_console = Console(stderr=True, theme=Theme(DEFAULT_THEME)) -class RichProtocol(Protocol): - def __rich__(self) -> str: - ... def is_interactive(console: Console | None = None) -> bool: From 296675e17ab15ee5dcd5086e3cae08ab72b8e5ea Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 15:20:11 +0000 Subject: [PATCH 10/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/pdm/termui.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pdm/termui.py b/src/pdm/termui.py index b08a7a2712..b4cd65d33f 100644 --- a/src/pdm/termui.py +++ b/src/pdm/termui.py @@ -15,7 +15,7 @@ from rich.table import Table from rich.theme import Theme -from pdm._types import Spinner, SpinnerT, RichProtocol +from pdm._types import RichProtocol, Spinner, SpinnerT logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) @@ -35,8 +35,6 @@ _err_console = Console(stderr=True, theme=Theme(DEFAULT_THEME)) - - def is_interactive(console: Console | None = None) -> bool: """Check if the terminal is run under interactive mode""" if console is None: From bb5bc0bce9f7f389db49889da691d6d8ad791b12 Mon Sep 17 00:00:00 2001 From: Gabriel Dugny Date: Sun, 22 Jan 2023 16:32:07 +0100 Subject: [PATCH 11/12] chore: flake8 --- src/pdm/cli/commands/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pdm/cli/commands/config.py b/src/pdm/cli/commands/config.py index f21dde90d1..48bd43ac91 100644 --- a/src/pdm/cli/commands/config.py +++ b/src/pdm/cli/commands/config.py @@ -81,9 +81,9 @@ def _show_config( extra_style = "dim" if superseded else None if canonical_key not in Config._config_map: if key.startswith("pypi."): - index_name = key.split(".")[1] + index = key.split(".")[1] self.ui.echo( - f"[warning]# Configuration of non-default Pypi index `{index_name}`", + f"[warning]# Configuration of non-default Pypi index `{index}`", style=extra_style, verbosity=termui.Verbosity.DETAIL, ) From 21cf79dfd512e5d81d7e2f99b82989c41064e1d1 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Sat, 28 Jan 2023 08:59:24 +0800 Subject: [PATCH 12/12] Apply suggestions from code review --- src/pdm/cli/commands/config.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pdm/cli/commands/config.py b/src/pdm/cli/commands/config.py index 48bd43ac91..9f394cdf69 100644 --- a/src/pdm/cli/commands/config.py +++ b/src/pdm/cli/commands/config.py @@ -88,8 +88,7 @@ def _show_config( verbosity=termui.Verbosity.DETAIL, ) self.ui.echo(RegistryConfig(**config[key], config_prefix=key)) - continue - if key.startswith(REPOSITORY): + elif key.startswith(REPOSITORY): for item in config[key]: self.ui.echo( f"[warning]# Configuration of custom repository `{item}`", @@ -101,7 +100,6 @@ def _show_config( **config[key][item], config_prefix=f"{key}.{item}" ) ) - continue continue config_item = Config._config_map[canonical_key] self.ui.echo(