@vzn/vx 0.0.549 → 0.0.551
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": "@vzn/vx",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.551",
|
|
4
4
|
"description": "The fastest task runner and build cache for JavaScript monorepos.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"node": ">=18"
|
|
22
22
|
},
|
|
23
23
|
"optionalDependencies": {
|
|
24
|
-
"@vzn/vx-linux-x64": "0.0.
|
|
25
|
-
"@vzn/vx-linux-arm64": "0.0.
|
|
26
|
-
"@vzn/vx-darwin-x64": "0.0.
|
|
27
|
-
"@vzn/vx-darwin-arm64": "0.0.
|
|
24
|
+
"@vzn/vx-linux-x64": "0.0.551",
|
|
25
|
+
"@vzn/vx-linux-arm64": "0.0.551",
|
|
26
|
+
"@vzn/vx-darwin-x64": "0.0.551",
|
|
27
|
+
"@vzn/vx-darwin-arm64": "0.0.551"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
|
@@ -23,16 +23,19 @@ import {
|
|
|
23
23
|
computeWorkspaceFingerprint,
|
|
24
24
|
findWorkspaceRoot,
|
|
25
25
|
type LoadReads,
|
|
26
|
-
loadProjectConfig,
|
|
27
26
|
loadWorkspace,
|
|
28
27
|
lockfilePath,
|
|
29
|
-
type ProjectMeta,
|
|
30
28
|
resolveCacheDir,
|
|
31
29
|
resolveStoreRoot,
|
|
32
30
|
} from '../workspace/index.js'
|
|
33
31
|
import { flakyTasks, type FlakyTask } from './failure-mode.js'
|
|
34
32
|
import type { VxPlugin } from './plugin.js'
|
|
35
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
discoverProjects,
|
|
35
|
+
type LoadProjectsArgs,
|
|
36
|
+
loadProjects,
|
|
37
|
+
loadWorkspacePlugins,
|
|
38
|
+
} from './projects.js'
|
|
36
39
|
|
|
37
40
|
const warnToStderr = (message: string): void => {
|
|
38
41
|
process.stderr.write(`${message}\n`)
|
|
@@ -167,23 +170,23 @@ async function collectWorkspaceInfo(
|
|
|
167
170
|
// The run path's load — a plugin's `project` stage counts — so the
|
|
168
171
|
// doctor's task count is the number a run would see. A broken config
|
|
169
172
|
// must not take the doctor down with it: the count then falls back to
|
|
170
|
-
// the
|
|
171
|
-
|
|
172
|
-
|
|
173
|
+
// the same load, one project at a time, the broken ones as zero.
|
|
174
|
+
const load = {
|
|
175
|
+
workspaceRoot: root,
|
|
176
|
+
cacheDir,
|
|
177
|
+
plugins,
|
|
178
|
+
projectMetas: metas,
|
|
179
|
+
closure: false,
|
|
180
|
+
lock: null,
|
|
181
|
+
evalCache: {
|
|
182
|
+
store: cache,
|
|
173
183
|
workspaceRoot: root,
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
evalCache: {
|
|
181
|
-
store: cache,
|
|
182
|
-
workspaceRoot: root,
|
|
183
|
-
workspaceFingerprint: await computeWorkspaceFingerprint(root, reads),
|
|
184
|
-
},
|
|
185
|
-
warn,
|
|
186
|
-
})
|
|
184
|
+
workspaceFingerprint: await computeWorkspaceFingerprint(root, reads),
|
|
185
|
+
},
|
|
186
|
+
warn,
|
|
187
|
+
} as const
|
|
188
|
+
try {
|
|
189
|
+
const loaded = await loadProjects({ ...load, seeds: 'all' })
|
|
187
190
|
for (const p of loaded.projects.values()) {
|
|
188
191
|
const tasks = p.config.tasks ?? {}
|
|
189
192
|
taskCount += Object.keys(tasks).length
|
|
@@ -197,7 +200,7 @@ async function collectWorkspaceInfo(
|
|
|
197
200
|
tasks: taskCount,
|
|
198
201
|
sandboxed,
|
|
199
202
|
errors: configErrors,
|
|
200
|
-
} = await countLoadableTasks(
|
|
203
|
+
} = await countLoadableTasks(load, root))
|
|
201
204
|
}
|
|
202
205
|
} finally {
|
|
203
206
|
cache.close()
|
|
@@ -362,18 +365,19 @@ function gitVersion(): string | null {
|
|
|
362
365
|
}
|
|
363
366
|
|
|
364
367
|
async function countLoadableTasks(
|
|
365
|
-
|
|
368
|
+
load: Omit<LoadProjectsArgs, 'seeds'> & { closure: false },
|
|
366
369
|
root: string,
|
|
367
370
|
): Promise<{ tasks: number; sandboxed: number; errors: InfoFacts['configErrors'] }> {
|
|
368
371
|
let tasks = 0
|
|
369
372
|
let sandboxed = 0
|
|
370
373
|
const errors: InfoFacts['configErrors'] = []
|
|
374
|
+
// No seeds loads nothing and answers which projects an 'all' load seeds.
|
|
375
|
+
const { configured } = await loadProjects({ ...load, seeds: [] })
|
|
371
376
|
await Promise.all(
|
|
372
|
-
|
|
373
|
-
if (meta.configPath === null) return
|
|
377
|
+
configured.map(async (meta) => {
|
|
374
378
|
try {
|
|
375
|
-
const
|
|
376
|
-
const declared = Object.values(config.tasks ?? {})
|
|
379
|
+
const loaded = await loadProjects({ ...load, seeds: [meta.name] })
|
|
380
|
+
const declared = Object.values(loaded.projects.get(meta.name)?.config.tasks ?? {})
|
|
377
381
|
tasks += declared.length
|
|
378
382
|
for (const t of declared) if (t?.exec?.sandbox !== undefined) sandboxed++
|
|
379
383
|
} catch (err) {
|
|
@@ -385,11 +389,12 @@ async function countLoadableTasks(
|
|
|
385
389
|
// still did).
|
|
386
390
|
const raw = err instanceof Error ? err.message : String(err)
|
|
387
391
|
const bare = raw.startsWith('Project config ') ? raw.slice('Project config '.length) : raw
|
|
388
|
-
const
|
|
389
|
-
|
|
392
|
+
const where = meta.configPath ?? meta.dir
|
|
393
|
+
const message = bare.startsWith(`${where}:`)
|
|
394
|
+
? bare.slice(where.length + 1).trimStart()
|
|
390
395
|
: raw
|
|
391
396
|
errors.push({
|
|
392
|
-
path: path.relative(root,
|
|
397
|
+
path: path.relative(root, where).split(path.sep).join('/'),
|
|
393
398
|
message,
|
|
394
399
|
})
|
|
395
400
|
}
|
|
@@ -175,7 +175,14 @@ self.onmessage = async (e) => {
|
|
|
175
175
|
fn: typeof mod === 'function',
|
|
176
176
|
changed: report,
|
|
177
177
|
})
|
|
178
|
-
} catch (
|
|
178
|
+
} catch (thrown) {
|
|
179
|
+
// Two syntax errors arrive as one AggregateError, whose own message
|
|
180
|
+
// names no line; the in-process load reports the first (X-6), so the
|
|
181
|
+
// hop does too (X-26).
|
|
182
|
+
const err =
|
|
183
|
+
thrown?.name === 'AggregateError' && Array.isArray(thrown.errors) && thrown.errors.length > 0
|
|
184
|
+
? thrown.errors[0]
|
|
185
|
+
: thrown
|
|
179
186
|
const report = changed()
|
|
180
187
|
umaskBack()
|
|
181
188
|
postMessage({
|
|
@@ -670,11 +670,14 @@ export function migrateScripts(
|
|
|
670
670
|
// insomnia's root is named as its `packages/insomnia`: a root config made
|
|
671
671
|
// it a project, and every later run was refused for the duplicate (D-129).
|
|
672
672
|
const clash = outsideName === undefined ? undefined : metas.find((m) => m.name === outsideName)
|
|
673
|
+
// A root with a config of its own is kept as written, and a run of `vx
|
|
674
|
+
// init` after the one that mapped it keeps it like a member's (X-27).
|
|
675
|
+
const rootKept = root !== undefined && root.configPath !== null
|
|
673
676
|
const rootMeta: ProjectMeta | undefined =
|
|
674
677
|
root !== undefined
|
|
675
|
-
?
|
|
676
|
-
?
|
|
677
|
-
:
|
|
678
|
+
? rootKept
|
|
679
|
+
? undefined
|
|
680
|
+
: root
|
|
678
681
|
: outsideName !== undefined && outsideDir !== undefined && clash === undefined
|
|
679
682
|
? { name: outsideName, dir: outsideDir, packageJson: outside as never, configPath: null }
|
|
680
683
|
: undefined
|
|
@@ -722,10 +725,9 @@ export function migrateScripts(
|
|
|
722
725
|
Object.entries(scripts).filter(([n, v]) => typeof v === 'string' && !out.has(n)),
|
|
723
726
|
)
|
|
724
727
|
}
|
|
725
|
-
const
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
: Object.keys(rootScripts(rootMeta)).filter((n) => !LIFECYCLE.test(n)).length
|
|
728
|
+
const mapsOf = (meta: ProjectMeta | undefined): number =>
|
|
729
|
+
meta === undefined ? 0 : Object.keys(rootScripts(meta)).filter((n) => !LIFECYCLE.test(n)).length
|
|
730
|
+
const rootMapped = mapsOf(rootMeta)
|
|
729
731
|
const listed = (names: readonly string[]): string =>
|
|
730
732
|
names.slice(0, 8).join(', ') + (names.length > 8 ? ` and ${names.length - 8} more` : '')
|
|
731
733
|
const outsideScripts = outside?.['scripts']
|
|
@@ -750,14 +752,15 @@ export function migrateScripts(
|
|
|
750
752
|
// Why a root mapped nothing: `eslint .` beside a member's `lint` runs
|
|
751
753
|
// nothing of the workspace, and the note said it did.
|
|
752
754
|
const rootLeftOut = (): string => {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
+
const judged = rootKept ? root : rootMeta
|
|
756
|
+
if (judged === undefined) return 'run the workspace'
|
|
757
|
+
const scripts = scriptsOf(judged)
|
|
755
758
|
const named = Object.keys(scripts).filter(
|
|
756
759
|
(n) => typeof scripts[n] === 'string' && scripts[n] !== '' && !LIFECYCLE.test(n),
|
|
757
760
|
)
|
|
758
761
|
const runs = runningMembers(
|
|
759
762
|
scripts,
|
|
760
|
-
|
|
763
|
+
judged.dir,
|
|
761
764
|
metas.filter((m) => m !== root).map((m) => m.dir),
|
|
762
765
|
)
|
|
763
766
|
const shared = named.filter((n) => memberTasks.has(n) && !runs.has(n))
|
|
@@ -796,7 +799,7 @@ export function migrateScripts(
|
|
|
796
799
|
notes.push(
|
|
797
800
|
`package.json (the workspace root) not mapped: it has no "name", and vx names a project by it; give it one and run \`vx init\` again to map ${would.length} of its scripts (${would.slice(0, 8).join(', ')}${would.length > 8 ? ', …' : ''})`,
|
|
798
801
|
)
|
|
799
|
-
} else if (rootName !== undefined) {
|
|
802
|
+
} else if (rootName !== undefined && !(rootKept && mapsOf(root) > 0)) {
|
|
800
803
|
// A nameless root's vx.config is skipped (vx names projects by their
|
|
801
804
|
// manifest's name), so the hand-written one needs a name first (vuejs/core).
|
|
802
805
|
notes.push(
|
|
@@ -276,6 +276,12 @@ export async function applyMigration(args: ApplyMigrationArgs): Promise<number>
|
|
|
276
276
|
kept.push(relPosix(root, existing))
|
|
277
277
|
return false
|
|
278
278
|
})
|
|
279
|
+
// A plan never maps a workspace root that has a config (D-45), even
|
|
280
|
+
// under `--force`; its file stays, so it is named with the rest (X-27).
|
|
281
|
+
const rootConfig = metas.find((m) => m.dir === root)?.configPath
|
|
282
|
+
if (init && rootConfig && !projects.some((p) => p.dir === root && p.tasks.length > 0)) {
|
|
283
|
+
kept.push(relPosix(root, rootConfig))
|
|
284
|
+
}
|
|
279
285
|
if (empty && !init) {
|
|
280
286
|
throw new UserError(
|
|
281
287
|
`nothing to migrate: no ${source === 'package.json scripts' ? 'package.json scripts in any workspace member' : 'tasks in ' + source}`,
|