|
| 1 | +from pathlib import Path |
1 | 2 | import nox |
| 3 | +import shutil |
2 | 4 |
|
3 | 5 | nox.options.stop_on_first_error = True |
4 | 6 | nox.options.reuse_existing_virtualenvs = False |
| 7 | +BUILD_DIRS = ["build", "dist"] |
5 | 8 |
|
6 | 9 | # Default sessions - all tests, but not packaging |
7 | 10 | nox.options.sessions = [ |
@@ -31,3 +34,74 @@ def lint(session): |
31 | 34 | "uv", "tool", "run", "black", "--verbose", "--check", "--diff", "--color", "." |
32 | 35 | ) |
33 | 36 | session.run("uv", "tool", "run", "ruff", "--verbose", "check", ".") |
| 37 | + |
| 38 | + |
| 39 | +@nox.session |
| 40 | +def watch(session): |
| 41 | + """Build and serve live docs for editing""" |
| 42 | + session.install("-e", ".[docs]") |
| 43 | + |
| 44 | + session.run("mkdocs", "serve") |
| 45 | + |
| 46 | + |
| 47 | +@nox.session |
| 48 | +def examples(session): |
| 49 | + session.install("-e", ".[test]") |
| 50 | + |
| 51 | + options = session.posargs |
| 52 | + |
| 53 | + # Because these example scripts can be long-running, output the |
| 54 | + # example's stdout so we know what's happening |
| 55 | + session.run("pytest", "--no-cov", "examples/", "-s", *options) |
| 56 | + |
| 57 | + |
| 58 | +@nox.session |
| 59 | +def build(session): |
| 60 | + """Build package""" |
| 61 | + # check preexisting |
| 62 | + exist_but_should_not = [p for p in BUILD_DIRS if Path(p).is_dir()] |
| 63 | + if exist_but_should_not: |
| 64 | + session.error( |
| 65 | + f"Pre-existing {', '.join(exist_but_should_not)}. " |
| 66 | + "Run clean session and try again" |
| 67 | + ) |
| 68 | + |
| 69 | + session.install("build", "twine", "check-wheel-contents") |
| 70 | + |
| 71 | + session.run(*"python -m build --sdist --wheel".split()) |
| 72 | + session.run("check-wheel-contents", "dist") |
| 73 | + |
| 74 | + |
| 75 | +@nox.session |
| 76 | +def clean(session): |
| 77 | + """Remove build directories""" |
| 78 | + to_remove = [Path(d) for d in BUILD_DIRS if Path(d).is_dir()] |
| 79 | + for p in to_remove: |
| 80 | + shutil.rmtree(p) |
| 81 | + |
| 82 | + |
| 83 | +@nox.session |
| 84 | +def publish_testpypi(session): |
| 85 | + """Publish to TestPyPi using API token""" |
| 86 | + _publish(session, "testpypi") |
| 87 | + |
| 88 | + |
| 89 | +@nox.session |
| 90 | +def publish_pypi(session): |
| 91 | + """Publish to PyPi using API token""" |
| 92 | + _publish(session, "pypi") |
| 93 | + |
| 94 | + |
| 95 | +def _publish(session, repository): |
| 96 | + missing = [p for p in BUILD_DIRS if not Path(p).is_dir()] |
| 97 | + if missing: |
| 98 | + session.error( |
| 99 | + f"Missing one or more build directories: {', '.join(missing)}. " |
| 100 | + "Run build session and try again" |
| 101 | + ) |
| 102 | + |
| 103 | + session.install("twine") |
| 104 | + |
| 105 | + files = [str(f) for f in Path("dist").iterdir()] |
| 106 | + session.run("twine", "check", *files) |
| 107 | + session.run("twine", "upload", f"--repository={repository}", "-u=__token__", *files) |
0 commit comments