Commit 1e158532 by Arun Babu Neelicattu Committed by Bjorn Neergaard

config: rework eval order and respect env vars

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.
parent 5b3df562
...@@ -15,8 +15,8 @@ from poetry.core.utils.helpers import canonicalize_name ...@@ -15,8 +15,8 @@ from poetry.core.utils.helpers import canonicalize_name
from poetry.config.dict_config_source import DictConfigSource from poetry.config.dict_config_source import DictConfigSource
from poetry.config.file_config_source import FileConfigSource from poetry.config.file_config_source import FileConfigSource
from poetry.locations import CACHE_DIR
from poetry.locations import CONFIG_DIR from poetry.locations import CONFIG_DIR
from poetry.locations import DEFAULT_CACHE_DIR
if TYPE_CHECKING: if TYPE_CHECKING:
...@@ -107,7 +107,7 @@ _default_config: Config | None = None ...@@ -107,7 +107,7 @@ _default_config: Config | None = None
class Config: class Config:
default_config: dict[str, Any] = { default_config: dict[str, Any] = {
"cache-dir": str(CACHE_DIR), "cache-dir": str(DEFAULT_CACHE_DIR),
"virtualenvs": { "virtualenvs": {
"create": True, "create": True,
"in-project": None, "in-project": None,
...@@ -202,6 +202,10 @@ class Config: ...@@ -202,6 +202,10 @@ class Config:
return repositories 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: def get(self, setting_name: str, default: Any = None) -> Any:
""" """
Retrieve a setting value. Retrieve a setting value.
......
...@@ -5,6 +5,7 @@ import os ...@@ -5,6 +5,7 @@ import os
from cleo.helpers import argument from cleo.helpers import argument
from cleo.helpers import option from cleo.helpers import option
from poetry.config.config import Config
from poetry.console.commands.command import Command from poetry.console.commands.command import Command
...@@ -19,17 +20,16 @@ class CacheClearCommand(Command): ...@@ -19,17 +20,16 @@ class CacheClearCommand(Command):
def handle(self) -> int: def handle(self) -> int:
from cachy import CacheManager from cachy import CacheManager
from poetry.locations import REPOSITORY_CACHE_DIR
cache = self.argument("cache") cache = self.argument("cache")
parts = cache.split(":") parts = cache.split(":")
root = parts[0] root = parts[0]
cache_dir = REPOSITORY_CACHE_DIR / root config = Config.create()
cache_dir = config.repository_cache_directory / root
try: try:
cache_dir.relative_to(REPOSITORY_CACHE_DIR) cache_dir.relative_to(config.repository_cache_directory)
except ValueError: except ValueError:
raise ValueError(f"{root} is not a valid repository cache") raise ValueError(f"{root} is not a valid repository cache")
......
from __future__ import annotations from __future__ import annotations
import os from poetry.config.config import Config
from poetry.console.commands.command import Command from poetry.console.commands.command import Command
...@@ -11,10 +10,9 @@ class CacheListCommand(Command): ...@@ -11,10 +10,9 @@ class CacheListCommand(Command):
description = "List Poetry's caches." description = "List Poetry's caches."
def handle(self) -> int | None: def handle(self) -> int | None:
from poetry.locations import REPOSITORY_CACHE_DIR config = Config.create()
if config.repository_cache_directory.exists():
if os.path.exists(str(REPOSITORY_CACHE_DIR)): caches = sorted(config.repository_cache_directory.iterdir())
caches = sorted(REPOSITORY_CACHE_DIR.iterdir())
if caches: if caches:
for cache in caches: for cache in caches:
self.line(f"<info>{cache.name}</>") self.line(f"<info>{cache.name}</>")
......
...@@ -53,13 +53,13 @@ To remove a repository (repo is a short alias for repositories): ...@@ -53,13 +53,13 @@ To remove a repository (repo is a short alias for repositories):
from poetry.config.config import boolean_normalizer from poetry.config.config import boolean_normalizer
from poetry.config.config import boolean_validator from poetry.config.config import boolean_validator
from poetry.config.config import int_normalizer from poetry.config.config import int_normalizer
from poetry.locations import CACHE_DIR from poetry.locations import DEFAULT_CACHE_DIR
unique_config_values = { unique_config_values = {
"cache-dir": ( "cache-dir": (
str, str,
lambda val: str(Path(val)), lambda val: str(Path(val)),
str(CACHE_DIR / "virtualenvs"), str(DEFAULT_CACHE_DIR / "virtualenvs"),
), ),
"virtualenvs.create": (boolean_validator, boolean_normalizer, True), "virtualenvs.create": (boolean_validator, boolean_normalizer, True),
"virtualenvs.in-project": (boolean_validator, boolean_normalizer, False), "virtualenvs.in-project": (boolean_validator, boolean_normalizer, False),
...@@ -86,7 +86,7 @@ To remove a repository (repo is a short alias for repositories): ...@@ -86,7 +86,7 @@ To remove a repository (repo is a short alias for repositories):
"virtualenvs.path": ( "virtualenvs.path": (
str, str,
lambda val: str(Path(val)), lambda val: str(Path(val)),
str(CACHE_DIR / "virtualenvs"), str(DEFAULT_CACHE_DIR / "virtualenvs"),
), ),
"virtualenvs.prefer-active-python": ( "virtualenvs.prefer-active-python": (
boolean_validator, boolean_validator,
......
...@@ -13,10 +13,13 @@ from platformdirs import user_data_path ...@@ -13,10 +13,13 @@ from platformdirs import user_data_path
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
CACHE_DIR = user_cache_path("pypoetry", appauthor=False) _APP_NAME = "pypoetry"
CONFIG_DIR = user_config_path("pypoetry", appauthor=False, roaming=True)
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 # platformdirs 2.0.0 corrected the OSX/macOS config directory from
# /Users/<user>/Library/Application Support/<appname> to # /Users/<user>/Library/Application Support/<appname> to
...@@ -24,7 +27,7 @@ REPOSITORY_CACHE_DIR = CACHE_DIR / "cache" / "repositories" ...@@ -24,7 +27,7 @@ REPOSITORY_CACHE_DIR = CACHE_DIR / "cache" / "repositories"
# #
# For now we only deprecate use of the old directory. # For now we only deprecate use of the old directory.
if sys.platform == "darwin": 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" config_toml = _LEGACY_CONFIG_DIR / "config.toml"
auth_toml = _LEGACY_CONFIG_DIR / "auth.toml" auth_toml = _LEGACY_CONFIG_DIR / "auth.toml"
...@@ -44,4 +47,4 @@ def data_dir() -> Path: ...@@ -44,4 +47,4 @@ def data_dir() -> Path:
if poetry_home: if poetry_home:
return Path(poetry_home).expanduser() 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,7 +8,7 @@ from typing import Any ...@@ -8,7 +8,7 @@ from typing import Any
from cachy import CacheManager from cachy import CacheManager
from poetry.core.semver.helpers import parse_constraint 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 from poetry.repositories.repository import Repository
...@@ -21,10 +21,12 @@ if TYPE_CHECKING: ...@@ -21,10 +21,12 @@ if TYPE_CHECKING:
class CachedRepository(Repository, ABC): class CachedRepository(Repository, ABC):
CACHE_VERSION = parse_constraint("1.0.0") 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) super().__init__(name)
self._disable_cache = disable_cache 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( self._cache = CacheManager(
{ {
"default": "releases", "default": "releases",
......
...@@ -41,7 +41,7 @@ class HTTPRepository(CachedRepository, ABC): ...@@ -41,7 +41,7 @@ class HTTPRepository(CachedRepository, ABC):
config: Config | None = None, config: Config | None = None,
disable_cache: bool = False, disable_cache: bool = False,
) -> None: ) -> None:
super().__init__(name, disable_cache) super().__init__(name, disable_cache, config)
self._url = url self._url = url
self._authenticator = Authenticator( self._authenticator = Authenticator(
config=config, config=config,
......
...@@ -20,7 +20,6 @@ from cachecontrol.caches import FileCache ...@@ -20,7 +20,6 @@ from cachecontrol.caches import FileCache
from poetry.config.config import Config from poetry.config.config import Config
from poetry.exceptions import PoetryException 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_cert
from poetry.utils.helpers import get_client_cert from poetry.utils.helpers import get_client_cert
from poetry.utils.password_manager import HTTPAuthCredential from poetry.utils.password_manager import HTTPAuthCredential
...@@ -99,7 +98,11 @@ class Authenticator: ...@@ -99,7 +98,11 @@ class Authenticator:
self._password_manager = PasswordManager(self._config) self._password_manager = PasswordManager(self._config)
self._cache_control = ( self._cache_control = (
FileCache( 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 if not disable_cache
else None else None
......
...@@ -34,7 +34,6 @@ from poetry.core.toml.file import TOMLFile ...@@ -34,7 +34,6 @@ from poetry.core.toml.file import TOMLFile
from poetry.core.utils.helpers import temporary_directory from poetry.core.utils.helpers import temporary_directory
from virtualenv.seed.wheels.embed import get_embed_wheel 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 decode
from poetry.utils._compat import encode from poetry.utils._compat import encode
from poetry.utils._compat import list_to_shell_command from poetry.utils._compat import list_to_shell_command
...@@ -554,7 +553,7 @@ class EnvManager: ...@@ -554,7 +553,7 @@ class EnvManager:
def activate(self, python: str, io: IO) -> Env: def activate(self, python: str, io: IO) -> Env:
venv_path = self._poetry.config.get("virtualenvs.path") venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None: if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs" venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else: else:
venv_path = Path(venv_path) venv_path = Path(venv_path)
...@@ -647,7 +646,7 @@ class EnvManager: ...@@ -647,7 +646,7 @@ class EnvManager:
def deactivate(self, io: IO) -> None: def deactivate(self, io: IO) -> None:
venv_path = self._poetry.config.get("virtualenvs.path") venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None: if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs" venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else: else:
venv_path = Path(venv_path) venv_path = Path(venv_path)
...@@ -673,7 +672,7 @@ class EnvManager: ...@@ -673,7 +672,7 @@ class EnvManager:
venv_path = self._poetry.config.get("virtualenvs.path") venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None: if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs" venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else: else:
venv_path = Path(venv_path) venv_path = Path(venv_path)
...@@ -714,7 +713,7 @@ class EnvManager: ...@@ -714,7 +713,7 @@ class EnvManager:
venv_path = self._poetry.config.get("virtualenvs.path") venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None: if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs" venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else: else:
venv_path = Path(venv_path) venv_path = Path(venv_path)
...@@ -744,7 +743,7 @@ class EnvManager: ...@@ -744,7 +743,7 @@ class EnvManager:
venv_path = self._poetry.config.get("virtualenvs.path") venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None: if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs" venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else: else:
venv_path = Path(venv_path) venv_path = Path(venv_path)
...@@ -764,7 +763,7 @@ class EnvManager: ...@@ -764,7 +763,7 @@ class EnvManager:
def remove(self, python: str) -> Env: def remove(self, python: str) -> Env:
venv_path = self._poetry.config.get("virtualenvs.path") venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None: if venv_path is None:
venv_path = CACHE_DIR / "virtualenvs" venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else: else:
venv_path = Path(venv_path) venv_path = Path(venv_path)
...@@ -887,7 +886,7 @@ class EnvManager: ...@@ -887,7 +886,7 @@ class EnvManager:
if root_venv: if root_venv:
venv_path = cwd / ".venv" venv_path = cwd / ".venv"
elif venv_path is None: elif venv_path is None:
venv_path = CACHE_DIR / "virtualenvs" venv_path = self._poetry.config.get("cache-dir") / "virtualenvs"
else: else:
venv_path = Path(venv_path) venv_path = Path(venv_path)
......
...@@ -13,18 +13,13 @@ if TYPE_CHECKING: ...@@ -13,18 +13,13 @@ if TYPE_CHECKING:
from _pytest.monkeypatch import MonkeyPatch from _pytest.monkeypatch import MonkeyPatch
from cleo.testers.command_tester import CommandTester from cleo.testers.command_tester import CommandTester
from tests.conftest import Config
from tests.types import CommandTesterFactory from tests.types import CommandTesterFactory
@pytest.fixture @pytest.fixture
def repository_cache_dir(monkeypatch: MonkeyPatch, tmpdir: Path) -> Path: def repository_cache_dir(monkeypatch: MonkeyPatch, config: Config) -> Path:
from pathlib import Path return config.repository_cache_directory
import poetry.locations
path = Path(str(tmpdir))
monkeypatch.setattr(poetry.locations, "REPOSITORY_CACHE_DIR", path)
return path
@pytest.fixture @pytest.fixture
...@@ -41,8 +36,8 @@ def repository_two() -> str: ...@@ -41,8 +36,8 @@ def repository_two() -> str:
def mock_caches( def mock_caches(
repository_cache_dir: Path, repository_one: str, repository_two: str repository_cache_dir: Path, repository_one: str, repository_two: str
) -> None: ) -> None:
(repository_cache_dir / repository_one).mkdir() (repository_cache_dir / repository_one).mkdir(parents=True)
(repository_cache_dir / repository_two).mkdir() (repository_cache_dir / repository_two).mkdir(parents=True)
@pytest.fixture @pytest.fixture
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment