1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
//! Fast compile-fail and compile-pass testing for Rust proc macros.
//!
//! `lihaaf` is a `trybuild`-style test harness optimized for quick iteration.
//! It is designed for proc-macro crates that need many compile-pass and
//! compile-fail fixtures without paying unnecessary rebuild overhead.
//!
//! `lihaaf` ("quilt"; Urdu and Punjabi, also written ਲਿਹਾਫ਼ in Gurmukhi)
//! compiles the consumer crate once as a dynamic
//! library, then runs each fixture as a standalone `rustc` invocation that
//! links the prebuilt dylib via `--extern`. In many real projects this is the
//! difference between waiting forever and getting quick feedback.
//!
//! ## Public surface
//!
//! The exposed surface is intentionally CLI-shaped:
//!
//! - The `cargo-lihaaf` binary (Cargo subcommand convention; invoked as
//! `cargo lihaaf [OPTIONS]`).
//! - `[package.metadata.lihaaf]` schema in the consumer's `Cargo.toml`
//! (see [`config::Config`]).
//! - Verdict catalog (see [`verdict::Verdict`]) and exit codes
//! (see [`exit::ExitCode`]).
//! - A small set of crate-root re-exports for adopters who do want to
//! drive lihaaf from Rust: [`Cli`], [`Config`], [`Verdict`],
//! [`ExitCode`], [`Error`], [`Outcome`], [`run`], [`Report`].
//! - **Compat mode** (`cargo lihaaf --compat`): a migration workflow for
//! trybuild fixture corpora that generates a deterministic JSON comparison
//! envelope. The compat mode Rust API surface is intentionally
//! `#[doc(hidden)]`; the supported entry is always the CLI.
//!
//! All other modules are `pub(crate)` and may evolve freely across
//! v0.1.x point releases. Adopters who want to drive lihaaf from Rust
//! today should prefer the crate-root re-exports above (or
//! subprocess-spawn `cargo lihaaf`); the internal module paths are not
//! part of any v0.1 stability contract.
//!
//! ## What lives where
//!
//! | Module | Responsibility |
//! |---|---|
//! | [`cli`] | `clap` argument parsing, flag-to-action mapping. |
//! | [`config`] | Parse + validate `[package.metadata.lihaaf]`. |
//! | `toolchain` | Capture `rustc --version --verbose` for drift checks. (pub(crate)) |
//! | `dylib` | `cargo rustc --crate-type=dylib` invocation, copy mechanic. (pub(crate)) |
//! | `suite_workspace` | Opted-in staged Cargo workspace that builds fixture `dev_deps` beside the dylib. (pub(crate)) |
//! | `manifest` | `target/lihaaf/manifest.json` schema + atomic write. (pub(crate)) |
//! | `freshness` | Per-dispatch the policy invariant re-check (mtime / SHA-256 / rustc). (pub(crate)) |
//! | `lock` | Session-wide advisory file lock on `target/lihaaf/.session.lock`. (pub(crate)) |
//! | `discovery` | Walk `fixture_dirs`, classify pass/fail, sort. (pub(crate)) |
//! | `worker` | Per-fixture `rustc` spawn, RSS sampling, OOM, timeout. (pub(crate)) |
//! | `normalize` | Stderr normalization (fixed-string, byte-level). (pub(crate)) |
//! | `diff` | Hand-rolled Myers diff with line granularity. (pub(crate)) |
//! | `snapshot` | `.stderr` file I/O + `--bless` semantics. (pub(crate)) |
//! | [`verdict`] | Per-fixture verdict + session reporter. |
//! | [`exit`] | Exit-code mapping per the policy. |
//! | `session` | Lifecycle orchestration (stages 1–9 of the policy). (pub(crate)) |
//! | `error` | Crate-wide error type. (pub(crate)) |
//! | `util` | Atomic file write + sha256 helpers. (pub(crate)) |
// A practical constraint: no regex engine in this crate. The dependency
// surface stays small via fixed-string handling and a tight normalization
// pass. Enforcement is convention + dependency checks in CI.
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
// Crate-root re-exports — the v0.1 stable Rust callable surface.
//
// `Outcome` is re-exported alongside `Error` because `Error::Session(Outcome)`
// is a public variant of `Error`; Rust requires every type appearing in a
// public enum's variants to be at least as visible as the enum itself
// (E0446). Re-exporting `Outcome` ratifies that surface explicitly.
pub use Cli;
pub use Config;
pub use ;
pub use ExitCode;
pub use ;
pub use Verdict;
// Compat-mode entry point. Re-exported because the
// `cargo-lihaaf` binary lives in a separate crate (`src/bin/`) and
// cannot reach `pub(crate)` items directly. Adopters should NOT
// drive compat mode from Rust; the supported entry is `cargo lihaaf
// --compat`. The Rust surface here exists for the binary and for
// future integration tests; the path and signature are not part of
// any v0.1 stability contract.
pub use CompatArgs;
pub use run as run_compat;
// Compat-mode overlay helper for integration tests. Hidden re-export;
// not part of the supported v0.1 Rust API.
//
// Only `materialize_overlay` is re-exported because that is what the
// integration tests exercise; the canonicalizer, key-order helper, and
// serializer are unit-tested inline within `src/compat/overlay.rs`.
// `compat::run` reaches them through `crate::compat::overlay::*`, not
// through a crate-root re-export.
pub use materialize_overlay as compat_overlay_materialize;
// Workspace-member compat helpers for integration tests. Hidden
// re-exports; the supported entry to compat mode is
// `cargo lihaaf --compat`.
pub use WorkspaceMemberContext as CompatWorkspaceMemberContext;
pub use materialize_overlay_with_metadata_and_workspace_member_context as compat_overlay_materialize_with_metadata_and_workspace_member_context;
pub use resolve_workspace_member_manifest as compat_resolve_workspace_member_manifest;
// Compat-mode baseline runner for integration tests. Hidden re-export;
// not part of the supported v0.1 Rust API.
pub use BaselineResult as CompatBaselineResult;
pub use run_baseline as compat_baseline_run;
// Compat-mode conservative trybuild baseline extraction for integration
// tests. Hidden re-exports; the supported entry to compat mode is
// `cargo lihaaf --compat`.
pub use BaselineMismatch as CompatBaselineMismatch;
pub use BaselineVerdict as CompatBaselineVerdict;
pub use FixtureId as CompatFixtureId;
pub use ParsedBaseline as CompatParsedBaseline;
pub use parse_libtest_output as compat_parse_libtest_output;
pub use run_baseline_with_recognized_fixtures as compat_baseline_run_with_recognized_fixtures;
// Compat-mode fixture-invocation discovery (§3.2.1 of the
// compatibility plan). Re-exported for the same reason as the overlay
// above — `tests/compat/discovery_syn.rs` lives in a separate test
// crate and reaches the discovery types through these `#[doc(hidden)]`
// re-exports. The stability contract is the same: NOT part of any
// v0.1 surface; the supported entry to compat mode is `cargo lihaaf
// --compat`. `compat::run` consumes `discover` directly via the
// in-crate path; the re-exports exist for the integration test crate.
pub use CallSite as CompatDiscoveryCallSite;
pub use DiscoveredFixture as CompatDiscoveredFixture;
pub use DiscoveryOutput as CompatDiscoveryOutput;
pub use DiscoveryUnrecognized as CompatDiscoveryUnrecognized;
pub use FixtureKind as CompatFixtureKind;
pub use discover as compat_discover;
// Compat-mode dirty-worktree cleanup. Re-exported for the same reason
// as the overlay above — `tests/compat/cleanup_dirty_worktree.rs` lives
// in a separate test crate and reaches the cleanup types through these
// `#[doc(hidden)]` re-exports. The stability contract is the same: NOT
// part of any v0.1 surface; the supported entry to compat mode is
// `cargo lihaaf --compat`.
//
// `install_panic_hook` is re-exported alongside the guard types
// because `compat::run` calls it and integration tests may need to
// drive it directly (in a child process so the process-wide hook does
// not perturb libtest's panic capture in the outer test runner).
pub use CleanupGuard as CompatCleanupGuard;
pub use GeneratedPath as CompatGeneratedPath;
pub use GeneratedPathClass as CompatGeneratedPathClass;
pub use install_panic_hook as compat_install_panic_hook;
// Compat-mode normalizer flag plumbing (§3.2.2 of the compatibility
// plan). Re-exported for the same reason as the other compat surfaces
// above — `tests/compat/normalizer_compat_cargo.rs` lives in a
// separate test crate and reaches the public `NormalizationContext` /
// `normalize` entry points through these `#[doc(hidden)]` re-exports.
// The stability contract is the same: NOT part of any v0.1 surface;
// the supported entry to compat mode is `cargo lihaaf --compat`.
pub use ;
// Compat-mode §3.3 deterministic envelope. Re-exported for the same
// reason as the other compat surfaces above —
// `tests/compat/report_determinism.rs` lives in a separate test crate
// and reaches the envelope struct + writer through these
// `#[doc(hidden)]` re-exports. The stability contract is the same:
// NOT part of any v0.1 surface; the supported entry to compat mode
// is `cargo lihaaf --compat`. `compat::run` consumes `write_envelope`
// directly via the in-crate path; the re-exports exist for the
// integration test crate and out-of-tree CI runners.
pub use BaselineCounts as CompatBaselineCounts;
pub use Commands as CompatCommands;
pub use CompatEnvelope;
pub use EnvelopeError as CompatEnvelopeError;
pub use ExcludedFixture as CompatExcludedFixture;
pub use GeneratedPath as CompatEnvelopeGeneratedPath;
pub use LihaafCounts as CompatLihaafCounts;
pub use MismatchExample as CompatMismatchExample;
pub use OverlayMetadata as CompatOverlayMetadata;
pub use Results as CompatResults;
pub use canonicalize as compat_canonicalize_envelope;
pub use generated_path_from_cleanup as compat_envelope_generated_path_from_cleanup;
pub use normalize_error_detail_paths as compat_normalize_error_detail_paths;
pub use write_envelope as compat_write_envelope;
// Compat-mode §5 pilot gate. Re-exported for the gate_smoke integration
// test crate and for the (future) CI runner that invokes the gate
// against an envelope artifact. Not part of any v0.1 stability contract.
pub use Ceiling as CompatGateCeiling;
pub use GateOutcome as CompatGateOutcome;
pub use check_gate as compat_check_gate;
pub use load_baseline as compat_load_baseline;
pub use parse_baseline as compat_parse_baseline;
// Compat-mode §3.4 active-toolchain capture. Re-exported for the same
// reason as the other compat surfaces above —
// `tests/compat/toolchain_resolution.rs` lives in a separate test crate
// and reaches the capture entry point + its internal "swap the program
// name" variant through these `#[doc(hidden)]` re-exports. The
// stability contract is the same: NOT part of any v0.1 surface; the
// supported entry to compat mode is `cargo lihaaf --compat`.
// `compat::run` calls `capture_active_toolchain` directly through
// `crate::compat::rustup::*`, not through this re-export.
pub use capture_active_toolchain as compat_capture_active_toolchain;
pub use capture_with_program as compat_capture_with_program;
/// The semver-stable lihaaf release the binary identifies as.
///
/// This is the value that lands in `manifest.json`'s `lihaaf_version`
/// field. It must track `Cargo.toml`'s `package.version` exactly. Tests
/// pin the value so a forgotten bump fails CI rather than shipping a
/// stale stamp.
pub const VERSION: &str = env!;
/// Self-test marker for the multi-suite end-to-end corpus. Exposed
/// only when the `suite_demo` Cargo feature is enabled — the named
/// `[[package.metadata.lihaaf.suite]]` entry in this crate's own
/// `Cargo.toml` enables that feature for its dedicated fixture
/// directory, and the `tests/lihaaf/compile_pass_suite_demo/`
/// fixture references this const. If feature propagation regresses
/// (the dylib build skips the feature, or the per-fixture rustc
/// invocation drops `--cfg feature="suite_demo"`), the fixture
/// fails to link with `unresolved import lihaaf::SUITE_DEMO_MARKER`
/// and lihaaf's own CI run fails — the test case bites without
/// needing a downstream adopter.
///
/// Not part of any public API contract.
pub const SUITE_DEMO_MARKER: &str = "lihaaf::SUITE_DEMO_MARKER";