nx 19.8.10 → 19.8.12
Sign up to get free protection for your applications and to get access to all the features.
- package/bin/nx.js +8 -0
- package/bin/post-install.js +2 -2
- package/package.json +12 -12
- package/src/daemon/server/shutdown-utils.js +2 -0
- package/src/native/index.d.ts +2 -0
- package/src/native/native-bindings.js +1 -0
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/project-graph/plugins/internal-api.d.ts +0 -4
- package/src/project-graph/plugins/internal-api.js +1 -6
- package/src/project-graph/plugins/isolation/messaging.d.ts +1 -5
- package/src/project-graph/plugins/isolation/plugin-pool.js +0 -22
- package/src/project-graph/plugins/isolation/plugin-worker.js +16 -15
- package/src/project-graph/utils/project-configuration-utils.js +4 -2
- package/src/tasks-runner/create-task-graph.d.ts +13 -16
- package/src/tasks-runner/create-task-graph.js +44 -48
- package/src/tasks-runner/task-graph-utils.d.ts +11 -0
- package/src/tasks-runner/task-graph-utils.js +23 -0
- package/src/utils/db-connection.d.ts +1 -0
- package/src/utils/db-connection.js +7 -0
package/bin/nx.js
CHANGED
@@ -16,6 +16,7 @@ const assert_supported_platform_1 = require("../src/native/assert-supported-plat
|
|
16
16
|
const perf_hooks_1 = require("perf_hooks");
|
17
17
|
const workspace_context_1 = require("../src/utils/workspace-context");
|
18
18
|
const client_1 = require("../src/daemon/client/client");
|
19
|
+
const db_connection_1 = require("../src/utils/db-connection");
|
19
20
|
function main() {
|
20
21
|
if (process.argv[2] !== 'report' &&
|
21
22
|
process.argv[2] !== '--version' &&
|
@@ -223,4 +224,11 @@ const getLatestVersionOfNx = ((fn) => {
|
|
223
224
|
let cache = null;
|
224
225
|
return () => cache || (cache = fn());
|
225
226
|
})(_getLatestVersionOfNx);
|
227
|
+
function nxCleanup() {
|
228
|
+
(0, db_connection_1.removeDbConnections)();
|
229
|
+
}
|
230
|
+
process.on('exit', nxCleanup);
|
231
|
+
process.on('SIGINT', nxCleanup);
|
232
|
+
process.on('SIGTERM', nxCleanup);
|
233
|
+
process.on('SIGHUP', nxCleanup);
|
226
234
|
main();
|
package/bin/post-install.js
CHANGED
@@ -10,14 +10,14 @@ const update_manager_1 = require("../src/nx-cloud/update-manager");
|
|
10
10
|
const get_cloud_options_1 = require("../src/nx-cloud/utilities/get-cloud-options");
|
11
11
|
const nx_cloud_utils_1 = require("../src/utils/nx-cloud-utils");
|
12
12
|
const nx_json_1 = require("../src/config/nx-json");
|
13
|
-
const workspace_context_1 = require("../src/utils/workspace-context");
|
14
13
|
const logger_1 = require("../src/utils/logger");
|
14
|
+
const workspace_context_1 = require("../src/utils/workspace-context");
|
15
15
|
(async () => {
|
16
16
|
const start = new Date();
|
17
17
|
try {
|
18
|
-
(0, workspace_context_1.setupWorkspaceContext)(workspace_root_1.workspaceRoot);
|
19
18
|
if (isMainNxPackage() && (0, fileutils_1.fileExists)((0, path_1.join)(workspace_root_1.workspaceRoot, 'nx.json'))) {
|
20
19
|
(0, assert_supported_platform_1.assertSupportedPlatform)();
|
20
|
+
(0, workspace_context_1.setupWorkspaceContext)(workspace_root_1.workspaceRoot);
|
21
21
|
try {
|
22
22
|
await client_1.daemonClient.stop();
|
23
23
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "nx",
|
3
|
-
"version": "19.8.
|
3
|
+
"version": "19.8.12",
|
4
4
|
"private": false,
|
5
5
|
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
6
6
|
"repository": {
|
@@ -67,7 +67,7 @@
|
|
67
67
|
"yargs-parser": "21.1.1",
|
68
68
|
"node-machine-id": "1.1.12",
|
69
69
|
"ora": "5.3.0",
|
70
|
-
"@nrwl/tao": "19.8.
|
70
|
+
"@nrwl/tao": "19.8.12"
|
71
71
|
},
|
72
72
|
"peerDependencies": {
|
73
73
|
"@swc-node/register": "^1.8.0",
|
@@ -82,16 +82,16 @@
|
|
82
82
|
}
|
83
83
|
},
|
84
84
|
"optionalDependencies": {
|
85
|
-
"@nx/nx-darwin-x64": "19.8.
|
86
|
-
"@nx/nx-darwin-arm64": "19.8.
|
87
|
-
"@nx/nx-linux-x64-gnu": "19.8.
|
88
|
-
"@nx/nx-linux-x64-musl": "19.8.
|
89
|
-
"@nx/nx-win32-x64-msvc": "19.8.
|
90
|
-
"@nx/nx-linux-arm64-gnu": "19.8.
|
91
|
-
"@nx/nx-linux-arm64-musl": "19.8.
|
92
|
-
"@nx/nx-linux-arm-gnueabihf": "19.8.
|
93
|
-
"@nx/nx-win32-arm64-msvc": "19.8.
|
94
|
-
"@nx/nx-freebsd-x64": "19.8.
|
85
|
+
"@nx/nx-darwin-x64": "19.8.12",
|
86
|
+
"@nx/nx-darwin-arm64": "19.8.12",
|
87
|
+
"@nx/nx-linux-x64-gnu": "19.8.12",
|
88
|
+
"@nx/nx-linux-x64-musl": "19.8.12",
|
89
|
+
"@nx/nx-win32-x64-msvc": "19.8.12",
|
90
|
+
"@nx/nx-linux-arm64-gnu": "19.8.12",
|
91
|
+
"@nx/nx-linux-arm64-musl": "19.8.12",
|
92
|
+
"@nx/nx-linux-arm-gnueabihf": "19.8.12",
|
93
|
+
"@nx/nx-win32-arm64-msvc": "19.8.12",
|
94
|
+
"@nx/nx-freebsd-x64": "19.8.12"
|
95
95
|
},
|
96
96
|
"nx-migrations": {
|
97
97
|
"migrations": "./migrations.json",
|
@@ -15,6 +15,7 @@ const socket_utils_1 = require("../socket-utils");
|
|
15
15
|
const cache_1 = require("../cache");
|
16
16
|
const plugins_1 = require("./plugins");
|
17
17
|
const error_types_1 = require("../../project-graph/error-types");
|
18
|
+
const db_connection_1 = require("../../utils/db-connection");
|
18
19
|
exports.SERVER_INACTIVITY_TIMEOUT_MS = 10800000; // 10800000 ms = 3 hours
|
19
20
|
let watcherInstance;
|
20
21
|
function storeWatcherInstance(instance) {
|
@@ -50,6 +51,7 @@ async function handleServerProcessTermination({ server, reason, sockets, }) {
|
|
50
51
|
}
|
51
52
|
(0, cache_1.deleteDaemonJsonProcessCache)();
|
52
53
|
(0, plugins_1.cleanupPlugins)();
|
54
|
+
(0, db_connection_1.removeDbConnections)();
|
53
55
|
logger_1.serverLogger.log(`Server stopped because: "${reason}"`);
|
54
56
|
}
|
55
57
|
finally {
|
package/src/native/index.d.ts
CHANGED
@@ -97,6 +97,8 @@ export interface CachedResult {
|
|
97
97
|
outputsPath: string
|
98
98
|
}
|
99
99
|
|
100
|
+
export declare export function closeDbConnection(connection: ExternalObject<NxDbConnection>): void
|
101
|
+
|
100
102
|
export declare export function connectToNxDb(cacheDir: string, nxVersion: string, dbName?: string | undefined | null): ExternalObject<NxDbConnection>
|
101
103
|
|
102
104
|
export declare export function copy(src: string, dest: string): void
|
@@ -371,6 +371,7 @@ module.exports.TaskDetails = nativeBinding.TaskDetails
|
|
371
371
|
module.exports.TaskHasher = nativeBinding.TaskHasher
|
372
372
|
module.exports.Watcher = nativeBinding.Watcher
|
373
373
|
module.exports.WorkspaceContext = nativeBinding.WorkspaceContext
|
374
|
+
module.exports.closeDbConnection = nativeBinding.closeDbConnection
|
374
375
|
module.exports.connectToNxDb = nativeBinding.connectToNxDb
|
375
376
|
module.exports.copy = nativeBinding.copy
|
376
377
|
module.exports.EventType = nativeBinding.EventType
|
Binary file
|
@@ -21,9 +21,5 @@ export type CreateNodesResultWithContext = CreateNodesResult & {
|
|
21
21
|
pluginName: string;
|
22
22
|
};
|
23
23
|
export type NormalizedPlugin = NxPluginV2 & Pick<NxPluginV1, 'processProjectGraph'>;
|
24
|
-
export declare const nxPluginCache: Map<unknown, [
|
25
|
-
Promise<LoadedNxPlugin>,
|
26
|
-
() => void
|
27
|
-
]>;
|
28
24
|
export declare function loadNxPlugins(plugins: PluginConfiguration[], root?: string): Promise<readonly [LoadedNxPlugin[], () => void]>;
|
29
25
|
export declare function getDefaultPlugins(root: string): Promise<string[]>;
|
@@ -2,7 +2,7 @@
|
|
2
2
|
// This file contains the bits and bobs of the internal API for loading and interacting with Nx plugins.
|
3
3
|
// For the public API, used by plugin authors, see `./public-api.ts`.
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
5
|
-
exports.
|
5
|
+
exports.LoadedNxPlugin = void 0;
|
6
6
|
exports.loadNxPlugins = loadNxPlugins;
|
7
7
|
exports.getDefaultPlugins = getDefaultPlugins;
|
8
8
|
const path_1 = require("path");
|
@@ -66,11 +66,6 @@ class LoadedNxPlugin {
|
|
66
66
|
}
|
67
67
|
}
|
68
68
|
exports.LoadedNxPlugin = LoadedNxPlugin;
|
69
|
-
// Short lived cache (cleared between cmd runs)
|
70
|
-
// holding resolved nx plugin objects.
|
71
|
-
// Allows loaded plugins to not be reloaded when
|
72
|
-
// referenced multiple times.
|
73
|
-
exports.nxPluginCache = new Map();
|
74
69
|
function isIsolationEnabled() {
|
75
70
|
// Explicitly enabled, regardless of further conditions
|
76
71
|
if (process.env.NX_ISOLATE_PLUGINS === 'true') {
|
@@ -106,11 +106,7 @@ export interface PluginWorkerProcessProjectGraphResult {
|
|
106
106
|
tx: string;
|
107
107
|
};
|
108
108
|
}
|
109
|
-
export
|
110
|
-
type: 'shutdown';
|
111
|
-
payload: {};
|
112
|
-
}
|
113
|
-
export type PluginWorkerMessage = PluginWorkerLoadMessage | PluginWorkerShutdownMessage | PluginWorkerCreateNodesMessage | PluginCreateDependenciesMessage | PluginWorkerProcessProjectGraphMessage | PluginCreateMetadataMessage;
|
109
|
+
export type PluginWorkerMessage = PluginWorkerLoadMessage | PluginWorkerCreateNodesMessage | PluginCreateDependenciesMessage | PluginWorkerProcessProjectGraphMessage | PluginCreateMetadataMessage;
|
114
110
|
export type PluginWorkerResult = PluginWorkerLoadResult | PluginWorkerCreateNodesResult | PluginCreateDependenciesResult | PluginWorkerProcessProjectGraphResult | PluginCreateMetadataResult;
|
115
111
|
export declare function isPluginWorkerMessage(message: Serializable): message is PluginWorkerMessage;
|
116
112
|
export declare function isPluginWorkerResult(message: Serializable): message is PluginWorkerResult;
|
@@ -4,12 +4,8 @@ exports.loadRemoteNxPlugin = loadRemoteNxPlugin;
|
|
4
4
|
const child_process_1 = require("child_process");
|
5
5
|
const path = require("path");
|
6
6
|
const net_1 = require("net");
|
7
|
-
// TODO (@AgentEnder): After scoped verbose logging is implemented, re-add verbose logs here.
|
8
|
-
// import { logger } from '../../utils/logger';
|
9
|
-
const internal_api_1 = require("../internal-api");
|
10
7
|
const socket_utils_1 = require("../../../daemon/socket-utils");
|
11
8
|
const consume_messages_from_socket_1 = require("../../../utils/consume-messages-from-socket");
|
12
|
-
const exit_codes_1 = require("../../../utils/exit-codes");
|
13
9
|
const messaging_1 = require("./messaging");
|
14
10
|
const cleanupFunctions = new Set();
|
15
11
|
const pluginNames = new Map();
|
@@ -29,7 +25,6 @@ async function loadRemoteNxPlugin(plugin, root) {
|
|
29
25
|
const exitHandler = createWorkerExitHandler(worker, pendingPromises);
|
30
26
|
const cleanupFunction = () => {
|
31
27
|
worker.off('exit', exitHandler);
|
32
|
-
shutdownPluginWorker(socket);
|
33
28
|
socket.destroy();
|
34
29
|
nxPluginWorkerCache.delete(cacheKey);
|
35
30
|
};
|
@@ -55,9 +50,6 @@ async function loadRemoteNxPlugin(plugin, root) {
|
|
55
50
|
nxPluginWorkerCache.set(cacheKey, pluginPromise);
|
56
51
|
return [pluginPromise, cleanupFunction];
|
57
52
|
}
|
58
|
-
function shutdownPluginWorker(socket) {
|
59
|
-
(0, messaging_1.sendMessageOverSocket)(socket, { type: 'shutdown', payload: {} });
|
60
|
-
}
|
61
53
|
/**
|
62
54
|
* Creates a message handler for the given worker.
|
63
55
|
* @param worker Instance of plugin-worker
|
@@ -195,20 +187,6 @@ function createWorkerExitHandler(worker, pendingPromises) {
|
|
195
187
|
}
|
196
188
|
};
|
197
189
|
}
|
198
|
-
let cleanedUp = false;
|
199
|
-
const exitHandler = () => {
|
200
|
-
internal_api_1.nxPluginCache.clear();
|
201
|
-
for (const fn of cleanupFunctions) {
|
202
|
-
fn();
|
203
|
-
}
|
204
|
-
cleanedUp = true;
|
205
|
-
};
|
206
|
-
process.on('exit', exitHandler);
|
207
|
-
process.on('SIGINT', () => {
|
208
|
-
exitHandler();
|
209
|
-
process.exit((0, exit_codes_1.signalToCode)('SIGINT'));
|
210
|
-
});
|
211
|
-
process.on('SIGTERM', exitHandler);
|
212
190
|
function registerPendingPromise(tx, pending, callback, context) {
|
213
191
|
let resolver, rejector, timeout;
|
214
192
|
const promise = new Promise((res, rej) => {
|
@@ -49,21 +49,6 @@ const server = (0, net_1.createServer)((socket) => {
|
|
49
49
|
};
|
50
50
|
}
|
51
51
|
},
|
52
|
-
shutdown: async () => {
|
53
|
-
// Stops accepting new connections, but existing connections are
|
54
|
-
// not closed immediately.
|
55
|
-
server.close(() => {
|
56
|
-
try {
|
57
|
-
(0, fs_1.unlinkSync)(socketPath);
|
58
|
-
}
|
59
|
-
catch (e) { }
|
60
|
-
process.exit(0);
|
61
|
-
});
|
62
|
-
// Closes existing connection.
|
63
|
-
socket.end();
|
64
|
-
// Destroys the socket once it's fully closed.
|
65
|
-
socket.destroySoon();
|
66
|
-
},
|
67
52
|
createNodes: async ({ configFiles, context, tx }) => {
|
68
53
|
try {
|
69
54
|
const result = await plugin.createNodes[1](configFiles, context);
|
@@ -142,6 +127,22 @@ const server = (0, net_1.createServer)((socket) => {
|
|
142
127
|
},
|
143
128
|
});
|
144
129
|
}));
|
130
|
+
// There should only ever be one host -> worker connection
|
131
|
+
// since the worker is spawned per host process. As such,
|
132
|
+
// we can safely close the worker when the host disconnects.
|
133
|
+
socket.on('end', () => {
|
134
|
+
// Stops accepting new connections, but existing connections are
|
135
|
+
// not closed immediately.
|
136
|
+
server.close(() => {
|
137
|
+
try {
|
138
|
+
(0, fs_1.unlinkSync)(socketPath);
|
139
|
+
}
|
140
|
+
catch (e) { }
|
141
|
+
process.exit(0);
|
142
|
+
});
|
143
|
+
// Destroys the socket once it's fully closed.
|
144
|
+
socket.destroySoon();
|
145
|
+
});
|
145
146
|
});
|
146
147
|
server.listen(socketPath);
|
147
148
|
const exitHandler = (exitCode) => () => {
|
@@ -253,8 +253,10 @@ plugins) {
|
|
253
253
|
else {
|
254
254
|
errorBodyLines.push(` - ${e.message}`);
|
255
255
|
}
|
256
|
-
|
257
|
-
|
256
|
+
if (e.stack) {
|
257
|
+
const innerStackTrace = ' ' + e.stack.split('\n')?.join('\n ');
|
258
|
+
errorBodyLines.push(innerStackTrace);
|
259
|
+
}
|
258
260
|
}
|
259
261
|
error.stack = errorBodyLines.join('\n');
|
260
262
|
// This represents a single plugin erroring out with a hard error.
|
@@ -22,22 +22,19 @@ export declare class ProcessTasks {
|
|
22
22
|
createTask(id: string, project: ProjectGraphProjectNode, target: string, resolvedConfiguration: string | undefined, overrides: Object): Task;
|
23
23
|
resolveConfiguration(project: ProjectGraphProjectNode, target: string, configuration: string | undefined): string;
|
24
24
|
getId(project: string, target: string, configuration: string | undefined): string;
|
25
|
-
/**
|
26
|
-
* this function is used to get the non dummy dependencies of a task recursively
|
27
|
-
* For example, when we have the following dependencies:
|
28
|
-
* {
|
29
|
-
* 'app1:compile': [ 'app2:__nx_dummy_task__' ],
|
30
|
-
* 'app2:__nx_dummy_task__': [ 'app3:__nx_dummy_task__' ],
|
31
|
-
* 'app3:__nx_dummy_task__': [ 'app4:precompile' ],
|
32
|
-
* 'app4:precompile': []
|
33
|
-
* }
|
34
|
-
* getNonDummyDeps('app1:compile') will return ['app1:compile']
|
35
|
-
* getNonDummyDeps('app2:__nx_dummy_task__') will return ['app4:precompile']
|
36
|
-
* getNonDummyDeps('app3:__nx_dummy_task__') will return ['app4:precompile']
|
37
|
-
* getNonDummyDeps('app4:precompile') will return ['app4:precompile']
|
38
|
-
*/
|
39
|
-
private getNonDummyDeps;
|
40
|
-
private filterDummyTasks;
|
41
25
|
}
|
42
26
|
export declare function createTaskGraph(projectGraph: ProjectGraph, extraTargetDependencies: TargetDependencies, projectNames: string[], targets: string[], configuration: string | undefined, overrides: Object, excludeTaskDependencies?: boolean): TaskGraph;
|
43
27
|
export declare function mapTargetDefaultsToDependencies(defaults: TargetDefaults | undefined): TargetDependencies;
|
28
|
+
/**
|
29
|
+
* This function is used to filter out the dummy tasks from the dependencies
|
30
|
+
* It will manipulate the dependencies object in place
|
31
|
+
*/
|
32
|
+
export declare function filterDummyTasks(dependencies: {
|
33
|
+
[k: string]: string[];
|
34
|
+
}): void;
|
35
|
+
/**
|
36
|
+
* this function is used to get the non dummy dependencies of a task recursively
|
37
|
+
*/
|
38
|
+
export declare function getNonDummyDeps(currentTask: string, dependencies: {
|
39
|
+
[k: string]: string[];
|
40
|
+
}, cycles?: Set<string>, seen?: Set<string>): string[];
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ProcessTasks = void 0;
|
4
4
|
exports.createTaskGraph = createTaskGraph;
|
5
5
|
exports.mapTargetDefaultsToDependencies = mapTargetDefaultsToDependencies;
|
6
|
+
exports.filterDummyTasks = filterDummyTasks;
|
7
|
+
exports.getNonDummyDeps = getNonDummyDeps;
|
6
8
|
const utils_1 = require("./utils");
|
7
9
|
const project_graph_utils_1 = require("../utils/project-graph-utils");
|
8
10
|
const output_1 = require("../utils/output");
|
@@ -54,7 +56,7 @@ class ProcessTasks {
|
|
54
56
|
this.dependencies[d] = this.dependencies[d].filter((dd) => !!initialTasks[dd]);
|
55
57
|
}
|
56
58
|
}
|
57
|
-
this.
|
59
|
+
filterDummyTasks(this.dependencies);
|
58
60
|
for (const taskId of Object.keys(this.dependencies)) {
|
59
61
|
if (this.dependencies[taskId].length > 0) {
|
60
62
|
this.dependencies[taskId] = [
|
@@ -138,7 +140,7 @@ class ProcessTasks {
|
|
138
140
|
}
|
139
141
|
}
|
140
142
|
else {
|
141
|
-
const dummyId = this.getId(depProject.name, DUMMY_TASK_TARGET, undefined);
|
143
|
+
const dummyId = this.getId(depProject.name, task.target.target + DUMMY_TASK_TARGET, undefined);
|
142
144
|
this.dependencies[task.id].push(dummyId);
|
143
145
|
this.dependencies[dummyId] ??= [];
|
144
146
|
const noopTask = this.createDummyTask(dummyId, task);
|
@@ -189,52 +191,6 @@ class ProcessTasks {
|
|
189
191
|
}
|
190
192
|
return id;
|
191
193
|
}
|
192
|
-
/**
|
193
|
-
* this function is used to get the non dummy dependencies of a task recursively
|
194
|
-
* For example, when we have the following dependencies:
|
195
|
-
* {
|
196
|
-
* 'app1:compile': [ 'app2:__nx_dummy_task__' ],
|
197
|
-
* 'app2:__nx_dummy_task__': [ 'app3:__nx_dummy_task__' ],
|
198
|
-
* 'app3:__nx_dummy_task__': [ 'app4:precompile' ],
|
199
|
-
* 'app4:precompile': []
|
200
|
-
* }
|
201
|
-
* getNonDummyDeps('app1:compile') will return ['app1:compile']
|
202
|
-
* getNonDummyDeps('app2:__nx_dummy_task__') will return ['app4:precompile']
|
203
|
-
* getNonDummyDeps('app3:__nx_dummy_task__') will return ['app4:precompile']
|
204
|
-
* getNonDummyDeps('app4:precompile') will return ['app4:precompile']
|
205
|
-
*/
|
206
|
-
getNonDummyDeps(currentTask, originalTask, cycle) {
|
207
|
-
if (currentTask === originalTask) {
|
208
|
-
return [];
|
209
|
-
}
|
210
|
-
else if (currentTask.endsWith(DUMMY_TASK_TARGET)) {
|
211
|
-
if (cycle?.length && cycle?.includes(currentTask)) {
|
212
|
-
return [];
|
213
|
-
}
|
214
|
-
// if not a cycle, recursively get the non dummy dependencies
|
215
|
-
return (this.dependencies[currentTask]?.flatMap((dep) => this.getNonDummyDeps(dep, originalTask, cycle)) ?? []);
|
216
|
-
}
|
217
|
-
else {
|
218
|
-
return [currentTask];
|
219
|
-
}
|
220
|
-
}
|
221
|
-
filterDummyTasks() {
|
222
|
-
const cycle = (0, task_graph_utils_1.findCycle)({ dependencies: this.dependencies });
|
223
|
-
for (const [key, deps] of Object.entries(this.dependencies)) {
|
224
|
-
if (!key.endsWith(DUMMY_TASK_TARGET)) {
|
225
|
-
const normalizedDeps = [];
|
226
|
-
for (const dep of deps) {
|
227
|
-
normalizedDeps.push(...this.getNonDummyDeps(dep, key, cycle));
|
228
|
-
}
|
229
|
-
this.dependencies[key] = normalizedDeps;
|
230
|
-
}
|
231
|
-
}
|
232
|
-
for (const key of Object.keys(this.dependencies)) {
|
233
|
-
if (key.endsWith(DUMMY_TASK_TARGET)) {
|
234
|
-
delete this.dependencies[key];
|
235
|
-
}
|
236
|
-
}
|
237
|
-
}
|
238
194
|
}
|
239
195
|
exports.ProcessTasks = ProcessTasks;
|
240
196
|
function createTaskGraph(projectGraph, extraTargetDependencies, projectNames, targets, configuration, overrides, excludeTaskDependencies = false) {
|
@@ -268,3 +224,43 @@ function interpolateOverrides(args, projectName, project) {
|
|
268
224
|
});
|
269
225
|
return interpolatedArgs;
|
270
226
|
}
|
227
|
+
/**
|
228
|
+
* This function is used to filter out the dummy tasks from the dependencies
|
229
|
+
* It will manipulate the dependencies object in place
|
230
|
+
*/
|
231
|
+
function filterDummyTasks(dependencies) {
|
232
|
+
const cycles = (0, task_graph_utils_1.findCycles)({ dependencies });
|
233
|
+
for (const [key, deps] of Object.entries(dependencies)) {
|
234
|
+
if (!key.endsWith(DUMMY_TASK_TARGET)) {
|
235
|
+
const normalizedDeps = [];
|
236
|
+
for (const dep of deps) {
|
237
|
+
normalizedDeps.push(...getNonDummyDeps(dep, dependencies, cycles, new Set([key])));
|
238
|
+
}
|
239
|
+
dependencies[key] = normalizedDeps;
|
240
|
+
}
|
241
|
+
}
|
242
|
+
for (const key of Object.keys(dependencies)) {
|
243
|
+
if (key.endsWith(DUMMY_TASK_TARGET)) {
|
244
|
+
delete dependencies[key];
|
245
|
+
}
|
246
|
+
}
|
247
|
+
}
|
248
|
+
/**
|
249
|
+
* this function is used to get the non dummy dependencies of a task recursively
|
250
|
+
*/
|
251
|
+
function getNonDummyDeps(currentTask, dependencies, cycles, seen = new Set()) {
|
252
|
+
if (seen.has(currentTask)) {
|
253
|
+
return [];
|
254
|
+
}
|
255
|
+
seen.add(currentTask);
|
256
|
+
if (currentTask.endsWith(DUMMY_TASK_TARGET)) {
|
257
|
+
if (cycles?.has(currentTask)) {
|
258
|
+
return [];
|
259
|
+
}
|
260
|
+
// if not a cycle, recursively get the non dummy dependencies
|
261
|
+
return (dependencies[currentTask]?.flatMap((dep) => getNonDummyDeps(dep, dependencies, cycles, seen)) ?? []);
|
262
|
+
}
|
263
|
+
else {
|
264
|
+
return [currentTask];
|
265
|
+
}
|
266
|
+
}
|
@@ -1,8 +1,19 @@
|
|
1
1
|
import { ProjectGraph } from '../config/project-graph';
|
2
2
|
import { TaskGraph } from '../config/task-graph';
|
3
|
+
/**
|
4
|
+
* This function finds a cycle in the graph.
|
5
|
+
* @returns the first cycle found, or null if no cycle is found.
|
6
|
+
*/
|
3
7
|
export declare function findCycle(graph: {
|
4
8
|
dependencies: Record<string, string[]>;
|
5
9
|
}): string[] | null;
|
10
|
+
/**
|
11
|
+
* This function finds all cycles in the graph.
|
12
|
+
* @returns a list of unique task ids in all cycles found, or null if no cycle is found.
|
13
|
+
*/
|
14
|
+
export declare function findCycles(graph: {
|
15
|
+
dependencies: Record<string, string[]>;
|
16
|
+
}): Set<string> | null;
|
6
17
|
export declare function makeAcyclic(graph: {
|
7
18
|
roots: string[];
|
8
19
|
dependencies: Record<string, string[]>;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.findCycle = findCycle;
|
4
|
+
exports.findCycles = findCycles;
|
4
5
|
exports.makeAcyclic = makeAcyclic;
|
5
6
|
exports.validateNoAtomizedTasks = validateNoAtomizedTasks;
|
6
7
|
const output_1 = require("../utils/output");
|
@@ -17,6 +18,10 @@ function _findCycle(graph, id, visited, path) {
|
|
17
18
|
}
|
18
19
|
return null;
|
19
20
|
}
|
21
|
+
/**
|
22
|
+
* This function finds a cycle in the graph.
|
23
|
+
* @returns the first cycle found, or null if no cycle is found.
|
24
|
+
*/
|
20
25
|
function findCycle(graph) {
|
21
26
|
const visited = {};
|
22
27
|
for (const t of Object.keys(graph.dependencies)) {
|
@@ -29,6 +34,24 @@ function findCycle(graph) {
|
|
29
34
|
}
|
30
35
|
return null;
|
31
36
|
}
|
37
|
+
/**
|
38
|
+
* This function finds all cycles in the graph.
|
39
|
+
* @returns a list of unique task ids in all cycles found, or null if no cycle is found.
|
40
|
+
*/
|
41
|
+
function findCycles(graph) {
|
42
|
+
const visited = {};
|
43
|
+
const cycles = new Set();
|
44
|
+
for (const t of Object.keys(graph.dependencies)) {
|
45
|
+
visited[t] = false;
|
46
|
+
}
|
47
|
+
for (const t of Object.keys(graph.dependencies)) {
|
48
|
+
const cycle = _findCycle(graph, t, visited, [t]);
|
49
|
+
if (cycle) {
|
50
|
+
cycle.forEach((t) => cycles.add(t));
|
51
|
+
}
|
52
|
+
}
|
53
|
+
return cycles.size ? cycles : null;
|
54
|
+
}
|
32
55
|
function _makeAcyclic(graph, id, visited, path) {
|
33
56
|
if (visited[id])
|
34
57
|
return;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.getDbConnection = getDbConnection;
|
4
|
+
exports.removeDbConnections = removeDbConnections;
|
4
5
|
const native_1 = require("../native");
|
5
6
|
const cache_directory_1 = require("./cache-directory");
|
6
7
|
const package_json_1 = require("../../package.json");
|
@@ -11,6 +12,12 @@ function getDbConnection(opts = {}) {
|
|
11
12
|
const connection = getEntryOrSet(dbConnectionMap, key, () => (0, native_1.connectToNxDb)(opts.directory, package_json_1.version, opts.dbName));
|
12
13
|
return connection;
|
13
14
|
}
|
15
|
+
function removeDbConnections() {
|
16
|
+
for (const connection of dbConnectionMap.values()) {
|
17
|
+
(0, native_1.closeDbConnection)(connection);
|
18
|
+
}
|
19
|
+
dbConnectionMap.clear();
|
20
|
+
}
|
14
21
|
function getEntryOrSet(map, key, defaultValue) {
|
15
22
|
const existing = map.get(key);
|
16
23
|
if (existing) {
|