Skip to content

Commit 465a463

Browse files
authored
fix(settings): use <CONFIG_ROOT>/copier as settings directory on Windows (copier-org#2071)
Deprecate `<CONFIG_ROOT>/copier/copier` and prefer `<CONFIG_ROOT>/copier` as the settings directory for consistency across operating systems.
1 parent 8f4b0e6 commit 465a463

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

copier/settings.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from pydantic import BaseModel, Field
1414

1515
from .errors import MissingSettingsWarning
16+
from .tools import OS
1617

1718
ENV_VAR = "COPIER_SETTINGS_PATH"
1819

@@ -27,6 +28,10 @@ class Settings(BaseModel):
2728
default_factory=set, description="List of trusted repositories or prefixes"
2829
)
2930

31+
@staticmethod
32+
def _default_settings_path() -> Path:
33+
return user_config_path("copier", appauthor=False) / "settings.yml"
34+
3035
@classmethod
3136
def from_file(cls, settings_path: Path | None = None) -> Settings:
3237
"""Load settings from a file."""
@@ -35,7 +40,19 @@ def from_file(cls, settings_path: Path | None = None) -> Settings:
3540
if env_path:
3641
settings_path = Path(env_path)
3742
else:
38-
settings_path = user_config_path("copier") / "settings.yml"
43+
settings_path = cls._default_settings_path()
44+
45+
# NOTE: Remove after a sufficiently long deprecation period.
46+
if OS == "windows":
47+
old_settings_path = user_config_path("copier") / "settings.yml"
48+
if old_settings_path.is_file():
49+
warnings.warn(
50+
f"Settings path {old_settings_path} is deprecated. "
51+
f"Please migrate to {settings_path}.",
52+
DeprecationWarning,
53+
stacklevel=2,
54+
)
55+
settings_path = old_settings_path
3956
if settings_path.is_file():
4057
data = yaml.safe_load(settings_path.read_bytes())
4158
return cls.model_validate(data)

docs/settings.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ standard configuration directory for your platform:
1010
- `%USERPROFILE%\AppData\Local\copier` on Windows as defined in
1111
[Known folders](https://docs.microsoft.com/en-us/windows/win32/shell/known-folders)
1212

13+
!!! note
14+
15+
Windows only: `%USERPROFILE%\AppData\Local\copier\copier` was the standard configuration directory until v9.6.0. This standard configuration directory is deprecated and will be removed in a future version.
16+
1317
This location can be overridden by setting the `COPIER_SETTINGS_PATH` environment
1418
variable.
1519

tests/test_settings.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import os
4+
import platform
35
import sys
46
from pathlib import Path
57

@@ -25,6 +27,18 @@ def test_settings_from_default_location(settings_path: Path) -> None:
2527
assert settings.defaults == {"foo": "bar"}
2628

2729

30+
@pytest.mark.skipif(platform.system() != "Windows", reason="Windows-only test")
31+
def test_default_windows_settings_path() -> None:
32+
settings = Settings()
33+
assert settings._default_settings_path() == Path(
34+
os.getenv("USERPROFILE", default=""),
35+
"AppData",
36+
"Local",
37+
"copier",
38+
"settings.yml",
39+
)
40+
41+
2842
@pytest.mark.usefixtures("config_path")
2943
def test_settings_from_default_location_dont_exists() -> None:
3044
settings = Settings.from_file()

0 commit comments

Comments
 (0)