@xemahq/repo-build-tooling 0.2.1 → 0.2.3
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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/repo-build-tooling",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Dev-time build tooling shared by every Xema repository. Ships as plain ESM with zero dependencies so the published artifact is the reviewed source.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Neuralchowder Inc. <developer@xema.dev> (https://xema.dev)",
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
},
|
|
18
18
|
"type": "module",
|
|
19
19
|
"files": [
|
|
20
|
-
"src",
|
|
21
20
|
"README.md"
|
|
22
21
|
],
|
|
23
22
|
"bin": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
// examined.
|
|
30
30
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
31
31
|
import { execFileSync } from 'node:child_process';
|
|
32
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
32
|
+
import { existsSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
|
|
33
33
|
import { join, relative } from 'node:path';
|
|
34
34
|
import { pathToFileURL } from 'node:url';
|
|
35
35
|
|
|
@@ -173,6 +173,42 @@ function main() {
|
|
|
173
173
|
|
|
174
174
|
// Importing this module must not run the scan — the test suite imports it for
|
|
175
175
|
// `satisfies` alone.
|
|
176
|
-
|
|
176
|
+
//
|
|
177
|
+
// COMPARE REALPATHS. `import.meta.url` is the RESOLVED path of this file;
|
|
178
|
+
// `process.argv[1]` is the path the shell was handed. Inside the xema-monorepo
|
|
179
|
+
// aggregator those are different strings for the same file, because
|
|
180
|
+
// `node_modules/@xemahq/repo-build-tooling` is a symlink into the workspace and
|
|
181
|
+
// pnpm's bin shim execs THROUGH it:
|
|
182
|
+
//
|
|
183
|
+
// argv[1] …/node_modules/@xemahq/repo-build-tooling/src/check-…mjs
|
|
184
|
+
// resolved …/repos/xema-runtime-core/packages/sdks/repo-build-tooling/src/check-…mjs
|
|
185
|
+
//
|
|
186
|
+
// So the guard was false, `main()` never ran, and the bin printed NOTHING and
|
|
187
|
+
// exited 0 — the check reporting green while executing nothing, which is this
|
|
188
|
+
// fleet's most-repeated defect and the one it has the most machinery against.
|
|
189
|
+
//
|
|
190
|
+
// Measured 2026-08-21: `repos/xema-biome-sdk` carried two `workspace:^6.1.0`
|
|
191
|
+
// declarations against a local `@xemahq/biome-sdk@7.0.0` — the exact dropped
|
|
192
|
+
// build edge this file exists to catch, and a range pnpm refuses outright with
|
|
193
|
+
// ERR_PNPM_NO_MATCHING_VERSION_INSIDE_WORKSPACE. `xema-check-workspace-ranges`
|
|
194
|
+
// exited 0 in silence; the same file run by its real path exited 1 and named
|
|
195
|
+
// both. Every carved repo's `pnpm check` and every pre-push hook in this
|
|
196
|
+
// checkout invoked it the silent way.
|
|
197
|
+
//
|
|
198
|
+
// A carved repo's own CI installs the PUBLISHED tarball, so there argv[1] is
|
|
199
|
+
// already a real path and the guard held. That is why the hole survived: it is
|
|
200
|
+
// invisible in exactly the lane people point at as proof.
|
|
201
|
+
const invokedPath = process.argv[1];
|
|
202
|
+
let invokedRealPath = null;
|
|
203
|
+
if (typeof invokedPath === 'string' && invokedPath.length > 0) {
|
|
204
|
+
try {
|
|
205
|
+
invokedRealPath = realpathSync(invokedPath);
|
|
206
|
+
} catch {
|
|
207
|
+
// Not a path on disk (a `node -e` entry, say). Nothing was invoked, so
|
|
208
|
+
// nothing should run — fall through as a plain import.
|
|
209
|
+
invokedRealPath = null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (invokedRealPath !== null && import.meta.url === pathToFileURL(invokedRealPath).href) {
|
|
177
213
|
process.exit(main());
|
|
178
214
|
}
|
|
@@ -303,7 +303,6 @@ function reExportsReach(entry, target, depth = 6, seen = new Set()) {
|
|
|
303
303
|
} catch {
|
|
304
304
|
return false;
|
|
305
305
|
}
|
|
306
|
-
const dir = dirname(entry);
|
|
307
306
|
for (const m of src.matchAll(/require\("(\.[^"]*)"\)/g)) {
|
|
308
307
|
let next;
|
|
309
308
|
try {
|
|
@@ -499,7 +498,7 @@ async function assertScannable(dir) {
|
|
|
499
498
|
}
|
|
500
499
|
if (!s.isDirectory()) throw new ScrubFailure(`not a directory: ${dir}`);
|
|
501
500
|
|
|
502
|
-
for await (const _file of walk(dir)) return;
|
|
501
|
+
for await (const _file of walk(dir)) return;
|
|
503
502
|
throw new ScrubFailure(
|
|
504
503
|
`output directory holds no compiled .js: ${dir}\n` +
|
|
505
504
|
` Same failure as a missing directory: nothing was scrubbed and nothing was verified.`,
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The whole check rests on ONE predicate — `satisfies` — so that is what these
|
|
3
|
-
* tests attack.
|
|
4
|
-
*
|
|
5
|
-
* The failure this guard exists to prevent is subtle in exactly one place: npm's
|
|
6
|
-
* `^0.y.z` rule pins the MINOR, not the major. A `satisfies` that treats `^` as
|
|
7
|
-
* "same major" uniformly would call `0.3.0` a match for `^0.2.0` and report a
|
|
8
|
-
* clean scan over all 58 real violations — a check that reports green while
|
|
9
|
-
* examining everything and concluding nothing. Every 0.x case below is aimed at
|
|
10
|
-
* that specific wrong implementation.
|
|
11
|
-
*/
|
|
12
|
-
import assert from 'node:assert/strict';
|
|
13
|
-
import test from 'node:test';
|
|
14
|
-
|
|
15
|
-
import { satisfies } from './check-workspace-range-matches-local.mjs';
|
|
16
|
-
|
|
17
|
-
test('^0.y.z pins the MINOR — the rule the whole check turns on', () => {
|
|
18
|
-
// The real defect: a client moved 0.2.0 -> 0.3.0 and fell out of every
|
|
19
|
-
// consumer's range, silently dropping the build edge.
|
|
20
|
-
assert.equal(satisfies('0.3.0', '^0.2.0'), false);
|
|
21
|
-
assert.equal(satisfies('0.2.9', '^0.2.0'), true);
|
|
22
|
-
assert.equal(satisfies('0.2.0', '^0.2.1'), false); // below the floor
|
|
23
|
-
assert.equal(satisfies('1.0.0', '^0.2.0'), false);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
test('^x.y.z (x > 0) pins the MAJOR', () => {
|
|
27
|
-
assert.equal(satisfies('1.9.3', '^1.2.0'), true);
|
|
28
|
-
assert.equal(satisfies('2.0.0', '^1.2.0'), false);
|
|
29
|
-
assert.equal(satisfies('1.1.0', '^1.2.0'), false); // below the floor
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test('~ pins the minor at every major', () => {
|
|
33
|
-
assert.equal(satisfies('1.2.9', '~1.2.0'), true);
|
|
34
|
-
assert.equal(satisfies('1.3.0', '~1.2.0'), false);
|
|
35
|
-
assert.equal(satisfies('0.2.9', '~0.2.0'), true);
|
|
36
|
-
assert.equal(satisfies('0.3.0', '~0.2.0'), false);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test('>= is a floor with no ceiling', () => {
|
|
40
|
-
assert.equal(satisfies('7.5.0', '>=0.14.0'), true);
|
|
41
|
-
assert.equal(satisfies('0.13.0', '>=0.14.0'), false);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('an exact range means exactly that version', () => {
|
|
45
|
-
assert.equal(satisfies('1.2.3', '1.2.3'), true);
|
|
46
|
-
assert.equal(satisfies('1.2.4', '1.2.3'), false);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test('a prerelease is compared on its release part, never string-wise', () => {
|
|
50
|
-
// `0.3.0-rc.1` must not read as "less than 0.3.0 therefore outside ^0.2.0
|
|
51
|
-
// is fine" — the range check has to reach the same verdict as `0.3.0`.
|
|
52
|
-
assert.equal(satisfies('0.3.0-rc.1', '^0.2.0'), false);
|
|
53
|
-
assert.equal(satisfies('0.2.5-rc.1', '^0.2.0'), true);
|
|
54
|
-
});
|