Skip to content

Commit

Permalink
config: rework eval order and respect env vars
Browse files Browse the repository at this point in the history
This change ensures that we respect `POETRY_CONFIG_DIR` as well as
ensure environment variables are respected for `POETRY_CACHE_DIR`.

This change also fixes an issue with repository cache directories not
respecting base cache directory configuration changes.
  • Loading branch information
abn committed May 23, 2022
1 parent 03e9c2b commit 5231b57
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 44 deletions.
8 changes: 6 additions & 2 deletions src/poetry/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

from poetry.config.dict_config_source import DictConfigSource
from poetry.config.file_config_source import FileConfigSource
from poetry.locations import CACHE_DIR
from poetry.locations import CONFIG_DIR
from poetry.locations import DEFAULT_CACHE_DIR


if TYPE_CHECKING:
Expand Down Expand Up @@ -107,7 +107,7 @@ def validator(cls, policy: str) -> bool:
class Config:

default_config: dict[str, Any] = {
"cache-dir": str(CACHE_DIR),
"cache-dir": str(DEFAULT_CACHE_DIR),
"virtualenvs": {
"create": True,
"in-project": None,
Expand Down Expand Up @@ -202,6 +202,10 @@ def _get_environment_repositories() -> dict[str, dict[str, str]]:

return repositories

@property
def repository_cache_directory(self) -> Path:
return Path(self.get("cache-dir")) / "cache" / "repositories"

def get(self, setting_name: str, default: Any = None) -> Any:
"""
Retrieve a setting value.
Expand Down
8 changes: 4 additions & 4 deletions src/poetry/console/commands/cache/clear.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from cleo.helpers import argument
from cleo.helpers import option

from poetry.config.config import Config
from poetry.console.commands.command import Command


Expand All @@ -19,17 +20,16 @@ class CacheClearCommand(Command):
def handle(self) -> int:
from cachy import CacheManager

from poetry.locations import REPOSITORY_CACHE_DIR

cache = self.argument("cache")

parts = cache.split(":")
root = parts[0]

cache_dir = REPOSITORY_CACHE_DIR / root
config = Config.create()
cache_dir = config.repository_cache_directory / root

try:
cache_dir.relative_to(REPOSITORY_CACHE_DIR)
cache_dir.relative_to(config.repository_cache_directory)
except ValueError:
raise ValueError(f"{root} is not a valid repository cache")

Expand Down
10 changes: 4 additions & 6 deletions src/poetry/console/commands/cache/list.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import os

from poetry.config.config import Config
from poetry.console.commands.command import Command


Expand All @@ -11,10 +10,9 @@ class CacheListCommand(Command):
description = "List Poetry's caches."

def handle(self) -> int | None:
from poetry.locations import REPOSITORY_CACHE_DIR

if os.path.exists(str(REPOSITORY_CACHE_DIR)):
caches = sorted(REPOSITORY_CACHE_DIR.iterdir())
config = Config.create()
if config.repository_cache_directory.exists():
caches = sorted(config.repository_cache_directory.iterdir())
if caches:
for cache in caches:
self.line(f"<info>{cache.name}</>")
Expand Down
6 changes: 3 additions & 3 deletions src/poetry/console/commands/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ def unique_config_values(self) -> dict[str, tuple[Any, Any, Any]]:
from poetry.config.config import boolean_normalizer
from poetry.config.config import boolean_validator
from poetry.config.config import int_normalizer
from poetry.locations import CACHE_DIR
from poetry.locations import DEFAULT_CACHE_DIR

unique_config_values = {
"cache-dir": (
str,
lambda val: str(Path(val)),
str(CACHE_DIR / "virtualenvs"),
str(DEFAULT_CACHE_DIR / "virtualenvs"),
),
"virtualenvs.create": (boolean_validator, boolean_normalizer, True),
"virtualenvs.in-project": (boolean_validator, boolean_normalizer, False),
Expand All @@ -86,7 +86,7 @@ def unique_config_values(self) -> dict[str, tuple[Any, Any, Any]]:
"virtualenvs.path": (
str,
lambda val: str(Path(val)),
str(CACHE_DIR / "virtualenvs"),
str(DEFAULT_CACHE_DIR / "virtualenvs"),
),
"virtualenvs.prefer-active-python": (
boolean_validator,
Expand Down
13 changes: 8 additions & 5 deletions src/poetry/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@

logger = logging.getLogger(__name__)

CACHE_DIR = user_cache_path("pypoetry", appauthor=False)
CONFIG_DIR = user_config_path("pypoetry", appauthor=False, roaming=True)
_APP_NAME = "pypoetry"

REPOSITORY_CACHE_DIR = CACHE_DIR / "cache" / "repositories"
DEFAULT_CACHE_DIR = user_cache_path(_APP_NAME, appauthor=False)
CONFIG_DIR = Path(
os.getenv("POETRY_CONFIG_DIR")
or user_config_path(_APP_NAME, appauthor=False, roaming=True)
)

# platformdirs 2.0.0 corrected the OSX/macOS config directory from
# /Users/<user>/Library/Application Support/<appname> to
# /Users/<user>/Library/Preferences/<appname>.
#
# For now we only deprecate use of the old directory.
if sys.platform == "darwin":
_LEGACY_CONFIG_DIR = CONFIG_DIR.parent.parent / "Application Support" / "pypoetry"
_LEGACY_CONFIG_DIR = CONFIG_DIR.parent.parent / "Application Support" / _APP_NAME
config_toml = _LEGACY_CONFIG_DIR / "config.toml"
auth_toml = _LEGACY_CONFIG_DIR / "auth.toml"

Expand All @@ -44,4 +47,4 @@ def data_dir() -> Path:
if poetry_home:
return Path(poetry_home).expanduser()

return user_data_path("pypoetry", appauthor=False, roaming=True)
return user_data_path(_APP_NAME, appauthor=False, roaming=True)
8 changes: 5 additions & 3 deletions src/poetry/repositories/cached.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from cachy import CacheManager
from poetry.core.semver.helpers import parse_constraint

from poetry.locations import REPOSITORY_CACHE_DIR
from poetry.config.config import Config
from poetry.repositories.repository import Repository


Expand All @@ -21,10 +21,12 @@
class CachedRepository(Repository, ABC):
CACHE_VERSION = parse_constraint("1.0.0")

def __init__(self, name: str, disable_cache: bool = False) -> None:
def __init__(
self, name: str, disable_cache: bool = False, config: Config | None = None
) -> None:
super().__init__(name)
self._disable_cache = disable_cache
self._cache_dir = REPOSITORY_CACHE_DIR / name
self._cache_dir = (config or Config.create()).repository_cache_directory / name
self._cache = CacheManager(
{
"default": "releases",
Expand Down
2 changes: 1 addition & 1 deletion src/poetry/repositories/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(
config: Config | None = None,
disable_cache: bool = False,
) -> None:
super().__init__(name, disable_cache)
super().__init__(name, disable_cache, config)
self._url = url
self._authenticator = Authenticator(
config=config,
Expand Down
7 changes: 5 additions & 2 deletions src/poetry/utils/authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

from poetry.config.config import Config
from poetry.exceptions import PoetryException
from poetry.locations import REPOSITORY_CACHE_DIR
from poetry.utils.helpers import get_cert
from poetry.utils.helpers import get_client_cert
from poetry.utils.password_manager import HTTPAuthCredential
Expand Down Expand Up @@ -99,7 +98,11 @@ def __init__(
self._password_manager = PasswordManager(self._config)
self._cache_control = (
FileCache(
str(REPOSITORY_CACHE_DIR / (cache_id or "_default_cache") / "_http")
str(
self._config.repository_cache_directory
/ (cache_id or "_default_cache")
/ "_http"
)
)
if not disable_cache
else None
Expand Down
15 changes: 7 additions & 8 deletions src/poetry/utils/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
from poetry.core.utils.helpers import temporary_directory
from virtualenv.seed.wheels.embed import get_embed_wheel

from poetry.locations import CACHE_DIR
from poetry.utils._compat import decode
from poetry.utils._compat import encode
from poetry.utils._compat import list_to_shell_command
Expand Down Expand Up @@ -554,7 +553,7 @@ def _detect_active_python(self, io: IO) -> str | None:
def activate(self, python: str, io: IO) -> Env:
venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs"
venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else:
venv_path = Path(venv_path)

Expand Down Expand Up @@ -647,7 +646,7 @@ def activate(self, python: str, io: IO) -> Env:
def deactivate(self, io: IO) -> None:
venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs"
venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else:
venv_path = Path(venv_path)

Expand All @@ -673,7 +672,7 @@ def get(self, reload: bool = False) -> Env:

venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs"
venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else:
venv_path = Path(venv_path)

Expand Down Expand Up @@ -714,7 +713,7 @@ def get(self, reload: bool = False) -> Env:

venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs"
venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else:
venv_path = Path(venv_path)

Expand Down Expand Up @@ -744,7 +743,7 @@ def list(self, name: str | None = None) -> list[VirtualEnv]:

venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs"
venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else:
venv_path = Path(venv_path)

Expand All @@ -764,7 +763,7 @@ def list(self, name: str | None = None) -> list[VirtualEnv]:
def remove(self, python: str) -> Env:
venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs"
venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else:
venv_path = Path(venv_path)

Expand Down Expand Up @@ -887,7 +886,7 @@ def create_venv(
if root_venv:
venv_path = cwd / ".venv"
elif venv_path is None:
venv_path = CACHE_DIR / "virtualenvs"
venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else:
venv_path = Path(venv_path)

Expand Down
15 changes: 5 additions & 10 deletions tests/console/commands/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,13 @@
from _pytest.monkeypatch import MonkeyPatch
from cleo.testers.command_tester import CommandTester

from tests.conftest import Config
from tests.types import CommandTesterFactory


@pytest.fixture
def repository_cache_dir(monkeypatch: MonkeyPatch, tmpdir: Path) -> Path:
from pathlib import Path

import poetry.locations

path = Path(str(tmpdir))
monkeypatch.setattr(poetry.locations, "REPOSITORY_CACHE_DIR", path)
return path
def repository_cache_dir(monkeypatch: MonkeyPatch, config: Config) -> Path:
return config.repository_cache_directory


@pytest.fixture
Expand All @@ -41,8 +36,8 @@ def repository_two() -> str:
def mock_caches(
repository_cache_dir: Path, repository_one: str, repository_two: str
) -> None:
(repository_cache_dir / repository_one).mkdir()
(repository_cache_dir / repository_two).mkdir()
(repository_cache_dir / repository_one).mkdir(parents=True)
(repository_cache_dir / repository_two).mkdir(parents=True)


@pytest.fixture
Expand Down

0 comments on commit 5231b57

Please sign in to comment.