feat(nickel): NickelEvaluator + LiveNickel + MockNickel — closes Plan §6.5#10
Merged
Conversation
…d_host
Plan §6.5 — first M1 Week 2 adapter probe path. The thinnest possible
shim around the `nickel` binary: argv-array subprocess invocation,
stdout capture, delegation to pearlite_schema::from_resolved_toml.
No Nickel parsing in Rust per Plan §6.5 hard rule.
Public surface (re-exported from lib.rs):
- pub trait NickelEvaluator { fn evaluate(&self, &Path) -> Result<String, NickelError>; }
- pub struct LiveNickel { binary: PathBuf }
- pub struct MockNickel — feature-gated behind test-mocks, in-memory
canned-output map BTreeMap<PathBuf, String>.
- pub fn load_host(host_file: &Path, eval: &dyn NickelEvaluator)
-> Result<DeclaredState, NickelError>.
- pub enum NickelError — NotInPath (hints `paru -S nickel-lang`),
Io, EvaluationFailed { code, stderr }, NotUtf8, Schema (transparent
to pearlite_schema::SchemaError), MockMissing.
LiveNickel:
- Default constructor resolves `nickel` from $PATH.
- with_binary() lets tests inject a known-good path.
- Spawn translates ErrorKind::NotFound to NickelError::NotInPath
with a runnable hint.
- Captures stderr verbatim; surfaces with exit code on non-zero.
CI:
- Add nickel-lang to taiki-e/install-action's tool list in T2 Unit so
the live tests actually exercise nickel rather than silent-skipping.
Tests (5 passing locally; live tests silent-skip when nickel isn't on
PATH — CI installs it so they exercise there):
- mock: canned_output_round_trips_to_declared_state.
- mock: missing_path_yields_mock_missing_error.
- live: nickel_not_in_path_error_class — pointed at a bogus path.
- live: version_probe_succeeds — nickel --version contains "nickel".
- live: minimal_host_evaluates — fixture host_minimal.ncl evaluates
to TOML that parses as DeclaredState.
Fixture: fixtures/nickel/host_minimal.ncl mirrors the schema fixture.
Cargo.toml: pearlite-schema dep pinned to "0.1" per the cargo-deny
wildcard rule (PR #9 precedent). New `test-mocks` feature.
Verification:
- cargo test -p pearlite-nickel (5 passed; 0 failed)
- cargo clippy --workspace --all-targets -- -D warnings (zero warnings)
- cargo fmt --all --check
- scripts/ci/check-spdx.sh
- pearlite-audit check . (1 check, 0 violations)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The library crate `nickel-lang` has no binaries; the CLI binary lives in the `nickel-lang-cli` crate. taiki-e/install-action's fallback to cargo-binstall correctly reported "no binaries specified" and failed the T2 Unit job. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
extractions/setup-just@v3 hit "no release for just matching version specifier" on every recent PR run — the action's default version resolution is broken. taiki-e/install-action is already used in every job for cargo tooling; adding `just` to its tool list is the consistent fix and avoids the second action entirely. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First M1 Week 2 adapter probe path. Thinnest possible shim around the
nickelbinary: argv-array subprocess invocation, stdout capture, delegation topearlite_schema::from_resolved_toml. No Nickel parsing in Rust per Plan §6.5 hard rule.Public surface
trait NickelEvaluator—evaluate(&self, &Path) -> Result<String, NickelError>.struct LiveNickel— production, defaultnickelfromPATH;with_binary()for test injection.struct MockNickel— feature-gated behindtest-mocks, in-memoryBTreeMap<PathBuf, String>.fn load_host(&Path, &dyn NickelEvaluator) -> Result<DeclaredState, NickelError>.enum NickelError—NotInPathcarries a runnable hint,EvaluationFailedcarries verbatim stderr,Schemais transparent topearlite-schema.CI
taiki-e/install-actionin the T2 Unit job now installsnickel-langso live tests actually exercise nickel rather than silent-skip.Tests (5 passing)
canned_output_round_trips_to_declared_state,missing_path_yields_mock_missing_errornickel_not_in_path_error_class,version_probe_succeeds,minimal_host_evaluatesLive tests silent-skip when nickel isn't on
PATH(dev convenience); CI installs nickel so they actually exercise.Verification
cargo test -p pearlite-nickel— 5 passed; 0 failedcargo clippy --workspace --all-targets -- -D warningscargo fmt --all --checkscripts/ci/check-spdx.shpearlite-audit check .— 1 check, 0 violations🤖 Generated with Claude Code