nx 19.7.0-canary.20240828-13170da → 19.7.0-canary.20240830-83a387a

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. package/package.json +12 -12
  2. package/schemas/nx-schema.json +7 -0
  3. package/src/command-line/connect/command-object.js +10 -3
  4. package/src/command-line/connect/connect-to-nx-cloud.d.ts +3 -1
  5. package/src/command-line/connect/connect-to-nx-cloud.js +7 -4
  6. package/src/command-line/import/command-object.js +4 -0
  7. package/src/command-line/import/import.d.ts +4 -0
  8. package/src/command-line/import/import.js +147 -12
  9. package/src/command-line/import/utils/prepare-source-repo.d.ts +1 -1
  10. package/src/command-line/import/utils/prepare-source-repo.js +31 -85
  11. package/src/command-line/sync/sync.js +12 -1
  12. package/src/command-line/yargs-utils/shared-options.js +1 -9
  13. package/src/config/nx-json.d.ts +5 -1
  14. package/src/daemon/server/sync-generators.d.ts +4 -0
  15. package/src/daemon/server/sync-generators.js +183 -55
  16. package/src/native/nx.wasm32-wasi.wasm +0 -0
  17. package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.d.ts +2 -1
  18. package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +16 -50
  19. package/src/nx-cloud/generators/connect-to-nx-cloud/schema.json +4 -0
  20. package/src/nx-cloud/update-manager.d.ts +1 -1
  21. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +8 -1
  22. package/src/tasks-runner/cache.js +2 -2
  23. package/src/tasks-runner/run-command.js +1 -10
  24. package/src/utils/git-utils.d.ts +7 -10
  25. package/src/utils/git-utils.js +61 -44
  26. package/src/utils/sync-generators.d.ts +8 -5
  27. package/src/utils/sync-generators.js +27 -5
  28. package/src/utils/squash.d.ts +0 -1
  29. package/src/utils/squash.js +0 -12
@@ -2,16 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GitRepository = void 0;
4
4
  exports.cloneFromUpstream = cloneFromUpstream;
5
- exports.updateRebaseFile = updateRebaseFile;
6
- exports.fetchGitRemote = fetchGitRemote;
7
5
  exports.getGithubSlugOrNull = getGithubSlugOrNull;
8
6
  exports.extractUserAndRepoFromGitHubUrl = extractUserAndRepoFromGitHubUrl;
9
7
  exports.commitChanges = commitChanges;
10
8
  exports.getLatestCommitSha = getLatestCommitSha;
11
9
  const child_process_1 = require("child_process");
12
- const devkit_exports_1 = require("../devkit-exports");
13
10
  const path_1 = require("path");
14
- const SQUASH_EDITOR = (0, path_1.join)(__dirname, 'squash.js');
11
+ const devkit_exports_1 = require("../devkit-exports");
15
12
  function execAsync(command, execOptions) {
16
13
  return new Promise((res, rej) => {
17
14
  (0, child_process_1.exec)(command, execOptions, (err, stdout, stderr) => {
@@ -22,9 +19,12 @@ function execAsync(command, execOptions) {
22
19
  });
23
20
  });
24
21
  }
25
- async function cloneFromUpstream(url, destination, { originName } = { originName: 'origin' }) {
26
- await execAsync(`git clone ${url} ${destination} --depth 1 --origin ${originName}`, {
22
+ async function cloneFromUpstream(url, destination, { originName, depth } = {
23
+ originName: 'origin',
24
+ }) {
25
+ await execAsync(`git clone ${url} ${destination} ${depth ? `--depth ${depth}` : ''} --origin ${originName}`, {
27
26
  cwd: (0, path_1.dirname)(destination),
27
+ maxBuffer: 10 * 1024 * 1024,
28
28
  });
29
29
  return new GitRepository(destination);
30
30
  }
@@ -40,13 +40,8 @@ class GitRepository {
40
40
  .toString()
41
41
  .trim();
42
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
- });
43
+ async addFetchRemote(remoteName, branch) {
44
+ return await this.execAsync(`git config --add remote.${remoteName}.fetch "+refs/heads/${branch}:refs/remotes/${remoteName}/${branch}"`);
50
45
  }
51
46
  async showStat() {
52
47
  return await this.execAsync(`git show --stat`);
@@ -61,62 +56,84 @@ class GitRepository {
61
56
  .replace('refs/heads/', ''));
62
57
  }
63
58
  async getGitFiles(path) {
64
- return (await this.execAsync(`git ls-files ${path}`))
59
+ // Use -z to return file names exactly as they are stored in git, separated by NULL (\x00) character.
60
+ // This avoids problems with special characters in file names.
61
+ return (await this.execAsync(`git ls-files -z ${path}`))
65
62
  .trim()
66
- .split('\n')
63
+ .split('\x00')
67
64
  .map((s) => s.trim())
68
65
  .filter(Boolean);
69
66
  }
70
67
  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`);
68
+ return await this.execAsync(`git reset ${ref} --hard`);
75
69
  }
76
70
  async mergeUnrelatedHistories(ref, message) {
77
- return this.execAsync(`git merge ${ref} -X ours --allow-unrelated-histories -m "${message}"`);
71
+ return await this.execAsync(`git merge ${ref} -X ours --allow-unrelated-histories -m "${message}"`);
78
72
  }
79
73
  async fetch(remote, ref) {
80
- return this.execAsync(`git fetch ${remote}${ref ? ` ${ref}` : ''}`);
74
+ return await this.execAsync(`git fetch ${remote}${ref ? ` ${ref}` : ''}`);
81
75
  }
82
76
  async checkout(branch, opts) {
83
- return this.execAsync(`git checkout ${opts.new ? '-b ' : ' '}${branch}${opts.base ? ' ' + opts.base : ''}`);
77
+ return await this.execAsync(`git checkout ${opts.new ? '-b ' : ' '}${branch}${opts.base ? ' ' + opts.base : ''}`);
84
78
  }
85
79
  async move(path, destination) {
86
- return this.execAsync(`git mv "${path}" "${destination}"`);
80
+ return await this.execAsync(`git mv ${this.quotePath(path)} ${this.quotePath(destination)}`);
87
81
  }
88
82
  async push(ref, remoteName) {
89
- return this.execAsync(`git push -u -f ${remoteName} ${ref}`);
83
+ return await this.execAsync(`git push -u -f ${remoteName} ${ref}`);
90
84
  }
91
85
  async commit(message) {
92
- return this.execAsync(`git commit -am "${message}"`);
86
+ return await this.execAsync(`git commit -am "${message}"`);
93
87
  }
94
88
  async amendCommit() {
95
- return this.execAsync(`git commit --amend -a --no-edit`);
89
+ return await this.execAsync(`git commit --amend -a --no-edit`);
96
90
  }
97
- deleteGitRemote(name) {
98
- return this.execAsync(`git remote rm ${name}`);
91
+ async deleteGitRemote(name) {
92
+ return await this.execAsync(`git remote rm ${name}`);
99
93
  }
100
- deleteBranch(branch) {
101
- return this.execAsync(`git branch -D ${branch}`);
94
+ async addGitRemote(name, url) {
95
+ return await this.execAsync(`git remote add ${name} ${url}`);
96
+ }
97
+ async hasFilterRepoInstalled() {
98
+ try {
99
+ await this.execAsync(`git filter-repo --help`);
100
+ return true;
101
+ }
102
+ catch {
103
+ return false;
104
+ }
102
105
  }
103
- addGitRemote(name, url) {
104
- return this.execAsync(`git remote add ${name} ${url}`);
106
+ // git-filter-repo is much faster than filter-branch, but needs to be installed by user
107
+ // Use `hasFilterRepoInstalled` to check if it's installed
108
+ async filterRepo(subdirectory) {
109
+ // filter-repo requires POSIX path to work
110
+ const posixPath = subdirectory.split(path_1.sep).join(path_1.posix.sep);
111
+ return await this.execAsync(`git filter-repo -f --subdirectory-filter ${this.quotePath(posixPath)}`);
112
+ }
113
+ async filterBranch(subdirectory, branchName) {
114
+ // filter-repo requires POSIX path to work
115
+ const posixPath = subdirectory.split(path_1.sep).join(path_1.posix.sep);
116
+ // We need non-ASCII file names to not be quoted, or else filter-branch will exclude them.
117
+ await this.execAsync(`git config core.quotepath false`);
118
+ return await this.execAsync(`git filter-branch --subdirectory-filter ${this.quotePath(posixPath)} -- ${branchName}`);
119
+ }
120
+ execAsync(command) {
121
+ return execAsync(command, {
122
+ cwd: this.root,
123
+ maxBuffer: 10 * 1024 * 1024,
124
+ });
125
+ }
126
+ quotePath(path) {
127
+ return process.platform === 'win32'
128
+ ? // Windows/CMD only understands double-quotes, single-quotes are treated as part of the file name
129
+ // Bash and other shells will substitute `$` in file names with a variable value.
130
+ `"${path}"`
131
+ : // e.g. `git mv "$$file.txt" "libs/a/$$file.txt"` will not work since `$$` is swapped with the PID of the last process.
132
+ // Using single-quotes prevents this substitution.
133
+ `'${path}'`;
105
134
  }
106
135
  }
107
136
  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
- }
120
137
  /**
121
138
  * This is currently duplicated in Nx Console. Please let @MaxKless know if you make changes here.
122
139
  */
@@ -1,7 +1,9 @@
1
1
  import type { GeneratorCallback } from '../config/misc-interfaces';
2
+ import { type NxJsonConfiguration } from '../config/nx-json';
2
3
  import type { ProjectGraph } from '../config/project-graph';
4
+ import type { TaskGraph } from '../config/task-graph';
3
5
  import type { ProjectConfiguration } from '../config/workspace-json-project-json';
4
- import { FsTree, type FileChange, type Tree } from '../generators/tree';
6
+ import { type FileChange, type Tree } from '../generators/tree';
5
7
  export type SyncGeneratorResult = void | {
6
8
  callback?: GeneratorCallback;
7
9
  outOfSyncMessage?: string;
@@ -15,8 +17,9 @@ export type SyncGeneratorChangesResult = {
15
17
  };
16
18
  export declare function getSyncGeneratorChanges(generators: string[]): Promise<SyncGeneratorChangesResult[]>;
17
19
  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>;
20
+ export declare function collectAllRegisteredSyncGenerators(projectGraph: ProjectGraph, nxJson: NxJsonConfiguration): Promise<string[]>;
21
+ export declare function runSyncGenerator(tree: Tree, generatorSpecifier: string, projects: Record<string, ProjectConfiguration>): Promise<SyncGeneratorChangesResult>;
22
+ export declare function collectEnabledTaskSyncGeneratorsFromProjectGraph(projectGraph: ProjectGraph, nxJson: NxJsonConfiguration): Set<string>;
23
+ export declare function collectEnabledTaskSyncGeneratorsFromTaskGraph(taskGraph: TaskGraph, projectGraph: ProjectGraph, nxJson: NxJsonConfiguration): Set<string>;
24
+ export declare function collectRegisteredGlobalSyncGenerators(nxJson?: NxJsonConfiguration<string[] | "*">): Set<string>;
22
25
  export declare function syncGeneratorResultsToMessageLines(results: SyncGeneratorChangesResult[]): string[];
@@ -4,7 +4,8 @@ exports.getSyncGeneratorChanges = getSyncGeneratorChanges;
4
4
  exports.flushSyncGeneratorChanges = flushSyncGeneratorChanges;
5
5
  exports.collectAllRegisteredSyncGenerators = collectAllRegisteredSyncGenerators;
6
6
  exports.runSyncGenerator = runSyncGenerator;
7
- exports.collectRegisteredTaskSyncGenerators = collectRegisteredTaskSyncGenerators;
7
+ exports.collectEnabledTaskSyncGeneratorsFromProjectGraph = collectEnabledTaskSyncGeneratorsFromProjectGraph;
8
+ exports.collectEnabledTaskSyncGeneratorsFromTaskGraph = collectEnabledTaskSyncGeneratorsFromTaskGraph;
8
9
  exports.collectRegisteredGlobalSyncGenerators = collectRegisteredGlobalSyncGenerators;
9
10
  exports.syncGeneratorResultsToMessageLines = syncGeneratorResultsToMessageLines;
10
11
  const perf_hooks_1 = require("perf_hooks");
@@ -39,10 +40,10 @@ async function flushSyncGeneratorChanges(results) {
39
40
  await client_1.daemonClient.flushSyncGeneratorChangesToDisk(results.map((r) => r.generatorName));
40
41
  }
41
42
  }
42
- async function collectAllRegisteredSyncGenerators(projectGraph) {
43
+ async function collectAllRegisteredSyncGenerators(projectGraph, nxJson) {
43
44
  if (!client_1.daemonClient.enabled()) {
44
45
  return [
45
- ...collectRegisteredTaskSyncGenerators(projectGraph),
46
+ ...collectEnabledTaskSyncGeneratorsFromProjectGraph(projectGraph, nxJson),
46
47
  ...collectRegisteredGlobalSyncGenerators(),
47
48
  ];
48
49
  }
@@ -69,17 +70,38 @@ async function runSyncGenerator(tree, generatorSpecifier, projects) {
69
70
  outOfSyncMessage,
70
71
  };
71
72
  }
72
- function collectRegisteredTaskSyncGenerators(projectGraph) {
73
+ function collectEnabledTaskSyncGeneratorsFromProjectGraph(projectGraph, nxJson) {
73
74
  const taskSyncGenerators = new Set();
75
+ const disabledTaskSyncGenerators = new Set(nxJson.sync?.disabledTaskSyncGenerators ?? []);
74
76
  for (const { data: { targets }, } of Object.values(projectGraph.nodes)) {
75
77
  if (!targets) {
76
78
  continue;
77
79
  }
78
80
  for (const target of Object.values(targets)) {
79
- if (!target.syncGenerators) {
81
+ if (!target.syncGenerators?.length) {
80
82
  continue;
81
83
  }
82
84
  for (const generator of target.syncGenerators) {
85
+ if (!disabledTaskSyncGenerators.has(generator) &&
86
+ !taskSyncGenerators.has(generator)) {
87
+ taskSyncGenerators.add(generator);
88
+ }
89
+ }
90
+ }
91
+ }
92
+ return taskSyncGenerators;
93
+ }
94
+ function collectEnabledTaskSyncGeneratorsFromTaskGraph(taskGraph, projectGraph, nxJson) {
95
+ const taskSyncGenerators = new Set();
96
+ const disabledTaskSyncGenerators = new Set(nxJson.sync?.disabledTaskSyncGenerators ?? []);
97
+ for (const { target } of Object.values(taskGraph.tasks)) {
98
+ const { syncGenerators } = projectGraph.nodes[target.project].data.targets[target.target];
99
+ if (!syncGenerators?.length) {
100
+ continue;
101
+ }
102
+ for (const generator of syncGenerators) {
103
+ if (!disabledTaskSyncGenerators.has(generator) &&
104
+ !taskSyncGenerators.has(generator)) {
83
105
  taskSyncGenerators.add(generator);
84
106
  }
85
107
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,12 +0,0 @@
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);