Skip to content

Commit c1f3224

Browse files
committed
feat: ensure rust session aren't created if not using maturin and add additional compatibility sessions for lint, publish, etc
1 parent 1b73640 commit c1f3224

File tree

1 file changed

+125
-10
lines changed

1 file changed

+125
-10
lines changed

{{cookiecutter.project_name}}/noxfile.py

Lines changed: 125 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,35 @@
2828
PACKAGE_NAME: str = "{{cookiecutter.package_name}}"
2929

3030

31+
@nox.session(python=DEFAULT_PYTHON_VERSION, name="setup-repo")
32+
def setup_repo(session: Session) -> None:
33+
"""Set up the repository for development.
34+
35+
Really this should only ever be used once upon repo creation. However, it is helpful to use in generating fake repos
36+
for use in testing the template itself.
37+
"""
38+
session.log("Installing development dependencies...")
39+
session.notify("setup-git")
40+
session.notify("setup-branches")
41+
session.install("-e", ".", "--group", "dev")
42+
43+
44+
@nox.session(python=DEFAULT_PYTHON_VERSION, name="setup-git")
45+
def setup_git(session: Session) -> None:
46+
"""Set up the git repo for the current project."""
47+
session.run("git", "init")
48+
session.run("git", "branch", "-M", "main")
49+
session.run("git", "add", ".")
50+
session.run("git", "commit", "-m", "feat: initial commit")
51+
52+
53+
@nox.session(python=DEFAULT_PYTHON_VERSION, name="setup-branches")
54+
def setup_branches(session: Session) -> None:
55+
"""Set up the git repo for the current project."""
56+
session.run("git", "checkout", "-b", "develop", "main")
57+
58+
59+
3160
@nox.session(python=DEFAULT_PYTHON_VERSION, name="pre-commit")
3261
def precommit(session: Session) -> None:
3362
"""Lint using pre-commit."""
@@ -41,6 +70,15 @@ def precommit(session: Session) -> None:
4170
activate_virtualenv_in_precommit_hooks(session)
4271

4372

73+
@nox.session(python=None, name="format")
74+
def _format(session: Session) -> None:
75+
"""Run all formatting checks (Ruff, Pydocstyle)."""
76+
session.log("Installing formatting dependencies...")
77+
if "format_rust" in dir():
78+
session.notify("format-rust")
79+
session.notify("format-python")
80+
81+
4482
@nox.session(python=DEFAULT_PYTHON_VERSION, name="format-python")
4583
def format_python(session: Session) -> None:
4684
"""Run Python code formatter (Ruff format)."""
@@ -52,6 +90,26 @@ def format_python(session: Session) -> None:
5290
session.run("ruff", "format", *session.posargs)
5391

5492

93+
{% if cookiecutter.add_rust_extension == "y" %}
94+
@nox.session(python=None, name="format-rust")
95+
def format_rust(session: Session) -> None:
96+
"""Run Rust code formatter (cargo fmt)."""
97+
session.log("Installing formatting dependencies...")
98+
session.run("cargo", "install", "cargo-fmt", external=True)
99+
session.run("cargo", "fmt", "--all", "--", "--check", external=True)
100+
session.run("cargo", "fmt", "--all", "--", "--write", external=True)
101+
102+
103+
{% endif %}
104+
@nox.session(python=None, name="lint")
105+
def lint(session: Session) -> None:
106+
"""Run all linting checks (Ruff, Pydocstyle)."""
107+
session.log("Installing linting dependencies...")
108+
if "lint_rust" in dir():
109+
session.notify("lint-rust")
110+
session.notify("lint-python")
111+
112+
55113
@nox.session(python=DEFAULT_PYTHON_VERSION, name="lint-python")
56114
def lint_python(session: Session) -> None:
57115
"""Run Python code linters (Ruff check, Pydocstyle rules)."""
@@ -62,6 +120,17 @@ def lint_python(session: Session) -> None:
62120
session.run("ruff", "check", "--verbose")
63121

64122

123+
{% if cookiecutter.add_rust_extension == "y" %}
124+
@nox.session(python=None, name="lint-rust")
125+
def lint_rust(session: Session) -> None:
126+
"""Run Rust code linters (cargo clippy)."""
127+
session.log("Installing linting dependencies...")
128+
session.run("cargo", "install", "cargo-clippy", external=True)
129+
session.run("cargo", "clippy", "--all-features", "--", "--check", external=True)
130+
session.run("cargo", "clippy", "--all-features", "--", "--write", external=True)
131+
132+
133+
{% endif %}
65134
@nox.session(python=PYTHON_VERSIONS)
66135
def typecheck(session: Session) -> None:
67136
"""Run static type checking (Pyright) on Python code."""
@@ -72,6 +141,15 @@ def typecheck(session: Session) -> None:
72141
session.run("pyright")
73142

74143

144+
@nox.session(python=None, name="security")
145+
def security(session: Session) -> None:
146+
"""Run code security checks."""
147+
session.log("Installing security dependencies...")
148+
if "security_rust" in dir():
149+
session.notify("security-rust")
150+
session.notify("security-python")
151+
152+
75153
@nox.session(python=DEFAULT_PYTHON_VERSION, name="security-python")
76154
def security_python(session: Session) -> None:
77155
"""Run code security checks (Bandit) on Python code."""
@@ -85,6 +163,24 @@ def security_python(session: Session) -> None:
85163
session.run("pip-audit")
86164

87165

166+
{% if cookiecutter.add_rust_extension == 'y' %}
167+
@nox.session(python=None, name="security-rust")
168+
def security_rust(session: Session) -> None:
169+
"""Run code security checks (cargo audit)."""
170+
session.log("Installing security dependencies...")
171+
session.run("cargo", "install", "cargo-audit", external=True)
172+
session.run("cargo", "audit", "--all", external=True)
173+
174+
175+
{% endif %}
176+
@nox.session(python=None, name="tests")
177+
def tests(session: Session) -> None:
178+
"""Run all Python and Rust tests."""
179+
if "tests_rust" in dir():
180+
session.notify("tests-rust")
181+
session.notify("tests-python")
182+
183+
88184
@nox.session(python=PYTHON_VERSIONS, name="tests-python")
89185
def tests_python(session: Session) -> None:
90186
"""Run the Python test suite (pytest with coverage)."""
@@ -105,6 +201,7 @@ def tests_python(session: Session) -> None:
105201
)
106202

107203

204+
{% if cookiecutter.add_rust_extension == 'y' %}
108205
@nox.session(python=None, name="tests-rust")
109206
def tests_rust(session: Session) -> None:
110207
"""Test the project's rust crates."""
@@ -114,6 +211,8 @@ def tests_rust(session: Session) -> None:
114211
session.run("cargo", "test", "--all-features", *crate_kwargs, external=True)
115212

116213

214+
215+
{% endif %}
117216
@nox.session(python=DEFAULT_PYTHON_VERSION, name="docs-build")
118217
def docs_build(session: Session) -> None:
119218
"""Build the project documentation (Sphinx)."""
@@ -130,6 +229,14 @@ def docs_build(session: Session) -> None:
130229
session.run("sphinx-build", "-b", "html", "docs", str(docs_build_dir), "-W")
131230

132231

232+
@nox.session(python=None, name="build")
233+
def build(session: Session) -> None:
234+
"""Build the project artifacts (Python packages, Rust crates)."""
235+
if "build_rust" in dir():
236+
session.notify("build-rust")
237+
session.notify("build-python")
238+
239+
133240
@nox.session(python=DEFAULT_PYTHON_VERSION, name="build-python")
134241
def build_python(session: Session) -> None:
135242
"""Build sdist and wheel packages (uv build)."""
@@ -180,6 +287,14 @@ def build_container(session: Session) -> None:
180287
session.log(f"Container image {project_image_name}:latest built locally.")
181288

182289

290+
@nox.session(python=None, name="publish")
291+
def publish(session: Session) -> None:
292+
"""Publish the project artifacts (Python packages, Rust crates)."""
293+
if "publish_rust" in dir():
294+
session.notify("publish-rust")
295+
session.notify("publish-python")
296+
297+
183298
@nox.session(python=DEFAULT_PYTHON_VERSION, name="publish-python")
184299
def publish_python(session: Session) -> None:
185300
"""Publish sdist and wheel packages to PyPI via uv publish.
@@ -196,6 +311,7 @@ def publish_python(session: Session) -> None:
196311
session.run("uv", "publish", "dist/*", external=True)
197312

198313

314+
{% if cookiecutter.add_rust_extension == "y" %}
199315
@nox.session(python=None, name="publish-rust")
200316
def publish_rust(session: Session) -> None:
201317
"""Publish built crates to crates.io."""
@@ -205,6 +321,7 @@ def publish_rust(session: Session) -> None:
205321
session.run("cargo", "publish", "-p", crate_folder.name)
206322

207323

324+
{% endif %}
208325
@nox.session(venv_backend="none")
209326
def release(session: Session) -> None:
210327
"""Run the release process using Commitizen.
@@ -278,28 +395,26 @@ def tox(session: Session) -> None:
278395
def build(session: Session) -> None:
279396
"""Orchestrates building all project artifacts (Python packages, potentially Rust)."""
280397
session.log(f"Queueing build sessions for py{session.python} if applicable.")
281-
# Build Rust crate first if included
282-
{% if cookiecutter.add_rust_extension == 'y' %}
283-
session.notify("build_rust") # Build Rust crate first if Rust is enabled
284-
{% endif %}
285-
# Then build the Python package (uv build)
286-
session.notify("build-python") # Build Python sdist/wheel
398+
if "build_rust" in dir():
399+
session.notify("build-rust")
400+
session.notify("build-python")
287401

288402

289403
@nox.session(python=DEFAULT_PYTHON_VERSION) # Run the orchestrator on the default Python version
290404
def publish(session: Session) -> None:
291405
"""Orchestrates publishing all project artifacts (Python packages, potentially Rust)."""
292406
session.log(f"Queueing publish sessions for py{session.python} if applicable.")
293-
session.notify("publish-python") # Publish Python sdist/wheel
294-
# Note: publish_rust session might be notified here if needed.
407+
if "publish_rust" in dir():
408+
session.notify("publish-rust")
409+
session.notify("publish-python")
295410

296411

297412
@nox.session(python=PYTHON_VERSIONS)
298413
def check(session: Session) -> None:
299414
"""Run primary quality checks (format, lint, typecheck, security)."""
300415
session.log(f"Queueing core check sessions for py{session.python} if applicable.")
301-
session.notify("format-python")
302-
session.notify("lint-python")
416+
session.notify("format")
417+
session.notify("lint")
303418
session.notify("typecheck")
304419
session.notify("security-python")
305420

0 commit comments

Comments
 (0)