nx 19.7.2 → 19.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +12 -12
- package/src/command-line/add/add.js +2 -2
- package/src/command-line/affected/command-object.js +6 -6
- package/src/command-line/deprecated/command-objects.js +3 -3
- package/src/command-line/generate/generate.js +2 -1
- package/src/command-line/import/command-object.js +8 -6
- package/src/command-line/import/import.d.ts +1 -1
- package/src/command-line/import/import.js +42 -27
- package/src/command-line/login/login.js +2 -2
- package/src/command-line/logout/logout.js +2 -2
- package/src/command-line/migrate/migrate.js +2 -2
- package/src/command-line/new/new.js +2 -1
- package/src/command-line/release/changelog.js +2 -2
- package/src/command-line/release/plan-check.js +2 -2
- package/src/command-line/release/plan.js +2 -2
- package/src/command-line/release/publish.js +2 -2
- package/src/command-line/release/release.js +2 -2
- package/src/command-line/release/version.js +2 -1
- package/src/command-line/repair/repair.js +2 -2
- package/src/command-line/run/command-object.js +3 -3
- package/src/command-line/run/run.js +3 -2
- package/src/command-line/run-many/command-object.js +2 -2
- package/src/command-line/show/command-object.js +3 -3
- package/src/command-line/sync/sync.js +69 -11
- package/src/daemon/client/client.d.ts +3 -3
- package/src/daemon/server/handle-flush-sync-generator-changes-to-disk.js +2 -2
- package/src/daemon/server/handle-get-sync-generator-changes.js +8 -6
- package/src/daemon/server/sync-generators.d.ts +4 -4
- package/src/daemon/server/sync-generators.js +11 -2
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +0 -1
- package/src/nx-cloud/utilities/get-cloud-options.d.ts +1 -0
- package/src/nx-cloud/utilities/get-cloud-options.js +4 -0
- package/src/nx-cloud/utilities/is-workspace-claimed.d.ts +1 -1
- package/src/nx-cloud/utilities/is-workspace-claimed.js +6 -5
- package/src/nx-cloud/utilities/onboarding.js +2 -2
- package/src/project-graph/error-types.d.ts +1 -1
- package/src/project-graph/error-types.js +19 -5
- package/src/tasks-runner/run-command.js +139 -29
- package/src/utils/handle-errors.d.ts +1 -0
- package/src/utils/handle-errors.js +71 -0
- package/src/utils/nx-cloud-utils.d.ts +0 -1
- package/src/utils/nx-cloud-utils.js +0 -10
- package/src/utils/params.d.ts +0 -1
- package/src/utils/params.js +0 -50
- package/src/utils/plugins/plugin-capabilities.js +4 -1
- package/src/utils/sync-generators.d.ts +35 -6
- package/src/utils/sync-generators.js +144 -47
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.yargsShowCommand = void 0;
|
4
4
|
const yargs_1 = require("yargs");
|
5
5
|
const shared_options_1 = require("../yargs-utils/shared-options");
|
6
|
-
const
|
6
|
+
const handle_errors_1 = require("../../utils/handle-errors");
|
7
7
|
exports.yargsShowCommand = {
|
8
8
|
command: 'show',
|
9
9
|
describe: 'Show information about the workspace (e.g., list of projects).',
|
@@ -65,7 +65,7 @@ const showProjectsCommand = {
|
|
65
65
|
.example('$0 show projects --type app --affected', 'Show affected apps in the workspace')
|
66
66
|
.example('$0 show projects --affected --exclude=*-e2e', 'Show affected projects in the workspace, excluding end-to-end projects'),
|
67
67
|
handler: async (args) => {
|
68
|
-
const exitCode = await (0,
|
68
|
+
const exitCode = await (0, handle_errors_1.handleErrors)(args.verbose, async () => {
|
69
69
|
const { showProjectsHandler } = await Promise.resolve().then(() => require('./projects'));
|
70
70
|
await showProjectsHandler(args);
|
71
71
|
});
|
@@ -106,7 +106,7 @@ const showProjectCommand = {
|
|
106
106
|
.example('$0 show project my-app', 'View project information for my-app in JSON format')
|
107
107
|
.example('$0 show project my-app --web', 'View project information for my-app in the browser'),
|
108
108
|
handler: async (args) => {
|
109
|
-
const exitCode = await (0,
|
109
|
+
const exitCode = await (0, handle_errors_1.handleErrors)(args.verbose, async () => {
|
110
110
|
const { showProjectHandler } = await Promise.resolve().then(() => require('./project'));
|
111
111
|
await showProjectHandler(args);
|
112
112
|
});
|
@@ -5,11 +5,11 @@ const ora = require("ora");
|
|
5
5
|
const nx_json_1 = require("../../config/nx-json");
|
6
6
|
const project_graph_1 = require("../../project-graph/project-graph");
|
7
7
|
const output_1 = require("../../utils/output");
|
8
|
-
const
|
8
|
+
const handle_errors_1 = require("../../utils/handle-errors");
|
9
9
|
const sync_generators_1 = require("../../utils/sync-generators");
|
10
10
|
const chalk = require("chalk");
|
11
11
|
function syncHandler(options) {
|
12
|
-
return (0,
|
12
|
+
return (0, handle_errors_1.handleErrors)(options.verbose, async () => {
|
13
13
|
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)();
|
14
14
|
const nxJson = (0, nx_json_1.readNxJson)();
|
15
15
|
const syncGenerators = await (0, sync_generators_1.collectAllRegisteredSyncGenerators)(projectGraph, nxJson);
|
@@ -32,24 +32,82 @@ function syncHandler(options) {
|
|
32
32
|
});
|
33
33
|
return 0;
|
34
34
|
}
|
35
|
+
const { failedGeneratorsCount, areAllResultsFailures, anySyncGeneratorsFailed, } = (0, sync_generators_1.processSyncGeneratorResultErrors)(results);
|
36
|
+
const failedSyncGeneratorsFixMessageLines = (0, sync_generators_1.getFailedSyncGeneratorsFixMessageLines)(results, options.verbose);
|
37
|
+
if (areAllResultsFailures) {
|
38
|
+
output_1.output.error({
|
39
|
+
title: `The workspace is probably out of sync because ${failedGeneratorsCount === 1
|
40
|
+
? 'a sync generator'
|
41
|
+
: 'some sync generators'} failed to run`,
|
42
|
+
bodyLines: failedSyncGeneratorsFixMessageLines,
|
43
|
+
});
|
44
|
+
return 1;
|
45
|
+
}
|
46
|
+
const resultBodyLines = (0, sync_generators_1.getSyncGeneratorSuccessResultsMessageLines)(results);
|
35
47
|
if (options.check) {
|
36
48
|
output_1.output.error({
|
37
|
-
title:
|
38
|
-
bodyLines:
|
49
|
+
title: 'The workspace is out of sync',
|
50
|
+
bodyLines: resultBodyLines,
|
39
51
|
});
|
52
|
+
if (anySyncGeneratorsFailed) {
|
53
|
+
output_1.output.error({
|
54
|
+
title: failedGeneratorsCount === 1
|
55
|
+
? 'A sync generator failed to run'
|
56
|
+
: 'Some sync generators failed to run',
|
57
|
+
bodyLines: failedSyncGeneratorsFixMessageLines,
|
58
|
+
});
|
59
|
+
}
|
40
60
|
return 1;
|
41
61
|
}
|
42
62
|
output_1.output.warn({
|
43
|
-
title:
|
44
|
-
bodyLines:
|
63
|
+
title: 'The workspace is out of sync',
|
64
|
+
bodyLines: resultBodyLines,
|
45
65
|
});
|
46
66
|
const spinner = ora('Syncing the workspace...');
|
47
67
|
spinner.start();
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
68
|
+
try {
|
69
|
+
const flushResult = await (0, sync_generators_1.flushSyncGeneratorChanges)(results);
|
70
|
+
if ('generatorFailures' in flushResult) {
|
71
|
+
spinner.fail();
|
72
|
+
output_1.output.error({
|
73
|
+
title: 'Failed to sync the workspace',
|
74
|
+
bodyLines: (0, sync_generators_1.getFlushFailureMessageLines)(flushResult, options.verbose),
|
75
|
+
});
|
76
|
+
return 1;
|
77
|
+
}
|
78
|
+
}
|
79
|
+
catch (e) {
|
80
|
+
spinner.fail();
|
81
|
+
output_1.output.error({
|
82
|
+
title: 'Failed to sync the workspace',
|
83
|
+
bodyLines: [
|
84
|
+
'Syncing the workspace failed with the following error:',
|
85
|
+
'',
|
86
|
+
e.message,
|
87
|
+
...(options.verbose && !!e.stack ? [`\n${e.stack}`] : []),
|
88
|
+
'',
|
89
|
+
'Please rerun with `--verbose` and report the error at: https://github.com/nrwl/nx/issues/new/choose',
|
90
|
+
],
|
91
|
+
});
|
92
|
+
return 1;
|
93
|
+
}
|
94
|
+
const successTitle = anySyncGeneratorsFailed
|
95
|
+
? // the identified changes were synced successfully, but the workspace
|
96
|
+
// is still not up to date, which we'll mention next
|
97
|
+
'The identified changes were synced successfully!'
|
98
|
+
: // the workspace is fully up to date
|
99
|
+
'The workspace was synced successfully!';
|
100
|
+
const successSubtitle = 'Please make sure to commit the changes to your repository.';
|
101
|
+
spinner.succeed(`${successTitle}\n\n${successSubtitle}`);
|
102
|
+
if (anySyncGeneratorsFailed) {
|
103
|
+
output_1.output.error({
|
104
|
+
title: `The workspace is probably still out of sync because ${failedGeneratorsCount === 1
|
105
|
+
? 'a sync generator'
|
106
|
+
: 'some sync generators'} failed to run`,
|
107
|
+
bodyLines: failedSyncGeneratorsFixMessageLines,
|
108
|
+
});
|
109
|
+
return 1;
|
110
|
+
}
|
53
111
|
return 0;
|
54
112
|
});
|
55
113
|
}
|
@@ -4,7 +4,7 @@ import { Hash } from '../../hasher/task-hasher';
|
|
4
4
|
import { Task, TaskGraph } from '../../config/task-graph';
|
5
5
|
import { ConfigurationSourceMaps } from '../../project-graph/utils/project-configuration-utils';
|
6
6
|
import { NxWorkspaceFiles, TaskRun } from '../../native';
|
7
|
-
import type {
|
7
|
+
import type { FlushSyncGeneratorChangesResult, SyncGeneratorRunResult } from '../../utils/sync-generators';
|
8
8
|
export type UnregisterCallback = () => void;
|
9
9
|
export type ChangedFile = {
|
10
10
|
path: string;
|
@@ -52,8 +52,8 @@ export declare class DaemonClient {
|
|
52
52
|
hashGlob(globs: string[], exclude?: string[]): Promise<string>;
|
53
53
|
getFlakyTasks(hashes: string[]): Promise<string[]>;
|
54
54
|
recordTaskRuns(taskRuns: TaskRun[]): Promise<void>;
|
55
|
-
getSyncGeneratorChanges(generators: string[]): Promise<
|
56
|
-
flushSyncGeneratorChangesToDisk(generators: string[]): Promise<
|
55
|
+
getSyncGeneratorChanges(generators: string[]): Promise<SyncGeneratorRunResult[]>;
|
56
|
+
flushSyncGeneratorChangesToDisk(generators: string[]): Promise<FlushSyncGeneratorChangesResult>;
|
57
57
|
getRegisteredSyncGenerators(): Promise<string[]>;
|
58
58
|
updateWorkspaceContext(createdFiles: string[], updatedFiles: string[], deletedFiles: string[]): Promise<void>;
|
59
59
|
isServerAvailable(): Promise<boolean>;
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleFlushSyncGeneratorChangesToDisk = handleFlushSyncGeneratorChangesToDisk;
|
4
4
|
const sync_generators_1 = require("./sync-generators");
|
5
5
|
async function handleFlushSyncGeneratorChangesToDisk(generators) {
|
6
|
-
await (0, sync_generators_1.flushSyncGeneratorChangesToDisk)(generators);
|
6
|
+
const result = await (0, sync_generators_1.flushSyncGeneratorChangesToDisk)(generators);
|
7
7
|
return {
|
8
|
-
response:
|
8
|
+
response: JSON.stringify(result),
|
9
9
|
description: 'handleFlushSyncGeneratorChangesToDisk',
|
10
10
|
};
|
11
11
|
}
|
@@ -4,12 +4,14 @@ exports.handleGetSyncGeneratorChanges = handleGetSyncGeneratorChanges;
|
|
4
4
|
const sync_generators_1 = require("./sync-generators");
|
5
5
|
async function handleGetSyncGeneratorChanges(generators) {
|
6
6
|
const changes = await (0, sync_generators_1.getCachedSyncGeneratorChanges)(generators);
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
const result = changes.map((change) => 'error' in change
|
8
|
+
? change
|
9
|
+
: // strip out the content of the changes and any potential callback
|
10
|
+
{
|
11
|
+
generatorName: change.generatorName,
|
12
|
+
changes: change.changes.map((c) => ({ ...c, content: null })),
|
13
|
+
outOfSyncMessage: change.outOfSyncMessage,
|
14
|
+
});
|
13
15
|
return {
|
14
16
|
response: JSON.stringify(result),
|
15
17
|
description: 'handleGetSyncGeneratorChanges',
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import type { ProjectGraph } from '../../config/project-graph';
|
2
|
-
import { type
|
3
|
-
export declare function getCachedSyncGeneratorChanges(generators: string[]): Promise<
|
4
|
-
export declare function flushSyncGeneratorChangesToDisk(generators: string[]): Promise<
|
2
|
+
import { type FlushSyncGeneratorChangesResult, type SyncGeneratorRunResult } from '../../utils/sync-generators';
|
3
|
+
export declare function getCachedSyncGeneratorChanges(generators: string[]): Promise<SyncGeneratorRunResult[]>;
|
4
|
+
export declare function flushSyncGeneratorChangesToDisk(generators: string[]): Promise<FlushSyncGeneratorChangesResult>;
|
5
5
|
export declare function collectAndScheduleSyncGenerators(projectGraph: ProjectGraph): void;
|
6
6
|
export declare function getCachedRegisteredSyncGenerators(): Promise<string[]>;
|
7
7
|
/**
|
8
8
|
* @internal
|
9
9
|
*/
|
10
|
-
export declare function _getConflictingGeneratorGroups(results:
|
10
|
+
export declare function _getConflictingGeneratorGroups(results: SyncGeneratorRunResult[]): string[][];
|
@@ -59,7 +59,7 @@ async function flushSyncGeneratorChangesToDisk(generators) {
|
|
59
59
|
for (const generator of generators) {
|
60
60
|
syncGeneratorsCacheResultPromises.delete(generator);
|
61
61
|
}
|
62
|
-
await (0, sync_generators_1.flushSyncGeneratorChanges)(results);
|
62
|
+
return await (0, sync_generators_1.flushSyncGeneratorChanges)(results);
|
63
63
|
}
|
64
64
|
function collectAndScheduleSyncGenerators(projectGraph) {
|
65
65
|
if (!projectGraph) {
|
@@ -191,6 +191,7 @@ async function processConflictingGenerators(conflicts, initialResults) {
|
|
191
191
|
const conflictRunResults = (await Promise.all(conflicts.map((generators) => {
|
192
192
|
const [firstGenerator, ...generatorsToRun] = generators;
|
193
193
|
// it must exists because the conflicts were identified from the initial results
|
194
|
+
// and it's guaranteed to be a success result
|
194
195
|
const firstGeneratorResult = initialResults.find((r) => r.generatorName === firstGenerator);
|
195
196
|
const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, false, `running sync generators ${generators.join(',')}`);
|
196
197
|
// pre-apply the changes from the first generator to avoid running it
|
@@ -234,6 +235,9 @@ async function processConflictingGenerators(conflicts, initialResults) {
|
|
234
235
|
function _getConflictingGeneratorGroups(results) {
|
235
236
|
const changedFileToGeneratorMap = new Map();
|
236
237
|
for (const result of results) {
|
238
|
+
if ('error' in result) {
|
239
|
+
continue;
|
240
|
+
}
|
237
241
|
for (const change of result.changes) {
|
238
242
|
if (!changedFileToGeneratorMap.has(change.path)) {
|
239
243
|
changedFileToGeneratorMap.set(change.path, new Set());
|
@@ -318,7 +322,12 @@ function runGenerator(generator, projects, tree) {
|
|
318
322
|
scheduledGenerators.delete(generator);
|
319
323
|
tree ??= new tree_1.FsTree(workspace_root_1.workspaceRoot, false, `running sync generator ${generator}`);
|
320
324
|
return (0, sync_generators_1.runSyncGenerator)(tree, generator, projects).then((result) => {
|
321
|
-
|
325
|
+
if ('error' in result) {
|
326
|
+
log(generator, 'error:', result.error.message);
|
327
|
+
}
|
328
|
+
else {
|
329
|
+
log(generator, 'changes:', result.changes.map((c) => c.path).join(', '));
|
330
|
+
}
|
322
331
|
return result;
|
323
332
|
});
|
324
333
|
}
|
Binary file
|
@@ -89,7 +89,6 @@ async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)
|
|
89
89
|
return null;
|
90
90
|
}
|
91
91
|
const isGitHubDetected = schema.github ?? (await (0, url_shorten_1.repoUsesGithub)(schema.github));
|
92
|
-
let responseFromCreateNxCloudWorkspaceV1;
|
93
92
|
let responseFromCreateNxCloudWorkspaceV2;
|
94
93
|
/**
|
95
94
|
* Do not create an Nx Cloud token if the user is using GitHub and
|
@@ -2,3 +2,4 @@ import { CloudTaskRunnerOptions } from '../nx-cloud-tasks-runner-shell';
|
|
2
2
|
export declare function getCloudOptions(directory?: string): CloudTaskRunnerOptions;
|
3
3
|
export declare function getCloudUrl(): string;
|
4
4
|
export declare function removeTrailingSlash(apiUrl: string): string;
|
5
|
+
export declare function isNxCloudId(token: string): boolean;
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getCloudOptions = getCloudOptions;
|
4
4
|
exports.getCloudUrl = getCloudUrl;
|
5
5
|
exports.removeTrailingSlash = removeTrailingSlash;
|
6
|
+
exports.isNxCloudId = isNxCloudId;
|
6
7
|
const nx_json_1 = require("../../config/nx-json");
|
7
8
|
const run_command_1 = require("../../tasks-runner/run-command");
|
8
9
|
const workspace_root_1 = require("../../utils/workspace-root");
|
@@ -17,3 +18,6 @@ function getCloudUrl() {
|
|
17
18
|
function removeTrailingSlash(apiUrl) {
|
18
19
|
return apiUrl[apiUrl.length - 1] === '/' ? apiUrl.slice(0, -1) : apiUrl;
|
19
20
|
}
|
21
|
+
function isNxCloudId(token) {
|
22
|
+
return token.length === 24;
|
23
|
+
}
|
@@ -1 +1 @@
|
|
1
|
-
export declare function isWorkspaceClaimed(
|
1
|
+
export declare function isWorkspaceClaimed(accessToken: string): Promise<any>;
|
@@ -2,14 +2,15 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.isWorkspaceClaimed = isWorkspaceClaimed;
|
4
4
|
const get_cloud_options_1 = require("./get-cloud-options");
|
5
|
-
async function isWorkspaceClaimed(
|
6
|
-
if (!
|
5
|
+
async function isWorkspaceClaimed(accessToken) {
|
6
|
+
if (!accessToken)
|
7
7
|
return false;
|
8
8
|
const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
|
9
9
|
try {
|
10
|
-
const
|
11
|
-
|
12
|
-
|
10
|
+
const requestData = (0, get_cloud_options_1.isNxCloudId)(accessToken)
|
11
|
+
? { nxCloudId: accessToken }
|
12
|
+
: { nxCloudAccessToken: accessToken };
|
13
|
+
const response = await require('axios').post(`${apiUrl}/nx-cloud/is-workspace-claimed`, requestData);
|
13
14
|
if (response.data.message) {
|
14
15
|
return false;
|
15
16
|
}
|
@@ -23,6 +23,6 @@ async function getNxCloudAppOnBoardingUrl(token) {
|
|
23
23
|
}
|
24
24
|
function readNxCloudToken(tree) {
|
25
25
|
const nxJson = (0, devkit_exports_1.readNxJson)(tree);
|
26
|
-
const { accessToken } = (0, run_command_1.getRunnerOptions)('default', nxJson, {}, true);
|
27
|
-
return accessToken;
|
26
|
+
const { accessToken, nxCloudId } = (0, run_command_1.getRunnerOptions)('default', nxJson, {}, true);
|
27
|
+
return accessToken || nxCloudId;
|
28
28
|
}
|
@@ -18,7 +18,7 @@ export declare class ProjectGraphError extends Error {
|
|
18
18
|
*/
|
19
19
|
getPartialProjectGraph(): ProjectGraph;
|
20
20
|
getPartialSourcemaps(): ConfigurationSourceMaps;
|
21
|
-
getErrors(): (AggregateCreateNodesError | MergeNodesError |
|
21
|
+
getErrors(): (AggregateCreateNodesError | MergeNodesError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError | CreateMetadataError | ProcessDependenciesError | ProcessProjectGraphError | WorkspaceValidityError)[];
|
22
22
|
}
|
23
23
|
export declare class MultipleProjectsWithSameNameError extends Error {
|
24
24
|
conflicts: Map<string, string[]>;
|
@@ -24,7 +24,7 @@ class ProjectGraphError extends Error {
|
|
24
24
|
tslib_1.__classPrivateFieldSet(this, _ProjectGraphError_partialProjectGraph, partialProjectGraph, "f");
|
25
25
|
tslib_1.__classPrivateFieldSet(this, _ProjectGraphError_partialSourceMaps, partialSourceMaps, "f");
|
26
26
|
this.stack = `${this.message}\n ${errors
|
27
|
-
.map((error) =>
|
27
|
+
.map((error) => indentString(formatErrorStackAndCause(error), 2))
|
28
28
|
.join('\n')}`;
|
29
29
|
}
|
30
30
|
/**
|
@@ -186,13 +186,13 @@ class MergeNodesError extends Error {
|
|
186
186
|
this.name = this.constructor.name;
|
187
187
|
this.file = file;
|
188
188
|
this.pluginName = pluginName;
|
189
|
-
this.stack = `${this.message}\n
|
189
|
+
this.stack = `${this.message}\n${indentString(formatErrorStackAndCause(error), 2)}`;
|
190
190
|
}
|
191
191
|
}
|
192
192
|
exports.MergeNodesError = MergeNodesError;
|
193
193
|
class CreateMetadataError extends Error {
|
194
194
|
constructor(error, plugin) {
|
195
|
-
super(`The "${plugin}" plugin threw an error while creating metadata
|
195
|
+
super(`The "${plugin}" plugin threw an error while creating metadata: ${error.message}`, {
|
196
196
|
cause: error,
|
197
197
|
});
|
198
198
|
this.error = error;
|
@@ -203,7 +203,7 @@ class CreateMetadataError extends Error {
|
|
203
203
|
exports.CreateMetadataError = CreateMetadataError;
|
204
204
|
class ProcessDependenciesError extends Error {
|
205
205
|
constructor(pluginName, { cause }) {
|
206
|
-
super(`The "${pluginName}" plugin threw an error while creating dependencies
|
206
|
+
super(`The "${pluginName}" plugin threw an error while creating dependencies: ${cause.message}`, {
|
207
207
|
cause,
|
208
208
|
});
|
209
209
|
this.pluginName = pluginName;
|
@@ -234,7 +234,7 @@ class ProcessProjectGraphError extends Error {
|
|
234
234
|
});
|
235
235
|
this.pluginName = pluginName;
|
236
236
|
this.name = this.constructor.name;
|
237
|
-
this.stack = `${this.message}\n
|
237
|
+
this.stack = `${this.message}\n${indentString(cause, 2)}`;
|
238
238
|
}
|
239
239
|
}
|
240
240
|
exports.ProcessProjectGraphError = ProcessProjectGraphError;
|
@@ -289,3 +289,17 @@ class LoadPluginError extends Error {
|
|
289
289
|
}
|
290
290
|
}
|
291
291
|
exports.LoadPluginError = LoadPluginError;
|
292
|
+
function indentString(str, indent) {
|
293
|
+
return (' '.repeat(indent) +
|
294
|
+
str
|
295
|
+
.split('\n')
|
296
|
+
.map((line) => ' '.repeat(indent) + line)
|
297
|
+
.join('\n'));
|
298
|
+
}
|
299
|
+
function formatErrorStackAndCause(error) {
|
300
|
+
const cause = error.cause && error.cause instanceof Error ? error.cause : null;
|
301
|
+
return (error.stack +
|
302
|
+
(cause
|
303
|
+
? `\nCaused by: \n${indentString(cause.stack ?? cause.message, 2)}`
|
304
|
+
: ''));
|
305
|
+
}
|
@@ -11,12 +11,13 @@ const nx_json_1 = require("../config/nx-json");
|
|
11
11
|
const client_1 = require("../daemon/client/client");
|
12
12
|
const create_task_hasher_1 = require("../hasher/create-task-hasher");
|
13
13
|
const hash_task_1 = require("../hasher/hash-task");
|
14
|
+
const native_1 = require("../native");
|
14
15
|
const project_graph_1 = require("../project-graph/project-graph");
|
15
16
|
const fileutils_1 = require("../utils/fileutils");
|
16
17
|
const is_ci_1 = require("../utils/is-ci");
|
17
18
|
const nx_cloud_utils_1 = require("../utils/nx-cloud-utils");
|
18
19
|
const output_1 = require("../utils/output");
|
19
|
-
const
|
20
|
+
const handle_errors_1 = require("../utils/handle-errors");
|
20
21
|
const sync_generators_1 = require("../utils/sync-generators");
|
21
22
|
const workspace_root_1 = require("../utils/workspace-root");
|
22
23
|
const create_task_graph_1 = require("./create-task-graph");
|
@@ -33,7 +34,6 @@ const task_timings_life_cycle_1 = require("./life-cycles/task-timings-life-cycle
|
|
33
34
|
const task_graph_utils_1 = require("./task-graph-utils");
|
34
35
|
const utils_1 = require("./utils");
|
35
36
|
const chalk = require("chalk");
|
36
|
-
const native_1 = require("../native");
|
37
37
|
async function getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks, nxArgs, nxJson, overrides) {
|
38
38
|
const { runnerOptions } = getRunner(nxArgs, nxJson);
|
39
39
|
const isRunOne = initiatingProject != null;
|
@@ -98,7 +98,7 @@ function createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies,
|
|
98
98
|
return taskGraph;
|
99
99
|
}
|
100
100
|
async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
|
101
|
-
const status = await (0,
|
101
|
+
const status = await (0, handle_errors_1.handleErrors)(process.env.NX_VERBOSE_LOGGING === 'true', async () => {
|
102
102
|
const projectNames = projectsToRun.map((t) => t.name);
|
103
103
|
const { projectGraph, taskGraph } = await ensureWorkspaceIsInSyncAndGetGraphs(currentProjectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions);
|
104
104
|
const tasks = Object.values(taskGraph.tasks);
|
@@ -135,14 +135,49 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
|
|
135
135
|
// There are no changes to sync, workspace is up to date
|
136
136
|
return { projectGraph, taskGraph };
|
137
137
|
}
|
138
|
+
const { failedGeneratorsCount, areAllResultsFailures, anySyncGeneratorsFailed, } = (0, sync_generators_1.processSyncGeneratorResultErrors)(results);
|
139
|
+
const failedSyncGeneratorsFixMessageLines = (0, sync_generators_1.getFailedSyncGeneratorsFixMessageLines)(results, nxArgs.verbose);
|
138
140
|
const outOfSyncTitle = 'The workspace is out of sync';
|
139
|
-
const resultBodyLines =
|
140
|
-
const fixMessage = 'You can manually run `nx sync` to update your workspace or you can set `sync.applyChanges` to `true` in your `nx.json` to apply the changes automatically when running tasks in interactive environments.';
|
141
|
-
const willErrorOnCiMessage = 'Please note that
|
141
|
+
const resultBodyLines = (0, sync_generators_1.getSyncGeneratorSuccessResultsMessageLines)(results);
|
142
|
+
const fixMessage = 'You can manually run `nx sync` to update your workspace with the identified changes or you can set `sync.applyChanges` to `true` in your `nx.json` to apply the changes automatically when running tasks in interactive environments.';
|
143
|
+
const willErrorOnCiMessage = 'Please note that having the workspace out of sync will result in an error in CI.';
|
142
144
|
if ((0, is_ci_1.isCI)() || !process.stdout.isTTY) {
|
143
145
|
// If the user is running in CI or is running in a non-TTY environment we
|
144
146
|
// throw an error to stop the execution of the tasks.
|
145
|
-
|
147
|
+
if (areAllResultsFailures) {
|
148
|
+
output_1.output.error({
|
149
|
+
title: `The workspace is probably out of sync because ${failedGeneratorsCount === 1
|
150
|
+
? 'a sync generator'
|
151
|
+
: 'some sync generators'} failed to run`,
|
152
|
+
bodyLines: failedSyncGeneratorsFixMessageLines,
|
153
|
+
});
|
154
|
+
}
|
155
|
+
else {
|
156
|
+
output_1.output.error({
|
157
|
+
title: outOfSyncTitle,
|
158
|
+
bodyLines: [...resultBodyLines, '', fixMessage],
|
159
|
+
});
|
160
|
+
if (anySyncGeneratorsFailed) {
|
161
|
+
output_1.output.error({
|
162
|
+
title: failedGeneratorsCount === 1
|
163
|
+
? 'A sync generator failed to run'
|
164
|
+
: 'Some sync generators failed to run',
|
165
|
+
bodyLines: failedSyncGeneratorsFixMessageLines,
|
166
|
+
});
|
167
|
+
}
|
168
|
+
}
|
169
|
+
process.exit(1);
|
170
|
+
}
|
171
|
+
if (areAllResultsFailures) {
|
172
|
+
output_1.output.warn({
|
173
|
+
title: `The workspace is probably out of sync because ${failedGeneratorsCount === 1
|
174
|
+
? 'a sync generator'
|
175
|
+
: 'some sync generators'} failed to run`,
|
176
|
+
bodyLines: failedSyncGeneratorsFixMessageLines,
|
177
|
+
});
|
178
|
+
await confirmRunningTasksWithSyncFailures();
|
179
|
+
// if all sync generators failed to run there's nothing to sync, we just let the tasks run
|
180
|
+
return { projectGraph, taskGraph };
|
146
181
|
}
|
147
182
|
if (nxJson.sync?.applyChanges === false) {
|
148
183
|
// If the user has set `sync.applyChanges` to `false` in their `nx.json`
|
@@ -153,19 +188,30 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
|
|
153
188
|
title: outOfSyncTitle,
|
154
189
|
bodyLines: [
|
155
190
|
...resultBodyLines,
|
156
|
-
'
|
191
|
+
'',
|
192
|
+
'Your workspace is set to not apply the identified changes automatically (`sync.applyChanges` is set to `false` in your `nx.json`).',
|
157
193
|
willErrorOnCiMessage,
|
158
194
|
fixMessage,
|
159
195
|
],
|
160
196
|
});
|
197
|
+
if (anySyncGeneratorsFailed) {
|
198
|
+
output_1.output.warn({
|
199
|
+
title: failedGeneratorsCount === 1
|
200
|
+
? 'A sync generator failed to run'
|
201
|
+
: 'Some sync generators failed to run',
|
202
|
+
bodyLines: failedSyncGeneratorsFixMessageLines,
|
203
|
+
});
|
204
|
+
await confirmRunningTasksWithSyncFailures();
|
205
|
+
}
|
161
206
|
return { projectGraph, taskGraph };
|
162
207
|
}
|
163
208
|
output_1.output.warn({
|
164
209
|
title: outOfSyncTitle,
|
165
210
|
bodyLines: [
|
166
211
|
...resultBodyLines,
|
212
|
+
'',
|
167
213
|
nxJson.sync?.applyChanges === true
|
168
|
-
? 'Proceeding to sync the changes automatically (`sync.applyChanges` is set to `true` in your `nx.json`).'
|
214
|
+
? 'Proceeding to sync the identified changes automatically (`sync.applyChanges` is set to `true` in your `nx.json`).'
|
169
215
|
: willErrorOnCiMessage,
|
170
216
|
],
|
171
217
|
});
|
@@ -175,31 +221,66 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
|
|
175
221
|
const spinner = ora('Syncing the workspace...');
|
176
222
|
spinner.start();
|
177
223
|
// Flush sync generator changes to disk
|
178
|
-
await (0, sync_generators_1.flushSyncGeneratorChanges)(results);
|
224
|
+
const flushResult = await (0, sync_generators_1.flushSyncGeneratorChanges)(results);
|
225
|
+
if ('generatorFailures' in flushResult) {
|
226
|
+
spinner.fail();
|
227
|
+
output_1.output.error({
|
228
|
+
title: 'Failed to sync the workspace',
|
229
|
+
bodyLines: [
|
230
|
+
...(0, sync_generators_1.getFlushFailureMessageLines)(flushResult, nxArgs.verbose),
|
231
|
+
...(flushResult.generalFailure
|
232
|
+
? [
|
233
|
+
'If needed, you can run the tasks with the `--skip-sync` flag to disable syncing.',
|
234
|
+
]
|
235
|
+
: []),
|
236
|
+
],
|
237
|
+
});
|
238
|
+
await confirmRunningTasksWithSyncFailures();
|
239
|
+
}
|
179
240
|
// Re-create project graph and task graph
|
180
241
|
projectGraph = await (0, project_graph_1.createProjectGraphAsync)();
|
181
242
|
taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
Please make sure to commit the changes to your repository
|
243
|
+
const successTitle = anySyncGeneratorsFailed
|
244
|
+
? // the identified changes were synced successfully, but the workspace
|
245
|
+
// is still not up to date, which we'll mention next
|
246
|
+
'The identified changes were synced successfully!'
|
247
|
+
: // the workspace is fully up to date
|
248
|
+
'The workspace was synced successfully!';
|
249
|
+
const successSubtitle = nxJson.sync?.applyChanges === true
|
250
|
+
? 'Please make sure to commit the changes to your repository or this will error in CI.'
|
251
|
+
: // The user was prompted and we already logged a message about erroring in CI
|
252
|
+
// so here we just tell them to commit the changes.
|
253
|
+
'Please make sure to commit the changes to your repository.';
|
254
|
+
spinner.succeed(`${successTitle}\n\n${successSubtitle}`);
|
255
|
+
if (anySyncGeneratorsFailed) {
|
256
|
+
output_1.output.warn({
|
257
|
+
title: `The workspace is probably still out of sync because ${failedGeneratorsCount === 1
|
258
|
+
? 'a sync generator'
|
259
|
+
: 'some sync generators'} failed to run`,
|
260
|
+
bodyLines: failedSyncGeneratorsFixMessageLines,
|
261
|
+
});
|
262
|
+
await confirmRunningTasksWithSyncFailures();
|
193
263
|
}
|
194
264
|
}
|
195
265
|
else {
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
266
|
+
if (anySyncGeneratorsFailed) {
|
267
|
+
output_1.output.warn({
|
268
|
+
title: failedGeneratorsCount === 1
|
269
|
+
? 'A sync generator failed to report the sync status'
|
270
|
+
: 'Some sync generators failed to report the sync status',
|
271
|
+
bodyLines: failedSyncGeneratorsFixMessageLines,
|
272
|
+
});
|
273
|
+
await confirmRunningTasksWithSyncFailures();
|
274
|
+
}
|
275
|
+
else {
|
276
|
+
output_1.output.warn({
|
277
|
+
title: 'Syncing the workspace was skipped',
|
278
|
+
bodyLines: [
|
279
|
+
'This could lead to unexpected results or errors when running tasks.',
|
280
|
+
fixMessage,
|
281
|
+
],
|
282
|
+
});
|
283
|
+
}
|
203
284
|
}
|
204
285
|
return { projectGraph, taskGraph };
|
205
286
|
}
|
@@ -208,7 +289,7 @@ async function promptForApplyingSyncGeneratorChanges() {
|
|
208
289
|
const promptConfig = {
|
209
290
|
name: 'applyChanges',
|
210
291
|
type: 'select',
|
211
|
-
message: 'Would you like to sync the changes to get your worskpace up to date?',
|
292
|
+
message: 'Would you like to sync the identified changes to get your worskpace up to date?',
|
212
293
|
choices: [
|
213
294
|
{
|
214
295
|
name: 'yes',
|
@@ -227,6 +308,35 @@ async function promptForApplyingSyncGeneratorChanges() {
|
|
227
308
|
process.exit(1);
|
228
309
|
}
|
229
310
|
}
|
311
|
+
async function confirmRunningTasksWithSyncFailures() {
|
312
|
+
try {
|
313
|
+
const promptConfig = {
|
314
|
+
name: 'runTasks',
|
315
|
+
type: 'select',
|
316
|
+
message: 'Would you like to ignore the sync failures and continue running the tasks?',
|
317
|
+
choices: [
|
318
|
+
{
|
319
|
+
name: 'yes',
|
320
|
+
message: 'Yes, ignore the failures and run the tasks',
|
321
|
+
},
|
322
|
+
{
|
323
|
+
name: 'no',
|
324
|
+
message: `No, don't run the tasks`,
|
325
|
+
},
|
326
|
+
],
|
327
|
+
footer: () => chalk.dim(`\nWhen running in CI and there are sync failures, the tasks won't run. Addressing the errors above is highly recommended to prevent failures in CI.`),
|
328
|
+
};
|
329
|
+
const runTasks = await (0, enquirer_1.prompt)([
|
330
|
+
promptConfig,
|
331
|
+
]).then(({ runTasks }) => runTasks === 'yes');
|
332
|
+
if (!runTasks) {
|
333
|
+
process.exit(1);
|
334
|
+
}
|
335
|
+
}
|
336
|
+
catch {
|
337
|
+
process.exit(1);
|
338
|
+
}
|
339
|
+
}
|
230
340
|
function setEnvVarsBasedOnArgs(nxArgs, loadDotEnvFiles) {
|
231
341
|
if (nxArgs.outputStyle == 'stream' ||
|
232
342
|
process.env.NX_BATCH_MODE === 'true' ||
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function handleErrors(isVerbose: boolean, fn: Function): Promise<number>;
|