Skip to content

fix(dsl): port corepack PM version pin to Python DSL; fail-fast on legacy pipeline(step) form#134

Merged
markovejnovic merged 1 commit into
mainfrom
relprep/7-fix-dsl-corepack-pin-and-pipeline-guard
Jun 10, 2026
Merged

fix(dsl): port corepack PM version pin to Python DSL; fail-fast on legacy pipeline(step) form#134
markovejnovic merged 1 commit into
mainfrom
relprep/7-fix-dsl-corepack-pin-and-pipeline-guard

Conversation

@markovejnovic

Copy link
Copy Markdown
Contributor

Summary

Two parity / sharp-edge fixes in the Python pipeline DSL, bringing it in line with the TypeScript DSL and giving a doctrine-shaped error for a legacy call form.

  • Corepack PM version pin (parity with the TS DSL): the packageManager version pin shipped in the TypeScript DSL only. DetectedToolchain now carries pm_version, detect_from_package_json captures the @-suffix of a known PM, and _pm_bootstrap emits corepack enable pnpm && corepack install -g pnpm@<v> (and the yarn form) when a version is present. The bootstrap step's cache switches to CacheOnChange(package.json) when a pin is present so the snapshot rebuilds when the pin changes (CacheForever otherwise). This keeps the emitted IR and cache keys identical between the two SDKs for any project that pins its package manager.
  • Fail-fast on the legacy pipeline(step) form: the polymorphic hm.pipeline() dispatcher only recognized a list/tuple of leaves. The pre-CLI-9 pipeline(step) / pipeline(a, b) forms fell through to the decorator and blew up far downstream with a cryptic AttributeError. The dispatcher now guards on all-Step positionals and raises a doctrine-shaped TypeError that names the observed shape and states the fix (wrap leaves in a list).

Findings addressed

  • js-corepack-pin-parity-1
  • py-pipeline-migration-error-1

Verification

PR diff vs origin/main is exactly the focused fix: 7 files (3 source, 4 test), +302 / -17.

Command Result
uv run pytest tests/test_detect.py tests/test_js.py tests/test_pipeline.py -q (in crates/hm-dsl-engine/harmont-py) 101 passed
cargo test -p hm-dsl-engine --test cross_sdk_cache_test 2 passed — incl. new cross_sdk_cache_keys_match_js_corepack_pin proving Python/TS IR + cache keys stay identical for a pinned packageManager

The new cross-SDK test closes the invariant gap that previously had no JS coverage.

Judge verdict

Approved. No blocking issues.


Generated by the Harmont release-readiness workflow (automated; needs human review before merge). 🤖

…eline(step)

Two parity/sharp-edge fixes in the Python pipeline DSL.

js-corepack-pin-parity-1 — the corepack package-manager version pin shipped
in the TypeScript DSL only. Python's DetectedToolchain had no pm_version, its
detect_from_package_json never extracted the @-suffix of `packageManager`, and
_pm_bootstrap always emitted the bare `corepack enable pnpm` / `corepack enable`
with a CacheForever bootstrap step. That diverged the emitted IR and cache keys
between the two SDKs for any project that pins its package manager. Port PR #86:

  - _detect.py: DetectedToolchain gains `pm_version`; detect_from_package_json
    captures the version segment when a known PM has one; detect() propagates it.
  - _js.py: _pm_bootstrap takes the detected version and emits
    `corepack enable pnpm && corepack install -g pnpm@<v>` (and the yarn form)
    when present; the bootstrap step's cache switches to CacheOnChange on
    package.json so the pin is rebuilt when it changes (CacheForever otherwise).

  Mirrors js.ts/detect.ts exactly. New Python tests assert the pinned command
  and the package.json-watch cache. cross_sdk_cache_test.rs gains a
  JS-toolchain pipeline with a pinned `packageManager`, proving the Python and
  TypeScript IR/cache keys stay identical (the invariant that previously had no
  JS coverage).

py-pipeline-migration-error-1 — the polymorphic hm.pipeline() dispatcher only
recognized a list/tuple of leaves; the pre-CLI-9 `pipeline(step)` form fell
through to the decorator and blew up far downstream with a cryptic
`AttributeError: 'function' object has no attribute 'get'`, while `pipeline(a, b)`
leaked the decorator's TypeError. Guard the dispatcher: when the positionals are
all Step objects, raise a doctrine-shaped TypeError that points at the observed
shape and states the fix (wrap the leaves in a list). Regression tests cover
both the single- and multi-leaf legacy forms.
@markovejnovic markovejnovic merged commit d466802 into main Jun 10, 2026
17 checks passed
@markovejnovic markovejnovic deleted the relprep/7-fix-dsl-corepack-pin-and-pipeline-guard branch June 10, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant