3939TEST : str = "test"
4040COVERAGE : str = "coverage"
4141SECURITY : str = "security"
42- PERF : str = "perf"
4342DOCS : str = "docs"
4443BUILD : str = "build"
4544RELEASE : str = "release"
4645QUALITY : str = "quality"
47- PYTHON : str = "python"
48- RUST : str = "rust"
4946
5047
5148@nox .session (python = False , name = "setup-git" , tags = [ENV ])
@@ -88,21 +85,39 @@ def precommit(session: Session) -> None:
8885 activate_virtualenv_in_precommit_hooks (session )
8986
9087
91- @nox .session (python = False , name = "format-python" , tags = [FORMAT , PYTHON , QUALITY ])
88+ @nox .session (python = False , name = "format-python" , tags = [FORMAT , QUALITY ])
9289def format_python (session : Session ) -> None :
9390 """Run Python code formatter (Ruff format)."""
9491 session .log (f"Running Ruff formatter check with py{ session .python } ." )
9592 session .run ("uvx" , "ruff" , "format" , * session .posargs )
9693
9794
98- @nox .session (python = False , name = "lint-python" , tags = [LINT , PYTHON , QUALITY ])
95+ @nox .session (python = False , name = "format-rust" , tags = [FORMAT ])
96+ def format_rust (session : Session ) -> None :
97+ """Run Rust code formatter (cargo fmt)."""
98+ session .log ("Ensuring rustfmt component is available..." )
99+ session .run ("rustup" , "component" , "add" , "rustfmt" , external = True )
100+ session .log ("Formatting Rust code..." )
101+ session .run ("cargo" , "fmt" , "--all" , external = True )
102+
103+
104+ @nox .session (python = False , name = "lint-python" , tags = [LINT , QUALITY ])
99105def lint_python (session : Session ) -> None :
100106 """Run Python code linters (Ruff check, Pydocstyle rules)."""
101107 session .log (f"Running Ruff check with py{ session .python } ." )
102108 session .run ("uvx" , "ruff" , "check" , "--fix" , "--verbose" )
103109
104110
105- @nox .session (python = PYTHON_VERSIONS , name = "typecheck" , tags = [TYPE , PYTHON ])
111+ @nox .session (python = False , name = "lint-rust" , tags = [LINT , QUALITY ])
112+ def lint_rust (session : Session ) -> None :
113+ """Run Rust code linters (cargo clippy)."""
114+ session .log ("Ensuring clippy component is available..." )
115+ session .run ("rustup" , "component" , "add" , "clippy" , external = True )
116+ session .log ("Running clippy lints..." )
117+ session .run ("cargo" , "clippy" , "--all-features" , "--" , "-D" , "warnings" , external = True )
118+
119+
120+ @nox .session (python = PYTHON_VERSIONS , name = "typecheck" )
106121def typecheck (session : Session ) -> None :
107122 """Run static type checking (Pyright) on Python code."""
108123 session .log ("Installing type checking dependencies..." )
@@ -112,7 +127,7 @@ def typecheck(session: Session) -> None:
112127 session .run ("pyright" , "--pythonversion" , session .python )
113128
114129
115- @nox .session (python = False , name = "security-python" , tags = [SECURITY , PYTHON ])
130+ @nox .session (python = False , name = "security-python" , tags = [SECURITY ])
116131def security_python (session : Session ) -> None :
117132 """Run code security checks (Bandit) on Python code."""
118133 session .log (f"Running Bandit static security analysis with py{ session .python } ." )
@@ -122,7 +137,15 @@ def security_python(session: Session) -> None:
122137 session .run ("uvx" , "pip-audit" )
123138
124139
125- @nox .session (python = PYTHON_VERSIONS , name = "tests-python" , tags = [TEST , PYTHON ])
140+ @nox .session (python = False , name = "security-rust" , tags = [SECURITY ])
141+ def security_rust (session : Session ) -> None :
142+ """Run code security checks (cargo audit)."""
143+ session .log ("Ensuring cargo-audit is available..." )
144+ session .run ("cargo" , "install" , "cargo-audit" , "--locked" , external = True )
145+ session .run ("cargo" , "audit" , "--all" , external = True )
146+
147+
148+ @nox .session (python = PYTHON_VERSIONS , name = "tests-python" , tags = [TEST ])
126149def tests_python (session : Session ) -> None :
127150 """Run the Python test suite (pytest with coverage)."""
128151 session .log ("Installing test dependencies..." )
@@ -144,6 +167,15 @@ def tests_python(session: Session) -> None:
144167 )
145168
146169
170+ @nox .session (python = False , name = "tests-rust" , tags = [TEST ])
171+ def tests_rust (session : Session ) -> None :
172+ """Test the project's rust crates."""
173+ crates : list [Path ] = [cargo_toml .parent for cargo_toml in CRATES_FOLDER .glob ("*/Cargo.toml" )]
174+ crate_kwargs : list [str ] = [f"-p { crate .name } " for crate in crates ]
175+ session .run ("cargo" , "test" , "--all-features" , "--no-run" , * crate_kwargs , external = True )
176+ session .run ("cargo" , "test" , "--all-features" , * crate_kwargs , external = True )
177+
178+
147179@nox .session (python = DEFAULT_PYTHON_VERSION , name = "build-docs" , tags = [DOCS , BUILD ])
148180def docs_build (session : Session ) -> None :
149181 """Build the project documentation (Sphinx)."""
@@ -160,16 +192,23 @@ def docs_build(session: Session) -> None:
160192 session .run ("sphinx-build" , "-b" , "html" , "docs" , str (docs_build_dir ), "-W" )
161193
162194
163- @nox .session (python = False , name = "build-python" , tags = [BUILD , PYTHON ])
195+ @nox .session (python = False , name = "build-python" , tags = [BUILD ])
164196def build_python (session : Session ) -> None :
165197 """Build sdist and wheel packages (uv build)."""
166198 session .log (f"Building sdist and wheel packages with py{ session .python } ." )
167- session .run ("uv " , "build " , "--sdist" , "--wheel" , "--out-dir" , "dist/" , external = True )
199+ session .run ("maturin " , "develop " , "--uv" )
168200 session .log ("Built packages in ./dist directory:" )
169201 for path in Path ("dist/" ).glob ("*" ):
170202 session .log (f"- { path .name } " )
171203
172204
205+ @nox .session (python = False , name = "build-rust" , tags = [BUILD ])
206+ def build_rust (session : Session ) -> None :
207+ """Build standalone Rust crates for potential independent publishing."""
208+ session .log ("Building Rust crates..." )
209+ session .run ("cargo" , "build" , "--release" , "--manifest-path" , "rust/Cargo.toml" , external = True )
210+
211+
173212@nox .session (python = False , name = "build-container" , tags = [BUILD ])
174213def build_container (session : Session ) -> None :
175214 """Build the Docker container image.
@@ -241,6 +280,15 @@ def publish_python(session: Session) -> None:
241280 session .run ("uv" , "publish" , "dist/*" , * session .posargs , external = True )
242281
243282
283+ @nox .session (python = False , name = "publish-rust" , tags = [RELEASE ])
284+ def publish_rust (session : Session ) -> None :
285+ """Publish built crates to crates.io."""
286+ session .log ("Publishing crates to crates.io" )
287+ for cargo_toml in CRATES_FOLDER .glob ("*/Cargo.toml" ):
288+ crate_folder : Path = cargo_toml .parent
289+ session .run ("cargo" , "publish" , "-p" , crate_folder .name )
290+
291+
244292@nox .session (python = False )
245293def tox (session : Session ) -> None :
246294 """Run the 'tox' test matrix.
0 commit comments