Repository navigation
Build targets: script and native binaries next to the zipapp, on pybash 0.4 - #58
Conversation
pybash 0.4.0 is not on PyPI yet, so uv resolves it from GitHub. The source override has to go before cliffy is released. The warning filter for the old pybash's re.sub() call is no longer needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shell lines are translated with runtime=pybash.RUNTIME_NAME. The generated code imports pybash.runtime as _pybash only when a line needs it (operators, values in > lines); plain commands stay bare subprocess calls. A shell line pybash cannot translate, or a Python syntax error in a run block, callback or function, now stops with the manifest file, the script, the line and the column instead of a traceback or a broken CLI. Three tests loaded run blocks that were not Python (echo without $); their inputs now say what they meant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Operators, redirects, $( ) capture, f{ } formatting, quoting of values in >
lines, {{! }}, continuation lines and comments, each with a tested snippet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A build target is a small class behind one interface; zipapp (shiv) stays the default. script writes one .py file with a uv shebang and PEP 723 inline metadata. native installs the CLI as a wheel into a standalone Python, embeds it in PyApp and compiles one executable that needs nothing installed. All targets paste the pybash helper into the code when the CLI uses shell operators, so a built CLI depends on its framework and its requires only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The building guide is organized around zipapp, script and native with a comparison table of measured sizes and start times. Adds the changelog and migration entries for the targets and for pybash 0.4, and removes the status line from SOUL.md now that all three targets exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Reviewer's GuideThis PR introduces pluggable zipapp, script, and native build targets, embeds the pybash 0.4 runtime when generated CLIs need advanced shell features, validates run-block syntax early with manifest-specific diagnostics, and updates tests, dependency resolution, and documentation for the new distribution and shell semantics. Sequence diagram for native CLI buildsequenceDiagram
participant User
participant Cliffy
participant UV
participant Cargo
participant PyApp
User->>Cliffy: cli build --target native
Cliffy->>UV: uv python install
Cliffy->>UV: uv build --wheel
Cliffy->>UV: uv pip install wheel and requirements
Cliffy->>Cliffy: archive Python distribution
Cliffy->>Cargo: cargo install pyapp
Cargo->>PyApp: compile with embedded archive
PyApp-->>Cliffy: native executable
Cliffy-->>User: artifact path and run notes
Sequence diagram for embedding the pybash runtime in built CLIssequenceDiagram
participant Manifest
participant Transformer
participant PyBash
participant Builder
participant Target
Manifest->>Transformer: load and generate CLI
Transformer->>PyBash: transform_script(run_block)
PyBash-->>Transformer: generated Python and runtime references
Transformer->>Builder: generated CLI code
Builder->>PyBash: runtime_source()
PyBash-->>Builder: inline runtime source
Builder->>Target: build standalone code and requirements
Target-->>Manifest: packaged CLI without cliffy or pybash dependency
Flow diagram for early run-block validationflowchart TD
Load[Load manifest] --> Transform[transform_script]
Transform --> Parse[ast.parse generated Python]
Parse --> Valid[Generate CLI]
Parse --> Invalid[ScriptError with manifest, line, column, and caret]
Invalid --> Stop[Report error and stop loading]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pybash 0.4.0 is published, so the temporary git source override is no longer needed and the lockfile resolves it from the index. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
cli buildgains two targets next to the shiv zipapp, picked with a flag, and cliffy moves to pybash 0.4 for$/>lines in run blocks.cliffy now requires
pybash>=0.4.0, which is on PyPI (jaykv/pybash#11).Build targets
cli build <manifest-or-loaded-cli> --target zipapp|script|native(defaultzipapp). The manifest does not change between targets. Blueprint-spec YAMLs work with all three.zipappdist/<name>, a shiv zipappscriptdist/<name>.py, executable,uv run --scriptshebang and a PEP 723 dependency blocknativedist/<name>, one compiled executable built with PyAppMeasured with
examples/hello.yamlon Apple Silicon:How the native target works: it installs a relocatable CPython with uv, builds a wheel of the generated CLI, installs the wheel and its dependencies into that Python, archives it, and compiles PyApp 0.30.0 with the archive embedded (
PYAPP_DISTRIBUTION_PATH,PYAPP_SKIP_INSTALL=1,PYAPP_FULL_ISOLATION=1). The binary therefore needs no network and no Python on first run; it only unpacks itself.Built CLIs depend on the framework and the manifest's
requiresonly. When a run block uses shell operators, the small pybash helper is pasted into the built file instead of imported, for every target.In
builder.pythe targets are small classes behind one interface (BuildTarget, registered inTARGETS), so a fourth target is one class.pybash 0.4
Run blocks can use
&&,||,;,|,|&, redirects (2>,&>,2>&1),$(command)capture, any expression in{{ }}, and injection-safe interpolation in>shell lines.import pybash.runtime as _pybashis added to a generated CLI only when its code uses an operator. Plain$ lsstays a baresubprocesscall.A bad
$line, or a Python syntax error in a run block, is reported against the manifest with no traceback:Changes in behaviour
run: echo "Hello"); they now use$ echo .... No assertion was changed.--pythonhas a per-target default, and is rejected for--target native.SOUL.md: the status line about unshipped targets is removed.How verified
ruff format --check,ruff check,mypy cliffy --strict,mypy testsclean;pytest -n auto548 passed, 1 skipped (the opt-in native test).make docs-checkandmkdocs build --strictpass.uv run, through its shebang and through the current interpreter, and checks that neither cliffy nor pybash is in its environment.examples/hello.yamland the blueprint specexamples/blueprints/text-tools.yaml. The binary was run withenv -i PATH=/bin HOME=<empty dir>inside a sandbox that denies network access, and printed its output. The opt-in testtest_native_build_runs_in_an_empty_environment(CLIFFY_TEST_NATIVE=1, needs cargo and uv) passed on 3.11 and 3.15.bin/python3, so Windows is not supported.Open items
examples/generated/*.pyare not regenerated and still show the old pybash formatting.PYAPP_*variables, so each build uses its own target directory.self remove; users delete PyApp's data directory to uninstall.🤖 Generated with Claude Code
Summary by Sourcery
Expand
cli buildbeyond zipapps and adopt pybash 0.4 for richer, safer shell-aware run blocks.New Features:
zipapp,script, andnativebuild targets selected throughcli build --target.Bug Fixes:
Enhancements:
Build:
Documentation:
Tests:
Chores: