mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-20 20:52:33 -04:00
f9b14b15ec4061b40bceff1f5ffeceb34b750313
Completes pacquet#397 item 5. Slice A+B's PR #425 moved `AllowBuildPolicy` off `package.json` onto `pnpm-workspace.yaml`; this commit ports the second half of upstream's matcher — the `expandPackageVersionSpecs` step that lets users write keys like `foo@1.0.0 || 2.0.0` in their `allowBuilds` map. ## What this adds New `pacquet_package_manager::version_policy` module porting [`config/version-policy/src/index.ts`](https://github.com/pnpm/pnpm/blob/b4f8f47ac2/config/version-policy/src/index.ts) at commit `b4f8f47ac2`. `expand_package_version_specs` parses each `allowBuilds` key into one or more `name` / `name@version` literal strings: - `foo` → `{"foo"}` - `foo@1.0.0` → `{"foo@1.0.0"}` - `foo@1.0.0 || 2.0.0` → `{"foo@1.0.0", "foo@2.0.0"}` - `@scope/foo@1.0.0` → `{"@scope/foo@1.0.0"}` Two error codes mirror upstream: - `ERR_PNPM_INVALID_VERSION_UNION` when a `||` member isn't valid semver - `ERR_PNPM_NAME_PATTERN_IN_VERSION_UNION` when a `*` wildcard in the name is combined with a version part Whitespace around `||` and within each version is trimmed before parsing, matching Node-semver's `valid()`. ## What this does NOT add Wildcards in the name (`is-*`, `@scope/*`) are accepted by the parser and land in the expanded set as literal strings, but `HashSet::contains` lookups mean they never match real package names. Mirrors upstream's `'should not allow patterns in allowBuilds'` test at [`building/policy/test/index.ts:28-34`](https://github.com/pnpm/pnpm/blob/b4f8f47ac2/building/policy/test/index.ts#L28-L34) — the original #397 audit incorrectly claimed `@scope/*` should work in `allowBuilds`; it doesn't, neither upstream nor here. `createPackageVersionPolicy` (which DOES support wildcards via `Matcher`) is a separate upstream function used by `minimumReleaseAgeExclude` / `dlx` — pacquet doesn't have those features yet. ## AllowBuildPolicy refactor `AllowBuildPolicy`'s internal storage changes from `HashMap<String, bool>` to two `HashSet<String>` (`expanded_allowed` and `expanded_disallowed`), populated through `expand_package_version_specs`. The `check` function checks `disallowed` before `allowed`, both against bare `name` and `name@version`, mirroring upstream's order at [`building/policy/src/index.ts:35-44`](https://github.com/pnpm/pnpm/blob/b4f8f47ac2/building/policy/src/index.ts#L35-L44). This fixes a pre-existing pacquet divergence: the old matcher checked exact-version first, then bare name. With upstream's order, a bare-name disallow now correctly wins over an exact-version allow. New `disallow_bare_name_wins_over_allow_exact_version` test pins the behavior; the old `exact_version_takes_precedence` test was removed (it asserted the divergent behavior). `AllowBuildPolicy::new` now takes the expanded sets directly (pure constructor — no IO). `AllowBuildPolicy::from_config` returns `Result<Self, VersionPolicyError>` so spec-parse failures surface at install time instead of being silently dropped. New `InstallFrozenLockfileError::VersionPolicy` variant propagates the error. ## Tests - 12 new tests in `version_policy::tests` covering: bare name, exact version, version union, scoped names, whitespace trimming in unions, name-with-wildcard-alone (literal), invalid version union (error), mixed valid/invalid (error), wildcard-with-version (error), empty input, duplicate collapse. - Ports of upstream's `building/policy/test/index.ts` cases: `allow_via_version_union` (version-union allows), `wildcard_name_in_allow_builds_does_not_match_real_package` (wildcards inert), `disallow_bare_name_wins_over_allow_exact_version` (matcher order), `disallow_exact_version_with_allow_bare_name` (converse). - `from_config` error-propagation tests for both `VersionPolicyError` variants. 598 tests pass; `just ready`, `just dylint`, `cargo doc -D warnings --document-private-items`, `taplo format --check` all clean.
Description
Languages
Rust
61.8%
TypeScript
37.7%
JavaScript
0.4%