Skip to content

fix(wrapper-generator): make the parity-data refresh runnable, and refresh it - #3745

Open
Joywambui-maina wants to merge 4 commits into
feat/wrapper-deltafrom
feat/wrapper-parity-data
Open

fix(wrapper-generator): make the parity-data refresh runnable, and refresh it#3745
Joywambui-maina wants to merge 4 commits into
feat/wrapper-deltafrom
feat/wrapper-parity-data

Conversation

@Joywambui-maina

Copy link
Copy Markdown

Changes proposed:

-Point Derive-ParityResolutions.ps1 and Invoke-WrapperGates.ps1 at the committed corpus. Both read //src/Cmdlets under artifacts/wrapper-modules — a layout superseded when the corpus moved under src//wrapper/ — so neither found a single module
-Make cmdlet-name collisions fatal only while the derived data is in use. Under --no-collision-data the collisions are the intended output, so throwing there made the documented capture procedure impossible: the derivation asked for a tree the generator refused to produce
-Stop passing -Configuration to Test-WrapperModule.ps1, which has no such parameter — the runtime gate errored on every run that reached the call
-Add -NoCollisionData and -GenerateOnly to Build-WrapperModule.ps1 for isolated capture, and Update-WrapperParityData.ps1 to orchestrate the refresh end to end
-Refresh the derived data itself: input ledger 13,946 → 14,001 rows, renames 1,726 → 2,126, suppressions 2,268 → 2,658, resolution ledger 10,928 → 12,588, with 27 deferred

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the wrapper-generator tooling so parity/collision-derived data can be regenerated against the committed wrapper corpus layout (src/<Module>/wrapper/<ApiVersion>/...) and adds an end-to-end refresh script that runs generation + derivation in an isolated git worktree.

Changes:

  • Make cmdlet-name collisions fatal only when collision data is enabled, and non-fatal (logged) under --no-collision-data to allow inventory capture runs.
  • Update wrapper gate + parity derivation scripts to read from the committed corpus layout and avoid hard-coded framework/output paths.
  • Add Update-WrapperParityData.ps1 plus new Build-WrapperModule.ps1 switches (-NoCollisionData, -GenerateOnly) to orchestrate a clean refresh.

Reviewed changes

Copilot reviewed 5 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tools/WrapperGenerator/PowerShellWrapperGenerationService.cs Makes collisions non-fatal when collision data is disabled; adds structured logging for raw collision inventory.
tools/Update-WrapperParityData.ps1 New orchestrator script: snapshots current tracked state, generates unresolved corpus in an isolated worktree, derives parity data, and publishes outputs.
tools/Invoke-WrapperGates.ps1 Updates gates to read committed corpus layout, adds -ApiVersion, and removes invalid -Configuration pass-through to Test-WrapperModule.ps1.
tools/Derive-ParityResolutions.ps1 Updates default/capture paths to the committed corpus layout (src/<Module>/wrapper/<ApiVersion>/Cmdlets).
tools/Build-WrapperModule.ps1 Adds -NoCollisionData and -GenerateOnly; supports parity/collision capture workflows and prevents -GenerateOnly + -Pack.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tools/Build-WrapperModule.ps1
Refreshing the derived parity data was impossible for three independent
reasons. Derive-ParityResolutions.ps1 and Invoke-WrapperGates.ps1 both read
modules from <root>/<Module>/src/Cmdlets under artifacts/wrapper-modules, a
layout superseded when the corpus moved under src/<Module>/wrapper/<version>,
so neither found a single module. The capture the derivation documents needs
a --no-collision-data tree, but the generator threw on cmdlet name collisions
unconditionally - and those collisions are that mode's entire output, so the
procedure asked for a tree the generator refused to produce. And the runtime
gate passed -Configuration to Test-WrapperModule.ps1, which has no such
parameter, so it errored out once it could reach the call at all. Collisions
are now fatal only while the derived data is in use; the gates read the
committed corpus through one shared discovery helper instead of four globs
that drifted apart; Build-WrapperModule.ps1 gains -NoCollisionData and
-GenerateOnly for isolated capture; and Update-WrapperParityData.ps1
orchestrates the refresh end to end. Verified: discovery finds 38 modules
where it found 0, and --no-collision-data exits 0 where it exited 127 while
still reporting every collision.
The checked-in data described a corpus several generator changes old: 14 rows
referenced files that no longer generate, one generated file had no row, and
five sat in a disposition the gate can no longer produce. Recaptured from an
isolated --no-collision-data worktree so the raw, unresolved command surface
is what gets swept - sweeping the resolved tree re-derives "nothing to fix"
and would have discarded most of the data. Input ledger 13,946 to 14,001
rows, renames 1,726 to 2,126, suppressions 2,268 to 2,658, resolution ledger
10,928 to 12,588, with 27 deferred (17 cross-path, 10 cross-path merge).
Byte-for-byte derivation validation passes and the runtime gate passes on
38 of 38 freshly packed modules with no stale packages.

@peombwa Peter Ombwa (peombwa) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a tools/README.md documenting:

  1. The dependency between scripts.
  2. The proposed workflow. How should the scripts be used? Think of it like a scenario guide.

…ata run

With -NoCollisionData the generator reports each cmdlet collision instead of
throwing, and that report IS the collision inventory: data/collision-inventory
is captured from it and Derive-CollisionResolutions.ps1 reads it. The output was
only inspected on failure and discarded otherwise, so the one run whose purpose
is to produce the inventory printed nothing and the capture had to be done by
invoking the generator directly. Written to the host, not the pipeline, because
Build-Module returns $result and emitted output would be merged into it.
The 13 wrapper scripts had no entry point: which one to run, what each reads
and writes, and which outputs feed which other script were only discoverable by
reading all of them. Documents the dependency chain and the tasks people
actually do - regenerate after a generator change, package for a tester, chase
a parity failure, refresh derived data, run the gates before a PR.

Calls out the two dependencies that are easy to miss: the collision inventory
is captured from a -NoCollisionData run rather than hand-written, and the
parity derivation invokes the parity gate rather than re-implementing its
oracle join. Scopes itself to the wrapper toolchain; the AutoRest v2 scripts in
the same directory are driven from build.proj and are not covered.
@Joywambui-maina

Joywambui-maina commented Aug 26, 2026

Copy link
Copy Markdown
Author

Added in 2bf5417 - tools/README.md.

Dependencies. A table of all 13 wrapper scripts with what each reads and writes, plus a diagram of how the outputs chain. It calls out the two that are easy to miss:

  • data/collision-inventory.<ver>.txt is captured from a Build-WrapperModule.ps1 -NoCollisionData run, not hand-written, and Derive-CollisionResolutions.ps1 reads that file.
  • Derive-ParityResolutions.ps1 -CaptureInput invokes Compare-WrapperCmdletNames.ps1 per module rather than re-implementing its oracle join, so the gate and the derivation cannot drift.

Workflow, as scenarios. Six of them: seeing what a generator change did to the output, trying a module, producing a package a tester can install, chasing a naming-parity failure, refreshing derived data, and what to run before opening a PR (with the eight gates listed in order and what each proves).

Scoped to the wrapper toolchain and says so at the top - the other 26 scripts in tools/ are the AutoRest v2 pipeline driven from build.proj, and I did not want to document those from guesswork.

Every script name, parameter and path in it is checked against the branch: 13 scripts exist, 12 documented parameters all resolve against the real parameter sets, and the Import-Module path was confirmed by building Mail and finding the psd1 where the doc says it lands.

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.

3 participants