Skip to content

Commit 4d4d19f

Browse files
committed
chore: Template upgrade
1 parent 23d5367 commit 4d4d19f

File tree

10 files changed

+102
-111
lines changed

10 files changed

+102
-111
lines changed

.copier-answers.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Changes here will be overwritten by Copier
2-
_commit: 1.4.0
2+
_commit: 1.4.5
33
_src_path: gh:pawamoy/copier-uv
44
author_email: [email protected]
55
author_fullname: Timothée Mazzucotelli

.github/workflows/ci.yml

+13-6
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,16 @@ jobs:
2929
- name: Fetch all tags
3030
run: git fetch --depth=1 --tags
3131

32-
- name: Set up Python
32+
- name: Setup Python
3333
uses: actions/setup-python@v5
3434
with:
3535
python-version: "3.11"
3636

37-
- name: Install uv
38-
run: pip install uv
37+
- name: Setup uv
38+
uses: astral-sh/setup-uv@v3
39+
with:
40+
enable-cache: true
41+
cache-dependency-glob: pyproject.toml
3942

4043
- name: Install dependencies
4144
run: make setup
@@ -103,14 +106,18 @@ jobs:
103106
- name: Checkout
104107
uses: actions/checkout@v4
105108

106-
- name: Set up Python
109+
- name: Setup Python
107110
uses: actions/setup-python@v5
108111
with:
109112
python-version: ${{ matrix.python-version }}
110113
allow-prereleases: true
111114

112-
- name: Install uv
113-
run: pip install uv
115+
- name: Setup uv
116+
uses: astral-sh/setup-uv@v3
117+
with:
118+
enable-cache: true
119+
cache-dependency-glob: pyproject.toml
120+
cache-suffix: py${{ matrix.python-version }}
114121

115122
- name: Install dependencies
116123
env:

.github/workflows/release.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
run: pip install build
2121
- name: Build dists
2222
if: github.repository_owner == 'pawamoy-insiders'
23-
run: python -m build
23+
run: pyproject-build
2424
- name: Upload dists artifact
2525
uses: actions/upload-artifact@v4
2626
if: github.repository_owner == 'pawamoy-insiders'
@@ -34,12 +34,12 @@ jobs:
3434
if: github.repository_owner != 'pawamoy-insiders'
3535
run: git-changelog --release-notes > release-notes.md
3636
- name: Create release with assets
37-
uses: softprops/action-gh-release@v1
37+
uses: softprops/action-gh-release@v2
3838
if: github.repository_owner == 'pawamoy-insiders'
3939
with:
4040
files: ./dist/*
4141
- name: Create release
42-
uses: softprops/action-gh-release@v1
42+
uses: softprops/action-gh-release@v2
4343
if: github.repository_owner != 'pawamoy-insiders'
4444
with:
4545
body_path: release-notes.md

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
/.pdm-build/
1616
/htmlcov/
1717
/site/
18+
uv.lock
1819

1920
# cache
2021
.cache/

devdeps.txt

-32
This file was deleted.

duties.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ def changelog(ctx: Context, bump: str = "") -> None:
5353
ctx.run(tools.git_changelog(bump=bump or None), title="Updating changelog")
5454

5555

56-
@duty(pre=["check_quality", "check_types", "check_docs", "check_dependencies", "check-api"])
57-
def check(ctx: Context) -> None: # noqa: ARG001
56+
@duty(pre=["check-quality", "check-types", "check-docs", "check-api"])
57+
def check(ctx: Context) -> None:
5858
"""Check it all!"""
5959

6060

@@ -121,9 +121,14 @@ def docs_deploy(ctx: Context) -> None:
121121
with material_insiders() as insiders:
122122
if not insiders:
123123
ctx.run(lambda: False, title="Not deploying docs without Material for MkDocs Insiders!")
124-
origin = ctx.run("git config --get remote.origin.url", silent=True)
124+
origin = ctx.run("git config --get remote.origin.url", silent=True, allow_overrides=False)
125125
if "pawamoy-insiders/griffe-typedoc" in origin:
126-
ctx.run("git remote add upstream [email protected]:mkdocstrings/griffe-typedoc", silent=True, nofail=True)
126+
ctx.run(
127+
"git remote add upstream [email protected]:mkdocstrings/griffe-typedoc",
128+
silent=True,
129+
nofail=True,
130+
allow_overrides=False,
131+
)
127132
ctx.run(
128133
tools.mkdocs.gh_deploy(remote_name="upstream", force=True),
129134
title="Deploying documentation",

mkdocs.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,15 @@ plugins:
132132
show_root_heading: true
133133
show_root_full_path: false
134134
show_signature_annotations: true
135+
show_source: false
135136
show_symbol_type_heading: true
136137
show_symbol_type_toc: true
137138
signature_crossrefs: true
138139
summary: true
139-
- git-committers:
140+
- git-revision-date-localized:
140141
enabled: !ENV [DEPLOY, false]
141-
repository: mkdocstrings/griffe-typedoc
142+
enable_creation_date: true
143+
type: timeago
142144
- minify:
143145
minify_html: !ENV [DEPLOY, false]
144146
- group:

pyproject.toml

+36-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ source-includes = [
5858
"scripts",
5959
"share",
6060
"tests",
61-
"devdeps.txt",
6261
"duties.py",
6362
"mkdocs.yml",
6463
"*.md",
@@ -69,3 +68,39 @@ source-includes = [
6968
data = [
7069
{path = "share/**/*", relative-to = "."},
7170
]
71+
72+
[tool.uv]
73+
dev-dependencies = [
74+
# dev
75+
"editables>=0.5",
76+
77+
# maintenance
78+
"build>=1.2",
79+
"git-changelog>=2.5",
80+
"twine>=5.0; python_version < '3.13'",
81+
82+
# ci
83+
"duty>=1.4",
84+
"ruff>=0.4",
85+
"pytest>=8.2",
86+
"pytest-cov>=5.0",
87+
"pytest-randomly>=3.15",
88+
"pytest-xdist>=3.6",
89+
"mypy>=1.10",
90+
"types-markdown>=3.6",
91+
"types-pyyaml>=6.0",
92+
93+
# docs
94+
"black>=24.4",
95+
"markdown-callouts>=0.4",
96+
"markdown-exec>=1.8",
97+
"mkdocs>=1.6",
98+
"mkdocs-coverage>=1.0",
99+
"mkdocs-gen-files>=0.5",
100+
"mkdocs-git-revision-date-localized-plugin>=1.2",
101+
"mkdocs-literate-nav>=0.6",
102+
"mkdocs-material>=9.5",
103+
"mkdocs-minify-plugin>=0.8",
104+
"mkdocstrings[python]>=0.25",
105+
"tomli>=2.0; python_version < '3.11'",
106+
]

scripts/gen_credits.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
pyproject = tomllib.load(pyproject_file)
2727
project = pyproject["project"]
2828
project_name = project["name"]
29-
with project_dir.joinpath("devdeps.txt").open() as devdeps_file:
30-
devdeps = [line.strip() for line in devdeps_file if line.strip() and not line.strip().startswith(("-e", "#"))]
29+
devdeps = [dep for dep in pyproject["tool"]["uv"]["dev-dependencies"] if not dep.startswith("-e")]
3130

3231
PackageMetadata = Dict[str, Union[str, Iterable[str]]]
3332
Metadata = Dict[str, PackageMetadata]

scripts/make

+34-60
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ import subprocess
99
import sys
1010
from contextlib import contextmanager
1111
from pathlib import Path
12+
from textwrap import dedent
1213
from typing import Any, Iterator
1314

1415
PYTHON_VERSIONS = os.getenv("PYTHON_VERSIONS", "3.8 3.9 3.10 3.11 3.12 3.13").split()
1516

16-
exe = ""
17-
prefix = ""
18-
1917

2018
def shell(cmd: str, capture_output: bool = False, **kwargs: Any) -> str | None:
2119
"""Run a shell command."""
@@ -37,18 +35,11 @@ def environ(**kwargs: str) -> Iterator[None]:
3735
os.environ.update(original)
3836

3937

40-
def uv_install() -> None:
38+
def uv_install(venv: Path) -> None:
4139
"""Install dependencies using uv."""
42-
uv_opts = ""
43-
if "UV_RESOLUTION" in os.environ:
44-
uv_opts = f"--resolution={os.getenv('UV_RESOLUTION')}"
45-
requirements = shell(f"uv pip compile {uv_opts} pyproject.toml devdeps.txt", capture_output=True)
46-
shell("uv pip install -r -", input=requirements, text=True)
47-
if "CI" not in os.environ:
48-
shell("uv pip install --no-deps -e .")
49-
else:
50-
shell("uv pip install --no-deps .")
51-
40+
with environ(UV_PROJECT_ENVIRONMENT=str(venv)):
41+
shell("uv sync")
42+
5243

5344
def setup() -> None:
5445
"""Setup the project."""
@@ -59,47 +50,27 @@ def setup() -> None:
5950
default_venv = Path(".venv")
6051
if not default_venv.exists():
6152
shell("uv venv --python python")
62-
uv_install()
53+
uv_install(default_venv)
6354

6455
if PYTHON_VERSIONS:
6556
for version in PYTHON_VERSIONS:
6657
print(f"\nInstalling dependencies (python{version})") # noqa: T201
6758
venv_path = Path(f".venvs/{version}")
6859
if not venv_path.exists():
6960
shell(f"uv venv --python {version} {venv_path}")
70-
with environ(VIRTUAL_ENV=str(venv_path.resolve())):
71-
uv_install()
72-
73-
74-
def activate(path: str) -> None:
75-
"""Activate a virtual environment."""
76-
global exe, prefix # noqa: PLW0603
77-
78-
if (bin := Path(path, "bin")).exists():
79-
activate_script = bin / "activate_this.py"
80-
elif (scripts := Path(path, "Scripts")).exists():
81-
activate_script = scripts / "activate_this.py"
82-
exe = ".exe"
83-
prefix = f"{path}/Scripts/"
84-
else:
85-
raise ValueError(f"make: activate: Cannot find activation script in {path}")
86-
87-
if not activate_script.exists():
88-
raise ValueError(f"make: activate: Cannot find activation script in {path}")
89-
90-
exec(activate_script.read_text(), {"__file__": str(activate_script)}) # noqa: S102
61+
with environ(UV_PROJECT_ENVIRONMENT=str(venv_path.resolve())):
62+
uv_install(venv_path)
9163

9264

9365
def run(version: str, cmd: str, *args: str, **kwargs: Any) -> None:
9466
"""Run a command in a virtual environment."""
9567
kwargs = {"check": True, **kwargs}
9668
if version == "default":
97-
activate(".venv")
98-
subprocess.run([f"{prefix}{cmd}{exe}", *args], **kwargs) # noqa: S603, PLW1510
69+
with environ(UV_PROJECT_ENVIRONMENT=".venv"):
70+
subprocess.run(["uv", "run", cmd, *args], **kwargs) # noqa: S603, PLW1510
9971
else:
100-
activate(f".venvs/{version}")
101-
os.environ["MULTIRUN"] = "1"
102-
subprocess.run([f"{prefix}{cmd}{exe}", *args], **kwargs) # noqa: S603, PLW1510
72+
with environ(UV_PROJECT_ENVIRONMENT=f".venvs/{version}", MULTIRUN="1"):
73+
subprocess.run(["uv", "run", cmd, *args], **kwargs) # noqa: S603, PLW1510
10374

10475

10576
def multirun(cmd: str, *args: str, **kwargs: Any) -> None:
@@ -124,10 +95,10 @@ def clean() -> None:
12495
for path in paths_to_clean:
12596
shell(f"rm -rf {path}")
12697

127-
cache_dirs = [".cache", ".pytest_cache", ".mypy_cache", ".ruff_cache", "__pycache__"]
128-
for dirpath in Path(".").rglob("*"):
129-
if any(dirpath.match(pattern) for pattern in cache_dirs) and not (dirpath.match(".venv") or dirpath.match(".venvs")):
130-
shutil.rmtree(path, ignore_errors=True)
98+
cache_dirs = {".cache", ".pytest_cache", ".mypy_cache", ".ruff_cache", "__pycache__"}
99+
for dirpath in Path(".").rglob("*/"):
100+
if dirpath.parts[0] not in (".venv", ".venvs") and dirpath.name in cache_dirs:
101+
shutil.rmtree(dirpath, ignore_errors=True)
131102

132103

133104
def vscode() -> None:
@@ -143,21 +114,24 @@ def main() -> int:
143114
if len(args) > 1:
144115
run("default", "duty", "--help", args[1])
145116
else:
146-
print("Available commands") # noqa: T201
147-
print(" help Print this help. Add task name to print help.") # noqa: T201
148-
print(" setup Setup all virtual environments (install dependencies).") # noqa: T201
149-
print(" run Run a command in the default virtual environment.") # noqa: T201
150-
print(" multirun Run a command for all configured Python versions.") # noqa: T201
151-
print(" allrun Run a command in all virtual environments.") # noqa: T201
152-
print(" 3.x Run a command in the virtual environment for Python 3.x.") # noqa: T201
153-
print(" clean Delete build artifacts and cache files.") # noqa: T201
154-
print(" vscode Configure VSCode to work on this project.") # noqa: T201
155-
try:
156-
run("default", "python", "-V", capture_output=True)
157-
except (subprocess.CalledProcessError, ValueError):
158-
pass
159-
else:
160-
print("\nAvailable tasks") # noqa: T201
117+
print(
118+
dedent(
119+
"""
120+
Available commands
121+
help Print this help. Add task name to print help.
122+
setup Setup all virtual environments (install dependencies).
123+
run Run a command in the default virtual environment.
124+
multirun Run a command for all configured Python versions.
125+
allrun Run a command in all virtual environments.
126+
3.x Run a command in the virtual environment for Python 3.x.
127+
clean Delete build artifacts and cache files.
128+
vscode Configure VSCode to work on this project.
129+
"""
130+
),
131+
flush=True,
132+
) # noqa: T201
133+
if os.path.exists(".venv"):
134+
print("\nAvailable tasks", flush=True) # noqa: T201
161135
run("default", "duty", "--list")
162136
return 0
163137

0 commit comments

Comments
 (0)