nx 19.6.0-canary.20240809-d3747e0 → 19.6.0-canary.20240814-6d83ae2
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/bin/post-install.js +9 -0
- package/package.json +12 -12
- package/schemas/nx-schema.json +55 -4
- package/schemas/project-schema.json +7 -0
- package/src/adapter/compat.d.ts +1 -1
- package/src/adapter/compat.js +1 -0
- package/src/command-line/import/command-object.d.ts +2 -0
- package/src/command-line/import/command-object.js +38 -0
- package/src/command-line/import/import.d.ts +21 -0
- package/src/command-line/import/import.js +173 -0
- package/src/command-line/import/utils/merge-remote-source.d.ts +2 -0
- package/src/command-line/import/utils/merge-remote-source.js +14 -0
- package/src/command-line/import/utils/needs-install.d.ts +3 -0
- package/src/command-line/import/utils/needs-install.js +31 -0
- package/src/command-line/import/utils/prepare-source-repo.d.ts +2 -0
- package/src/command-line/import/utils/prepare-source-repo.js +104 -0
- package/src/command-line/init/init-v2.d.ts +7 -0
- package/src/command-line/init/init-v2.js +49 -16
- package/src/command-line/nx-commands.js +33 -28
- package/src/command-line/release/changelog.js +9 -9
- package/src/command-line/release/command-object.d.ts +12 -3
- package/src/command-line/release/command-object.js +16 -1
- package/src/command-line/release/config/config.js +4 -2
- package/src/command-line/release/config/filter-release-groups.d.ts +2 -2
- package/src/command-line/release/config/filter-release-groups.js +1 -1
- package/src/command-line/release/config/version-plans.d.ts +1 -1
- package/src/command-line/release/config/version-plans.js +12 -12
- package/src/command-line/release/plan-check.d.ts +4 -0
- package/src/command-line/release/plan-check.js +225 -0
- package/src/command-line/release/plan.js +1 -1
- package/src/command-line/release/release.js +3 -3
- package/src/command-line/release/version.js +1 -1
- package/src/command-line/sync/command-object.d.ts +6 -0
- package/src/command-line/sync/command-object.js +25 -0
- package/src/command-line/sync/sync.d.ts +6 -0
- package/src/command-line/sync/sync.js +30 -0
- package/src/command-line/yargs-utils/shared-options.d.ts +1 -1
- package/src/config/nx-json.d.ts +32 -2
- package/src/config/workspace-json-project-json.d.ts +5 -0
- package/src/core/graph/main.js +1 -1
- package/src/daemon/cache.d.ts +1 -0
- package/src/daemon/cache.js +25 -18
- package/src/daemon/client/client.d.ts +5 -0
- package/src/daemon/client/client.js +42 -1
- package/src/daemon/message-types/flush-sync-generator-changes-to-disk.d.ts +6 -0
- package/src/daemon/message-types/flush-sync-generator-changes-to-disk.js +11 -0
- package/src/daemon/message-types/force-shutdown.d.ts +5 -0
- package/src/daemon/message-types/force-shutdown.js +11 -0
- package/src/daemon/message-types/get-registered-sync-generators.d.ts +5 -0
- package/src/daemon/message-types/get-registered-sync-generators.js +11 -0
- package/src/daemon/message-types/get-sync-generator-changes.d.ts +6 -0
- package/src/daemon/message-types/get-sync-generator-changes.js +11 -0
- package/src/daemon/message-types/update-workspace-context.d.ts +8 -0
- package/src/daemon/message-types/update-workspace-context.js +11 -0
- package/src/daemon/server/handle-flush-sync-generator-changes-to-disk.d.ts +2 -0
- package/src/daemon/server/handle-flush-sync-generator-changes-to-disk.js +11 -0
- package/src/daemon/server/handle-force-shutdown.d.ts +5 -0
- package/src/daemon/server/handle-force-shutdown.js +18 -0
- package/src/daemon/server/handle-get-registered-sync-generators.d.ts +2 -0
- package/src/daemon/server/handle-get-registered-sync-generators.js +11 -0
- package/src/daemon/server/handle-get-sync-generator-changes.d.ts +2 -0
- package/src/daemon/server/handle-get-sync-generator-changes.js +17 -0
- package/src/daemon/server/handle-request-shutdown.js +2 -0
- package/src/daemon/server/handle-update-workspace-context.d.ts +2 -0
- package/src/daemon/server/handle-update-workspace-context.js +11 -0
- package/src/daemon/server/project-graph-incremental-recomputation.d.ts +1 -0
- package/src/daemon/server/project-graph-incremental-recomputation.js +20 -3
- package/src/daemon/server/server.d.ts +1 -0
- package/src/daemon/server/server.js +39 -0
- package/src/daemon/server/shutdown-utils.d.ts +2 -1
- package/src/daemon/server/shutdown-utils.js +11 -4
- package/src/daemon/server/sync-generators.d.ts +6 -0
- package/src/daemon/server/sync-generators.js +202 -0
- package/src/daemon/server/watcher.js +3 -0
- package/src/daemon/socket-utils.js +18 -5
- package/src/daemon/tmp-dir.js +2 -1
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +1 -1
- package/src/nx-cloud/models/onboarding-status.d.ts +1 -0
- package/src/nx-cloud/models/onboarding-status.js +2 -0
- package/src/nx-cloud/utilities/is-workspace-claimed.d.ts +1 -0
- package/src/nx-cloud/utilities/is-workspace-claimed.js +24 -0
- package/src/nx-cloud/utilities/onboarding.d.ts +5 -0
- package/src/nx-cloud/utilities/onboarding.js +28 -0
- package/src/project-graph/plugins/internal-api.js +16 -5
- package/src/project-graph/plugins/isolation/messaging.d.ts +5 -1
- package/src/project-graph/plugins/isolation/messaging.js +1 -0
- package/src/project-graph/plugins/isolation/plugin-pool.js +4 -6
- package/src/project-graph/plugins/isolation/plugin-worker.js +15 -0
- package/src/project-graph/utils/project-configuration-utils.js +5 -2
- package/src/tasks-runner/run-command.d.ts +1 -1
- package/src/tasks-runner/run-command.js +117 -2
- package/src/utils/command-line-utils.d.ts +1 -0
- package/src/utils/command-line-utils.js +6 -3
- package/src/utils/git-utils.d.ts +35 -0
- package/src/utils/git-utils.js +111 -0
- package/src/utils/package-manager.js +1 -1
- package/src/utils/plugins/output.js +1 -1
- package/src/utils/squash.d.ts +1 -0
- package/src/utils/squash.js +12 -0
- package/src/utils/sync-generators.d.ts +22 -0
- package/src/utils/sync-generators.js +161 -0
- package/src/utils/workspace-context.d.ts +2 -1
- package/src/utils/workspace-context.js +18 -1
- package/src/daemon/message-types/update-context-files.d.ts +0 -7
- package/src/daemon/message-types/update-context-files.js +0 -11
@@ -4,16 +4,20 @@ exports.runCommand = runCommand;
|
|
4
4
|
exports.invokeTasksRunner = invokeTasksRunner;
|
5
5
|
exports.getRunner = getRunner;
|
6
6
|
exports.getRunnerOptions = getRunnerOptions;
|
7
|
+
const enquirer_1 = require("enquirer");
|
8
|
+
const ora = require("ora");
|
7
9
|
const path_1 = require("path");
|
8
10
|
const nx_json_1 = require("../config/nx-json");
|
9
11
|
const client_1 = require("../daemon/client/client");
|
10
12
|
const create_task_hasher_1 = require("../hasher/create-task-hasher");
|
11
13
|
const hash_task_1 = require("../hasher/hash-task");
|
14
|
+
const project_graph_1 = require("../project-graph/project-graph");
|
12
15
|
const fileutils_1 = require("../utils/fileutils");
|
13
16
|
const is_ci_1 = require("../utils/is-ci");
|
14
17
|
const nx_cloud_utils_1 = require("../utils/nx-cloud-utils");
|
15
18
|
const output_1 = require("../utils/output");
|
16
19
|
const params_1 = require("../utils/params");
|
20
|
+
const sync_generators_1 = require("../utils/sync-generators");
|
17
21
|
const workspace_root_1 = require("../utils/workspace-root");
|
18
22
|
const create_task_graph_1 = require("./create-task-graph");
|
19
23
|
const life_cycle_1 = require("./life-cycle");
|
@@ -27,6 +31,7 @@ const task_profiling_life_cycle_1 = require("./life-cycles/task-profiling-life-c
|
|
27
31
|
const task_timings_life_cycle_1 = require("./life-cycles/task-timings-life-cycle");
|
28
32
|
const task_graph_utils_1 = require("./task-graph-utils");
|
29
33
|
const utils_1 = require("./utils");
|
34
|
+
const chalk = require("chalk");
|
30
35
|
async function getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks, nxArgs, nxJson, overrides) {
|
31
36
|
const { runnerOptions } = getRunner(nxArgs, nxJson);
|
32
37
|
const isRunOne = initiatingProject != null;
|
@@ -90,10 +95,10 @@ function createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies,
|
|
90
95
|
}
|
91
96
|
return taskGraph;
|
92
97
|
}
|
93
|
-
async function runCommand(projectsToRun,
|
98
|
+
async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
|
94
99
|
const status = await (0, params_1.handleErrors)(process.env.NX_VERBOSE_LOGGING === 'true', async () => {
|
95
100
|
const projectNames = projectsToRun.map((t) => t.name);
|
96
|
-
const taskGraph =
|
101
|
+
const { projectGraph, taskGraph } = await ensureWorkspaceIsInSyncAndGetGraphs(currentProjectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions);
|
97
102
|
const tasks = Object.values(taskGraph.tasks);
|
98
103
|
const { lifeCycle, renderIsDone } = await getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks, nxArgs, nxJson, overrides);
|
99
104
|
const status = await invokeTasksRunner({
|
@@ -111,6 +116,116 @@ async function runCommand(projectsToRun, projectGraph, { nxJson }, nxArgs, overr
|
|
111
116
|
});
|
112
117
|
return status;
|
113
118
|
}
|
119
|
+
async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions) {
|
120
|
+
let taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
|
121
|
+
// collect unique syncGenerators from the tasks
|
122
|
+
const uniqueSyncGenerators = new Set();
|
123
|
+
for (const { target } of Object.values(taskGraph.tasks)) {
|
124
|
+
const { syncGenerators } = projectGraph.nodes[target.project].data.targets[target.target];
|
125
|
+
if (!syncGenerators) {
|
126
|
+
continue;
|
127
|
+
}
|
128
|
+
for (const generator of syncGenerators) {
|
129
|
+
uniqueSyncGenerators.add(generator);
|
130
|
+
}
|
131
|
+
}
|
132
|
+
if (!uniqueSyncGenerators.size) {
|
133
|
+
// There are no sync generators registered in the tasks to run
|
134
|
+
return { projectGraph, taskGraph };
|
135
|
+
}
|
136
|
+
const syncGenerators = Array.from(uniqueSyncGenerators);
|
137
|
+
const results = await (0, sync_generators_1.getSyncGeneratorChanges)(syncGenerators);
|
138
|
+
if (!results.length) {
|
139
|
+
// There are no changes to sync, workspace is up to date
|
140
|
+
return { projectGraph, taskGraph };
|
141
|
+
}
|
142
|
+
const outOfSyncTitle = 'The workspace is out of sync';
|
143
|
+
const resultBodyLines = (0, sync_generators_1.syncGeneratorResultsToMessageLines)(results);
|
144
|
+
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.';
|
145
|
+
const willErrorOnCiMessage = 'Please note that this will be an error on CI.';
|
146
|
+
if ((0, is_ci_1.isCI)() || !process.stdout.isTTY) {
|
147
|
+
// If the user is running in CI or is running in a non-TTY environment we
|
148
|
+
// throw an error to stop the execution of the tasks.
|
149
|
+
throw new Error(`${outOfSyncTitle}\n${resultBodyLines.join('\n')}\n${fixMessage}`);
|
150
|
+
}
|
151
|
+
if (nxJson.sync?.applyChanges === false) {
|
152
|
+
// If the user has set `sync.applyChanges` to `false` in their `nx.json`
|
153
|
+
// we don't prompt the them and just log a warning informing them that
|
154
|
+
// the workspace is out of sync and they have it set to not apply changes
|
155
|
+
// automatically.
|
156
|
+
output_1.output.warn({
|
157
|
+
title: outOfSyncTitle,
|
158
|
+
bodyLines: [
|
159
|
+
...resultBodyLines,
|
160
|
+
'Your workspace is set to not apply changes automatically (`sync.applyChanges` is set to `false` in your `nx.json`).',
|
161
|
+
willErrorOnCiMessage,
|
162
|
+
fixMessage,
|
163
|
+
],
|
164
|
+
});
|
165
|
+
return { projectGraph, taskGraph };
|
166
|
+
}
|
167
|
+
output_1.output.warn({
|
168
|
+
title: outOfSyncTitle,
|
169
|
+
bodyLines: [
|
170
|
+
...resultBodyLines,
|
171
|
+
nxJson.sync?.applyChanges === true
|
172
|
+
? 'Proceeding to sync the changes automatically (`sync.applyChanges` is set to `true` in your `nx.json`).'
|
173
|
+
: willErrorOnCiMessage,
|
174
|
+
],
|
175
|
+
});
|
176
|
+
const applyChanges = nxJson.sync?.applyChanges === true ||
|
177
|
+
(await promptForApplyingSyncGeneratorChanges());
|
178
|
+
if (applyChanges) {
|
179
|
+
const spinner = ora('Syncing the workspace...');
|
180
|
+
spinner.start();
|
181
|
+
// Flush sync generator changes to disk
|
182
|
+
await (0, sync_generators_1.flushSyncGeneratorChanges)(results);
|
183
|
+
// Re-create project graph and task graph
|
184
|
+
projectGraph = await (0, project_graph_1.createProjectGraphAsync)();
|
185
|
+
taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
|
186
|
+
if (nxJson.sync?.applyChanges === true) {
|
187
|
+
spinner.succeed(`The workspace was synced successfully!
|
188
|
+
|
189
|
+
Please make sure to commit the changes to your repository or this will error on CI.`);
|
190
|
+
}
|
191
|
+
else {
|
192
|
+
// The user was prompted and we already logged a message about erroring on CI
|
193
|
+
// so here we just tell them to commit the changes.
|
194
|
+
spinner.succeed(`The workspace was synced successfully!
|
195
|
+
|
196
|
+
Please make sure to commit the changes to your repository.`);
|
197
|
+
}
|
198
|
+
}
|
199
|
+
else {
|
200
|
+
output_1.output.warn({
|
201
|
+
title: 'Syncing the workspace was skipped',
|
202
|
+
bodyLines: [
|
203
|
+
'This could lead to unexpected results or errors when running tasks.',
|
204
|
+
fixMessage,
|
205
|
+
],
|
206
|
+
});
|
207
|
+
}
|
208
|
+
return { projectGraph, taskGraph };
|
209
|
+
}
|
210
|
+
async function promptForApplyingSyncGeneratorChanges() {
|
211
|
+
const promptConfig = {
|
212
|
+
name: 'applyChanges',
|
213
|
+
type: 'select',
|
214
|
+
message: 'Would you like to sync the changes to get your worskpace up to date?',
|
215
|
+
choices: [
|
216
|
+
{
|
217
|
+
name: 'yes',
|
218
|
+
message: 'Yes, sync the changes and run the tasks',
|
219
|
+
},
|
220
|
+
{
|
221
|
+
name: 'no',
|
222
|
+
message: 'No, run the tasks without syncing the changes',
|
223
|
+
},
|
224
|
+
],
|
225
|
+
footer: () => chalk.dim('\nYou can skip this prompt by setting the `sync.applyChanges` option in your `nx.json`.'),
|
226
|
+
};
|
227
|
+
return await (0, enquirer_1.prompt)([promptConfig]).then(({ applyChanges }) => applyChanges === 'yes');
|
228
|
+
}
|
114
229
|
function setEnvVarsBasedOnArgs(nxArgs, loadDotEnvFiles) {
|
115
230
|
if (nxArgs.outputStyle == 'stream' ||
|
116
231
|
process.env.NX_BATCH_MODE === 'true' ||
|
@@ -32,6 +32,7 @@ export interface NxArgs {
|
|
32
32
|
excludeTaskDependencies?: boolean;
|
33
33
|
}
|
34
34
|
export declare function createOverrides(__overrides_unparsed__?: string[]): Record<string, any>;
|
35
|
+
export declare function getBaseRef(nxJson: NxJsonConfiguration): string;
|
35
36
|
export declare function splitArgsIntoNxArgsAndOverrides(args: {
|
36
37
|
[k: string]: any;
|
37
38
|
}, mode: 'run-one' | 'run-many' | 'affected' | 'print-affected', options: {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.createOverrides = createOverrides;
|
4
|
+
exports.getBaseRef = getBaseRef;
|
4
5
|
exports.splitArgsIntoNxArgsAndOverrides = splitArgsIntoNxArgsAndOverrides;
|
5
6
|
exports.readParallelFromArgsAndEnv = readParallelFromArgsAndEnv;
|
6
7
|
exports.parseFiles = parseFiles;
|
@@ -24,6 +25,9 @@ function createOverrides(__overrides_unparsed__ = []) {
|
|
24
25
|
overrides.__overrides_unparsed__ = __overrides_unparsed__;
|
25
26
|
return overrides;
|
26
27
|
}
|
28
|
+
function getBaseRef(nxJson) {
|
29
|
+
return nxJson.defaultBase ?? nxJson.affected?.defaultBase ?? 'main';
|
30
|
+
}
|
27
31
|
function splitArgsIntoNxArgsAndOverrides(args, mode, options = { printWarnings: true }, nxJson) {
|
28
32
|
// this is to lerna case when this function is invoked imperatively
|
29
33
|
if (args['target'] && !args['targets']) {
|
@@ -70,7 +74,7 @@ function splitArgsIntoNxArgsAndOverrides(args, mode, options = { printWarnings:
|
|
70
74
|
],
|
71
75
|
});
|
72
76
|
}
|
73
|
-
// Allow setting base and head via environment variables (lower priority
|
77
|
+
// Allow setting base and head via environment variables (lower priority than direct command arguments)
|
74
78
|
if (!nxArgs.base && process.env.NX_BASE) {
|
75
79
|
nxArgs.base = process.env.NX_BASE;
|
76
80
|
if (options.printWarnings) {
|
@@ -88,8 +92,7 @@ function splitArgsIntoNxArgsAndOverrides(args, mode, options = { printWarnings:
|
|
88
92
|
}
|
89
93
|
}
|
90
94
|
if (!nxArgs.base) {
|
91
|
-
nxArgs.base =
|
92
|
-
nxJson.defaultBase ?? nxJson.affected?.defaultBase ?? 'main';
|
95
|
+
nxArgs.base = getBaseRef(nxJson);
|
93
96
|
// No user-provided arguments to set the affected criteria, so inform the user of the defaults being used
|
94
97
|
if (options.printWarnings &&
|
95
98
|
!nxArgs.head &&
|
package/src/utils/git-utils.d.ts
CHANGED
@@ -1,3 +1,38 @@
|
|
1
|
+
import { ExecSyncOptions } from 'child_process';
|
2
|
+
export declare function cloneFromUpstream(url: string, destination: string, { originName }?: {
|
3
|
+
originName: string;
|
4
|
+
}): Promise<GitRepository>;
|
5
|
+
export declare class GitRepository {
|
6
|
+
private directory;
|
7
|
+
root: string;
|
8
|
+
constructor(directory: string);
|
9
|
+
getGitRootPath(cwd: string): string;
|
10
|
+
addFetchRemote(remoteName: string, branch: string): Promise<string>;
|
11
|
+
private execAsync;
|
12
|
+
showStat(): Promise<string>;
|
13
|
+
listBranches(): Promise<string[]>;
|
14
|
+
getGitFiles(path: string): Promise<string[]>;
|
15
|
+
reset(ref: string): Promise<string>;
|
16
|
+
squashLastTwoCommits(): Promise<string>;
|
17
|
+
mergeUnrelatedHistories(ref: string, message: string): Promise<string>;
|
18
|
+
fetch(remote: string, ref?: string): Promise<string>;
|
19
|
+
checkout(branch: string, opts: {
|
20
|
+
new: boolean;
|
21
|
+
base: string;
|
22
|
+
}): Promise<string>;
|
23
|
+
move(path: string, destination: string): Promise<string>;
|
24
|
+
push(ref: string, remoteName: string): Promise<string>;
|
25
|
+
commit(message: string): Promise<string>;
|
26
|
+
amendCommit(): Promise<string>;
|
27
|
+
deleteGitRemote(name: string): Promise<string>;
|
28
|
+
deleteBranch(branch: string): Promise<string>;
|
29
|
+
addGitRemote(name: string, url: string): Promise<string>;
|
30
|
+
}
|
31
|
+
/**
|
32
|
+
* This is used by the squash editor script to update the rebase file.
|
33
|
+
*/
|
34
|
+
export declare function updateRebaseFile(contents: string): string;
|
35
|
+
export declare function fetchGitRemote(name: string, branch: string, execOptions: ExecSyncOptions): string | Buffer;
|
1
36
|
export declare function getGithubSlugOrNull(): string | null;
|
2
37
|
export declare function extractUserAndRepoFromGitHubUrl(gitRemotes: string): string | null;
|
3
38
|
export declare function commitChanges(commitMessage: string, directory?: string): string | null;
|
package/src/utils/git-utils.js
CHANGED
@@ -1,11 +1,122 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.GitRepository = void 0;
|
4
|
+
exports.cloneFromUpstream = cloneFromUpstream;
|
5
|
+
exports.updateRebaseFile = updateRebaseFile;
|
6
|
+
exports.fetchGitRemote = fetchGitRemote;
|
3
7
|
exports.getGithubSlugOrNull = getGithubSlugOrNull;
|
4
8
|
exports.extractUserAndRepoFromGitHubUrl = extractUserAndRepoFromGitHubUrl;
|
5
9
|
exports.commitChanges = commitChanges;
|
6
10
|
exports.getLatestCommitSha = getLatestCommitSha;
|
7
11
|
const child_process_1 = require("child_process");
|
8
12
|
const devkit_exports_1 = require("../devkit-exports");
|
13
|
+
const path_1 = require("path");
|
14
|
+
const SQUASH_EDITOR = (0, path_1.join)(__dirname, 'squash.js');
|
15
|
+
function execAsync(command, execOptions) {
|
16
|
+
return new Promise((res, rej) => {
|
17
|
+
(0, child_process_1.exec)(command, execOptions, (err, stdout, stderr) => {
|
18
|
+
if (err) {
|
19
|
+
return rej(err);
|
20
|
+
}
|
21
|
+
res(stdout);
|
22
|
+
});
|
23
|
+
});
|
24
|
+
}
|
25
|
+
async function cloneFromUpstream(url, destination, { originName } = { originName: 'origin' }) {
|
26
|
+
await execAsync(`git clone ${url} ${destination} --depth 1 --origin ${originName}`, {
|
27
|
+
cwd: (0, path_1.dirname)(destination),
|
28
|
+
});
|
29
|
+
return new GitRepository(destination);
|
30
|
+
}
|
31
|
+
class GitRepository {
|
32
|
+
constructor(directory) {
|
33
|
+
this.directory = directory;
|
34
|
+
this.root = this.getGitRootPath(this.directory);
|
35
|
+
}
|
36
|
+
getGitRootPath(cwd) {
|
37
|
+
return (0, child_process_1.execSync)('git rev-parse --show-toplevel', {
|
38
|
+
cwd,
|
39
|
+
})
|
40
|
+
.toString()
|
41
|
+
.trim();
|
42
|
+
}
|
43
|
+
addFetchRemote(remoteName, branch) {
|
44
|
+
return this.execAsync(`git config --add remote.${remoteName}.fetch "+refs/heads/${branch}:refs/remotes/${remoteName}/${branch}"`);
|
45
|
+
}
|
46
|
+
execAsync(command) {
|
47
|
+
return execAsync(command, {
|
48
|
+
cwd: this.root,
|
49
|
+
});
|
50
|
+
}
|
51
|
+
async showStat() {
|
52
|
+
return await this.execAsync(`git show --stat`);
|
53
|
+
}
|
54
|
+
async listBranches() {
|
55
|
+
return (await this.execAsync(`git ls-remote --heads --quiet`))
|
56
|
+
.trim()
|
57
|
+
.split('\n')
|
58
|
+
.map((s) => s
|
59
|
+
.trim()
|
60
|
+
.substring(s.indexOf('\t') + 1)
|
61
|
+
.replace('refs/heads/', ''));
|
62
|
+
}
|
63
|
+
async getGitFiles(path) {
|
64
|
+
return (await this.execAsync(`git ls-files ${path}`))
|
65
|
+
.trim()
|
66
|
+
.split('\n')
|
67
|
+
.map((s) => s.trim())
|
68
|
+
.filter(Boolean);
|
69
|
+
}
|
70
|
+
async reset(ref) {
|
71
|
+
return this.execAsync(`git reset ${ref} --hard`);
|
72
|
+
}
|
73
|
+
async squashLastTwoCommits() {
|
74
|
+
return this.execAsync(`git -c core.editor="node ${SQUASH_EDITOR}" rebase --interactive --no-autosquash HEAD~2`);
|
75
|
+
}
|
76
|
+
async mergeUnrelatedHistories(ref, message) {
|
77
|
+
return this.execAsync(`git merge ${ref} -X ours --allow-unrelated-histories -m "${message}"`);
|
78
|
+
}
|
79
|
+
async fetch(remote, ref) {
|
80
|
+
return this.execAsync(`git fetch ${remote}${ref ? ` ${ref}` : ''}`);
|
81
|
+
}
|
82
|
+
async checkout(branch, opts) {
|
83
|
+
return this.execAsync(`git checkout ${opts.new ? '-b ' : ' '}${branch}${opts.base ? ' ' + opts.base : ''}`);
|
84
|
+
}
|
85
|
+
async move(path, destination) {
|
86
|
+
return this.execAsync(`git mv ${path} ${destination}`);
|
87
|
+
}
|
88
|
+
async push(ref, remoteName) {
|
89
|
+
return this.execAsync(`git push -u -f ${remoteName} ${ref}`);
|
90
|
+
}
|
91
|
+
async commit(message) {
|
92
|
+
return this.execAsync(`git commit -am "${message}"`);
|
93
|
+
}
|
94
|
+
async amendCommit() {
|
95
|
+
return this.execAsync(`git commit --amend -a --no-edit`);
|
96
|
+
}
|
97
|
+
deleteGitRemote(name) {
|
98
|
+
return this.execAsync(`git remote rm ${name}`);
|
99
|
+
}
|
100
|
+
deleteBranch(branch) {
|
101
|
+
return this.execAsync(`git branch -D ${branch}`);
|
102
|
+
}
|
103
|
+
addGitRemote(name, url) {
|
104
|
+
return this.execAsync(`git remote add ${name} ${url}`);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
exports.GitRepository = GitRepository;
|
108
|
+
/**
|
109
|
+
* This is used by the squash editor script to update the rebase file.
|
110
|
+
*/
|
111
|
+
function updateRebaseFile(contents) {
|
112
|
+
const lines = contents.split('\n');
|
113
|
+
const lastCommitIndex = lines.findIndex((line) => line === '') - 1;
|
114
|
+
lines[lastCommitIndex] = lines[lastCommitIndex].replace('pick', 'fixup');
|
115
|
+
return lines.join('\n');
|
116
|
+
}
|
117
|
+
function fetchGitRemote(name, branch, execOptions) {
|
118
|
+
return (0, child_process_1.execSync)(`git fetch ${name} ${branch} --depth 1`, execOptions);
|
119
|
+
}
|
9
120
|
function getGithubSlugOrNull() {
|
10
121
|
try {
|
11
122
|
const gitRemote = (0, child_process_1.execSync)('git remote -v', {
|
@@ -49,7 +49,7 @@ function isWorkspacesEnabled(packageManager = detectPackageManager(), root = wor
|
|
49
49
|
if (packageManager === 'pnpm') {
|
50
50
|
return (0, fs_1.existsSync)((0, path_1.join)(root, 'pnpm-workspace.yaml'));
|
51
51
|
}
|
52
|
-
// yarn and
|
52
|
+
// yarn and npm both use the same 'workspaces' property in package.json
|
53
53
|
const packageJson = (0, file_utils_1.readPackageJson)();
|
54
54
|
return !!packageJson?.workspaces;
|
55
55
|
}
|
@@ -27,7 +27,7 @@ function listPlugins(plugins, title) {
|
|
27
27
|
if (p.projectInference) {
|
28
28
|
capabilities.push('project-inference');
|
29
29
|
}
|
30
|
-
bodyLines.push(`${chalk.bold(p.name)} (${capabilities.join()})`);
|
30
|
+
bodyLines.push(`${chalk.bold(p.name)} ${capabilities.length >= 1 ? `(${capabilities.join()})` : ''}`);
|
31
31
|
}
|
32
32
|
output_1.output.log({
|
33
33
|
title: title,
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const fs_1 = require("fs");
|
4
|
+
const git_utils_1 = require("./git-utils");
|
5
|
+
// This script is used as an editor for git rebase -i
|
6
|
+
// This is the file which git creates. When this script exits, the updates should be written to this file.
|
7
|
+
const filePath = process.argv[2];
|
8
|
+
// Change the second commit from pick to fixup
|
9
|
+
const contents = (0, fs_1.readFileSync)(filePath).toString();
|
10
|
+
const newContents = (0, git_utils_1.updateRebaseFile)(contents);
|
11
|
+
// Write the updated contents back to the file
|
12
|
+
(0, fs_1.writeFileSync)(filePath, newContents);
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import type { GeneratorCallback } from '../config/misc-interfaces';
|
2
|
+
import type { ProjectGraph } from '../config/project-graph';
|
3
|
+
import type { ProjectConfiguration } from '../config/workspace-json-project-json';
|
4
|
+
import { FsTree, type FileChange, type Tree } from '../generators/tree';
|
5
|
+
export type SyncGeneratorResult = void | {
|
6
|
+
callback?: GeneratorCallback;
|
7
|
+
outOfSyncMessage?: string;
|
8
|
+
};
|
9
|
+
export type SyncGenerator = (tree: Tree) => SyncGeneratorResult | Promise<SyncGeneratorResult>;
|
10
|
+
export type SyncGeneratorChangesResult = {
|
11
|
+
changes: FileChange[];
|
12
|
+
generatorName: string;
|
13
|
+
callback?: GeneratorCallback;
|
14
|
+
outOfSyncMessage?: string;
|
15
|
+
};
|
16
|
+
export declare function getSyncGeneratorChanges(generators: string[]): Promise<SyncGeneratorChangesResult[]>;
|
17
|
+
export declare function flushSyncGeneratorChanges(results: SyncGeneratorChangesResult[]): Promise<void>;
|
18
|
+
export declare function collectAllRegisteredSyncGenerators(projectGraph: ProjectGraph): Promise<string[]>;
|
19
|
+
export declare function runSyncGenerator(tree: FsTree, generatorSpecifier: string, projects: Record<string, ProjectConfiguration>): Promise<SyncGeneratorChangesResult>;
|
20
|
+
export declare function collectRegisteredTaskSyncGenerators(projectGraph: ProjectGraph): Set<string>;
|
21
|
+
export declare function collectRegisteredGlobalSyncGenerators(nxJson?: import("../config/nx-json").NxJsonConfiguration<string[] | "*">): Set<string>;
|
22
|
+
export declare function syncGeneratorResultsToMessageLines(results: SyncGeneratorChangesResult[]): string[];
|
@@ -0,0 +1,161 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getSyncGeneratorChanges = getSyncGeneratorChanges;
|
4
|
+
exports.flushSyncGeneratorChanges = flushSyncGeneratorChanges;
|
5
|
+
exports.collectAllRegisteredSyncGenerators = collectAllRegisteredSyncGenerators;
|
6
|
+
exports.runSyncGenerator = runSyncGenerator;
|
7
|
+
exports.collectRegisteredTaskSyncGenerators = collectRegisteredTaskSyncGenerators;
|
8
|
+
exports.collectRegisteredGlobalSyncGenerators = collectRegisteredGlobalSyncGenerators;
|
9
|
+
exports.syncGeneratorResultsToMessageLines = syncGeneratorResultsToMessageLines;
|
10
|
+
const perf_hooks_1 = require("perf_hooks");
|
11
|
+
const generate_1 = require("../command-line/generate/generate");
|
12
|
+
const generator_utils_1 = require("../command-line/generate/generator-utils");
|
13
|
+
const nx_json_1 = require("../config/nx-json");
|
14
|
+
const client_1 = require("../daemon/client/client");
|
15
|
+
const is_on_daemon_1 = require("../daemon/is-on-daemon");
|
16
|
+
const tree_1 = require("../generators/tree");
|
17
|
+
const project_graph_1 = require("../project-graph/project-graph");
|
18
|
+
const workspace_context_1 = require("./workspace-context");
|
19
|
+
const workspace_root_1 = require("./workspace-root");
|
20
|
+
const chalk = require("chalk");
|
21
|
+
async function getSyncGeneratorChanges(generators) {
|
22
|
+
perf_hooks_1.performance.mark('get-sync-generators-changes:start');
|
23
|
+
let results;
|
24
|
+
if (!client_1.daemonClient.enabled()) {
|
25
|
+
results = await runSyncGenerators(generators);
|
26
|
+
}
|
27
|
+
else {
|
28
|
+
results = await client_1.daemonClient.getSyncGeneratorChanges(generators);
|
29
|
+
}
|
30
|
+
perf_hooks_1.performance.mark('get-sync-generators-changes:end');
|
31
|
+
perf_hooks_1.performance.measure('get-sync-generators-changes', 'get-sync-generators-changes:start', 'get-sync-generators-changes:end');
|
32
|
+
return results.filter((r) => r.changes.length > 0);
|
33
|
+
}
|
34
|
+
async function flushSyncGeneratorChanges(results) {
|
35
|
+
if ((0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
|
36
|
+
await flushSyncGeneratorChangesToDisk(results);
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
await client_1.daemonClient.flushSyncGeneratorChangesToDisk(results.map((r) => r.generatorName));
|
40
|
+
}
|
41
|
+
}
|
42
|
+
async function collectAllRegisteredSyncGenerators(projectGraph) {
|
43
|
+
if (!client_1.daemonClient.enabled()) {
|
44
|
+
return [
|
45
|
+
...collectRegisteredTaskSyncGenerators(projectGraph),
|
46
|
+
...collectRegisteredGlobalSyncGenerators(),
|
47
|
+
];
|
48
|
+
}
|
49
|
+
return await client_1.daemonClient.getRegisteredSyncGenerators();
|
50
|
+
}
|
51
|
+
async function runSyncGenerator(tree, generatorSpecifier, projects) {
|
52
|
+
perf_hooks_1.performance.mark(`run-sync-generator:${generatorSpecifier}:start`);
|
53
|
+
const { collection, generator } = (0, generate_1.parseGeneratorString)(generatorSpecifier);
|
54
|
+
const { implementationFactory } = (0, generator_utils_1.getGeneratorInformation)(collection, generator, workspace_root_1.workspaceRoot, projects);
|
55
|
+
const implementation = implementationFactory();
|
56
|
+
const result = await implementation(tree);
|
57
|
+
let callback;
|
58
|
+
let outOfSyncMessage;
|
59
|
+
if (result && typeof result === 'object') {
|
60
|
+
callback = result.callback;
|
61
|
+
outOfSyncMessage = result.outOfSyncMessage;
|
62
|
+
}
|
63
|
+
perf_hooks_1.performance.mark(`run-sync-generator:${generatorSpecifier}:end`);
|
64
|
+
perf_hooks_1.performance.measure(`run-sync-generator:${generatorSpecifier}`, `run-sync-generator:${generatorSpecifier}:start`, `run-sync-generator:${generatorSpecifier}:end`);
|
65
|
+
return {
|
66
|
+
changes: tree.listChanges(),
|
67
|
+
generatorName: generatorSpecifier,
|
68
|
+
callback,
|
69
|
+
outOfSyncMessage,
|
70
|
+
};
|
71
|
+
}
|
72
|
+
function collectRegisteredTaskSyncGenerators(projectGraph) {
|
73
|
+
const taskSyncGenerators = new Set();
|
74
|
+
for (const { data: { targets }, } of Object.values(projectGraph.nodes)) {
|
75
|
+
if (!targets) {
|
76
|
+
continue;
|
77
|
+
}
|
78
|
+
for (const target of Object.values(targets)) {
|
79
|
+
if (!target.syncGenerators) {
|
80
|
+
continue;
|
81
|
+
}
|
82
|
+
for (const generator of target.syncGenerators) {
|
83
|
+
taskSyncGenerators.add(generator);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
return taskSyncGenerators;
|
88
|
+
}
|
89
|
+
function collectRegisteredGlobalSyncGenerators(nxJson = (0, nx_json_1.readNxJson)()) {
|
90
|
+
const globalSyncGenerators = new Set();
|
91
|
+
if (!nxJson.sync?.globalGenerators?.length) {
|
92
|
+
return globalSyncGenerators;
|
93
|
+
}
|
94
|
+
for (const generator of nxJson.sync.globalGenerators) {
|
95
|
+
globalSyncGenerators.add(generator);
|
96
|
+
}
|
97
|
+
return globalSyncGenerators;
|
98
|
+
}
|
99
|
+
function syncGeneratorResultsToMessageLines(results) {
|
100
|
+
const messageLines = [];
|
101
|
+
for (const result of results) {
|
102
|
+
messageLines.push(`The ${chalk.bold(result.generatorName)} sync generator identified ${chalk.bold(result.changes.length)} file${result.changes.length === 1 ? '' : 's'} in the workspace that ${result.changes.length === 1 ? 'is' : 'are'} out of sync${result.outOfSyncMessage ? ':' : '.'}`);
|
103
|
+
if (result.outOfSyncMessage) {
|
104
|
+
messageLines.push(result.outOfSyncMessage);
|
105
|
+
}
|
106
|
+
messageLines.push('');
|
107
|
+
}
|
108
|
+
return messageLines;
|
109
|
+
}
|
110
|
+
async function runSyncGenerators(generators) {
|
111
|
+
const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, false, 'running sync generators');
|
112
|
+
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)();
|
113
|
+
const { projects } = (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph);
|
114
|
+
const results = [];
|
115
|
+
for (const generator of generators) {
|
116
|
+
const result = await runSyncGenerator(tree, generator, projects);
|
117
|
+
results.push(result);
|
118
|
+
}
|
119
|
+
return results;
|
120
|
+
}
|
121
|
+
async function flushSyncGeneratorChangesToDisk(results) {
|
122
|
+
perf_hooks_1.performance.mark('flush-sync-generator-changes-to-disk:start');
|
123
|
+
const { changes, createdFiles, updatedFiles, deletedFiles, callbacks } = processSyncGeneratorResults(results);
|
124
|
+
// Write changes to disk
|
125
|
+
(0, tree_1.flushChanges)(workspace_root_1.workspaceRoot, changes);
|
126
|
+
// Run the callbacks
|
127
|
+
if (callbacks.length) {
|
128
|
+
for (const callback of callbacks) {
|
129
|
+
await callback();
|
130
|
+
}
|
131
|
+
}
|
132
|
+
// Update the context files
|
133
|
+
await (0, workspace_context_1.updateContextWithChangedFiles)(workspace_root_1.workspaceRoot, createdFiles, updatedFiles, deletedFiles);
|
134
|
+
perf_hooks_1.performance.mark('flush-sync-generator-changes-to-disk:end');
|
135
|
+
perf_hooks_1.performance.measure('flush sync generator changes to disk', 'flush-sync-generator-changes-to-disk:start', 'flush-sync-generator-changes-to-disk:end');
|
136
|
+
}
|
137
|
+
function processSyncGeneratorResults(results) {
|
138
|
+
const changes = [];
|
139
|
+
const createdFiles = [];
|
140
|
+
const updatedFiles = [];
|
141
|
+
const deletedFiles = [];
|
142
|
+
const callbacks = [];
|
143
|
+
for (const result of results) {
|
144
|
+
if (result.callback) {
|
145
|
+
callbacks.push(result.callback);
|
146
|
+
}
|
147
|
+
for (const change of result.changes) {
|
148
|
+
changes.push(change);
|
149
|
+
if (change.type === 'CREATE') {
|
150
|
+
createdFiles.push(change.path);
|
151
|
+
}
|
152
|
+
else if (change.type === 'UPDATE') {
|
153
|
+
updatedFiles.push(change.path);
|
154
|
+
}
|
155
|
+
else if (change.type === 'DELETE') {
|
156
|
+
deletedFiles.push(change.path);
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
return { changes, createdFiles, updatedFiles, deletedFiles, callbacks };
|
161
|
+
}
|
@@ -11,7 +11,8 @@ export declare function getNxWorkspaceFilesFromContext(workspaceRoot: string, pr
|
|
11
11
|
export declare function globWithWorkspaceContextSync(workspaceRoot: string, globs: string[], exclude?: string[]): string[];
|
12
12
|
export declare function globWithWorkspaceContext(workspaceRoot: string, globs: string[], exclude?: string[]): Promise<string[]>;
|
13
13
|
export declare function hashWithWorkspaceContext(workspaceRoot: string, globs: string[], exclude?: string[]): Promise<string>;
|
14
|
-
export declare function
|
14
|
+
export declare function updateContextWithChangedFiles(workspaceRoot: string, createdFiles: string[], updatedFiles: string[], deletedFiles: string[]): Promise<void>;
|
15
|
+
export declare function updateFilesInContext(workspaceRoot: string, updatedFiles: string[], deletedFiles: string[]): Record<string, string>;
|
15
16
|
export declare function getAllFileDataInContext(workspaceRoot: string): Promise<import("../native").FileData[]>;
|
16
17
|
export declare function getFilesInDirectoryUsingContext(workspaceRoot: string, dir: string): Promise<string[]>;
|
17
18
|
export declare function updateProjectFiles(projectRootMappings: Record<string, string>, rustReferences: NxWorkspaceFilesExternals, updatedFiles: Record<string, string>, deletedFiles: string[]): import("../native").UpdatedWorkspaceFiles;
|
@@ -5,6 +5,7 @@ exports.getNxWorkspaceFilesFromContext = getNxWorkspaceFilesFromContext;
|
|
5
5
|
exports.globWithWorkspaceContextSync = globWithWorkspaceContextSync;
|
6
6
|
exports.globWithWorkspaceContext = globWithWorkspaceContext;
|
7
7
|
exports.hashWithWorkspaceContext = hashWithWorkspaceContext;
|
8
|
+
exports.updateContextWithChangedFiles = updateContextWithChangedFiles;
|
8
9
|
exports.updateFilesInContext = updateFilesInContext;
|
9
10
|
exports.getAllFileDataInContext = getAllFileDataInContext;
|
10
11
|
exports.getFilesInDirectoryUsingContext = getFilesInDirectoryUsingContext;
|
@@ -56,7 +57,23 @@ async function hashWithWorkspaceContext(workspaceRoot, globs, exclude) {
|
|
56
57
|
}
|
57
58
|
return client_1.daemonClient.hashGlob(globs, exclude);
|
58
59
|
}
|
59
|
-
function
|
60
|
+
async function updateContextWithChangedFiles(workspaceRoot, createdFiles, updatedFiles, deletedFiles) {
|
61
|
+
if (!client_1.daemonClient.enabled()) {
|
62
|
+
updateFilesInContext(workspaceRoot, [...createdFiles, ...updatedFiles], deletedFiles);
|
63
|
+
}
|
64
|
+
else if ((0, is_on_daemon_1.isOnDaemon)()) {
|
65
|
+
// make sure to only import this when running on the daemon
|
66
|
+
const { addUpdatedAndDeletedFiles } = await Promise.resolve().then(() => require('../daemon/server/project-graph-incremental-recomputation'));
|
67
|
+
// update files for the incremental graph recomputation on the daemon
|
68
|
+
addUpdatedAndDeletedFiles(createdFiles, updatedFiles, deletedFiles);
|
69
|
+
}
|
70
|
+
else {
|
71
|
+
// daemon is enabled but we are not running on it, ask the daemon to update the context
|
72
|
+
await client_1.daemonClient.updateWorkspaceContext(createdFiles, updatedFiles, deletedFiles);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
function updateFilesInContext(workspaceRoot, updatedFiles, deletedFiles) {
|
76
|
+
ensureContextAvailable(workspaceRoot);
|
60
77
|
return workspaceContext?.incrementalUpdate(updatedFiles, deletedFiles);
|
61
78
|
}
|
62
79
|
async function getAllFileDataInContext(workspaceRoot) {
|
@@ -1,7 +0,0 @@
|
|
1
|
-
export declare const GLOB: "GLOB";
|
2
|
-
export type HandleUpdateContextMessage = {
|
3
|
-
type: typeof GLOB;
|
4
|
-
updatedFiles: string[];
|
5
|
-
deletedFiles: string[];
|
6
|
-
};
|
7
|
-
export declare function isHandleUpdateContextMessage(message: unknown): message is HandleUpdateContextMessage;
|
@@ -1,11 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.GLOB = void 0;
|
4
|
-
exports.isHandleUpdateContextMessage = isHandleUpdateContextMessage;
|
5
|
-
exports.GLOB = 'GLOB';
|
6
|
-
function isHandleUpdateContextMessage(message) {
|
7
|
-
return (typeof message === 'object' &&
|
8
|
-
message !== null &&
|
9
|
-
'type' in message &&
|
10
|
-
message['type'] === exports.GLOB);
|
11
|
-
}
|