Skip to content

chore(deps): Bump openjd-* Rust crates to 0.8.0 - #365

Merged
leongdl merged 1 commit into
OpenJobDescription:mainlinefrom
leongdl:chore/bump-openjd-rs-0.8.0
Sep 16, 2026
Merged

leongdl merged 1 commit into
OpenJobDescription:mainlinefrom
leongdl:chore/bump-openjd-rs-0.8.0

Conversation

@leongdl

@leongdl leongdl commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Fixes: n/a (dependency bump for OpenJobDescription/openjd-rs#395)

What was the problem/requirement? (What/Why)

openjd-rs published a release on 2026-09-15: openjd-expr 0.8.0, openjd-model 0.8.0, openjd-sessions 0.6.0. This package pinned 0.7.0 / 0.7.1 / 0.5.8. The release carries six fixes, two of them tagged breaking in the changelog.

What was the solution? (How)

Bump the three pins in rust-bindings/Cargo.toml. Cargo.lock moved only those three packages; THIRD-PARTY-LICENSES.txt regenerated with only the three version lines changing.

Public API. A source diff of the published crates and of upstream's specs/*/public-api.md shows one addition: openjd_expr::FormatString::segment_count() and literal_segments(), added by openjd-rs#383 for the model validator. Both are now exposed on openjd.expr.FormatString, with the .pyi stub and specs/python-expr-interface.md updated. openjd-model and openjd-sessions have no public signature changes, so the bindings built with no edits. The two [breaking] tags (#396, #383) are behavioural, not API.

Behaviour changes, each exercised through this package's API (v1 and the v0 reference side by side where both apply):

Upstream Reachable here through 0.7.x 0.8.0 v0 reference
#396 membership item type-check openjd.expr.evaluate_expression 'a' in [1, 2] is False raises ExpressionError n/a
#383 resolved-value constraints at validation decode_job_template name resolving to 129 chars accepted; chunks defaultTaskCount naming an undeclared parameter accepted both rejected at decode already rejected both
#383 / #397 chunks target-typed int create_job "not a valid integer" "Cannot convert 'not-an-integer' to int", same ExpressionError class Pydantic message
#397 whole-field allOf element deferred decode_job_template + create_job ["linux", "{{Param.X}}"] rejected at decode accepted at decode (can null-skip); create_job rejects X="windows", accepts X resolving to null rejects at decode
#397 control char in resolved name create_job job created with render-a\nb DecodeValidationError rejects
#398 NONCONTIGUOUS chunk rendering StepParameterSpaceIterator [1,2,4,6] renders 1,2-6:2 1,2,4,6 1,2,4,6 (agrees on all 4 probed shapes)
#384 empty LIST[PATH] round-trip preprocess_job_parameters second pass refuses first pass output accepted; create_job accepts n/a (v0 preprocess input shape differs)
#359 embedded filename ., .., NUL decode_job_template accepted rejected accepts all three

Not reachable from this repo's tests: the openjd-sessions half of #359 (Windows drive-relative anchors C:, D:relative). The model layer accepts those strings and the sessions check is Windows-only. Coverage lives in openjd-rs.

What is the impact of this change?

Two existing v1 tests changed:

  • test_chunks_with_format_string_default_task_count used a template referencing Param.ChunkSize without declaring it. It passed only because 0.7.1 did not validate chunk fields; the v0 reference rejects that template. It now declares the parameter, and a new test pins the rejection.
  • test_chunk_default_task_count_invalid_int pins the exception class, which is unchanged; its message regex moves to the evaluator's coercion message.

No other test changed. Nothing regressed.

How was this change tested?

hatch run test: 6058 passed, 24 skipped, 3 xfailed (pre-existing, unrelated), coverage 94.14%. hatch run lint (ruff, black, mypy) clean. cargo fmt --check and cargo clippy -p openjd-python --all-targets -- -D warnings clean.

New tests: TestListMembershipElementTypeCheck (cases copied from upstream test_comparison.rs), TestEmbeddedFileFilenameIsASinglePathComponent, TestResolvedValueConstraintsAtTemplateValidation, TestPreprocessAcceptsItsOwnEmptyListPath, TestResolvedJobNameControlCharacters, TestDeferredSingleValuedAllOfIsRecheckedAtJobCreation, TestNoncontiguousChunkRendering, plus segment_count / literal_segments cases in TestFormatString.

Mutation check: with the three pins reverted to 0.7.0 / 0.7.1 / 0.5.8 (and the two new bindings removed so the crate compiles), 30 tests fail, all in the new or updated classes. The whole-field allOf deferral was measured as rejected on 0.7.1 by probe. Two new cases were already rejected on 0.7.1 and are labelled as controls in their docstrings: a tab in a literal run of an interpolated job name, and two certain allOf elements. The two new binding methods were also mutated independently (wrong segment_count shape, literal_segments returning the raw text); each mutant fails 3 tests.

Was this change documented?

Yes: docstrings on the two new bindings, the .pyi stub, and specs/python-expr-interface.md. Every new test docstring states what 0.7.1 did with the same input and cites the spec section where one applies.

Is this a breaking change?

No public contract of this package changes. Callers see stricter validation from openjd-model 0.8.0 on templates that were invalid per the spec (see table). One message string changes for a non-integer defaultTaskCount.

Does this change impact security?

No.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

openjd-expr 0.7.0 -> 0.8.0, openjd-model 0.7.1 -> 0.8.0, and
openjd-sessions 0.5.8 -> 0.6.0 (openjd-rs release PR #395).

Six upstream changes land, reconciled against a source diff of the
published crates. The only new public API is two methods on
openjd_expr::FormatString, segment_count and literal_segments, which
the model crate's validator uses (#383). Both are now exposed on
openjd.expr.FormatString, with the stub and specs/python-expr-interface.md
updated. openjd-model and openjd-sessions have no public signature
changes; the two [breaking] changelog entries are behavioural.

Each change exercised through this package's API, v1 and v0 side by
side where both apply:

* openjd-rs#396 type-checks an `in`/`not in` item against the list's
  element type. `'a' in [1, 2]` now raises where it returned False.
  Int/float and path/string coercion kept; `x in []` is False for any x.
* openjd-rs#383 checks resolved-value constraints at template
  validation. A job name resolving to 129 characters, and a chunks
  defaultTaskCount naming an undeclared parameter, are now rejected at
  decode. v0 already rejected both. The whole-field chunks expression
  is resolved with target type int, so a STRING value fails inside the
  evaluator: test_chunk_default_task_count_invalid_int's message match
  moves from "not a valid integer" to "Cannot convert ... to int"; the
  exception class it pins is unchanged.
* openjd-rs#397: a single-valued allOf with one literal and one
  whole-field expression is now accepted at validation (0.7.1 rejected
  it) because the expression can null-skip, and job creation re-checks
  the resolved count. A control character in a resolved job name is
  rejected at create_job; 0.7.1 produced the job.
* openjd-rs#398 renders NONCONTIGUOUS chunks like the v0 reference:
  [1,2,4,6] is "1,2,4,6", not "1,2-6:2". Both paths agree on all four
  probed shapes.
* openjd-rs#384: preprocess_job_parameters accepts its own output for a
  LIST[PATH] parameter defaulting to []. 0.7.1 refused the second pass.
* openjd-rs#359 rejects embedded filenames ".", ".." and any containing
  a null byte at template validation. v0 accepts all three. The
  sessions-side check for Windows drive anchors ("C:", "D:relative") is
  not reachable from this repo's tests: the model layer accepts them
  and the check is Windows-only.

One test template was invalid and passed only because 0.7.1 did not
validate chunk fields: test_chunks_with_format_string_default_task_count
now declares the parameter it references.

Old-pins mutant: with the three pins reverted and the two new bindings
removed, 30 tests fail, all in the new or updated classes, and the
whole-field allOf deferral was measured as rejected on 0.7.1. Two new
cases (a tab in a literal run of an interpolated name, two certain
allOf elements) were already rejected on 0.7.1 and are labelled
controls.

THIRD-PARTY-LICENSES.txt regenerated; only the three crate versions
changed. Cargo.lock moved only those three packages.

Signed-off-by: David Leong <116610336+leongdl@users.noreply.github.com>
@leongdl
leongdl requested a review from a team as a code owner September 16, 2026 17:06
@leongdl leongdl closed this Sep 16, 2026
@leongdl leongdl reopened this Sep 16, 2026
@leongdl
leongdl enabled auto-merge (squash) September 16, 2026 18:41
@leongdl
leongdl merged commit 1d0cc51 into OpenJobDescription:mainline Sep 16, 2026
42 of 114 checks passed
@github-actions github-actions Bot mentioned this pull request Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants