Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ jobs:
sed -i "s/^version = \".*\"/version = \"${VERSION}\"/" pyproject.toml
grep "^version = \"${VERSION}\"" pyproject.toml

- name: Sync uv.lock to the new version
run: |
uv lock
grep -A1 '^name = "bambox"' uv.lock | grep "^version = \"${{ inputs.version }}\""

- name: Build changelog with towncrier
run: |
VERSION="${{ inputs.version }}"
Expand All @@ -87,7 +92,7 @@ jobs:
BRANCH="release/v${VERSION}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add pyproject.toml CHANGELOG.md changes/
git add pyproject.toml uv.lock CHANGELOG.md changes/
git commit -m "Release v${VERSION}"
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git"
git push --force origin "$BRANCH"
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ Or with [uv](https://docs.astral.sh/uv/):

```bash
uv pip install bambox
uv tool install bambox # just the CLI
```

The core install covers packing, repacking and validation. Two optional
extras pull in heavier dependencies only if you need them:

| Extra | Pulls in | Needed for |
|-------|----------|------------|
| `templates` | Jinja2 | `bambox.templates.render_template()` — rendering bundled G-code templates |
| `thumbnail` | Pillow | `bambox.thumbnail.gcode_thumbnail()` — rendering toolpath previews |

```bash
pip install "bambox[templates,thumbnail]"
```

### Supported printers and filaments
Expand Down
1 change: 1 addition & 0 deletions changes/274.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Declare the `templates` (Jinja2) and `thumbnail` (Pillow) extras that `render_template()` and `gcode_thumbnail()` already told users to install, and give `gcode_thumbnail()` the same actionable error as `render_template()` when Pillow is missing.
1 change: 1 addition & 0 deletions changes/274.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Prepare Release now re-locks `uv.lock` with the new version, so the lockfile no longer drifts behind `pyproject.toml` after each release.
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ classifiers = [
]

[project.optional-dependencies]
templates = [
"jinja2>=3.1.0",
]
thumbnail = [
"pillow>=10.0.0",
]
dev = [
"pytest>=8.0.0",
"pytest-cov>=6.0.0",
Expand Down
8 changes: 7 additions & 1 deletion src/bambox/thumbnail.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ def gcode_thumbnail(
Parses G0/G1 extrusion moves from the print body (skipping startup
G-code) and draws them on a dark background. Returns PNG bytes.
"""
from PIL import Image, ImageDraw
try:
from PIL import Image, ImageDraw
except ImportError:
raise ImportError(
"Pillow is required for thumbnail rendering. "
"Install with: pip install bambox[thumbnail]"
)

if isinstance(gcode, bytes):
gcode = gcode.decode(errors="replace")
Expand Down
16 changes: 16 additions & 0 deletions tests/test_release_readiness.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,19 @@ def test_notices_force_included_in_wheel(self) -> None:
"THIRD-PARTY-NOTICES should be placed under bambox/ in the wheel "
"so it's discoverable next to the installed package."
)


# ---------------------------------------------------------------------------
# 5. Optional extras named in ImportError hints must exist
# ---------------------------------------------------------------------------


class TestOptionalExtras:
"""`pip install bambox[<extra>]` hints must point at a real extra."""

@pytest.mark.parametrize("extra", ["templates", "thumbnail"])
def test_extra_is_declared(self, extra: str) -> None:
from importlib.metadata import metadata

declared = metadata("bambox").get_all("Provides-Extra") or []
assert extra in declared
12 changes: 10 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading