putitoutthere 0.3.17 → 0.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/check/check-cargo-shape-findings.d.ts +4 -0
  2. package/dist/check/check-cargo-shape-findings.d.ts.map +1 -0
  3. package/dist/check/check-cargo-shape-findings.js +10 -0
  4. package/dist/check/check-cargo-shape-findings.js.map +1 -0
  5. package/dist/check/check-crates-package-metadata.d.ts +4 -0
  6. package/dist/check/check-crates-package-metadata.d.ts.map +1 -0
  7. package/dist/check/check-crates-package-metadata.js +11 -0
  8. package/dist/check/check-crates-package-metadata.js.map +1 -0
  9. package/dist/check/check-depends-on.d.ts +4 -0
  10. package/dist/check/check-depends-on.d.ts.map +1 -0
  11. package/dist/check/check-depends-on.js +13 -0
  12. package/dist/check/check-depends-on.js.map +1 -0
  13. package/dist/check/check-globs-match-tracked-files.d.ts +4 -0
  14. package/dist/check/check-globs-match-tracked-files.d.ts.map +1 -0
  15. package/dist/check/check-globs-match-tracked-files.js +18 -0
  16. package/dist/check/check-globs-match-tracked-files.js.map +1 -0
  17. package/dist/check/check-npm-repository.d.ts +4 -0
  18. package/dist/check/check-npm-repository.d.ts.map +1 -0
  19. package/dist/check/check-npm-repository.js +14 -0
  20. package/dist/check/check-npm-repository.js.map +1 -0
  21. package/dist/check/check-npm-target-triples.d.ts +4 -0
  22. package/dist/check/check-npm-target-triples.d.ts.map +1 -0
  23. package/dist/check/check-npm-target-triples.js +27 -0
  24. package/dist/check/check-npm-target-triples.js.map +1 -0
  25. package/dist/check/check-package-json-shape-findings.d.ts +4 -0
  26. package/dist/check/check-package-json-shape-findings.d.ts.map +1 -0
  27. package/dist/check/check-package-json-shape-findings.js +10 -0
  28. package/dist/check/check-package-json-shape-findings.js.map +1 -0
  29. package/dist/check/check-paths.d.ts +4 -0
  30. package/dist/check/check-paths.d.ts.map +1 -0
  31. package/dist/check/check-paths.js +13 -0
  32. package/dist/check/check-paths.js.map +1 -0
  33. package/dist/check/check-pypi-version.d.ts +4 -0
  34. package/dist/check/check-pypi-version.d.ts.map +1 -0
  35. package/dist/check/check-pypi-version.js +11 -0
  36. package/dist/check/check-pypi-version.js.map +1 -0
  37. package/dist/check/check-pyproject-and-bundle-cli.d.ts +4 -0
  38. package/dist/check/check-pyproject-and-bundle-cli.d.ts.map +1 -0
  39. package/dist/check/check-pyproject-and-bundle-cli.js +52 -0
  40. package/dist/check/check-pyproject-and-bundle-cli.js.map +1 -0
  41. package/dist/check/check-pyproject-shape-findings.d.ts +4 -0
  42. package/dist/check/check-pyproject-shape-findings.d.ts.map +1 -0
  43. package/dist/check/check-pyproject-shape-findings.js +10 -0
  44. package/dist/check/check-pyproject-shape-findings.js.map +1 -0
  45. package/dist/check/check-repo-url-match-findings.d.ts +4 -0
  46. package/dist/check/check-repo-url-match-findings.d.ts.map +1 -0
  47. package/dist/check/check-repo-url-match-findings.js +17 -0
  48. package/dist/check/check-repo-url-match-findings.js.map +1 -0
  49. package/dist/check/check-tag-template-collisions.d.ts +4 -0
  50. package/dist/check/check-tag-template-collisions.d.ts.map +1 -0
  51. package/dist/check/check-tag-template-collisions.js +22 -0
  52. package/dist/check/check-tag-template-collisions.js.map +1 -0
  53. package/dist/check/collect-bins-from-manifest.d.ts +2 -0
  54. package/dist/check/collect-bins-from-manifest.d.ts.map +1 -0
  55. package/dist/check/collect-bins-from-manifest.js +27 -0
  56. package/dist/check/collect-bins-from-manifest.js.map +1 -0
  57. package/dist/check/list-tracked-files.d.ts +2 -0
  58. package/dist/check/list-tracked-files.d.ts.map +1 -0
  59. package/dist/check/list-tracked-files.js +11 -0
  60. package/dist/check/list-tracked-files.js.map +1 -0
  61. package/dist/check/parse-cargo-toml.d.ts +2 -0
  62. package/dist/check/parse-cargo-toml.d.ts.map +1 -0
  63. package/dist/check/parse-cargo-toml.js +11 -0
  64. package/dist/check/parse-cargo-toml.js.map +1 -0
  65. package/dist/check/read-declared-bins.d.ts +2 -0
  66. package/dist/check/read-declared-bins.d.ts.map +1 -0
  67. package/dist/check/read-declared-bins.js +33 -0
  68. package/dist/check/read-declared-bins.js.map +1 -0
  69. package/dist/check/workspace-member-manifests.d.ts +2 -0
  70. package/dist/check/workspace-member-manifests.d.ts.map +1 -0
  71. package/dist/check/workspace-member-manifests.js +23 -0
  72. package/dist/check/workspace-member-manifests.js.map +1 -0
  73. package/dist/check.d.ts +6 -5
  74. package/dist/check.d.ts.map +1 -1
  75. package/dist/check.js +21 -307
  76. package/dist/check.js.map +1 -1
  77. package/dist/handlers/classify-npm-view-failure.d.ts +35 -0
  78. package/dist/handlers/classify-npm-view-failure.d.ts.map +1 -0
  79. package/dist/handlers/classify-npm-view-failure.js +77 -0
  80. package/dist/handlers/classify-npm-view-failure.js.map +1 -0
  81. package/dist/handlers/crates.d.ts +6 -4
  82. package/dist/handlers/crates.d.ts.map +1 -1
  83. package/dist/handlers/crates.js +18 -6
  84. package/dist/handlers/crates.js.map +1 -1
  85. package/dist/handlers/npm.d.ts.map +1 -1
  86. package/dist/handlers/npm.js +37 -6
  87. package/dist/handlers/npm.js.map +1 -1
  88. package/dist/write-dependent-version-reqs.d.ts +50 -0
  89. package/dist/write-dependent-version-reqs.d.ts.map +1 -0
  90. package/dist/write-dependent-version-reqs.js +158 -0
  91. package/dist/write-dependent-version-reqs.js.map +1 -0
  92. package/package.json +1 -1
@@ -0,0 +1,23 @@
1
+ import { dirname, join } from 'node:path';
2
+ import { expandDirGlob } from '../glob.js';
3
+ export async function workspaceMemberManifests(parsed, cargoTomlPath) {
4
+ const workspace = parsed.workspace;
5
+ if (typeof workspace !== 'object' || workspace === null) {
6
+ return [];
7
+ }
8
+ const members = workspace.members;
9
+ if (!Array.isArray(members)) {
10
+ return [];
11
+ }
12
+ const workspaceDir = dirname(cargoTomlPath);
13
+ const out = [];
14
+ for (const m of members) {
15
+ if (typeof m === 'string') {
16
+ for (const memberDir of await expandDirGlob(workspaceDir, m)) {
17
+ out.push(join(memberDir, 'Cargo.toml'));
18
+ }
19
+ }
20
+ }
21
+ return out;
22
+ }
23
+ //# sourceMappingURL=workspace-member-manifests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-member-manifests.js","sourceRoot":"","sources":["../../src/check/workspace-member-manifests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAA+B,EAC/B,aAAqB;IAErB,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACnC,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QAAA,OAAO,EAAE,CAAC;IAAA,CAAC;IACrE,MAAM,OAAO,GAAI,SAAmC,CAAC,OAAO,CAAC;IAC7D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAAA,OAAO,EAAE,CAAC;IAAA,CAAC;IACzC,MAAM,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,KAAK,MAAM,SAAS,IAAI,MAAM,aAAa,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC7D,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
package/dist/check.d.ts CHANGED
@@ -6,11 +6,12 @@
6
6
  * consumer's repo state alone runs at PR time, before a release run
7
7
  * could fail mid-publish on a precondition checkable in milliseconds.
8
8
  *
9
- * Each check function returns findings; the top-level `runChecks`
10
- * aggregates them so the consumer fixes everything in one round-trip
11
- * rather than chasing one error at a time across re-runs. `require-`
12
- * style throwing helpers live in `preflight.ts` for the publish path;
13
- * this file is read-only diagnostic.
9
+ * Each check function (one per module under `check/`) returns
10
+ * findings; the top-level `runChecks` aggregates them so the consumer
11
+ * fixes everything in one round-trip rather than chasing one error at
12
+ * a time across re-runs. `require-` style throwing helpers live in
13
+ * `preflight.ts` for the publish path; this entry point is read-only
14
+ * diagnostic.
14
15
  *
15
16
  * Non-goal #8 (parallel diagnostic surfaces): every check here either
16
17
  * already runs at publish time via `preflight.ts` / `plan.ts` /
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA4BH,MAAM,WAAW,YAAY;IAC3B;yEACqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;iDAC6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA6C3E"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAsBH,MAAM,WAAW,YAAY;IAC3B;yEACqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;iDAC6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA6C3E"}
package/dist/check.js CHANGED
@@ -6,11 +6,12 @@
6
6
  * consumer's repo state alone runs at PR time, before a release run
7
7
  * could fail mid-publish on a precondition checkable in milliseconds.
8
8
  *
9
- * Each check function returns findings; the top-level `runChecks`
10
- * aggregates them so the consumer fixes everything in one round-trip
11
- * rather than chasing one error at a time across re-runs. `require-`
12
- * style throwing helpers live in `preflight.ts` for the publish path;
13
- * this file is read-only diagnostic.
9
+ * Each check function (one per module under `check/`) returns
10
+ * findings; the top-level `runChecks` aggregates them so the consumer
11
+ * fixes everything in one round-trip rather than chasing one error at
12
+ * a time across re-runs. `require-` style throwing helpers live in
13
+ * `preflight.ts` for the publish path; this entry point is read-only
14
+ * diagnostic.
14
15
  *
15
16
  * Non-goal #8 (parallel diagnostic surfaces): every check here either
16
17
  * already runs at publish time via `preflight.ts` / `plan.ts` /
@@ -22,21 +23,24 @@
22
23
  *
23
24
  * Issue #319.
24
25
  */
25
- import { readFile, stat } from 'node:fs/promises';
26
- import { dirname, isAbsolute, join, resolve } from 'node:path';
27
- import { parse as parseToml } from 'smol-toml';
28
- import { assertNoCycles } from './cascade.js';
26
+ import { isAbsolute, join, resolve } from 'node:path';
29
27
  import { checkCratesPackageSize } from './check-crate-size.js';
28
+ import { checkCargoShapeFindings } from './check/check-cargo-shape-findings.js';
29
+ import { checkCratesPackageMetadata } from './check/check-crates-package-metadata.js';
30
+ import { checkDependsOn } from './check/check-depends-on.js';
31
+ import { checkGlobsMatchTrackedFiles } from './check/check-globs-match-tracked-files.js';
32
+ import { checkNpmRepository } from './check/check-npm-repository.js';
33
+ import { checkNpmTargetTriples } from './check/check-npm-target-triples.js';
34
+ import { checkPackageJsonShapeFindings } from './check/check-package-json-shape-findings.js';
35
+ import { checkPaths } from './check/check-paths.js';
36
+ import { checkPypiVersion } from './check/check-pypi-version.js';
37
+ import { checkPyprojectAndBundleCli } from './check/check-pyproject-and-bundle-cli.js';
38
+ import { checkPyprojectShapeFindings } from './check/check-pyproject-shape-findings.js';
39
+ import { checkRepoUrlMatchFindings } from './check/check-repo-url-match-findings.js';
40
+ import { checkTagTemplateCollisions } from './check/check-tag-template-collisions.js';
30
41
  import { loadConfig } from './config.js';
31
- import { ErrorCodes } from './error-codes.js';
32
- import { expandDirGlob, matchesAny } from './glob.js';
33
- import { execCapture } from './utils/exec-capture.js';
34
- import { pathExists } from './utils/path-exists.js';
35
- import { assertTripleSupported } from './handlers/npm-platform.js';
36
- import { checkCargoShape, checkCratesMetadata, checkPackageJsonShape, checkProvenanceMetadata, checkPyprojectShape, checkPypiVersionSource, checkRepoUrlMatch, } from './preflight.js';
37
- import { formatTag } from './tag-template.js';
38
42
  import { toError } from './to-error.js';
39
- import { normalizeTarget } from './types.js';
43
+ import { pathExists } from './utils/path-exists.js';
40
44
  /**
41
45
  * Run every check that's knowable from the consumer's repo state
42
46
  * alone. Returns an aggregated finding list; an empty list means a
@@ -90,294 +94,4 @@ export async function runChecks(opts) {
90
94
  await checkRepoUrlMatchFindings(packages, findings);
91
95
  return findings;
92
96
  }
93
- async function checkRepoUrlMatchFindings(packages, findings) {
94
- // Sourced from GHA's process env at PR time when this runs inside the
95
- // reusable workflow. Locally invoked `putitoutthere check` outside any
96
- // GHA context will skip the check (the preflight returns no findings
97
- // when GITHUB_REPOSITORY is unset), which is the right behaviour:
98
- // there is no workflow source to disagree with.
99
- const githubRepository = process.env.GITHUB_REPOSITORY;
100
- for (const f of await checkRepoUrlMatch(packages, { githubRepository })) {
101
- findings.push({
102
- package: f.package,
103
- message: `[${ErrorCodes.REPO_URL_MISMATCH}] ${f.manifestPath}: declared repository "${f.declaredOwnerRepo}" does not match GITHUB_REPOSITORY "${f.expectedOwnerRepo}". npm rejects \`--provenance\` publishes whose package.json#repository.url disagrees with the OIDC source claim (422); crates.io / PyPI trusted-publisher paths carry the same risk.`,
104
- });
105
- }
106
- }
107
- async function checkPyprojectShapeFindings(packages, findings) {
108
- for (const f of await checkPyprojectShape(packages)) {
109
- findings.push({
110
- package: f.package,
111
- message: `[${f.code}] ${f.pyprojectPath}: ${f.detail}`,
112
- });
113
- }
114
- }
115
- async function checkCargoShapeFindings(packages, cwd, findings) {
116
- for (const f of await checkCargoShape(packages, { cwd })) {
117
- findings.push({
118
- package: f.package,
119
- message: `[${f.code}] ${f.cargoTomlPath}: ${f.detail}`,
120
- });
121
- }
122
- }
123
- async function checkPackageJsonShapeFindings(packages, findings) {
124
- for (const f of await checkPackageJsonShape(packages)) {
125
- findings.push({
126
- package: f.package,
127
- message: `[${f.code}] ${f.packageJsonPath}: ${f.detail}`,
128
- });
129
- }
130
- }
131
- /* ----------------------------- internals ----------------------------- */
132
- async function checkPaths(packages, findings) {
133
- for (const p of packages) {
134
- if (!(await pathExists(p.path)) || !(await stat(p.path)).isDirectory()) {
135
- findings.push({
136
- package: p.name,
137
- message: `path "${p.path}" does not exist or is not a directory in the worktree`,
138
- });
139
- }
140
- }
141
- }
142
- async function checkGlobsMatchTrackedFiles(packages, cwd, findings) {
143
- const tracked = await listTrackedFiles(cwd);
144
- if (tracked === null) {
145
- return;
146
- }
147
- for (const p of packages) {
148
- const matched = tracked.some((f) => matchesAny(p.globs, f));
149
- if (!matched) {
150
- findings.push({
151
- package: p.name,
152
- message: `globs ${JSON.stringify(p.globs)} matched no tracked files. Empty globs mean the package will never cascade on a real commit.`,
153
- });
154
- }
155
- }
156
- }
157
- function checkDependsOn(packages, findings) {
158
- try {
159
- assertNoCycles(packages);
160
- }
161
- catch (err) {
162
- findings.push({
163
- message: toError(err).message,
164
- });
165
- }
166
- }
167
- function checkTagTemplateCollisions(packages, findings) {
168
- // Templates collide when they resolve to the same tag at the same
169
- // version — typically when `{name}` is omitted and every package
170
- // thereafter races for one tag slot. A sentinel version is enough:
171
- // differing templates differ on every version, identical templates
172
- // collide on every version.
173
- const seen = new Map();
174
- for (const p of packages) {
175
- const sentinel = formatTag(p.tag_format, { name: p.name, version: '0.0.0' });
176
- const prior = seen.get(sentinel);
177
- if (prior !== undefined) {
178
- findings.push({
179
- message: `tag_format collision: "${p.name}" and "${prior}" both resolve to tag "${sentinel}" at the same version. Include {name} in tag_format to disambiguate.`,
180
- });
181
- }
182
- else {
183
- seen.set(sentinel, p.name);
184
- }
185
- }
186
- }
187
- async function checkNpmRepository(packages, findings) {
188
- for (const f of await checkProvenanceMetadata(packages)) {
189
- const reason = f.reason === 'missing'
190
- ? `${f.packageJsonPath} not found`
191
- : `${f.packageJsonPath} has missing or empty \`repository\``;
192
- findings.push({
193
- package: f.package,
194
- message: `[${ErrorCodes.NPM_MISSING_REPOSITORY}] ${reason}. \`npm publish --provenance\` hard-requires a non-empty repository.url.`,
195
- });
196
- }
197
- }
198
- async function checkCratesPackageMetadata(packages, findings) {
199
- for (const f of await checkCratesMetadata(packages)) {
200
- findings.push({
201
- package: f.package,
202
- message: `[${ErrorCodes.CRATES_MISSING_METADATA}] ${f.cargoTomlPath} missing required Cargo.toml [package] field(s): ${f.missing.join(', ')}. crates.io rejects the publish after cargo's verification build.`,
203
- });
204
- }
205
- }
206
- async function checkPyprojectAndBundleCli(packages, cwd, findings) {
207
- for (const p of packages) {
208
- if (p.kind !== 'pypi') {
209
- continue;
210
- }
211
- const pyprojectPath = join(p.path, 'pyproject.toml');
212
- if (!(await pathExists(pyprojectPath))) {
213
- findings.push({
214
- package: p.name,
215
- message: `pyproject.toml not found at ${pyprojectPath}`,
216
- });
217
- continue;
218
- }
219
- if (p.build !== 'maturin' || p.bundle_cli === undefined) {
220
- continue;
221
- }
222
- const bundleCli = p.bundle_cli;
223
- // `bundle_cli.crate_path` is documented as relative to the repo
224
- // root (see config.ts: default = "."). Resolve against `cwd`,
225
- // not the package path.
226
- const cratePathAbs = isAbsolute(bundleCli.crate_path)
227
- ? bundleCli.crate_path
228
- : resolve(cwd, bundleCli.crate_path);
229
- const cargoTomlPath = join(cratePathAbs, 'Cargo.toml');
230
- if (!(await pathExists(cratePathAbs)) || !(await stat(cratePathAbs)).isDirectory()) {
231
- findings.push({
232
- package: p.name,
233
- message: `bundle_cli.crate_path "${bundleCli.crate_path}" does not exist or is not a directory`,
234
- });
235
- continue;
236
- }
237
- if (!(await pathExists(cargoTomlPath))) {
238
- findings.push({
239
- package: p.name,
240
- message: `bundle_cli.crate_path "${bundleCli.crate_path}" has no Cargo.toml`,
241
- });
242
- continue;
243
- }
244
- const declaredBins = await readDeclaredBins(cargoTomlPath);
245
- if (!declaredBins.includes(bundleCli.bin)) {
246
- findings.push({
247
- package: p.name,
248
- message: `bundle_cli.bin "${bundleCli.bin}" is not declared as a [[bin]] in ${cargoTomlPath}. Declared bins: ${declaredBins.length === 0 ? '(none)' : declaredBins.join(', ')}.`,
249
- });
250
- }
251
- }
252
- }
253
- async function checkPypiVersion(packages, findings) {
254
- for (const f of await checkPypiVersionSource(packages)) {
255
- findings.push({
256
- package: f.package,
257
- message: `[${ErrorCodes.PYPI_STATIC_VERSION}] ${f.pyprojectPath} declares a static \`[project].version\` literal. Use \`[project].dynamic = ["version"]\` with hatch-vcs (recommended), setuptools-scm, or the maturin Cargo.toml-driven path — putitoutthere does not edit pyproject.toml at release time, so a literal silently ships the previous release.`,
258
- });
259
- }
260
- }
261
- function checkNpmTargetTriples(packages, findings) {
262
- for (const p of packages) {
263
- if (p.kind !== 'npm') {
264
- continue;
265
- }
266
- const targets = p.targets;
267
- if (!targets) {
268
- continue;
269
- }
270
- for (const t of targets) {
271
- const { triple } = normalizeTarget(t);
272
- try {
273
- assertTripleSupported(triple, p.name);
274
- }
275
- catch (err) {
276
- findings.push({
277
- package: p.name,
278
- message: toError(err).message,
279
- });
280
- }
281
- }
282
- }
283
- }
284
- async function listTrackedFiles(cwd) {
285
- try {
286
- const { stdout } = await execCapture('git', ['ls-files'], { cwd });
287
- return stdout.split('\n').filter((l) => l.length > 0);
288
- }
289
- catch {
290
- return null;
291
- }
292
- }
293
- async function readDeclaredBins(cargoTomlPath) {
294
- const parsed = await parseCargoToml(cargoTomlPath);
295
- if (parsed === null) {
296
- return [];
297
- }
298
- const result = collectBinsFromManifest(parsed);
299
- // Workspace manifests delegate [[bin]] declarations to member crates
300
- // (#337). `cargo build --bin X` from anywhere in the workspace
301
- // resolves X transparently, so a check that only reads the
302
- // workspace-root manifest reports bins as missing even when they
303
- // exist in a member. Walk `[workspace].members` so `crate_path = "."`
304
- // (the default) satisfies the standard cargo-workspace shape.
305
- // `members` entries are globs, expanded against the filesystem the way
306
- // cargo resolves them. parseCargoToml returns null for missing /
307
- // malformed manifests, so stray entries silently drop out — cargo's
308
- // own diagnostics own surfacing those.
309
- for (const memberManifest of await workspaceMemberManifests(parsed, cargoTomlPath)) {
310
- const memberParsed = await parseCargoToml(memberManifest);
311
- if (memberParsed === null) {
312
- continue;
313
- }
314
- for (const b of collectBinsFromManifest(memberParsed)) {
315
- if (!result.includes(b)) {
316
- result.push(b);
317
- }
318
- }
319
- }
320
- return result;
321
- }
322
- async function workspaceMemberManifests(parsed, cargoTomlPath) {
323
- const workspace = parsed.workspace;
324
- if (typeof workspace !== 'object' || workspace === null) {
325
- return [];
326
- }
327
- const members = workspace.members;
328
- if (!Array.isArray(members)) {
329
- return [];
330
- }
331
- const workspaceDir = dirname(cargoTomlPath);
332
- const out = [];
333
- for (const m of members) {
334
- if (typeof m === 'string') {
335
- for (const memberDir of await expandDirGlob(workspaceDir, m)) {
336
- out.push(join(memberDir, 'Cargo.toml'));
337
- }
338
- }
339
- }
340
- return out;
341
- }
342
- async function parseCargoToml(path) {
343
- let raw;
344
- try {
345
- raw = await readFile(path, 'utf8');
346
- }
347
- catch {
348
- return null;
349
- }
350
- try {
351
- return parseToml(raw);
352
- }
353
- catch {
354
- return null;
355
- }
356
- }
357
- function collectBinsFromManifest(parsed) {
358
- const result = [];
359
- const bins = parsed.bin;
360
- if (Array.isArray(bins)) {
361
- for (const entry of bins) {
362
- if (typeof entry === 'object' && entry !== null) {
363
- const name = entry.name;
364
- if (typeof name === 'string') {
365
- result.push(name);
366
- }
367
- }
368
- }
369
- }
370
- // Cargo's implicit-binary rule: a crate without any explicit [[bin]]
371
- // table ships a binary named after `[package].name` when
372
- // `src/main.rs` exists. Include that name as a candidate so the
373
- // common single-binary shape (one crate, one bin, no [[bin]] block)
374
- // doesn't spuriously fail this check.
375
- if (result.length === 0) {
376
- const pkg = parsed.package;
377
- if (pkg && typeof pkg.name === 'string') {
378
- result.push(pkg.name);
379
- }
380
- }
381
- return result;
382
- }
383
97
  //# sourceMappingURL=check.js.map
package/dist/check.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * What a failed `npm view` probe actually means (#650).
3
+ *
4
+ * `isPublished` asks npm whether a version exists by shelling out to
5
+ * `npm view <name>@<version> version` and reading the exit status. Every
6
+ * non-zero exit used to mean the same thing — "not published" — which is
7
+ * true for the answer the probe was written for (`E404`) and false for
8
+ * every way the question can fail to be asked at all. A hermetic
9
+ * (`--network none`) `plan` run reported `verdict: publish` for packages it
10
+ * had never reached the registry to ask about.
11
+ *
12
+ * Three outcomes, keyed off npm's own machine-readable `npm error code`
13
+ * line:
14
+ *
15
+ * - `absent` — the registry answered and the version is not there
16
+ * (`E404`), plus anything unrecognised. The historical behaviour, and
17
+ * the conservative default: an unfamiliar code keeps the pre-#650
18
+ * reading rather than inventing a new failure mode for it.
19
+ * - `unreachable` — the registry hostname does not resolve
20
+ * (`ENOTFOUND` / `EAI_AGAIN`). Deterministic within a run: no retry can
21
+ * turn a name that does not resolve into one that does, and no answer
22
+ * is coming, so the caller reports "unknown", not "not published".
23
+ * - `transient` — the registry was reached and faltered (timeouts, reset
24
+ * connections, 429, 5xx). These are the cases the retry policy was
25
+ * written for, so the caller raises a `TransientError` and lets
26
+ * `withRetry` do its job.
27
+ *
28
+ * Matching npm's `code` line rather than its prose keeps this stable
29
+ * across npm's message rewrites; both the modern `npm error` prefix (npm
30
+ * 11) and the legacy `npm ERR!` one (npm ≤ 10, still on plenty of
31
+ * consumer runners) are accepted.
32
+ */
33
+ export type NpmViewFailure = 'absent' | 'unreachable' | 'transient';
34
+ export declare function classifyNpmViewFailure(stderr: string): NpmViewFailure;
35
+ //# sourceMappingURL=classify-npm-view-failure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify-npm-view-failure.d.ts","sourceRoot":"","sources":["../../src/handlers/classify-npm-view-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,aAAa,GAAG,WAAW,CAAC;AAEpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAsCrE"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * What a failed `npm view` probe actually means (#650).
3
+ *
4
+ * `isPublished` asks npm whether a version exists by shelling out to
5
+ * `npm view <name>@<version> version` and reading the exit status. Every
6
+ * non-zero exit used to mean the same thing — "not published" — which is
7
+ * true for the answer the probe was written for (`E404`) and false for
8
+ * every way the question can fail to be asked at all. A hermetic
9
+ * (`--network none`) `plan` run reported `verdict: publish` for packages it
10
+ * had never reached the registry to ask about.
11
+ *
12
+ * Three outcomes, keyed off npm's own machine-readable `npm error code`
13
+ * line:
14
+ *
15
+ * - `absent` — the registry answered and the version is not there
16
+ * (`E404`), plus anything unrecognised. The historical behaviour, and
17
+ * the conservative default: an unfamiliar code keeps the pre-#650
18
+ * reading rather than inventing a new failure mode for it.
19
+ * - `unreachable` — the registry hostname does not resolve
20
+ * (`ENOTFOUND` / `EAI_AGAIN`). Deterministic within a run: no retry can
21
+ * turn a name that does not resolve into one that does, and no answer
22
+ * is coming, so the caller reports "unknown", not "not published".
23
+ * - `transient` — the registry was reached and faltered (timeouts, reset
24
+ * connections, 429, 5xx). These are the cases the retry policy was
25
+ * written for, so the caller raises a `TransientError` and lets
26
+ * `withRetry` do its job.
27
+ *
28
+ * Matching npm's `code` line rather than its prose keeps this stable
29
+ * across npm's message rewrites; both the modern `npm error` prefix (npm
30
+ * 11) and the legacy `npm ERR!` one (npm ≤ 10, still on plenty of
31
+ * consumer runners) are accepted.
32
+ */
33
+ export function classifyNpmViewFailure(stderr) {
34
+ // Function-scoped, not module-scoped: mutants in module-level initializers
35
+ // run once at import, where the mutation gate's per-test switching cannot
36
+ // reach them, so they were reported surviving despite the colocated tests
37
+ // killing every one when applied by hand.
38
+ /**
39
+ * npm's machine-readable failure code, in either prefix spelling:
40
+ * `npm error code ENOTFOUND` (npm 11) / `npm ERR! code ENOTFOUND` (npm <= 10).
41
+ *
42
+ * The prefix sits in a lookbehind rather than a capture group so the match
43
+ * *is* the code. A capture group would be typed `string | undefined` under
44
+ * `noUncheckedIndexedAccess`, forcing a `?? ''` fallback for a group that
45
+ * cannot fail to participate — an unreachable default no test can pin.
46
+ */
47
+ const codeLine = /(?<=^npm (?:error|ERR!) code )\S+$/m;
48
+ /** DNS resolution failed — there is no registry to talk to. */
49
+ const unreachableCodes = new Set(['ENOTFOUND', 'EAI_AGAIN']);
50
+ /** The registry was reached and the request faltered. */
51
+ const transientCodes = new Set([
52
+ 'ETIMEDOUT',
53
+ 'ECONNRESET',
54
+ 'ERR_SOCKET_TIMEOUT',
55
+ 'E429',
56
+ ]);
57
+ /** npm renders an HTTP status as `E<status>`; 5xx is the registry's fault. */
58
+ const serverErrorCode = /^E5[0-9][0-9]$/;
59
+ const match = codeLine.exec(stderr);
60
+ if (match === null) {
61
+ // npm said nothing we can read a code out of. Unrecognised shapes keep
62
+ // the pre-#650 reading rather than inventing a failure mode for them.
63
+ return 'absent';
64
+ }
65
+ const code = match[0];
66
+ if (unreachableCodes.has(code)) {
67
+ return 'unreachable';
68
+ }
69
+ if (transientCodes.has(code)) {
70
+ return 'transient';
71
+ }
72
+ if (serverErrorCode.test(code)) {
73
+ return 'transient';
74
+ }
75
+ return 'absent';
76
+ }
77
+ //# sourceMappingURL=classify-npm-view-failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify-npm-view-failure.js","sourceRoot":"","sources":["../../src/handlers/classify-npm-view-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,2EAA2E;IAC3E,0EAA0E;IAC1E,0EAA0E;IAC1E,0CAA0C;IAC1C;;;;;;;;OAQG;IACH,MAAM,QAAQ,GAAG,qCAAqC,CAAC;IACvD,+DAA+D;IAC/D,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;IAClF,yDAAyD;IACzD,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;QAClD,WAAW;QACX,YAAY;QACZ,oBAAoB;QACpB,MAAM;KACP,CAAC,CAAC;IACH,8EAA8E;IAC9E,MAAM,eAAe,GAAG,gBAAgB,CAAC;IAEzC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,uEAAuE;QACvE,sEAAsE;QACtE,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAAA,OAAO,aAAa,CAAC;IAAA,CAAC;IACvD,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAAA,OAAO,WAAW,CAAC;IAAA,CAAC;IACnD,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAAA,OAAO,WAAW,CAAC;IAAA,CAAC;IACrD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -31,10 +31,12 @@
31
31
  * narrower version of that check: before invoking cargo, scan the
32
32
  * working tree via `git status --porcelain` and refuse to publish
33
33
  * if anything is dirty outside the manifests writeVersion just wrote.
34
- * "Manifests", plural: an inheriting crate's version lives at the
35
- * workspace root, so the file the bump lands in can sit outside the
36
- * package directory entirely (#639). If we can't scan (e.g. no git
37
- * repo), we fall back to cargo's own --allow-dirty behavior.
34
+ * "Manifests", plural, for two reasons: an inheriting crate's version
35
+ * lives at the workspace root (#639), and bumping a crate also moves the
36
+ * in-repo requirements that point at it (#640), which live in other
37
+ * crates' files. Either way the write can land outside the package
38
+ * directory entirely. If we can't scan (e.g. no git repo), we fall back
39
+ * to cargo's own --allow-dirty behavior.
38
40
  *
39
41
  * OIDC: the crates-io-auth-action GHA step exchanges the OIDC JWT for
40
42
  * a short-lived CARGO_REGISTRY_TOKEN in the env. The handler doesn't
@@ -1 +1 @@
1
- {"version":3,"file":"crates.d.ts","sourceRoot":"","sources":["../../src/handlers/crates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAKH,OAAO,KAAK,EAAO,OAAO,EAA+B,MAAM,aAAa,CAAC;AA8P7E;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACtB,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,EACvC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,GACvC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAqF1B;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOnE;AA6CD,eAAO,MAAM,MAAM,EAAE,OAOpB,CAAC"}
1
+ {"version":3,"file":"crates.d.ts","sourceRoot":"","sources":["../../src/handlers/crates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAKH,OAAO,KAAK,EAAO,OAAO,EAA+B,MAAM,aAAa,CAAC;AA0Q7E;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACtB,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,EACvC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,GACvC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAqF1B;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOnE;AA6CD,eAAO,MAAM,MAAM,EAAE,OAOpB,CAAC"}
@@ -31,10 +31,12 @@
31
31
  * narrower version of that check: before invoking cargo, scan the
32
32
  * working tree via `git status --porcelain` and refuse to publish
33
33
  * if anything is dirty outside the manifests writeVersion just wrote.
34
- * "Manifests", plural: an inheriting crate's version lives at the
35
- * workspace root, so the file the bump lands in can sit outside the
36
- * package directory entirely (#639). If we can't scan (e.g. no git
37
- * repo), we fall back to cargo's own --allow-dirty behavior.
34
+ * "Manifests", plural, for two reasons: an inheriting crate's version
35
+ * lives at the workspace root (#639), and bumping a crate also moves the
36
+ * in-repo requirements that point at it (#640), which live in other
37
+ * crates' files. Either way the write can land outside the package
38
+ * directory entirely. If we can't scan (e.g. no git repo), we fall back
39
+ * to cargo's own --allow-dirty behavior.
38
40
  *
39
41
  * OIDC: the crates-io-auth-action GHA step exchanges the OIDC JWT for
40
42
  * a short-lived CARGO_REGISTRY_TOKEN in the env. The handler doesn't
@@ -51,6 +53,7 @@ import { USER_AGENT } from '../version.js';
51
53
  import { execCapture } from '../utils/exec-capture.js';
52
54
  import { elideMiddle } from '../utils/elide-middle.js';
53
55
  import { repoRelativePaths } from '../repo-relative-paths.js';
56
+ import { writeDependentVersionReqs } from '../write-dependent-version-reqs.js';
54
57
  import { writeResolvedCargoVersion } from '../write-resolved-cargo-version.js';
55
58
  import { ExecError } from '../utils/exec-error.js';
56
59
  import { matchFirstPublishTpRejection } from './match-first-publish-tp-rejection.js';
@@ -79,7 +82,7 @@ async function isPublishedImpl(pkg, version, _ctx) {
79
82
  // returns 200/404 for this endpoint, so anything else is a genuine fault.
80
83
  throw new Error(`crates.io GET ${url} returned ${res.status}`);
81
84
  }
82
- async function writeVersionImpl(pkg, version, _ctx) {
85
+ async function writeVersionImpl(pkg, version, ctx) {
83
86
  const cargoPath = join(pkg.path, 'Cargo.toml');
84
87
  let original;
85
88
  try {
@@ -102,12 +105,21 @@ async function writeVersionImpl(pkg, version, _ctx) {
102
105
  // Returns the manifests this write MANAGES, which is what the pre-publish
103
106
  // dirty-tree guard needs: for an inheriting crate that is a file outside
104
107
  // the package directory, and the guard would otherwise refuse on it.
108
+ let written;
105
109
  try {
106
- return await writeResolvedCargoVersion(pkg.path, original, version);
110
+ written = [...(await writeResolvedCargoVersion(pkg.path, original, version))];
107
111
  }
108
112
  catch (err) {
109
113
  throw toError(err);
110
114
  }
115
+ // #640: bumping this crate moves it out of range of every in-repo
116
+ // requirement that pointed at the old version, and cargo then refuses to
117
+ // resolve the workspace at all — a hard failure before anything compiles,
118
+ // hit by the next crates.io package in the cascade rather than by this
119
+ // one. The build-time writers learned this in #621; the publish path is
120
+ // the other half.
121
+ written.push(...(await writeDependentVersionReqs(pkg.path, version, ctx.siblingPackagePaths)));
122
+ return written;
111
123
  }
112
124
  async function publishImpl(pkg, version, ctx) {
113
125
  if (await isPublishedImpl(pkg, version, ctx)) {