feat(reporter): emit pnpm:summary at install end#355
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #355 +/- ##
==========================================
- Coverage 88.57% 88.56% -0.01%
==========================================
Files 65 65
Lines 5784 5790 +6
==========================================
+ Hits 5123 5128 +5
- Misses 661 662 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Micro-Benchmark ResultsLinux |
Integrated-Benchmark Report (Linux)Scenario: Frozen Lockfile
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 2.7227958476,
"stddev": 0.06703708249889809,
"median": 2.7284134709999996,
"user": 2.4098531800000003,
"system": 3.456330659999999,
"min": 2.633259897,
"max": 2.851789528,
"times": [
2.851789528,
2.786657424,
2.761441812,
2.687807104,
2.645548513,
2.633259897,
2.72937372,
2.7348904700000003,
2.727453222,
2.669736786
]
},
{
"command": "pacquet@main",
"mean": 2.7135279850000003,
"stddev": 0.07690225338281903,
"median": 2.7084330795000002,
"user": 2.43763428,
"system": 3.420420059999999,
"min": 2.629276455,
"max": 2.835715241,
"times": [
2.719719038,
2.835715241,
2.657987537,
2.765786562,
2.8320093920000002,
2.629276455,
2.716581591,
2.638705617,
2.639213849,
2.7002845680000003
]
},
{
"command": "pnpm",
"mean": 6.6178745444,
"stddev": 0.06925407582807729,
"median": 6.606608444500001,
"user": 9.178740079999999,
"system": 4.524236859999999,
"min": 6.475539525,
"max": 6.7409299570000005,
"times": [
6.635538212,
6.587693888,
6.684639064000001,
6.612004158,
6.475539525,
6.5947488320000005,
6.647497704,
6.7409299570000005,
6.601212731,
6.598941373000001
]
}
]
}Scenario: Frozen Lockfile (Hot Cache)
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 0.74184535672,
"stddev": 0.042510642054007876,
"median": 0.7263425535200001,
"user": 0.24491543999999998,
"system": 1.40026908,
"min": 0.69881924502,
"max": 0.80652972302,
"times": [
0.80236694302,
0.80652972302,
0.79442062502,
0.70256237802,
0.69881924502,
0.72185363702,
0.73083147002,
0.73302961702,
0.7065464020200001,
0.72149352702
]
},
{
"command": "pacquet@main",
"mean": 0.7432855968200001,
"stddev": 0.061260900529532904,
"median": 0.71844345302,
"user": 0.25330324000000004,
"system": 1.3618994799999997,
"min": 0.69056219502,
"max": 0.8692366880200001,
"times": [
0.8692366880200001,
0.6930406920200001,
0.83963177002,
0.71643845102,
0.69056219502,
0.71410422202,
0.72044845502,
0.73650278502,
0.7440302980200001,
0.70886041202
]
},
{
"command": "pnpm",
"mean": 2.68102461442,
"stddev": 0.08217258816340818,
"median": 2.6661718920200004,
"user": 3.266750739999999,
"system": 2.2401537799999995,
"min": 2.56902871402,
"max": 2.83127277202,
"times": [
2.76526763402,
2.56902871402,
2.83127277202,
2.67055849302,
2.6063318510199998,
2.66178529102,
2.61411665702,
2.7583545270200003,
2.63817687402,
2.69535333102
]
}
]
} |
a6a2ab4 to
f8a4e47
Compare
bbd6d3e to
682bc70
Compare
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe changes extend the logging event schema by introducing a new Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Review rate limit: 8/10 reviews remaining, refill in 10 minutes and 53 seconds. Comment |
There was a problem hiding this comment.
Pull request overview
Adds the pnpm:summary reporting channel to the reporter wire format and emits it at the end of Install::run, aligning pacquet’s install lifecycle events more closely with pnpm so downstream pnpm-compatible reporters can render end-of-install summaries.
Changes:
- Added
LogEvent::Summary/SummaryLogtopacquet-reporterwithpnpm:summaryserde tagging. - Emitted
pnpm:summaryafterpnpm:stage importing_doneinInstall::run. - Extended reporter/unit tests and renamed/extended the package-manager integration test to assert the new 4-event sequence.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| crates/reporter/src/lib.rs | Adds pnpm:summary event variant + payload type for serialization. |
| crates/reporter/src/tests.rs | Adds a wire-shape test for the new summary event. |
| crates/package-manager/src/install.rs | Emits pnpm:summary at install end and updates the integration test to assert the full event sequence. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Adds the `PackageImportMethod` variant to `LogEvent` and emits it from `Install::run` after `pnpm:context`, before `pnpm:stage importing_started`. Mirrors pnpm's emit at https://github.com/pnpm/pnpm/blob/086c5e91e8/fs/indexed-pkg-importer/src/index.ts#L32. The wire-format enum has only `clone | hardlink | copy`; pacquet's `Npmrc::package_import_method` adds `Auto` and `CloneOrCopy`. Both collapse to `clone` because that's the optimistic path the upstream auto-importer attempts first. For the explicit `Hardlink` / `Copy` / `Clone` settings the wire value matches reality. A TODO at the emit site notes that the value should be re-derived after the first successful import once the fallback signal is surfaced past the per-package import path. While auditing this channel, also deferred `pnpm:stage resolution_started/done`: pacquet's no-lockfile flow interleaves resolution and import per dependency, so emitting `resolution_done` after import work has already happened would break the JS reporter's per-package state. Pick this back up once pacquet's no-lockfile flow gains a separate resolution pass. Frozen-lockfile installs (pacquet's primary path today) don't need these events anyway — pnpm itself skips them in `deps-restorer`. The deferral is recorded under #347. Tests: - New `package_import_method_event_matches_pnpm_wire_shape` in the reporter crate asserts every wire value renders correctly. - The install integration test grows to assert the five-event success sequence (Context, PackageImportMethod, ImportingStarted, ImportingDone, Summary) and spot-checks the wire mapping for the default `Auto` config (collapses to `Clone`). - Verified the test catches the regression by temporarily commenting out the new emit and confirming the failure shape, then restored. Refs #347. Engine: #345. Previous channel: #355.
Adds the `Summary` variant to `LogEvent` and emits it from `Install::run` immediately after `pnpm:stage importing_done`. Mirrors pnpm's emit at https://github.com/pnpm/pnpm/blob/086c5e91e8/installing/deps-installer/src/install/index.ts#L1663. The payload carries only `prefix`; the reporter combines this with the accumulated `pnpm:root` events (still TODO under #347) to render the final "+N -M" diff block. Test: extends the install integration test (renamed to `install_emits_pnpm_event_sequence` to match the growing scope) to assert the four-event success sequence (`Context`, `ImportingStarted`, `ImportingDone`, `Summary`) and spot-checks summary's `prefix`. Verified the test catches the regression by temporarily commenting out the emit and confirming it failed with a Summary-shaped gap. Refs #347. Engine: #345. Previous channel: #354.
Per review feedback on #355: the original wording said the `pnpm:summary` payload "is just `prefix`", which omitted the `level` field that's also part of the serialized record. `level` is the bunyan-envelope severity carried by every channel, not channel-specific to summary; say so explicitly so a reader doesn't try to "fix" the struct based on the comment. Same fix applied to the wire-shape test's doc comment.
682bc70 to
baaeb0b
Compare
Adds the `PackageImportMethod` variant to `LogEvent` and emits it from `Install::run` after `pnpm:context`, before `pnpm:stage importing_started`. Mirrors pnpm's emit at https://github.com/pnpm/pnpm/blob/086c5e91e8/fs/indexed-pkg-importer/src/index.ts#L32. The wire-format enum has only `clone | hardlink | copy`; pacquet's `Npmrc::package_import_method` adds `Auto` and `CloneOrCopy`. Both collapse to `clone` because that's the optimistic path the upstream auto-importer attempts first. For the explicit `Hardlink` / `Copy` / `Clone` settings the wire value matches reality. A TODO at the emit site notes that the value should be re-derived after the first successful import once the fallback signal is surfaced past the per-package import path. While auditing this channel, also deferred `pnpm:stage resolution_started/done`: pacquet's no-lockfile flow interleaves resolution and import per dependency, so emitting `resolution_done` after import work has already happened would break the JS reporter's per-package state. Pick this back up once pacquet's no-lockfile flow gains a separate resolution pass. Frozen-lockfile installs (pacquet's primary path today) don't need these events anyway — pnpm itself skips them in `deps-restorer`. The deferral is recorded under #347. Tests: - New `package_import_method_event_matches_pnpm_wire_shape` in the reporter crate asserts every wire value renders correctly. - The install integration test grows to assert the five-event success sequence (Context, PackageImportMethod, ImportingStarted, ImportingDone, Summary) and spot-checks the wire mapping for the default `Auto` config (collapses to `Clone`). - Verified the test catches the regression by temporarily commenting out the new emit and confirming the failure shape, then restored. Refs #347. Engine: #345. Previous channel: #355.
Adds the `PackageImportMethod` variant to `LogEvent` and emits it from `Install::run` after `pnpm:context`, before `pnpm:stage importing_started`. Mirrors pnpm's emit at https://github.com/pnpm/pnpm/blob/086c5e91e8/fs/indexed-pkg-importer/src/index.ts#L32. The wire-format enum has only `clone | hardlink | copy`; pacquet's `Npmrc::package_import_method` adds `Auto` and `CloneOrCopy`. Both collapse to `clone` because that's the optimistic path the upstream auto-importer attempts first. For the explicit `Hardlink` / `Copy` / `Clone` settings the wire value matches reality. A TODO at the emit site notes that the value should be re-derived after the first successful import once the fallback signal is surfaced past the per-package import path. While auditing this channel, also deferred `pnpm:stage resolution_started/done`: pacquet's no-lockfile flow interleaves resolution and import per dependency, so emitting `resolution_done` after import work has already happened would break the JS reporter's per-package state. Pick this back up once pacquet's no-lockfile flow gains a separate resolution pass. Frozen-lockfile installs (pacquet's primary path today) don't need these events anyway — pnpm itself skips them in `deps-restorer`. The deferral is recorded under #347. Tests: - New `package_import_method_event_matches_pnpm_wire_shape` in the reporter crate asserts every wire value renders correctly. - The install integration test grows to assert the five-event success sequence (Context, PackageImportMethod, ImportingStarted, ImportingDone, Summary) and spot-checks the wire mapping for the default `Auto` config (collapses to `Clone`). - Verified the test catches the regression by temporarily commenting out the new emit and confirming the failure shape, then restored. Refs #347. Engine: #345. Previous channel: #355.
Closes #346. Adds a "Reporter / log events" section to `CODE_STYLE_GUIDE.md` covering the convention for porting reporter emissions: - **Finding the upstream emit** — three call shapes to grep for in `pnpm/pnpm` (`globalLogger.<channel>.<level>(...)`, `logger.<level>({ name: 'pnpm:<channel>', ... })`, and direct `streamParser.write(...)` calls). - **Channel mapping** — `crates/reporter/src/lib.rs`'s `LogEvent` enum is the canonical list, with each variant pinning `#[serde(rename = "pnpm:<channel>")]`. Includes the convention for adding a new channel (mirror the upstream TS shape field-for-field, add a wire-shape unit test). - **Threading** — `<R: Reporter>` generic on every fn that emits, turbofish at the production entry point, install-scoped state via parameters where dedup matters (e.g. `link_file`'s `&AtomicU8`). - **Where to put the emit** — match the upstream call site's position relative to side effects; cite the upstream permalink at a pinned SHA in the code comment. - **Testing** — recording-fake DI per #339, a `static Mutex<Vec<LogEvent>>` per test, sequence assertion via `matches!`. Verify the test catches the regression. - **What not to do** — don't reformat upstream messages, don't invent channels, don't change emit granularity in either direction. - **Worked example** — `pnpm:summary` in `Install::run` (landed in #355): shows the upstream permalink, the pacquet emit, and the test that pins the sequence. Adds a sixth bullet to `AGENTS.md`'s cardinal rule pointing at the new section, so the "match pnpm" mandate explicitly covers log emissions.
A style guide should let a porter read it linearly without context-switching to GitHub. The four issue references (#345 for the reporter origin, #347 for the channel-backfill audit, #339 for the recording-fake pattern, #355 for the worked example's PR) were project history, not convention — none of them carried information the doc itself didn't already restate inline. Replace each with the concrete fact the reader needs: the reporter lives in `crates/reporter` (with its trait, enum, and sinks named in place); to add a new channel, do X, Y, Z (instead of "the work tracked under #347"); the recording-fake pattern is the unit-struct + static-mutex shape (described directly, no "from #339"); and the worked example is just the code, no "added in #355".
Summary
Second channel from the backfill (#347). Adds the
Summaryvariant toLogEventand emits it fromInstall::runafter the existingpnpm:stage importing_done.Mirrors pnpm's emit at
installing/deps-installer/src/install/index.ts:1663.The payload carries only
prefix; pnpm's reporter combines this withthe accumulated
pnpm:rootevents to render the final "+N -M" diffblock.
pnpm:rootis its own backfill item (still unchecked in #347),so today the summary is emitted but the diff block stays empty — same
as pnpm's behavior on a no-op install.
Stacked on #354 (
pnpm:context).Convention compliance
Per the per-PR conventions in #347:
LogEvent::Summarymirrors the upstream payload field-for-field.the pinned SHA (
086c5e91e8).emit, confirmed
unexpected event sequence: [Context, ImportingStarted, ImportingDone],restored.
pnpm:summarybox in chore(reporter): backfill missing log events in already-ported code #347 on merge.Drive-by rename
Renamed the install integration test from
install_emits_context_and_stage_eventstoinstall_emits_pnpm_event_sequence. The test now asserts four events(context, importing_started, importing_done, summary) and will keep
growing as more channels land at the install boundary
(
pnpm:package-manifest,pnpm:stats, etc.). A stable name avoidschurn in subsequent PRs.
Test plan
cargo nextest run -p pacquet-reporter— 6 tests, including thenew
summary_event_matches_pnpm_wire_shape.cargo nextest run -p pacquet-package-manager install_emits_pnpm_event_sequence— passes; full sequence and summary's prefix spot-checked.
just ready— 255 tests pass, lint clean.pacquet install --reporter=ndjsonemits apnpm:summaryline after the closingpnpm:stageline.References
pnpm:context): feat(reporter): emit pnpm:context at install start #354.core/core-loggers/src/summaryLogger.ts.installing/deps-installer/src/install/index.ts:1663.Summary by CodeRabbit
New Features
Tests