nx 23.0.0-beta.5 → 23.0.0-beta.7
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/dist/plugins/package-json.js +4 -2
- package/dist/src/analytics/analytics.js +10 -1
- package/dist/src/config/task-graph.d.ts +4 -107
- package/dist/src/hasher/hash-plan-inspector.d.ts +1 -1
- package/dist/src/native/index.d.ts +44 -1
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/plugins/js/lock-file/npm-parser.js +37 -19
- package/dist/src/plugins/js/lock-file/pnpm-parser.js +51 -4
- package/dist/src/plugins/js/lock-file/project-graph-pruning.js +12 -4
- package/dist/src/plugins/package-json/create-nodes.d.ts +3 -2
- package/dist/src/plugins/package-json/create-nodes.js +7 -5
- package/dist/src/tasks-runner/create-task-graph.d.ts +4 -4
- package/dist/src/tasks-runner/life-cycle.d.ts +7 -8
- package/dist/src/tasks-runner/life-cycles/invoke-runner-terminal-output-life-cycle.js +6 -6
- package/dist/src/tasks-runner/utils.d.ts +1 -0
- package/dist/src/tasks-runner/utils.js +7 -2
- package/dist/src/utils/child-process.js +2 -2
- package/dist/src/utils/package-json.d.ts +1 -1
- package/dist/src/utils/package-json.js +3 -5
- package/dist/src/utils/plugin-cache-utils.d.ts +13 -4
- package/dist/src/utils/plugin-cache-utils.js +23 -13
- package/package.json +11 -11
|
@@ -8,6 +8,7 @@ const cache_directory_1 = require("../src/utils/cache-directory");
|
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const fileutils_1 = require("../src/utils/fileutils");
|
|
10
10
|
const plugin_cache_utils_1 = require("../src/utils/plugin-cache-utils");
|
|
11
|
+
const package_manager_1 = require("../src/utils/package-manager");
|
|
11
12
|
const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'package-json.hash');
|
|
12
13
|
let packageJsonPluginCache = null;
|
|
13
14
|
function readPackageJsonConfigurationCache() {
|
|
@@ -16,7 +17,7 @@ function readPackageJsonConfigurationCache() {
|
|
|
16
17
|
}
|
|
17
18
|
function writeCache() {
|
|
18
19
|
if (packageJsonPluginCache) {
|
|
19
|
-
packageJsonPluginCache.writeToDisk(
|
|
20
|
+
packageJsonPluginCache.writeToDisk();
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
const plugin = {
|
|
@@ -27,7 +28,8 @@ const plugin = {
|
|
|
27
28
|
const cache = readPackageJsonConfigurationCache();
|
|
28
29
|
const patterns = (0, package_json_1.buildPackageJsonPatterns)(context.workspaceRoot, (f) => (0, fileutils_1.readJsonFile)((0, path_1.join)(context.workspaceRoot, f)));
|
|
29
30
|
const isInPackageJsonWorkspaces = (0, package_json_1.buildPackageJsonWorkspacesMatcher)(patterns);
|
|
30
|
-
const
|
|
31
|
+
const packageManagerCommand = (0, package_manager_1.getPackageManagerCommand)((0, package_manager_1.detectPackageManager)(context.workspaceRoot), context.workspaceRoot);
|
|
32
|
+
const result = (0, plugins_1.createNodesFromFiles)((packageJsonPath) => (0, package_json_1.createNodeFromPackageJson)(packageJsonPath, workspace_root_1.workspaceRoot, cache, isInPackageJsonWorkspaces(packageJsonPath), packageManagerCommand), configFiles, options, context);
|
|
31
33
|
writeCache();
|
|
32
34
|
return result;
|
|
33
35
|
},
|
|
@@ -16,6 +16,7 @@ const native_1 = require("../native");
|
|
|
16
16
|
const package_manager_1 = require("../utils/package-manager");
|
|
17
17
|
const semver_1 = require("semver");
|
|
18
18
|
const os = tslib_1.__importStar(require("os"));
|
|
19
|
+
const crypto_1 = require("crypto");
|
|
19
20
|
const machine_id_cache_1 = require("../utils/machine-id-cache");
|
|
20
21
|
const is_ci_1 = require("../utils/is-ci");
|
|
21
22
|
const analytics_prompt_1 = require("../utils/analytics-prompt");
|
|
@@ -56,7 +57,7 @@ async function startAnalytics() {
|
|
|
56
57
|
return;
|
|
57
58
|
}
|
|
58
59
|
const isNxCloud = !!(nxJson?.nxCloudId ?? nxJson?.nxCloudAccessToken);
|
|
59
|
-
const userId = await (
|
|
60
|
+
const userId = await getTelemetryUserId(workspaceId);
|
|
60
61
|
const packageManagerInfo = getPackageManagerInfo();
|
|
61
62
|
const nodeVersion = (0, semver_1.parse)(process.version);
|
|
62
63
|
const nodeVersionString = nodeVersion
|
|
@@ -225,3 +226,11 @@ function isAnalyticsEnabled() {
|
|
|
225
226
|
const nxJson = (0, nx_json_1.readNxJson)(workspace_root_1.workspaceRoot);
|
|
226
227
|
return nxJson?.analytics === true;
|
|
227
228
|
}
|
|
229
|
+
// Mix workspace id in: shared Docker images (Gitpod, Cypress, etc.) bake
|
|
230
|
+
// in /etc/machine-id, so machine-id alone collapses many users into one.
|
|
231
|
+
async function getTelemetryUserId(workspaceId) {
|
|
232
|
+
const machineId = await (0, machine_id_cache_1.getCurrentMachineId)();
|
|
233
|
+
return (0, crypto_1.createHash)('sha256')
|
|
234
|
+
.update(`${machineId}|${workspaceId}`)
|
|
235
|
+
.digest('hex');
|
|
236
|
+
}
|
|
@@ -1,109 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* `Task` and `TaskGraph` are defined as Rust structs in
|
|
3
|
+
* `packages/nx/src/native/tasks/types.rs` and exposed to TypeScript via NAPI.
|
|
4
|
+
* This file re-exports them so existing imports keep working.
|
|
3
5
|
*/
|
|
4
|
-
export
|
|
5
|
-
/**
|
|
6
|
-
* Unique ID
|
|
7
|
-
*/
|
|
8
|
-
id: string;
|
|
9
|
-
/**
|
|
10
|
-
* Details about which project, target, and configuration to run.
|
|
11
|
-
*/
|
|
12
|
-
target: {
|
|
13
|
-
/**
|
|
14
|
-
* The project for which the task belongs to
|
|
15
|
-
*/
|
|
16
|
-
project: string;
|
|
17
|
-
/**
|
|
18
|
-
* The target name which the task should invoke
|
|
19
|
-
*/
|
|
20
|
-
target: string;
|
|
21
|
-
/**
|
|
22
|
-
* The configuration of the target which the task invokes
|
|
23
|
-
*/
|
|
24
|
-
configuration?: string;
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Overrides for the configured options of the target
|
|
28
|
-
*/
|
|
29
|
-
overrides: any;
|
|
30
|
-
/**
|
|
31
|
-
* The outputs the task may produce
|
|
32
|
-
*/
|
|
33
|
-
outputs: string[];
|
|
34
|
-
/**
|
|
35
|
-
* Root of the project the task belongs to
|
|
36
|
-
*/
|
|
37
|
-
projectRoot?: string;
|
|
38
|
-
/**
|
|
39
|
-
* Hash of the task which is used for caching.
|
|
40
|
-
*/
|
|
41
|
-
hash?: string;
|
|
42
|
-
/**
|
|
43
|
-
* Details about the composition of the hash
|
|
44
|
-
*/
|
|
45
|
-
hashDetails?: {
|
|
46
|
-
/**
|
|
47
|
-
* Command of the task
|
|
48
|
-
*/
|
|
49
|
-
command: string;
|
|
50
|
-
/**
|
|
51
|
-
* Hashes of inputs used in the hash
|
|
52
|
-
*/
|
|
53
|
-
nodes: {
|
|
54
|
-
[name: string]: string;
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Hashes of implicit dependencies which are included in the hash
|
|
58
|
-
*/
|
|
59
|
-
implicitDeps?: {
|
|
60
|
-
[fileName: string]: string;
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* Hash of the runtime environment which the task was executed
|
|
64
|
-
*/
|
|
65
|
-
runtime?: {
|
|
66
|
-
[input: string]: string;
|
|
67
|
-
};
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
*
|
|
71
|
-
* Unix timestamp of when a Batch Task starts
|
|
72
|
-
**/
|
|
73
|
-
startTime?: number;
|
|
74
|
-
/**
|
|
75
|
-
*
|
|
76
|
-
* Unix timestamp of when a Batch Task ends
|
|
77
|
-
**/
|
|
78
|
-
endTime?: number;
|
|
79
|
-
/**
|
|
80
|
-
* Determines if a given task should be cacheable.
|
|
81
|
-
*/
|
|
82
|
-
cache?: boolean;
|
|
83
|
-
/**
|
|
84
|
-
* Determines if a given task should be parallelizable.
|
|
85
|
-
*/
|
|
86
|
-
parallelism: boolean;
|
|
87
|
-
/**
|
|
88
|
-
* This denotes if the task runs continuously
|
|
89
|
-
*/
|
|
90
|
-
continuous?: boolean;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Graph of Tasks to be executed
|
|
94
|
-
*/
|
|
95
|
-
export interface TaskGraph {
|
|
96
|
-
/**
|
|
97
|
-
* IDs of Tasks which do not have any dependencies and are thus ready to execute immediately
|
|
98
|
-
*/
|
|
99
|
-
roots: string[];
|
|
100
|
-
/**
|
|
101
|
-
* Map of Task IDs to Tasks
|
|
102
|
-
*/
|
|
103
|
-
tasks: Record<string, Task>;
|
|
104
|
-
/**
|
|
105
|
-
* Map of Task IDs to IDs of tasks which the task depends on
|
|
106
|
-
*/
|
|
107
|
-
dependencies: Record<string, string[]>;
|
|
108
|
-
continuousDependencies: Record<string, string[]>;
|
|
109
|
-
}
|
|
6
|
+
export type { Task, TaskGraph, TaskTarget, TaskHashDetails } from '../native';
|
|
@@ -15,7 +15,7 @@ export declare class HashPlanInspector {
|
|
|
15
15
|
/**
|
|
16
16
|
* This is a lower level method which will inspect the hash plan for a set of tasks.
|
|
17
17
|
*/
|
|
18
|
-
inspectHashPlan(projectNames: string[], targets: string[], configuration?: string, overrides?:
|
|
18
|
+
inspectHashPlan(projectNames: string[], targets: string[], configuration?: string, overrides?: Record<string, unknown>, extraTargetDependencies?: TargetDependencies, excludeTaskDependencies?: boolean): Record<string, string[]>;
|
|
19
19
|
/**
|
|
20
20
|
* This inspects tasks involved in the execution of a task, including its dependencies by default.
|
|
21
21
|
* @deprecated Prefer inspectTaskInputs
|
|
@@ -581,26 +581,66 @@ export interface Target {
|
|
|
581
581
|
parallelism?: boolean
|
|
582
582
|
}
|
|
583
583
|
|
|
584
|
+
/** A representation of the invocation of an Executor */
|
|
584
585
|
export interface Task {
|
|
586
|
+
/** Unique ID */
|
|
585
587
|
id: string
|
|
588
|
+
/** Details about which project, target, and configuration to run. */
|
|
586
589
|
target: TaskTarget
|
|
590
|
+
/** Overrides for the configured options of the target */
|
|
591
|
+
overrides: Record<string, unknown>
|
|
592
|
+
/** The outputs the task may produce */
|
|
587
593
|
outputs: Array<string>
|
|
594
|
+
/** Root of the project the task belongs to */
|
|
588
595
|
projectRoot?: string
|
|
596
|
+
/** Hash of the task which is used for caching. */
|
|
597
|
+
hash?: string
|
|
598
|
+
/** Details about the composition of the hash */
|
|
599
|
+
hashDetails?: TaskHashDetails
|
|
600
|
+
/** Unix timestamp of when a Batch Task starts */
|
|
589
601
|
startTime?: number
|
|
602
|
+
/** Unix timestamp of when a Batch Task ends */
|
|
590
603
|
endTime?: number
|
|
604
|
+
/** Determines if a given task should be cacheable. */
|
|
605
|
+
cache?: boolean
|
|
606
|
+
/** Determines if a given task should be parallelizable. */
|
|
607
|
+
parallelism?: boolean
|
|
608
|
+
/** This denotes if the task runs continuously */
|
|
591
609
|
continuous?: boolean
|
|
592
610
|
}
|
|
593
611
|
|
|
612
|
+
/** Graph of Tasks to be executed */
|
|
594
613
|
export interface TaskGraph {
|
|
614
|
+
/** IDs of Tasks which do not have any dependencies and are thus ready to execute immediately */
|
|
595
615
|
roots: Array<string>
|
|
616
|
+
/** Map of Task IDs to Tasks */
|
|
596
617
|
tasks: Record<string, Task>
|
|
618
|
+
/** Map of Task IDs to IDs of tasks which the task depends on */
|
|
597
619
|
dependencies: Record<string, Array<string>>
|
|
598
620
|
continuousDependencies: Record<string, Array<string>>
|
|
599
621
|
}
|
|
600
622
|
|
|
623
|
+
/** Details about the composition of a task's hash */
|
|
624
|
+
export interface TaskHashDetails {
|
|
625
|
+
/** Command of the task */
|
|
626
|
+
command: string
|
|
627
|
+
/** Hashes of inputs used in the hash */
|
|
628
|
+
nodes: Record<string, string>
|
|
629
|
+
/** Hashes of implicit dependencies which are included in the hash */
|
|
630
|
+
implicitDeps?: Record<string, string>
|
|
631
|
+
/** Hash of the runtime environment which the task was executed */
|
|
632
|
+
runtime?: Record<string, string>
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* The result of a completed Task.
|
|
637
|
+
*
|
|
638
|
+
* Task timing information (start and end timestamps) is available
|
|
639
|
+
* on the Task object itself via `Task.startTime` and `Task.endTime`.
|
|
640
|
+
*/
|
|
601
641
|
export interface TaskResult {
|
|
602
642
|
task: Task
|
|
603
|
-
status:
|
|
643
|
+
status: 'success' | 'failure' | 'skipped' | 'stopped' | 'local-cache-kept-existing' | 'local-cache' | 'remote-cache'
|
|
604
644
|
code: number
|
|
605
645
|
terminalOutput?: string
|
|
606
646
|
}
|
|
@@ -627,8 +667,11 @@ export declare const enum TaskStatus {
|
|
|
627
667
|
}
|
|
628
668
|
|
|
629
669
|
export interface TaskTarget {
|
|
670
|
+
/** The project for which the task belongs to */
|
|
630
671
|
project: string
|
|
672
|
+
/** The target name which the task should invoke */
|
|
631
673
|
target: string
|
|
674
|
+
/** The configuration of the target which the task invokes */
|
|
632
675
|
configuration?: string
|
|
633
676
|
}
|
|
634
677
|
|
|
Binary file
|
|
Binary file
|
|
@@ -270,27 +270,45 @@ function stringifyNpmLockfile(graph, rootLockFileContent, packageJson) {
|
|
|
270
270
|
}
|
|
271
271
|
return JSON.stringify(output, null, 2);
|
|
272
272
|
}
|
|
273
|
+
const WORKSPACE_DEP_TYPES = [
|
|
274
|
+
'dependencies',
|
|
275
|
+
'optionalDependencies',
|
|
276
|
+
'peerDependencies',
|
|
277
|
+
];
|
|
273
278
|
function mapWorkspaceModules(packageJson, rootLockFile, workspaceModules) {
|
|
274
279
|
const output = {};
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
280
|
+
const snapshotsByName = new Map();
|
|
281
|
+
for (const snapshot of Object.values(rootLockFile.packages || rootLockFile.dependencies || {})) {
|
|
282
|
+
if (snapshot.name)
|
|
283
|
+
snapshotsByName.set(snapshot.name, snapshot);
|
|
284
|
+
}
|
|
285
|
+
// Walk transitive workspace deps so every workspace package
|
|
286
|
+
// copy-workspace-modules writes to disk has matching lockfile entries.
|
|
287
|
+
// Without this, `npm ci` errors with "Missing: <pkg> from lock file".
|
|
288
|
+
const queue = Object.keys(packageJson.dependencies ?? {});
|
|
289
|
+
const visited = new Set();
|
|
290
|
+
while (queue.length > 0) {
|
|
291
|
+
const pkgName = queue.shift();
|
|
292
|
+
if (visited.has(pkgName) || !workspaceModules.has(pkgName))
|
|
293
|
+
continue;
|
|
294
|
+
visited.add(pkgName);
|
|
295
|
+
const snapshot = snapshotsByName.get(pkgName);
|
|
296
|
+
output[`node_modules/${pkgName}`] = {
|
|
297
|
+
version: `file:./workspace_modules/${pkgName}`,
|
|
298
|
+
resolved: `workspace_modules/${pkgName}`,
|
|
299
|
+
link: true,
|
|
300
|
+
};
|
|
301
|
+
output[`workspace_modules/${pkgName}`] = {
|
|
302
|
+
name: pkgName,
|
|
303
|
+
version: `0.0.1`,
|
|
304
|
+
dependencies: snapshot?.dependencies,
|
|
305
|
+
};
|
|
306
|
+
for (const depType of WORKSPACE_DEP_TYPES) {
|
|
307
|
+
const deps = snapshot?.[depType];
|
|
308
|
+
if (!deps)
|
|
309
|
+
continue;
|
|
310
|
+
for (const depName of Object.keys(deps))
|
|
311
|
+
queue.push(depName);
|
|
294
312
|
}
|
|
295
313
|
}
|
|
296
314
|
return output;
|
|
@@ -14,6 +14,11 @@ const project_graph_pruning_1 = require("./project-graph-pruning");
|
|
|
14
14
|
const path_1 = require("path");
|
|
15
15
|
const get_workspace_packages_from_graph_1 = require("../utils/get-workspace-packages-from-graph");
|
|
16
16
|
const semver_1 = require("semver");
|
|
17
|
+
const WORKSPACE_DEP_TYPES = [
|
|
18
|
+
'dependencies',
|
|
19
|
+
'optionalDependencies',
|
|
20
|
+
'peerDependencies',
|
|
21
|
+
];
|
|
17
22
|
let currentLockFileHash;
|
|
18
23
|
let parsedLockFile;
|
|
19
24
|
function parsePnpmLockFile(lockFileContent, lockFileHash) {
|
|
@@ -389,13 +394,55 @@ function stringifyPnpmLockfile(graph, rootLockFileContent, packageJson, workspac
|
|
|
389
394
|
const { lockfileVersion, packages, importers } = data;
|
|
390
395
|
const { snapshot: rootSnapshot, importers: requiredImporters } = mapRootSnapshot(packageJson, importers, packages, graph, +lockfileVersion, workspaceRoot);
|
|
391
396
|
const snapshots = mapSnapshots(data.packages, graph.externalNodes, +lockfileVersion);
|
|
397
|
+
const workspaceModules = (0, get_workspace_packages_from_graph_1.getWorkspacePackagesFromGraph)(graph);
|
|
398
|
+
// Walk transitive workspace deps so every package copy-workspace-modules
|
|
399
|
+
// writes to disk has a matching importer block. Without this, pnpm errors
|
|
400
|
+
// with ERR_PNPM_OUTDATED_LOCKFILE on transitive workspace chains.
|
|
401
|
+
const allRequiredImporters = { ...requiredImporters };
|
|
402
|
+
const queue = Object.keys(requiredImporters);
|
|
403
|
+
while (queue.length > 0) {
|
|
404
|
+
const pkgName = queue.shift();
|
|
405
|
+
const importer = importers[allRequiredImporters[pkgName]];
|
|
406
|
+
if (!importer)
|
|
407
|
+
continue;
|
|
408
|
+
for (const depType of WORKSPACE_DEP_TYPES) {
|
|
409
|
+
const deps = importer[depType];
|
|
410
|
+
if (!deps)
|
|
411
|
+
continue;
|
|
412
|
+
for (const depName of Object.keys(deps)) {
|
|
413
|
+
if (workspaceModules.has(depName) && !allRequiredImporters[depName]) {
|
|
414
|
+
allRequiredImporters[depName] =
|
|
415
|
+
workspaceModules.get(depName).data.root;
|
|
416
|
+
queue.push(depName);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
392
421
|
const workspaceDependencyImporters = {};
|
|
393
|
-
for (const [packageName, importerPath] of Object.entries(
|
|
422
|
+
for (const [packageName, importerPath] of Object.entries(allRequiredImporters)) {
|
|
394
423
|
const baseImporter = importers[importerPath];
|
|
395
|
-
if (baseImporter)
|
|
396
|
-
|
|
397
|
-
|
|
424
|
+
if (!baseImporter)
|
|
425
|
+
continue;
|
|
426
|
+
const importer = structuredClone(baseImporter);
|
|
427
|
+
for (const depType of WORKSPACE_DEP_TYPES) {
|
|
428
|
+
const deps = importer[depType];
|
|
429
|
+
if (!deps)
|
|
430
|
+
continue;
|
|
431
|
+
for (const depName of Object.keys(deps)) {
|
|
432
|
+
if (!workspaceModules.has(depName))
|
|
433
|
+
continue;
|
|
434
|
+
// All workspace modules are siblings under workspace_modules/, so the
|
|
435
|
+
// relative path between them is relative(packageName, depName).
|
|
436
|
+
// Specifier must match the file: ref copy-workspace-modules writes
|
|
437
|
+
// to the package's package.json — pnpm errors on a mismatch.
|
|
438
|
+
const rel = (0, path_1.relative)(packageName, depName).split(path_1.sep).join('/');
|
|
439
|
+
if (!importer.specifiers)
|
|
440
|
+
importer.specifiers = {};
|
|
441
|
+
importer.specifiers[depName] = `file:${rel}`;
|
|
442
|
+
deps[depName] = `link:${rel}`;
|
|
443
|
+
}
|
|
398
444
|
}
|
|
445
|
+
workspaceDependencyImporters[`workspace_modules/${packageName}`] = importer;
|
|
399
446
|
}
|
|
400
447
|
const output = {
|
|
401
448
|
...data,
|
|
@@ -115,11 +115,19 @@ function traverseNode(graph, builder, node) {
|
|
|
115
115
|
builder.addStaticDependency(node.name, dep.target);
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
|
-
function traverseWorkspaceNode(graph, builder, node) {
|
|
118
|
+
function traverseWorkspaceNode(graph, builder, node, visited = new Set()) {
|
|
119
|
+
if (visited.has(node.name))
|
|
120
|
+
return;
|
|
121
|
+
visited.add(node.name);
|
|
119
122
|
graph.dependencies[node.name]?.forEach((dep) => {
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
122
|
-
traverseNode(graph, builder,
|
|
123
|
+
const externalDepNode = graph.externalNodes[dep.target];
|
|
124
|
+
if (externalDepNode) {
|
|
125
|
+
traverseNode(graph, builder, externalDepNode);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const workspaceDepNode = graph.nodes[dep.target];
|
|
129
|
+
if (workspaceDepNode) {
|
|
130
|
+
traverseWorkspaceNode(graph, builder, workspaceDepNode, visited);
|
|
123
131
|
}
|
|
124
132
|
});
|
|
125
133
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NxJsonConfiguration } from '../../config/nx-json';
|
|
2
2
|
import type { ProjectConfiguration } from '../../config/workspace-json-project-json';
|
|
3
3
|
import { PackageJson } from '../../utils/package-json';
|
|
4
|
+
import { PackageManagerCommands } from '../../utils/package-manager';
|
|
4
5
|
import { CreateNodesV2 } from '../../project-graph/plugins';
|
|
5
6
|
import { PackageJsonConfigurationCache } from '../../../plugins/package-json';
|
|
6
7
|
export declare const createNodesV2: CreateNodesV2;
|
|
@@ -12,12 +13,12 @@ type PackageJsonPatterns = {
|
|
|
12
13
|
negativeLookup: Record<string, boolean>;
|
|
13
14
|
};
|
|
14
15
|
export declare function buildPackageJsonWorkspacesMatcher(patterns: PackageJsonPatterns): (p: any) => boolean;
|
|
15
|
-
export declare function createNodeFromPackageJson(pkgJsonPath: string, workspaceRoot: string, cache: PackageJsonConfigurationCache, isInPackageManagerWorkspaces: boolean): {
|
|
16
|
+
export declare function createNodeFromPackageJson(pkgJsonPath: string, workspaceRoot: string, cache: PackageJsonConfigurationCache, isInPackageManagerWorkspaces: boolean, packageManagerCommand: PackageManagerCommands): {
|
|
16
17
|
projects: {
|
|
17
18
|
[x: string]: ProjectConfiguration;
|
|
18
19
|
};
|
|
19
20
|
};
|
|
20
|
-
export declare function buildProjectConfigurationFromPackageJson(packageJson: PackageJson, workspaceRoot: string, packageJsonPath: string, nxJson: NxJsonConfiguration, isInPackageManagerWorkspaces: boolean): ProjectConfiguration & {
|
|
21
|
+
export declare function buildProjectConfigurationFromPackageJson(packageJson: PackageJson, workspaceRoot: string, packageJsonPath: string, nxJson: NxJsonConfiguration, isInPackageManagerWorkspaces: boolean, packageManagerCommand: PackageManagerCommands): ProjectConfiguration & {
|
|
21
22
|
name: string;
|
|
22
23
|
};
|
|
23
24
|
/**
|
|
@@ -16,6 +16,7 @@ const globs_1 = require("../../utils/globs");
|
|
|
16
16
|
const logger_1 = require("../../utils/logger");
|
|
17
17
|
const output_1 = require("../../utils/output");
|
|
18
18
|
const package_json_1 = require("../../utils/package-json");
|
|
19
|
+
const package_manager_1 = require("../../utils/package-manager");
|
|
19
20
|
const path_1 = require("../../utils/path");
|
|
20
21
|
const versions_1 = require("../../utils/versions");
|
|
21
22
|
const plugins_1 = require("../../project-graph/plugins");
|
|
@@ -38,6 +39,7 @@ exports.createNodesV2 = [
|
|
|
38
39
|
return projectJsonRoots.has((0, node_path_1.dirname)(packageJsonPath));
|
|
39
40
|
};
|
|
40
41
|
const cache = (0, package_json_2.readPackageJsonConfigurationCache)();
|
|
42
|
+
const packageManagerCommand = (0, package_manager_1.getPackageManagerCommand)((0, package_manager_1.detectPackageManager)(context.workspaceRoot), context.workspaceRoot);
|
|
41
43
|
return (0, plugins_1.createNodesFromFiles)((packageJsonPath, options, context) => {
|
|
42
44
|
const isInPackageManagerWorkspaces = isInPackageJsonWorkspaces(packageJsonPath);
|
|
43
45
|
if (!isInPackageManagerWorkspaces &&
|
|
@@ -45,7 +47,7 @@ exports.createNodesV2 = [
|
|
|
45
47
|
// Skip if package.json is not part of the package.json workspaces and not next to a project.json.
|
|
46
48
|
return null;
|
|
47
49
|
}
|
|
48
|
-
return createNodeFromPackageJson(packageJsonPath, context.workspaceRoot, cache, isInPackageManagerWorkspaces);
|
|
50
|
+
return createNodeFromPackageJson(packageJsonPath, context.workspaceRoot, cache, isInPackageManagerWorkspaces, packageManagerCommand);
|
|
49
51
|
}, packageJsons, _, context);
|
|
50
52
|
},
|
|
51
53
|
];
|
|
@@ -111,7 +113,7 @@ function buildPackageJsonWorkspacesMatcher(patterns) {
|
|
|
111
113
|
!patterns.negativeLookup[p] &&
|
|
112
114
|
patterns.negative.every((negative) => (0, minimatch_1.minimatch)(p, negative));
|
|
113
115
|
}
|
|
114
|
-
function createNodeFromPackageJson(pkgJsonPath, workspaceRoot, cache, isInPackageManagerWorkspaces) {
|
|
116
|
+
function createNodeFromPackageJson(pkgJsonPath, workspaceRoot, cache, isInPackageManagerWorkspaces, packageManagerCommand) {
|
|
115
117
|
const json = (0, fileutils_1.readJsonFile)((0, node_path_1.join)(workspaceRoot, pkgJsonPath));
|
|
116
118
|
const projectRoot = (0, node_path_1.dirname)(pkgJsonPath);
|
|
117
119
|
const hash = (0, file_hasher_1.hashObject)({
|
|
@@ -128,7 +130,7 @@ function createNodeFromPackageJson(pkgJsonPath, workspaceRoot, cache, isInPackag
|
|
|
128
130
|
},
|
|
129
131
|
};
|
|
130
132
|
}
|
|
131
|
-
const project = buildProjectConfigurationFromPackageJson(json, workspaceRoot, pkgJsonPath, (0, nx_json_1.readNxJson)(workspaceRoot), isInPackageManagerWorkspaces);
|
|
133
|
+
const project = buildProjectConfigurationFromPackageJson(json, workspaceRoot, pkgJsonPath, (0, nx_json_1.readNxJson)(workspaceRoot), isInPackageManagerWorkspaces, packageManagerCommand);
|
|
132
134
|
cache.set(hash, project);
|
|
133
135
|
return {
|
|
134
136
|
projects: {
|
|
@@ -136,7 +138,7 @@ function createNodeFromPackageJson(pkgJsonPath, workspaceRoot, cache, isInPackag
|
|
|
136
138
|
},
|
|
137
139
|
};
|
|
138
140
|
}
|
|
139
|
-
function buildProjectConfigurationFromPackageJson(packageJson, workspaceRoot, packageJsonPath, nxJson, isInPackageManagerWorkspaces) {
|
|
141
|
+
function buildProjectConfigurationFromPackageJson(packageJson, workspaceRoot, packageJsonPath, nxJson, isInPackageManagerWorkspaces, packageManagerCommand) {
|
|
140
142
|
const normalizedPath = packageJsonPath.split('\\').join('/');
|
|
141
143
|
const projectRoot = (0, node_path_1.dirname)(normalizedPath);
|
|
142
144
|
const siblingProjectJson = tryReadJson((0, node_path_1.join)(workspaceRoot, projectRoot, 'project.json'));
|
|
@@ -161,7 +163,7 @@ function buildProjectConfigurationFromPackageJson(packageJson, workspaceRoot, pa
|
|
|
161
163
|
root: projectRoot,
|
|
162
164
|
name,
|
|
163
165
|
...packageJson.nx,
|
|
164
|
-
targets: (0, package_json_1.readTargetsFromPackageJson)(packageJson, nxJson, projectRoot, workspaceRoot),
|
|
166
|
+
targets: (0, package_json_1.readTargetsFromPackageJson)(packageJson, nxJson, projectRoot, workspaceRoot, packageManagerCommand),
|
|
165
167
|
tags: (0, package_json_1.getTagsFromPackageJson)(packageJson),
|
|
166
168
|
metadata: (0, package_json_1.getMetadataFromPackageJson)(packageJson, isInPackageManagerWorkspaces),
|
|
167
169
|
};
|
|
@@ -16,16 +16,16 @@ export declare class ProcessTasks {
|
|
|
16
16
|
};
|
|
17
17
|
private readonly allTargetNames;
|
|
18
18
|
constructor(extraTargetDependencies: TargetDependencies, projectGraph: ProjectGraph);
|
|
19
|
-
processTasks(projectNames: string[], targets: string[], configuration: string, overrides:
|
|
20
|
-
processTask(task: Task, projectUsedToDeriveDependencies: string, configuration: string, overrides:
|
|
19
|
+
processTasks(projectNames: string[], targets: string[], configuration: string, overrides: Record<string, unknown>, excludeTaskDependencies: boolean): string[];
|
|
20
|
+
processTask(task: Task, projectUsedToDeriveDependencies: string, configuration: string, overrides: Record<string, unknown>): void;
|
|
21
21
|
private processTasksForMultipleProjects;
|
|
22
22
|
private processTasksForSingleProject;
|
|
23
23
|
private processTasksForDependencies;
|
|
24
24
|
private createDummyTask;
|
|
25
|
-
createTask(id: string, project: ProjectGraphProjectNode, target: string, resolvedConfiguration: string | undefined, overrides:
|
|
25
|
+
createTask(id: string, project: ProjectGraphProjectNode, target: string, resolvedConfiguration: string | undefined, overrides: Record<string, unknown>): Task;
|
|
26
26
|
resolveConfiguration(project: ProjectGraphProjectNode, target: string, configuration: string | undefined): string;
|
|
27
27
|
}
|
|
28
|
-
export declare function createTaskGraph(projectGraph: ProjectGraph, extraTargetDependencies: TargetDependencies, projectNames: string[], targets: string[], configuration: string | undefined, overrides:
|
|
28
|
+
export declare function createTaskGraph(projectGraph: ProjectGraph, extraTargetDependencies: TargetDependencies, projectNames: string[], targets: string[], configuration: string | undefined, overrides: Record<string, unknown>, excludeTaskDependencies?: boolean): TaskGraph;
|
|
29
29
|
export declare function mapTargetDefaultsToDependencies(defaults: TargetDefaults | undefined): TargetDependencies;
|
|
30
30
|
/**
|
|
31
31
|
* This function is used to filter out the dummy tasks from the dependencies
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { Task } from '../config/task-graph';
|
|
2
|
-
import { BatchInfo, BatchStatus, ExternalObject, TaskStatus as NativeTaskStatus } from '../native';
|
|
2
|
+
import { BatchInfo, BatchStatus, ExternalObject, TaskResult, TaskStatus as NativeTaskStatus } from '../native';
|
|
3
3
|
import { TaskStatus } from './tasks-runner';
|
|
4
4
|
/**
|
|
5
|
-
* The result of a completed {@link Task}
|
|
5
|
+
* The result of a completed {@link Task}.
|
|
6
|
+
*
|
|
7
|
+
* Defined as a Rust struct in `packages/nx/src/native/tasks/types.rs` and
|
|
8
|
+
* exposed to TypeScript via NAPI. Re-exported here so existing imports
|
|
9
|
+
* keep working.
|
|
6
10
|
*
|
|
7
11
|
* Task timing information (start and end timestamps) is available
|
|
8
12
|
* on the {@link Task} object itself via {@link Task.startTime} and
|
|
9
13
|
* {@link Task.endTime}.
|
|
10
14
|
*/
|
|
11
|
-
export
|
|
12
|
-
task: Task;
|
|
13
|
-
status: TaskStatus;
|
|
14
|
-
code: number;
|
|
15
|
-
terminalOutput?: string;
|
|
16
|
-
}
|
|
15
|
+
export type { TaskResult };
|
|
17
16
|
/**
|
|
18
17
|
* A map of {@link TaskResult} keyed by the ID of the completed {@link Task}s
|
|
19
18
|
*/
|
|
@@ -13,9 +13,10 @@ class InvokeRunnerTerminalOutputLifeCycle {
|
|
|
13
13
|
output_1.output.log({
|
|
14
14
|
color: 'cyan',
|
|
15
15
|
title: `Running ${this.tasks.length} tasks:`,
|
|
16
|
-
bodyLines: this.tasks.map((task) =>
|
|
17
|
-
|
|
18
|
-
: ''}`
|
|
16
|
+
bodyLines: this.tasks.map((task) => {
|
|
17
|
+
const unparsed = (0, utils_1.getUnparsedOverrideArgs)(task);
|
|
18
|
+
return `- Task ${task.id} ${unparsed.length > 0 ? `Overrides: ${unparsed.join(' ')}` : ''}`;
|
|
19
|
+
}),
|
|
19
20
|
});
|
|
20
21
|
output_1.output.addVerticalSeparatorWithoutNewLines('cyan');
|
|
21
22
|
}
|
|
@@ -24,9 +25,8 @@ class InvokeRunnerTerminalOutputLifeCycle {
|
|
|
24
25
|
const taskIds = this.tasks.map((task) => {
|
|
25
26
|
const cached = this.cachedTasks.indexOf(task) !== -1;
|
|
26
27
|
const failed = this.failedTasks.indexOf(task) !== -1;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
: ''} ${cached ? 'CACHED' : ''} ${failed ? 'FAILED' : ''}`;
|
|
28
|
+
const unparsed = (0, utils_1.getUnparsedOverrideArgs)(task);
|
|
29
|
+
return `- Task ${task.id} ${unparsed.length > 0 ? `Overrides: ${unparsed.join(' ')}` : ''} ${cached ? 'CACHED' : ''} ${failed ? 'FAILED' : ''}`;
|
|
30
30
|
});
|
|
31
31
|
if (this.failedTasks.length === 0) {
|
|
32
32
|
output_1.output.addVerticalSeparatorWithoutNewLines('green');
|
|
@@ -50,6 +50,7 @@ export declare function getCustomHasher(task: Task, projects: Record<string, Pro
|
|
|
50
50
|
export declare function removeTasksFromTaskGraph(graph: TaskGraph, ids: string[]): TaskGraph;
|
|
51
51
|
export declare function calculateReverseDeps(taskGraph: TaskGraph): Record<string, string[]>;
|
|
52
52
|
export declare function getCliPath(): string;
|
|
53
|
+
export declare function getUnparsedOverrideArgs(task: Task): string[];
|
|
53
54
|
export declare function getPrintableCommandArgsForTask(task: Task): string[];
|
|
54
55
|
export declare function getSerializedArgsForTask(task: Task, isVerbose: boolean): string[];
|
|
55
56
|
export declare function shouldStreamOutput(task: Task, initiatingProject: string | null): boolean;
|
|
@@ -20,6 +20,7 @@ exports.getCustomHasher = getCustomHasher;
|
|
|
20
20
|
exports.removeTasksFromTaskGraph = removeTasksFromTaskGraph;
|
|
21
21
|
exports.calculateReverseDeps = calculateReverseDeps;
|
|
22
22
|
exports.getCliPath = getCliPath;
|
|
23
|
+
exports.getUnparsedOverrideArgs = getUnparsedOverrideArgs;
|
|
23
24
|
exports.getPrintableCommandArgsForTask = getPrintableCommandArgsForTask;
|
|
24
25
|
exports.getSerializedArgsForTask = getSerializedArgsForTask;
|
|
25
26
|
exports.shouldStreamOutput = shouldStreamOutput;
|
|
@@ -206,7 +207,7 @@ function transformLegacyOutputs(projectRoot, outputs) {
|
|
|
206
207
|
function getOutputsForTargetAndConfiguration(taskTargetOrTask, overridesOrNode, node) {
|
|
207
208
|
const taskTarget = 'id' in taskTargetOrTask ? taskTargetOrTask.target : taskTargetOrTask;
|
|
208
209
|
const overrides = 'id' in taskTargetOrTask ? taskTargetOrTask.overrides : overridesOrNode;
|
|
209
|
-
node = 'id' in taskTargetOrTask ? overridesOrNode : node;
|
|
210
|
+
node = ('id' in taskTargetOrTask ? overridesOrNode : node);
|
|
210
211
|
const { target, configuration } = taskTarget;
|
|
211
212
|
const targetConfiguration = node.data.targets[target];
|
|
212
213
|
const options = {
|
|
@@ -385,8 +386,12 @@ function calculateReverseDeps(taskGraph) {
|
|
|
385
386
|
function getCliPath() {
|
|
386
387
|
return require.resolve(`../../bin/run-executor.js`);
|
|
387
388
|
}
|
|
389
|
+
function getUnparsedOverrideArgs(task) {
|
|
390
|
+
return task.overrides
|
|
391
|
+
.__overrides_unparsed__;
|
|
392
|
+
}
|
|
388
393
|
function getPrintableCommandArgsForTask(task) {
|
|
389
|
-
const args = task
|
|
394
|
+
const args = getUnparsedOverrideArgs(task);
|
|
390
395
|
const target = task.target.target.includes(':')
|
|
391
396
|
? `"${task.target.target}"`
|
|
392
397
|
: task.target.target;
|
|
@@ -13,8 +13,8 @@ const exit_codes_1 = require("./exit-codes");
|
|
|
13
13
|
function getRunNxBaseCommand(packageManagerCommand, cwd = process.cwd()) {
|
|
14
14
|
if ((0, fs_1.existsSync)((0, path_1.join)(workspace_root_1.workspaceRoot, 'package.json'))) {
|
|
15
15
|
if (!packageManagerCommand) {
|
|
16
|
-
const pm = (0, package_manager_1.detectPackageManager)();
|
|
17
|
-
packageManagerCommand = (0, package_manager_1.getPackageManagerCommand)(pm);
|
|
16
|
+
const pm = (0, package_manager_1.detectPackageManager)(workspace_root_1.workspaceRoot);
|
|
17
|
+
packageManagerCommand = (0, package_manager_1.getPackageManagerCommand)(pm, workspace_root_1.workspaceRoot);
|
|
18
18
|
}
|
|
19
19
|
return `${packageManagerCommand.exec} nx`;
|
|
20
20
|
}
|
|
@@ -94,7 +94,7 @@ export declare function readNxMigrateConfig(json: Partial<PackageJson>): NxMigra
|
|
|
94
94
|
export declare function buildTargetFromScript(script: string, scripts: Record<string, string>, packageManagerCommand: PackageManagerCommands): TargetConfiguration;
|
|
95
95
|
export declare function getMetadataFromPackageJson(packageJson: PackageJson, isInPackageManagerWorkspaces: boolean): ProjectMetadata;
|
|
96
96
|
export declare function getTagsFromPackageJson(packageJson: PackageJson): string[];
|
|
97
|
-
export declare function readTargetsFromPackageJson(packageJson: PackageJson, nxJson: NxJsonConfiguration, projectRoot: string, workspaceRoot: string): Record<string, TargetConfiguration<any>>;
|
|
97
|
+
export declare function readTargetsFromPackageJson(packageJson: PackageJson, nxJson: NxJsonConfiguration, projectRoot: string, workspaceRoot: string, packageManagerCommand: PackageManagerCommands): Record<string, TargetConfiguration<any>>;
|
|
98
98
|
/**
|
|
99
99
|
* Uses `require.resolve` to read the package.json for a module.
|
|
100
100
|
*
|
|
@@ -67,7 +67,6 @@ function buildTargetFromScript(script, scripts = {}, packageManagerCommand) {
|
|
|
67
67
|
},
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
-
let packageManagerCommand;
|
|
71
70
|
function getMetadataFromPackageJson(packageJson, isInPackageManagerWorkspaces) {
|
|
72
71
|
const { scripts, nx, description, name, exports, main, version } = packageJson;
|
|
73
72
|
const includedScripts = nx?.includedScripts || Object.keys(scripts ?? {});
|
|
@@ -95,12 +94,11 @@ function getTagsFromPackageJson(packageJson) {
|
|
|
95
94
|
}
|
|
96
95
|
return tags;
|
|
97
96
|
}
|
|
98
|
-
function readTargetsFromPackageJson(packageJson, nxJson, projectRoot, workspaceRoot) {
|
|
97
|
+
function readTargetsFromPackageJson(packageJson, nxJson, projectRoot, workspaceRoot, packageManagerCommand) {
|
|
99
98
|
const { scripts, nx, private: isPrivate } = packageJson ?? {};
|
|
100
99
|
const res = {};
|
|
101
100
|
const includedScripts = nx?.includedScripts || Object.keys(scripts ?? {});
|
|
102
101
|
for (const script of includedScripts) {
|
|
103
|
-
packageManagerCommand ??= (0, package_manager_1.getPackageManagerCommand)();
|
|
104
102
|
res[script] = buildTargetFromScript(script, scripts, packageManagerCommand);
|
|
105
103
|
}
|
|
106
104
|
for (const targetName in nx?.targets) {
|
|
@@ -210,11 +208,11 @@ function preparePackageInstallation(pkg, requiredVersion) {
|
|
|
210
208
|
cleanup: () => { },
|
|
211
209
|
};
|
|
212
210
|
console.log(`Fetching ${pkg}...`);
|
|
213
|
-
const packageManager = (0, package_manager_1.detectPackageManager)();
|
|
211
|
+
const packageManager = (0, package_manager_1.detectPackageManager)(workspace_root_1.workspaceRoot);
|
|
214
212
|
const isVerbose = process.env.NX_VERBOSE_LOGGING === 'true';
|
|
215
213
|
generatePackageManagerFiles(tempDir, packageManager);
|
|
216
|
-
const preInstallCommand = (0, package_manager_1.getPackageManagerCommand)(packageManager).preInstall;
|
|
217
214
|
const pmCommands = (0, package_manager_1.getPackageManagerCommand)(packageManager);
|
|
215
|
+
const preInstallCommand = pmCommands.preInstall;
|
|
218
216
|
let addCommand = pmCommands.addDev;
|
|
219
217
|
if (packageManager === 'pnpm') {
|
|
220
218
|
addCommand = 'pnpm add -D'; // we need to ensure that we are not using workspace command
|
|
@@ -21,8 +21,17 @@ interface PluginCacheData<T> {
|
|
|
21
21
|
export declare class PluginCache<T> {
|
|
22
22
|
private entries;
|
|
23
23
|
private accessOrder;
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
private cachePath;
|
|
25
|
+
/**
|
|
26
|
+
* Constructs a `PluginCache`. The `cachePath` is the single source of truth
|
|
27
|
+
* for both reading and writing — `writeToDisk()` writes to it.
|
|
28
|
+
*
|
|
29
|
+
* If `entries` is omitted, the cache is loaded from `cachePath` on disk.
|
|
30
|
+
* If `entries` is provided, those entries are used as the in-memory state
|
|
31
|
+
* and the on-disk file is not read (useful for tests or for seeding the
|
|
32
|
+
* cache with known state).
|
|
33
|
+
*/
|
|
34
|
+
constructor(cachePath: string, entries?: Record<string, T>, accessOrder?: string[] | Set<string>);
|
|
26
35
|
private touch;
|
|
27
36
|
/**
|
|
28
37
|
* Returns the value for `key`, or `undefined` if not present.
|
|
@@ -44,7 +53,7 @@ export declare class PluginCache<T> {
|
|
|
44
53
|
*/
|
|
45
54
|
toSerializable(): PluginCacheData<T>;
|
|
46
55
|
/**
|
|
47
|
-
* Safely writes this cache to
|
|
56
|
+
* Safely writes this cache to the path it was constructed with.
|
|
48
57
|
*
|
|
49
58
|
* Strategy:
|
|
50
59
|
* 1. Serialize to JSON
|
|
@@ -55,7 +64,7 @@ export declare class PluginCache<T> {
|
|
|
55
64
|
* 3. On total serialization failure (even after eviction),
|
|
56
65
|
* write an empty cache so the file is valid
|
|
57
66
|
*/
|
|
58
|
-
writeToDisk(
|
|
67
|
+
writeToDisk(): void;
|
|
59
68
|
/**
|
|
60
69
|
* Evicts the oldest 50% of entries (front of the access-order queue)
|
|
61
70
|
* and returns the remaining entries + accessOrder as a plain object.
|
|
@@ -20,17 +20,27 @@ const logger_1 = require("./logger");
|
|
|
20
20
|
* least recently used keys.
|
|
21
21
|
*/
|
|
22
22
|
class PluginCache {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Constructs a `PluginCache`. The `cachePath` is the single source of truth
|
|
25
|
+
* for both reading and writing — `writeToDisk()` writes to it.
|
|
26
|
+
*
|
|
27
|
+
* If `entries` is omitted, the cache is loaded from `cachePath` on disk.
|
|
28
|
+
* If `entries` is provided, those entries are used as the in-memory state
|
|
29
|
+
* and the on-disk file is not read (useful for tests or for seeding the
|
|
30
|
+
* cache with known state).
|
|
31
|
+
*/
|
|
32
|
+
constructor(cachePath, entries, accessOrder) {
|
|
33
|
+
this.cachePath = cachePath;
|
|
34
|
+
if (entries !== undefined) {
|
|
35
|
+
this.entries = entries;
|
|
31
36
|
this.accessOrder =
|
|
32
37
|
accessOrder instanceof Set ? accessOrder : new Set(accessOrder ?? []);
|
|
33
38
|
}
|
|
39
|
+
else {
|
|
40
|
+
const loaded = loadFromDisk(cachePath);
|
|
41
|
+
this.entries = loaded.entries;
|
|
42
|
+
this.accessOrder = loaded.accessOrder;
|
|
43
|
+
}
|
|
34
44
|
}
|
|
35
45
|
touch(key) {
|
|
36
46
|
// Sets are guaranteed to maintain insertion order, so we can delete and re-add to move it to the end.
|
|
@@ -73,7 +83,7 @@ class PluginCache {
|
|
|
73
83
|
};
|
|
74
84
|
}
|
|
75
85
|
/**
|
|
76
|
-
* Safely writes this cache to
|
|
86
|
+
* Safely writes this cache to the path it was constructed with.
|
|
77
87
|
*
|
|
78
88
|
* Strategy:
|
|
79
89
|
* 1. Serialize to JSON
|
|
@@ -84,8 +94,8 @@ class PluginCache {
|
|
|
84
94
|
* 3. On total serialization failure (even after eviction),
|
|
85
95
|
* write an empty cache so the file is valid
|
|
86
96
|
*/
|
|
87
|
-
writeToDisk(
|
|
88
|
-
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(cachePath), { recursive: true });
|
|
97
|
+
writeToDisk() {
|
|
98
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(this.cachePath), { recursive: true });
|
|
89
99
|
let content;
|
|
90
100
|
try {
|
|
91
101
|
content = JSON.stringify({
|
|
@@ -115,11 +125,11 @@ class PluginCache {
|
|
|
115
125
|
}
|
|
116
126
|
// Attempt to write the serialized content to disk
|
|
117
127
|
try {
|
|
118
|
-
(0, node_fs_1.writeFileSync)(cachePath, content);
|
|
128
|
+
(0, node_fs_1.writeFileSync)(this.cachePath, content);
|
|
119
129
|
}
|
|
120
130
|
catch {
|
|
121
131
|
// Filesystem error — wipe cache so a corrupted file doesn't persist
|
|
122
|
-
tryRemoveFile(cachePath);
|
|
132
|
+
tryRemoveFile(this.cachePath);
|
|
123
133
|
}
|
|
124
134
|
}
|
|
125
135
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nx",
|
|
3
|
-
"version": "23.0.0-beta.
|
|
3
|
+
"version": "23.0.0-beta.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
|
@@ -171,16 +171,16 @@
|
|
|
171
171
|
}
|
|
172
172
|
},
|
|
173
173
|
"optionalDependencies": {
|
|
174
|
-
"@nx/nx-darwin-arm64": "23.0.0-beta.
|
|
175
|
-
"@nx/nx-darwin-x64": "23.0.0-beta.
|
|
176
|
-
"@nx/nx-freebsd-x64": "23.0.0-beta.
|
|
177
|
-
"@nx/nx-linux-arm-gnueabihf": "23.0.0-beta.
|
|
178
|
-
"@nx/nx-linux-arm64-gnu": "23.0.0-beta.
|
|
179
|
-
"@nx/nx-linux-arm64-musl": "23.0.0-beta.
|
|
180
|
-
"@nx/nx-linux-x64-gnu": "23.0.0-beta.
|
|
181
|
-
"@nx/nx-linux-x64-musl": "23.0.0-beta.
|
|
182
|
-
"@nx/nx-win32-arm64-msvc": "23.0.0-beta.
|
|
183
|
-
"@nx/nx-win32-x64-msvc": "23.0.0-beta.
|
|
174
|
+
"@nx/nx-darwin-arm64": "23.0.0-beta.7",
|
|
175
|
+
"@nx/nx-darwin-x64": "23.0.0-beta.7",
|
|
176
|
+
"@nx/nx-freebsd-x64": "23.0.0-beta.7",
|
|
177
|
+
"@nx/nx-linux-arm-gnueabihf": "23.0.0-beta.7",
|
|
178
|
+
"@nx/nx-linux-arm64-gnu": "23.0.0-beta.7",
|
|
179
|
+
"@nx/nx-linux-arm64-musl": "23.0.0-beta.7",
|
|
180
|
+
"@nx/nx-linux-x64-gnu": "23.0.0-beta.7",
|
|
181
|
+
"@nx/nx-linux-x64-musl": "23.0.0-beta.7",
|
|
182
|
+
"@nx/nx-win32-arm64-msvc": "23.0.0-beta.7",
|
|
183
|
+
"@nx/nx-win32-x64-msvc": "23.0.0-beta.7"
|
|
184
184
|
},
|
|
185
185
|
"nx-migrations": {
|
|
186
186
|
"migrations": "./migrations.json",
|