Skip to content

test(config): check the package files list with publint over npm's real pack list - #568

Merged
Vivswan merged 1 commit into
mainfrom
refactor/package-json-publint
Oct 27, 2026
Merged

Vivswan merged 1 commit into
mainfrom
refactor/package-json-publint

Conversation

@Vivswan

@Vivswan Vivswan commented Oct 26, 2026

Copy link
Copy Markdown
Owner

What this changes

isPacked: files entries read as literal paths, matched by equality or prefix
  ->  publint (pack: "npm") over a scratch package carrying the manifest and a stub at every file it points at,
      level warning, strict: the policy lint:package already runs

differential, old against publint over npm's real pack list, 14 manifests:
  real, plain, outside-files export or types, a glob missing its .d.ts, empty files, no trailing slash, parent dir   same verdict
  bin outside files, files as globs, ./-prefixed entries, a bare basename, a negation beside its directory          differ; each is npm's real behavior

How

  • npm packs bins whatever files says, so a bin outside files now passes where the old loop refused; a !lib/pkg/index.js beside lib/pkg/ is now refused where the prefix match let it through. The real manifest uses none of these.
  • The test pins npm as the packer because npm publishes the package; lint:package in CI auto-detects bun from the lockfile.
  • Library: publint 0.3.25, already a direct devDependency; withTempDir from the test helpers.

Proof

  • Tests: package-json 7 pass (two new: the real manifest yields no message, and an export outside files pins the FILE_NOT_PUBLISHED line); dropping lib/pkg/ from files fails with four such lines.
  • Gates: typecheck, fleet biome 0, member-shape 0, line cap.
Technical details
  • publint on the real manifest reports nothing at any level; on the unbuilt tree only FILE_DOES_NOT_EXIST for the six lib/pkg targets, which is why the test stubs them.
  • Runtime: about four seconds for the two npm pack --dry-run runs; npm comes from the runner image, as package-smoke already assumes.
  • Files: test/config/package-json.test.ts.

The package.json test asserted that every export target, declaration file, and bin was covered by the `files` list with a hand-rolled isPacked: each entry read as a literal file or directory, with or without a trailing slash, matched by equality or prefix. That loop is deleted. manifestMessages builds a scratch package through withTempDir holding the manifest and an empty stub at every file it points a consumer at (a bin stub carries the shebang publint requires), and runs publint's API with pack: "npm", so `npm pack --json --dry-run --ignore-scripts` computes the list npm would publish, at level warning with strict on, as lint:package runs it in the package-smoke job. The real manifest must produce no messages, and a negative control adds an export outside `files` and pins publint's FILE_NOT_PUBLISHED message for it. publint was already a direct devDependency, so nothing is added; manifestTargets now takes the manifest it reads and manifestDeclarations gathers the `types` paths the test collected inline.

Differential, the old loop against publint over npm's pack list, on 14 manifests: the real one and a plain hand-made one accept both ways; an export or a types target outside `files`, a glob that misses the declarations, and an empty `files` refuse both ways; `files` without the trailing slash, as the parent directory, or negating the bin accept both ways. Five differ, and in each npm's behavior is the answer: a bin outside `files` (the old loop refused it; npm always packs the files `bin` names), `files` as globs (refused; npm expands them), `./`-prefixed entries (refused; npm accepts them), an entry naming a file by its basename (refused; npm matches it at any depth), and a negated `!lib/pkg/index.js` beside `lib/pkg/` (the old loop accepted it through the directory prefix; npm excludes it, so it is now refused). The real manifest uses none of those shapes. Dropping `lib/pkg/` from `files` fails the new test with four FILE_NOT_PUBLISHED lines, the two export targets and their declarations; the bins stay absent because npm packs them regardless.

publint has nothing else to say about the real manifest at any level; on an unbuilt tree it reports only FILE_DOES_NOT_EXIST for the six lib/pkg targets, which is what the stubs stand in for. The test pins npm as the packer because npm publishes the package, where lint:package's auto-detection picks bun from bun.lock.
Copilot AI balanced review requested due to automatic review settings October 26, 2026 20:47
@github-actions

Copy link
Copy Markdown
Contributor

File size check

0 over a hard cap (fails), 6 warning(s).

File Size Tier Cap
src/engine/diff.ts:56 11 comment lines warn 10
src/github/api-error.ts:9 11 comment lines warn 10
src/problem.ts:73 18 comment lines warn 10
src/sections/contract/errors.ts:13 11 comment lines warn 10
src/sections/contract/module.ts:55 12 comment lines warn 10
src/sections/shared/list/decl.ts:265 14 comment lines warn 10

Split the file, wrap the line, shorten or exempt the comment, or list the path in .file-size-allow.local with a # reason.

5 managed file(s) skipped; repo-platform owns them.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused test-only changes preserve existing checks and verify an unpublished export, with no blocking defects identified.

No open issues 🎉

What changed in this PR

This PR checks package file inclusion using publint with npm's actual pack list, replacing literal path matching in the manifest tests.

Changes:

  • Creates a temporary package with stubbed export, declaration, and bin targets.
  • Runs publint with npm packing and strict warning checks.
  • Adds checks for the real manifest and an unpublished export while preserving existing manifest assertions.
File Description
test/​config/​package-json.test.ts Replaces the path-prefix packing check with publint and adds positive and negative packaging tests.

Review effort: Balanced

@Vivswan
Vivswan marked this pull request as ready for review October 26, 2026 20:52
@Vivswan
Vivswan merged commit 36a6cf0 into main Oct 27, 2026
29 checks passed
@Vivswan
Vivswan deleted the refactor/package-json-publint branch October 27, 2026 07:18
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.

2 participants