nx 19.8.2 → 19.8.4
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/.eslintrc.json +12 -2
- package/package.json +12 -12
- package/src/command-line/add/add.js +2 -2
- package/src/command-line/import/utils/prepare-source-repo.js +8 -3
- package/src/command-line/nx-commands.js +31 -10
- package/src/command-line/release/utils/print-changes.js +6 -4
- package/src/command-line/release/utils/resolve-nx-json-error-message.js +4 -3
- package/src/command-line/reset/reset.js +16 -9
- package/src/command-line/yargs-utils/shared-options.js +2 -2
- package/src/core/graph/main.js +1 -1
- package/src/executors/run-commands/run-commands.impl.js +15 -22
- package/src/hasher/hash-task.d.ts +4 -2
- package/src/hasher/hash-task.js +6 -9
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +54 -6
- package/src/nx-cloud/utilities/axios.js +1 -2
- package/src/nx-cloud/utilities/onboarding.js +2 -2
- package/src/nx-cloud/utilities/url-shorten.js +5 -5
- package/src/project-graph/utils/project-configuration-utils.js +1 -1
- package/src/tasks-runner/cache.d.ts +2 -1
- package/src/tasks-runner/cache.js +10 -6
- package/src/tasks-runner/create-task-graph.d.ts +2 -0
- package/src/tasks-runner/create-task-graph.js +39 -5
- package/src/tasks-runner/life-cycles/dynamic-run-many-terminal-output-life-cycle.js +5 -0
- package/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +7 -0
- package/src/tasks-runner/run-command.js +3 -1
- package/src/tasks-runner/task-orchestrator.d.ts +1 -0
- package/src/tasks-runner/task-orchestrator.js +7 -3
- package/src/tasks-runner/tasks-schedule.d.ts +1 -0
- package/src/tasks-runner/tasks-schedule.js +6 -2
- package/src/utils/git-utils.js +2 -2
- package/src/utils/plugins/output.js +1 -1
@@ -16,22 +16,11 @@ let pseudoTerminal;
|
|
16
16
|
const childProcesses = new Set();
|
17
17
|
function loadEnvVarsFile(path, env = {}) {
|
18
18
|
(0, task_env_1.unloadDotEnvFile)(path, env);
|
19
|
-
const result = (0, task_env_1.loadAndExpandDotEnvFile)(path, env
|
19
|
+
const result = (0, task_env_1.loadAndExpandDotEnvFile)(path, env);
|
20
20
|
if (result.error) {
|
21
21
|
throw result.error;
|
22
22
|
}
|
23
23
|
}
|
24
|
-
function loadEnvVars(path, env = {}) {
|
25
|
-
if (path) {
|
26
|
-
loadEnvVarsFile(path, env);
|
27
|
-
}
|
28
|
-
else {
|
29
|
-
try {
|
30
|
-
loadEnvVarsFile('.env', env);
|
31
|
-
}
|
32
|
-
catch { }
|
33
|
-
}
|
34
|
-
}
|
35
24
|
const propKeys = [
|
36
25
|
'command',
|
37
26
|
'commands',
|
@@ -292,20 +281,24 @@ function calculateCwd(cwd, context) {
|
|
292
281
|
return cwd;
|
293
282
|
return path.join(context.root, cwd);
|
294
283
|
}
|
295
|
-
|
296
|
-
|
297
|
-
|
284
|
+
/**
|
285
|
+
* Env variables are processed in the following order:
|
286
|
+
* - env option from executor options
|
287
|
+
* - env file from envFile option if provided
|
288
|
+
* - local env variables
|
289
|
+
*/
|
290
|
+
function processEnv(color, cwd, envOptionFromExecutor, envFile) {
|
291
|
+
let localEnv = (0, npm_run_path_1.env)({ cwd: cwd ?? process.cwd() });
|
292
|
+
localEnv = {
|
298
293
|
...process.env,
|
299
294
|
...localEnv,
|
300
295
|
};
|
301
|
-
|
302
|
-
|
303
|
-
loadEnvVars(envFile, res);
|
296
|
+
if (process.env.NX_LOAD_DOT_ENV_FILES !== 'false' && envFile) {
|
297
|
+
loadEnvVarsFile(envFile, localEnv);
|
304
298
|
}
|
305
|
-
|
306
|
-
|
307
|
-
...
|
308
|
-
...env,
|
299
|
+
let res = {
|
300
|
+
...localEnv,
|
301
|
+
...envOptionFromExecutor,
|
309
302
|
};
|
310
303
|
// need to override PATH to make sure we are using the local node_modules
|
311
304
|
if (localEnv.PATH)
|
@@ -2,5 +2,7 @@ import { Task, TaskGraph } from '../config/task-graph';
|
|
2
2
|
import { TaskHasher } from './task-hasher';
|
3
3
|
import { ProjectGraph } from '../config/project-graph';
|
4
4
|
import { NxJsonConfiguration } from '../config/nx-json';
|
5
|
-
|
6
|
-
export declare function
|
5
|
+
import { TaskDetails } from '../native';
|
6
|
+
export declare function getTaskDetails(): TaskDetails | null;
|
7
|
+
export declare function hashTasksThatDoNotDependOnOutputsOfOtherTasks(hasher: TaskHasher, projectGraph: ProjectGraph, taskGraph: TaskGraph, nxJson: NxJsonConfiguration, tasksDetails: TaskDetails | null): Promise<void>;
|
8
|
+
export declare function hashTask(hasher: TaskHasher, projectGraph: ProjectGraph, taskGraph: TaskGraph, task: Task, env: NodeJS.ProcessEnv, taskDetails: TaskDetails | null): Promise<void>;
|
package/src/hasher/hash-task.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getTaskDetails = getTaskDetails;
|
3
4
|
exports.hashTasksThatDoNotDependOnOutputsOfOtherTasks = hashTasksThatDoNotDependOnOutputsOfOtherTasks;
|
4
5
|
exports.hashTask = hashTask;
|
5
6
|
const utils_1 = require("../tasks-runner/utils");
|
@@ -19,9 +20,8 @@ function getTaskDetails() {
|
|
19
20
|
}
|
20
21
|
return taskDetails;
|
21
22
|
}
|
22
|
-
async function hashTasksThatDoNotDependOnOutputsOfOtherTasks(hasher, projectGraph, taskGraph, nxJson) {
|
23
|
+
async function hashTasksThatDoNotDependOnOutputsOfOtherTasks(hasher, projectGraph, taskGraph, nxJson, tasksDetails) {
|
23
24
|
performance.mark('hashMultipleTasks:start');
|
24
|
-
const taskDetails = getTaskDetails();
|
25
25
|
const tasks = Object.values(taskGraph.tasks);
|
26
26
|
const tasksWithHashers = await Promise.all(tasks.map(async (task) => {
|
27
27
|
const customHasher = (0, utils_1.getCustomHasher)(task, projectGraph);
|
@@ -42,9 +42,8 @@ async function hashTasksThatDoNotDependOnOutputsOfOtherTasks(hasher, projectGrap
|
|
42
42
|
tasksToHash[i].hash = hashes[i].value;
|
43
43
|
tasksToHash[i].hashDetails = hashes[i].details;
|
44
44
|
}
|
45
|
-
|
46
|
-
|
47
|
-
taskDetails.recordTaskDetails(tasksToHash.map((task) => ({
|
45
|
+
if (tasksDetails?.recordTaskDetails) {
|
46
|
+
tasksDetails.recordTaskDetails(tasksToHash.map((task) => ({
|
48
47
|
hash: task.hash,
|
49
48
|
project: task.target.project,
|
50
49
|
target: task.target.target,
|
@@ -54,9 +53,8 @@ async function hashTasksThatDoNotDependOnOutputsOfOtherTasks(hasher, projectGrap
|
|
54
53
|
performance.mark('hashMultipleTasks:end');
|
55
54
|
performance.measure('hashMultipleTasks', 'hashMultipleTasks:start', 'hashMultipleTasks:end');
|
56
55
|
}
|
57
|
-
async function hashTask(hasher, projectGraph, taskGraph, task, env) {
|
56
|
+
async function hashTask(hasher, projectGraph, taskGraph, task, env, taskDetails) {
|
58
57
|
performance.mark('hashSingleTask:start');
|
59
|
-
const taskDetails = getTaskDetails();
|
60
58
|
const customHasher = (0, utils_1.getCustomHasher)(task, projectGraph);
|
61
59
|
const projectsConfigurations = (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph);
|
62
60
|
const { value, details } = await (customHasher
|
@@ -72,8 +70,7 @@ async function hashTask(hasher, projectGraph, taskGraph, task, env) {
|
|
72
70
|
: hasher.hashTask(task, taskGraph, env));
|
73
71
|
task.hash = value;
|
74
72
|
task.hashDetails = details;
|
75
|
-
|
76
|
-
if (taskDetails) {
|
73
|
+
if (taskDetails?.recordTaskDetails) {
|
77
74
|
taskDetails.recordTaskDetails([
|
78
75
|
{
|
79
76
|
hash: task.hash,
|
Binary file
|
@@ -42,6 +42,18 @@ function getNxInitDate() {
|
|
42
42
|
return null;
|
43
43
|
}
|
44
44
|
}
|
45
|
+
async function createNxCloudWorkspaceV1(workspaceName, installationSource, nxInitDate) {
|
46
|
+
const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
|
47
|
+
const response = await require('axios').post(`${apiUrl}/nx-cloud/create-org-and-workspace`, {
|
48
|
+
workspaceName,
|
49
|
+
installationSource,
|
50
|
+
nxInitDate,
|
51
|
+
});
|
52
|
+
if (response.data.message) {
|
53
|
+
throw new Error(response.data.message);
|
54
|
+
}
|
55
|
+
return response.data;
|
56
|
+
}
|
45
57
|
async function createNxCloudWorkspaceV2(workspaceName, installationSource, nxInitDate) {
|
46
58
|
const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
|
47
59
|
const response = await require('axios').post(`${apiUrl}/nx-cloud/v2/create-org-and-workspace`, {
|
@@ -69,6 +81,19 @@ async function printSuccessMessage(token, installationSource, usesGithub) {
|
|
69
81
|
});
|
70
82
|
return connectCloudUrl;
|
71
83
|
}
|
84
|
+
function addNxCloudAccessTokenToNxJson(tree, token, directory = '') {
|
85
|
+
const nxJsonPath = (0, path_1.join)(directory, 'nx.json');
|
86
|
+
if (tree.exists(nxJsonPath)) {
|
87
|
+
(0, json_1.updateJson)(tree, (0, path_1.join)(directory, 'nx.json'), (nxJson) => {
|
88
|
+
const overrideUrl = process.env.NX_CLOUD_API || process.env.NRWL_API;
|
89
|
+
if (overrideUrl) {
|
90
|
+
nxJson.nxCloudUrl = overrideUrl;
|
91
|
+
}
|
92
|
+
nxJson.nxCloudAccessToken = token;
|
93
|
+
return nxJson;
|
94
|
+
});
|
95
|
+
}
|
96
|
+
}
|
72
97
|
function addNxCloudIdToNxJson(tree, nxCloudId, directory = '') {
|
73
98
|
const nxJsonPath = (0, path_1.join)(directory, 'nx.json');
|
74
99
|
if (tree.exists(nxJsonPath)) {
|
@@ -89,6 +114,7 @@ async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)
|
|
89
114
|
return null;
|
90
115
|
}
|
91
116
|
const isGitHubDetected = schema.github ?? (await (0, url_shorten_1.repoUsesGithub)(schema.github));
|
117
|
+
let responseFromCreateNxCloudWorkspaceV1;
|
92
118
|
let responseFromCreateNxCloudWorkspaceV2;
|
93
119
|
/**
|
94
120
|
* Do not create an Nx Cloud token if the user is using GitHub and
|
@@ -98,12 +124,34 @@ async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)
|
|
98
124
|
isGitHubDetected &&
|
99
125
|
schema.installationSource === 'nx-connect')
|
100
126
|
return null;
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
127
|
+
try {
|
128
|
+
responseFromCreateNxCloudWorkspaceV2 = await createNxCloudWorkspaceV2(getRootPackageName(tree), schema.installationSource, getNxInitDate());
|
129
|
+
}
|
130
|
+
catch (e) {
|
131
|
+
if (e.response?.status === 404) {
|
132
|
+
responseFromCreateNxCloudWorkspaceV1 = await createNxCloudWorkspaceV1(getRootPackageName(tree), schema.installationSource, getNxInitDate());
|
133
|
+
}
|
134
|
+
else {
|
135
|
+
throw e;
|
136
|
+
}
|
137
|
+
}
|
138
|
+
if (responseFromCreateNxCloudWorkspaceV2) {
|
139
|
+
addNxCloudIdToNxJson(tree, responseFromCreateNxCloudWorkspaceV2?.nxCloudId, schema.directory);
|
140
|
+
await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
|
141
|
+
silent: schema.hideFormatLogs,
|
142
|
+
});
|
143
|
+
return responseFromCreateNxCloudWorkspaceV2.nxCloudId;
|
144
|
+
}
|
145
|
+
else if (responseFromCreateNxCloudWorkspaceV1) {
|
146
|
+
addNxCloudAccessTokenToNxJson(tree, responseFromCreateNxCloudWorkspaceV1?.token, schema.directory);
|
147
|
+
await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
|
148
|
+
silent: schema.hideFormatLogs,
|
149
|
+
});
|
150
|
+
return responseFromCreateNxCloudWorkspaceV1.token;
|
151
|
+
}
|
152
|
+
else {
|
153
|
+
throw new Error('Could not create an Nx Cloud Workspace. Please try again.');
|
154
|
+
}
|
107
155
|
}
|
108
156
|
async function connectToNxCloudGenerator(tree, options) {
|
109
157
|
await connectToNxCloud(tree, options);
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createApiAxiosInstance = createApiAxiosInstance;
|
4
4
|
const path_1 = require("path");
|
5
5
|
const environment_1 = require("./environment");
|
6
|
-
const axios = require('axios');
|
7
6
|
function createApiAxiosInstance(options) {
|
8
7
|
let axiosConfigBuilder = (axiosConfig) => axiosConfig;
|
9
8
|
const baseUrl = process.env.NX_CLOUD_API || options.url || 'https://cloud.nx.app';
|
@@ -17,7 +16,7 @@ function createApiAxiosInstance(options) {
|
|
17
16
|
const { nxCloudProxyConfig } = require((0, path_1.join)(process.cwd(), options.customProxyConfigPath));
|
18
17
|
axiosConfigBuilder = nxCloudProxyConfig ?? axiosConfigBuilder;
|
19
18
|
}
|
20
|
-
return axios.create(axiosConfigBuilder({
|
19
|
+
return require('axios').create(axiosConfigBuilder({
|
21
20
|
baseURL: baseUrl,
|
22
21
|
timeout: environment_1.NX_CLOUD_NO_TIMEOUTS ? environment_1.UNLIMITED_TIMEOUT : 10000,
|
23
22
|
headers: { authorization: accessToken },
|
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createNxCloudOnboardingURLForWelcomeApp = createNxCloudOnboardingURLForWelcomeApp;
|
4
4
|
exports.getNxCloudAppOnBoardingUrl = getNxCloudAppOnBoardingUrl;
|
5
5
|
exports.readNxCloudToken = readNxCloudToken;
|
6
|
-
const devkit_exports_1 = require("../../devkit-exports");
|
7
6
|
const is_workspace_claimed_1 = require("./is-workspace-claimed");
|
8
7
|
const url_shorten_1 = require("./url-shorten");
|
9
8
|
const run_command_1 = require("../../tasks-runner/run-command");
|
9
|
+
const nx_json_1 = require("../../generators/utils/nx-json");
|
10
10
|
async function createNxCloudOnboardingURLForWelcomeApp(tree, token) {
|
11
11
|
token = token || readNxCloudToken(tree);
|
12
12
|
if (!token) {
|
@@ -22,7 +22,7 @@ async function getNxCloudAppOnBoardingUrl(token) {
|
|
22
22
|
return onboardingUrl;
|
23
23
|
}
|
24
24
|
function readNxCloudToken(tree) {
|
25
|
-
const nxJson = (0,
|
25
|
+
const nxJson = (0, nx_json_1.readNxJson)(tree);
|
26
26
|
const { accessToken, nxCloudId } = (0, run_command_1.getRunnerOptions)('default', nxJson, {}, true);
|
27
27
|
return accessToken || nxCloudId;
|
28
28
|
}
|
@@ -7,7 +7,7 @@ exports.getNxCloudVersion = getNxCloudVersion;
|
|
7
7
|
exports.removeVersionModifier = removeVersionModifier;
|
8
8
|
exports.versionIsValid = versionIsValid;
|
9
9
|
exports.compareCleanCloudVersions = compareCleanCloudVersions;
|
10
|
-
const
|
10
|
+
const logger_1 = require("../../utils/logger");
|
11
11
|
const git_utils_1 = require("../../utils/git-utils");
|
12
12
|
const get_cloud_options_1 = require("./get-cloud-options");
|
13
13
|
/**
|
@@ -27,7 +27,7 @@ async function createNxCloudOnboardingURL(onboardingSource, accessToken, usesGit
|
|
27
27
|
}
|
28
28
|
}
|
29
29
|
catch (e) {
|
30
|
-
|
30
|
+
logger_1.logger.verbose(`Failed to get Nx Cloud version.
|
31
31
|
${e}`);
|
32
32
|
return apiUrl;
|
33
33
|
}
|
@@ -46,7 +46,7 @@ async function createNxCloudOnboardingURL(onboardingSource, accessToken, usesGit
|
|
46
46
|
return `${apiUrl}/connect/${response.data}`;
|
47
47
|
}
|
48
48
|
catch (e) {
|
49
|
-
|
49
|
+
logger_1.logger.verbose(`Failed to shorten Nx Cloud URL.
|
50
50
|
${e}`);
|
51
51
|
return getURLifShortenFailed(usesGithub, githubSlug === 'github' ? null : githubSlug, apiUrl, source, accessToken);
|
52
52
|
}
|
@@ -96,7 +96,7 @@ async function getInstallationSupportsGitHub(apiUrl) {
|
|
96
96
|
}
|
97
97
|
catch (e) {
|
98
98
|
if (process.env.NX_VERBOSE_LOGGING === 'true') {
|
99
|
-
|
99
|
+
logger_1.logger.warn(`Failed to access system features. GitHub integration assumed to be disabled.
|
100
100
|
${e}`);
|
101
101
|
}
|
102
102
|
return false;
|
@@ -116,7 +116,7 @@ async function getNxCloudVersion(apiUrl) {
|
|
116
116
|
return version;
|
117
117
|
}
|
118
118
|
catch (e) {
|
119
|
-
|
119
|
+
logger_1.logger.verbose(`Failed to get version of Nx Cloud.
|
120
120
|
${e}`);
|
121
121
|
return null;
|
122
122
|
}
|
@@ -184,7 +184,7 @@ function mergeMetadata(sourceMap, sourceInformation, baseSourceMapPath, metadata
|
|
184
184
|
}
|
185
185
|
}
|
186
186
|
else {
|
187
|
-
result[metadataKey] = value;
|
187
|
+
result[metadataKey][key] = value[key];
|
188
188
|
if (sourceMap) {
|
189
189
|
sourceMap[`${baseSourceMapPath}.${metadataKey}`] =
|
190
190
|
sourceInformation;
|
@@ -11,7 +11,8 @@ export type TaskWithCachedResult = {
|
|
11
11
|
task: Task;
|
12
12
|
cachedResult: CachedResult;
|
13
13
|
};
|
14
|
-
export declare function
|
14
|
+
export declare function dbCacheEnabled(nxJson?: NxJsonConfiguration): boolean;
|
15
|
+
export declare function getCache(options: DefaultTasksRunnerOptions): DbCache | Cache;
|
15
16
|
export declare class DbCache {
|
16
17
|
private readonly options;
|
17
18
|
private cache;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.Cache = exports.DbCache = void 0;
|
4
|
+
exports.dbCacheEnabled = dbCacheEnabled;
|
4
5
|
exports.getCache = getCache;
|
5
6
|
const workspace_root_1 = require("../utils/workspace-root");
|
6
7
|
const path_1 = require("path");
|
@@ -19,14 +20,17 @@ const update_manager_1 = require("../nx-cloud/update-manager");
|
|
19
20
|
const get_cloud_options_1 = require("../nx-cloud/utilities/get-cloud-options");
|
20
21
|
const is_ci_1 = require("../utils/is-ci");
|
21
22
|
const output_1 = require("../utils/output");
|
22
|
-
function
|
23
|
-
return process.env.NX_DISABLE_DB !== 'true' &&
|
24
|
-
(nxJson.enableDbCache === true || process.env.NX_DB_CACHE === 'true')
|
23
|
+
function dbCacheEnabled(nxJson = (0, nx_json_1.readNxJson)()) {
|
24
|
+
return (process.env.NX_DISABLE_DB !== 'true' &&
|
25
|
+
(nxJson.enableDbCache === true || process.env.NX_DB_CACHE === 'true'));
|
26
|
+
}
|
27
|
+
// Do not change the order of these arguments as this function is used by nx cloud
|
28
|
+
function getCache(options) {
|
29
|
+
const nxJson = (0, nx_json_1.readNxJson)();
|
30
|
+
return dbCacheEnabled(nxJson)
|
25
31
|
? new DbCache({
|
26
32
|
// Remove this in Nx 21
|
27
|
-
nxCloudRemoteCache: (0, nx_cloud_utils_1.isNxCloudUsed)(
|
28
|
-
? options.remoteCache
|
29
|
-
: null,
|
33
|
+
nxCloudRemoteCache: (0, nx_cloud_utils_1.isNxCloudUsed)(nxJson) ? options.remoteCache : null,
|
30
34
|
})
|
31
35
|
: new Cache(options);
|
32
36
|
}
|
@@ -18,9 +18,11 @@ export declare class ProcessTasks {
|
|
18
18
|
private processTasksForMultipleProjects;
|
19
19
|
private processTasksForSingleProject;
|
20
20
|
private processTasksForDependencies;
|
21
|
+
private createDummyTask;
|
21
22
|
createTask(id: string, project: ProjectGraphProjectNode, target: string, resolvedConfiguration: string | undefined, overrides: Object): Task;
|
22
23
|
resolveConfiguration(project: ProjectGraphProjectNode, target: string, configuration: string | undefined): string;
|
23
24
|
getId(project: string, target: string, configuration: string | undefined): string;
|
25
|
+
private filterDummyTasks;
|
24
26
|
}
|
25
27
|
export declare function createTaskGraph(projectGraph: ProjectGraph, extraTargetDependencies: TargetDependencies, projectNames: string[], targets: string[], configuration: string | undefined, overrides: Object, excludeTaskDependencies?: boolean): TaskGraph;
|
26
28
|
export declare function mapTargetDefaultsToDependencies(defaults: TargetDefaults | undefined): TargetDependencies;
|
@@ -6,6 +6,7 @@ exports.mapTargetDefaultsToDependencies = mapTargetDefaultsToDependencies;
|
|
6
6
|
const utils_1 = require("./utils");
|
7
7
|
const project_graph_utils_1 = require("../utils/project-graph-utils");
|
8
8
|
const output_1 = require("../utils/output");
|
9
|
+
const DUMMY_TASK_TARGET = '__nx_dummy_task__';
|
9
10
|
class ProcessTasks {
|
10
11
|
constructor(extraTargetDependencies, projectGraph) {
|
11
12
|
this.extraTargetDependencies = extraTargetDependencies;
|
@@ -52,10 +53,11 @@ class ProcessTasks {
|
|
52
53
|
this.dependencies[d] = this.dependencies[d].filter((dd) => !!initialTasks[dd]);
|
53
54
|
}
|
54
55
|
}
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
this.filterDummyTasks();
|
57
|
+
for (const taskId of Object.keys(this.dependencies)) {
|
58
|
+
if (this.dependencies[taskId].length > 0) {
|
59
|
+
this.dependencies[taskId] = [
|
60
|
+
...new Set(this.dependencies[taskId].filter((d) => d !== taskId)).values(),
|
59
61
|
];
|
60
62
|
}
|
61
63
|
}
|
@@ -113,6 +115,9 @@ class ProcessTasks {
|
|
113
115
|
}
|
114
116
|
}
|
115
117
|
processTasksForDependencies(projectUsedToDeriveDependencies, dependencyConfig, configuration, task, taskOverrides, overrides) {
|
118
|
+
if (!this.projectGraph.dependencies.hasOwnProperty(projectUsedToDeriveDependencies)) {
|
119
|
+
return;
|
120
|
+
}
|
116
121
|
for (const dep of this.projectGraph.dependencies[projectUsedToDeriveDependencies]) {
|
117
122
|
const depProject = this.projectGraph.nodes[dep.target];
|
118
123
|
// this is to handle external dependencies
|
@@ -132,10 +137,20 @@ class ProcessTasks {
|
|
132
137
|
}
|
133
138
|
}
|
134
139
|
else {
|
135
|
-
this.
|
140
|
+
const dummyId = this.getId(depProject.name, DUMMY_TASK_TARGET, undefined);
|
141
|
+
this.dependencies[task.id].push(dummyId);
|
142
|
+
this.dependencies[dummyId] = [];
|
143
|
+
const noopTask = this.createDummyTask(dummyId, task);
|
144
|
+
this.processTask(noopTask, depProject.name, configuration, overrides);
|
136
145
|
}
|
137
146
|
}
|
138
147
|
}
|
148
|
+
createDummyTask(id, task) {
|
149
|
+
return {
|
150
|
+
...task,
|
151
|
+
id,
|
152
|
+
};
|
153
|
+
}
|
139
154
|
createTask(id, project, target, resolvedConfiguration, overrides) {
|
140
155
|
if (!project.data.targets[target]) {
|
141
156
|
throw new Error(`Cannot find configuration for task ${project.name}:${target}`);
|
@@ -173,6 +188,25 @@ class ProcessTasks {
|
|
173
188
|
}
|
174
189
|
return id;
|
175
190
|
}
|
191
|
+
filterDummyTasks() {
|
192
|
+
for (const [key, deps] of Object.entries(this.dependencies)) {
|
193
|
+
const normalizedDeps = [];
|
194
|
+
for (const dep of deps) {
|
195
|
+
if (dep.endsWith(DUMMY_TASK_TARGET)) {
|
196
|
+
normalizedDeps.push(...this.dependencies[dep].filter((d) => !d.endsWith(DUMMY_TASK_TARGET)));
|
197
|
+
}
|
198
|
+
else {
|
199
|
+
normalizedDeps.push(dep);
|
200
|
+
}
|
201
|
+
}
|
202
|
+
this.dependencies[key] = normalizedDeps;
|
203
|
+
}
|
204
|
+
for (const key of Object.keys(this.dependencies)) {
|
205
|
+
if (key.endsWith(DUMMY_TASK_TARGET)) {
|
206
|
+
delete this.dependencies[key];
|
207
|
+
}
|
208
|
+
}
|
209
|
+
}
|
176
210
|
}
|
177
211
|
exports.ProcessTasks = ProcessTasks;
|
178
212
|
function createTaskGraph(projectGraph, extraTargetDependencies, projectNames, targets, configuration, overrides, excludeTaskDependencies = false) {
|
@@ -224,6 +224,11 @@ async function createRunManyDynamicOutputRenderer({ projectNames, tasks, args, o
|
|
224
224
|
clearRenderInterval();
|
225
225
|
const timeTakenText = (0, pretty_time_1.prettyTime)(process.hrtime(start));
|
226
226
|
moveCursorToStartOfPinnedFooter();
|
227
|
+
if (totalTasks === 0) {
|
228
|
+
renderPinnedFooter([output_1.output.applyNxPrefix('gray', 'No tasks were run')]);
|
229
|
+
resolveRenderIsDonePromise();
|
230
|
+
return;
|
231
|
+
}
|
227
232
|
if (totalSuccessfulTasks === totalTasks) {
|
228
233
|
const text = `Successfully ran ${(0, formatting_utils_1.formatTargetsAndProjects)(projectNames, targets, tasks)}`;
|
229
234
|
const taskOverridesRows = [];
|
@@ -23,6 +23,9 @@ class StaticRunManyTerminalOutputLifeCycle {
|
|
23
23
|
this.allCompletedTasks = new Map();
|
24
24
|
}
|
25
25
|
startCommand() {
|
26
|
+
if (this.tasks.length === 0) {
|
27
|
+
return;
|
28
|
+
}
|
26
29
|
if (this.projectNames.length <= 0) {
|
27
30
|
output_1.output.logSingleLine(`No projects with ${(0, formatting_utils_1.formatTargetsAndProjects)(this.projectNames, this.args.targets, this.tasks)} were run`);
|
28
31
|
return;
|
@@ -45,6 +48,10 @@ class StaticRunManyTerminalOutputLifeCycle {
|
|
45
48
|
}
|
46
49
|
endCommand() {
|
47
50
|
output_1.output.addNewline();
|
51
|
+
if (this.tasks.length === 0) {
|
52
|
+
output_1.output.logSingleLine(`No tasks were run`);
|
53
|
+
return;
|
54
|
+
}
|
48
55
|
if (this.failedTasks.length === 0) {
|
49
56
|
output_1.output.addVerticalSeparatorWithoutNewLines('green');
|
50
57
|
const bodyLines = this.cachedTasks.length > 0
|
@@ -363,12 +363,14 @@ function setEnvVarsBasedOnArgs(nxArgs, loadDotEnvFiles) {
|
|
363
363
|
}
|
364
364
|
async function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, }) {
|
365
365
|
setEnvVarsBasedOnArgs(nxArgs, loadDotEnvFiles);
|
366
|
+
// this needs to be done before we start to run the tasks
|
367
|
+
const taskDetails = (0, hash_task_1.getTaskDetails)();
|
366
368
|
const { tasksRunner, runnerOptions } = getRunner(nxArgs, nxJson);
|
367
369
|
let hasher = (0, create_task_hasher_1.createTaskHasher)(projectGraph, nxJson, runnerOptions);
|
368
370
|
// this is used for two reasons: to fetch all remote cache hits AND
|
369
371
|
// to submit everything that is known in advance to Nx Cloud to run in
|
370
372
|
// a distributed fashion
|
371
|
-
await (0, hash_task_1.hashTasksThatDoNotDependOnOutputsOfOtherTasks)(hasher, projectGraph, taskGraph, nxJson);
|
373
|
+
await (0, hash_task_1.hashTasksThatDoNotDependOnOutputsOfOtherTasks)(hasher, projectGraph, taskGraph, nxJson, taskDetails);
|
372
374
|
const taskResultsLifecycle = new task_results_life_cycle_1.TaskResultsLifeCycle();
|
373
375
|
const compositedLifeCycle = new life_cycle_1.CompositeLifeCycle([
|
374
376
|
...constructLifeCycles(lifeCycle),
|
@@ -27,7 +27,8 @@ class TaskOrchestrator {
|
|
27
27
|
this.bail = bail;
|
28
28
|
this.daemon = daemon;
|
29
29
|
this.outputStyle = outputStyle;
|
30
|
-
this.
|
30
|
+
this.taskDetails = (0, hash_task_1.getTaskDetails)();
|
31
|
+
this.cache = (0, cache_1.getCache)(this.options);
|
31
32
|
this.forkedProcessTaskRunner = new forked_process_task_runner_1.ForkedProcessTaskRunner(this.options);
|
32
33
|
this.tasksSchedule = new tasks_schedule_1.TasksSchedule(this.projectGraph, this.taskGraph, this.options);
|
33
34
|
// region internal state
|
@@ -93,7 +94,7 @@ class TaskOrchestrator {
|
|
93
94
|
const task = this.taskGraph.tasks[taskId];
|
94
95
|
const taskSpecificEnv = (0, task_env_1.getTaskSpecificEnv)(task);
|
95
96
|
if (!task.hash) {
|
96
|
-
await (0, hash_task_1.hashTask)(this.hasher, this.projectGraph, this.taskGraph, task, taskSpecificEnv);
|
97
|
+
await (0, hash_task_1.hashTask)(this.hasher, this.projectGraph, this.taskGraph, task, taskSpecificEnv, this.taskDetails);
|
97
98
|
}
|
98
99
|
await this.options.lifeCycle.scheduleTask(task);
|
99
100
|
return taskSpecificEnv;
|
@@ -101,7 +102,7 @@ class TaskOrchestrator {
|
|
101
102
|
async processScheduledBatch(batch) {
|
102
103
|
await Promise.all(Object.values(batch.taskGraph.tasks).map(async (task) => {
|
103
104
|
if (!task.hash) {
|
104
|
-
await (0, hash_task_1.hashTask)(this.hasher, this.projectGraph, this.taskGraph, task, this.batchEnv);
|
105
|
+
await (0, hash_task_1.hashTask)(this.hasher, this.projectGraph, this.taskGraph, task, this.batchEnv, this.taskDetails);
|
105
106
|
}
|
106
107
|
await this.options.lifeCycle.scheduleTask(task);
|
107
108
|
}));
|
@@ -321,6 +322,9 @@ class TaskOrchestrator {
|
|
321
322
|
};
|
322
323
|
}
|
323
324
|
catch (e) {
|
325
|
+
if (process.env.NX_VERBOSE_LOGGING === 'true') {
|
326
|
+
console.error(e);
|
327
|
+
}
|
324
328
|
return {
|
325
329
|
code: 1,
|
326
330
|
};
|
@@ -19,6 +19,7 @@ export declare class TasksSchedule {
|
|
19
19
|
private completedTasks;
|
20
20
|
private scheduleRequestsExecutionChain;
|
21
21
|
private estimatedTaskTimings;
|
22
|
+
private projectDependencies;
|
22
23
|
constructor(projectGraph: ProjectGraph, taskGraph: TaskGraph, options: DefaultTasksRunnerOptions);
|
23
24
|
init(): Promise<void>;
|
24
25
|
scheduleNextTasks(): Promise<void>;
|
@@ -20,12 +20,16 @@ class TasksSchedule {
|
|
20
20
|
this.completedTasks = new Set();
|
21
21
|
this.scheduleRequestsExecutionChain = Promise.resolve();
|
22
22
|
this.estimatedTaskTimings = {};
|
23
|
+
this.projectDependencies = {};
|
23
24
|
}
|
24
25
|
async init() {
|
25
26
|
if (this.taskHistory) {
|
26
27
|
this.estimatedTaskTimings =
|
27
28
|
await this.taskHistory.getEstimatedTaskTimings(Object.values(this.taskGraph.tasks).map((t) => t.target));
|
28
29
|
}
|
30
|
+
for (const project of Object.values(this.taskGraph.tasks).map((t) => t.target.project)) {
|
31
|
+
this.projectDependencies[project] ??= (0, project_graph_utils_1.findAllProjectNodeDependencies)(project, this.reverseProjectGraph).length;
|
32
|
+
}
|
29
33
|
}
|
30
34
|
async scheduleNextTasks() {
|
31
35
|
this.scheduleRequestsExecutionChain =
|
@@ -90,8 +94,8 @@ class TasksSchedule {
|
|
90
94
|
// Most likely tasks with no dependencies such as test
|
91
95
|
const project1 = this.taskGraph.tasks[taskId1].target.project;
|
92
96
|
const project2 = this.taskGraph.tasks[taskId2].target.project;
|
93
|
-
const project1NodeDependencies =
|
94
|
-
const project2NodeDependencies =
|
97
|
+
const project1NodeDependencies = this.projectDependencies[project1];
|
98
|
+
const project2NodeDependencies = this.projectDependencies[project2];
|
95
99
|
const dependenciesDiff = project2NodeDependencies - project1NodeDependencies;
|
96
100
|
if (dependenciesDiff !== 0) {
|
97
101
|
return dependenciesDiff;
|
package/src/utils/git-utils.js
CHANGED
@@ -8,7 +8,7 @@ exports.commitChanges = commitChanges;
|
|
8
8
|
exports.getLatestCommitSha = getLatestCommitSha;
|
9
9
|
const child_process_1 = require("child_process");
|
10
10
|
const path_1 = require("path");
|
11
|
-
const
|
11
|
+
const logger_1 = require("./logger");
|
12
12
|
function execAsync(command, execOptions) {
|
13
13
|
return new Promise((res, rej) => {
|
14
14
|
(0, child_process_1.exec)(command, execOptions, (err, stdout, stderr) => {
|
@@ -236,7 +236,7 @@ function commitChanges(commitMessage, directory) {
|
|
236
236
|
// We don't want to throw during create-nx-workspace
|
237
237
|
// because maybe there was an error when setting up git
|
238
238
|
// initially.
|
239
|
-
|
239
|
+
logger_1.logger.verbose(`Git may not be set up correctly for this new workspace.
|
240
240
|
${err}`);
|
241
241
|
}
|
242
242
|
else {
|
@@ -47,7 +47,7 @@ function listAlsoAvailableCorePlugins(installedPlugins) {
|
|
47
47
|
}
|
48
48
|
}
|
49
49
|
function listPowerpackPlugins() {
|
50
|
-
const powerpackLink = 'https://nx.dev/plugin-registry';
|
50
|
+
const powerpackLink = 'https://nx.dev/plugin-registry#powerpack';
|
51
51
|
output_1.output.log({
|
52
52
|
title: `Available Powerpack Plugins: ${powerpackLink}`,
|
53
53
|
});
|