@nx/gradle 22.6.4 → 22.6.5

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.
@@ -4,7 +4,6 @@ exports.batchRunnerPath = void 0;
4
4
  exports.default = gradleBatch;
5
5
  exports.getGradlewTasksToRun = getGradlewTasksToRun;
6
6
  const devkit_1 = require("@nx/devkit");
7
- const run_commands_impl_1 = require("nx/src/executors/run-commands/run-commands.impl");
8
7
  const exec_gradle_1 = require("../../utils/exec-gradle");
9
8
  const path_1 = require("path");
10
9
  const child_process_1 = require("child_process");
@@ -111,20 +110,40 @@ function getGradlewTasksToRun(taskIds, taskGraph, inputs, nodes) {
111
110
  }
112
111
  async function runTasksInBatch(gradlewTasksToRun, excludeTasks, excludeTestTasks, args, root) {
113
112
  const gradlewBatchStart = performance.mark(`gradlew-batch:start`);
114
- const debugOptions = ' ' + (process.env.NX_GRADLE_BATCH_DEBUG ?? '');
115
- const command = `java${debugOptions} -jar ${exports.batchRunnerPath} --tasks='${JSON.stringify(gradlewTasksToRun)}' --workspaceRoot=${root} --args='${args
116
- .join(' ')
117
- .replaceAll("'", '"')}' --excludeTasks='${Array.from(excludeTasks).join(',')}' --excludeTestTasks='${Array.from(excludeTestTasks).join(',')}' ${process.env.NX_VERBOSE_LOGGING === 'true' ? '' : '--quiet'}`;
113
+ const debugOptions = (process.env.NX_GRADLE_BATCH_DEBUG ?? '').trim();
114
+ const spawnArgs = [
115
+ ...(debugOptions ? debugOptions.split(/\s+/) : []),
116
+ '-jar',
117
+ exports.batchRunnerPath,
118
+ `--tasks=${JSON.stringify(gradlewTasksToRun)}`,
119
+ `--workspaceRoot=${root}`,
120
+ `--args=${args.join(' ').replaceAll("'", '"')}`,
121
+ `--excludeTasks=${Array.from(excludeTasks).join(',')}`,
122
+ `--excludeTestTasks=${Array.from(excludeTestTasks).join(',')}`,
123
+ ...(process.env.NX_VERBOSE_LOGGING === 'true' ? [] : ['--quiet']),
124
+ ];
118
125
  // Use 'inherit' for stderr so Gradle output (tee'd to System.err
119
126
  // by TeeOutputStream) flows to the terminal in real-time.
120
127
  // stdout is piped to capture the JSON batch results.
121
- const batchResults = (0, child_process_1.execSync)(command, {
122
- cwd: devkit_1.workspaceRoot,
123
- windowsHide: true,
124
- env: process.env,
125
- stdio: ['pipe', 'pipe', 'inherit'],
126
- maxBuffer: run_commands_impl_1.LARGE_BUFFER,
127
- }).toString();
128
+ const batchResults = await new Promise((resolve, reject) => {
129
+ const cp = (0, child_process_1.spawn)('java', spawnArgs, {
130
+ cwd: devkit_1.workspaceRoot,
131
+ windowsHide: true,
132
+ env: process.env,
133
+ stdio: ['pipe', 'pipe', 'inherit'],
134
+ });
135
+ const chunks = [];
136
+ cp.stdout.on('data', (chunk) => chunks.push(chunk));
137
+ cp.on('error', reject);
138
+ cp.on('close', (code) => {
139
+ if (code !== 0) {
140
+ reject(new Error(`Gradle batch runner exited with code ${code}`));
141
+ }
142
+ else {
143
+ resolve(Buffer.concat(chunks).toString());
144
+ }
145
+ });
146
+ });
128
147
  const gradlewBatchEnd = performance.mark(`gradlew-batch:end`);
129
148
  performance.measure(`gradlew-batch`, gradlewBatchStart.name, gradlewBatchEnd.name);
130
149
  const gradlewBatchResults = JSON.parse(batchResults);
@@ -1 +1 @@
1
- {"version":3,"file":"get-project-graph-from-gradle-plugin.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/plugin/utils/get-project-graph-from-gradle-plugin.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,oBAAoB,EACpB,wBAAwB,EAExB,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,mBAAmB,EAAoB,MAAM,yBAAyB,CAAC;AAIhF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE;QACL,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;KAClD,CAAC;IACF,YAAY,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IACzD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE,IAAI,EAAE,MAAM,CAAC;CACd;AAiBD,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,QAgBb;AAQD,wBAAgB,4BAA4B,IAAI,kBAAkB,CAejE;AAED,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAG/C;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA6Df;AAED,wBAAgB,qBAAqB,CACnC,iBAAiB,EAAE,MAAM,EAAE,GAC1B,kBAAkB,CAkDpB"}
1
+ {"version":3,"file":"get-project-graph-from-gradle-plugin.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/plugin/utils/get-project-graph-from-gradle-plugin.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,oBAAoB,EACpB,wBAAwB,EAExB,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,mBAAmB,EAAoB,MAAM,yBAAyB,CAAC;AAIhF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE;QACL,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;KAClD,CAAC;IACF,YAAY,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IACzD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE,IAAI,EAAE,MAAM,CAAC;CACd;AAiBD,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,QAgBb;AAOD,wBAAgB,4BAA4B,IAAI,kBAAkB,CAejE;AAED,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAG/C;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAyEf;AAED,wBAAgB,qBAAqB,CACnC,iBAAiB,EAAE,MAAM,EAAE,GAC1B,kBAAkB,CAkDpB"}
@@ -75,14 +75,25 @@ async function populateProjectGraph(workspaceRoot, gradlewFiles, options) {
75
75
  return;
76
76
  }
77
77
  const gradleProjectGraphReportStart = performance.mark('gradleProjectGraphReport:start');
78
- const projectGraphLines = await gradlewFiles.reduce(async (projectGraphLines, gradlewFile) => {
79
- const getNxProjectGraphLinesStart = performance.mark(`${gradlewFile}GetNxProjectGraphLines:start`);
80
- const allLines = await projectGraphLines;
81
- const currentLines = await (0, get_project_graph_lines_1.getNxProjectGraphLines)(gradlewFile, gradleConfigHash, normalizedOptions);
82
- const getNxProjectGraphLinesEnd = performance.mark(`${gradlewFile}GetNxProjectGraphLines:end`);
83
- performance.measure(`${gradlewFile}GetNxProjectGraphLines`, getNxProjectGraphLinesStart.name, getNxProjectGraphLinesEnd.name);
84
- return [...allLines, ...currentLines];
85
- }, Promise.resolve([]));
78
+ let projectGraphLines;
79
+ try {
80
+ projectGraphLines = await gradlewFiles.reduce(async (projectGraphLines, gradlewFile) => {
81
+ const getNxProjectGraphLinesStart = performance.mark(`${gradlewFile}GetNxProjectGraphLines:start`);
82
+ const allLines = await projectGraphLines;
83
+ const currentLines = await (0, get_project_graph_lines_1.getNxProjectGraphLines)(gradlewFile, gradleConfigHash, normalizedOptions);
84
+ const getNxProjectGraphLinesEnd = performance.mark(`${gradlewFile}GetNxProjectGraphLines:end`);
85
+ performance.measure(`${gradlewFile}GetNxProjectGraphLines`, getNxProjectGraphLinesStart.name, getNxProjectGraphLinesEnd.name);
86
+ return [...allLines, ...currentLines];
87
+ }, Promise.resolve([]));
88
+ }
89
+ catch (e) {
90
+ if (e instanceof Error &&
91
+ e.message === 'Gradle project graph generation was cancelled') {
92
+ // Cancelled by a newer populateProjectGraph call — silently return
93
+ return;
94
+ }
95
+ throw e;
96
+ }
86
97
  const gradleProjectGraphReportEnd = performance.mark('gradleProjectGraphReport:end');
87
98
  performance.measure('gradleProjectGraphReport', gradleProjectGraphReportStart.name, gradleProjectGraphReportEnd.name);
88
99
  projectGraphReportCache = processNxProjectGraph(projectGraphLines);
@@ -1,4 +1,9 @@
1
1
  import { GradlePluginOptions } from './gradle-plugin-options';
2
+ /**
3
+ * Cancel any in-flight Gradle project graph process.
4
+ * Safe to call even if nothing is running.
5
+ */
6
+ export declare function cancelPendingProjectGraphRequest(): void;
2
7
  export declare function getGraphTimeoutMs(): number;
3
8
  export declare function getNxProjectGraphLines(gradlewFile: string, gradleConfigHash: string, gradlePluginOptions: GradlePluginOptions): Promise<string[]>;
4
9
  //# sourceMappingURL=get-project-graph-lines.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-project-graph-lines.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/plugin/utils/get-project-graph-lines.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAI9D,wBAAgB,iBAAiB,IAAI,MAAM,CAS1C;AAED,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,mBAAmB,EAAE,mBAAmB,GACvC,OAAO,CAAC,MAAM,EAAE,CAAC,CAoGnB"}
1
+ {"version":3,"file":"get-project-graph-lines.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/plugin/utils/get-project-graph-lines.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAM9D;;;GAGG;AACH,wBAAgB,gCAAgC,IAAI,IAAI,CAKvD;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAS1C;AAED,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,mBAAmB,EAAE,mBAAmB,GACvC,OAAO,CAAC,MAAM,EAAE,CAAC,CA6GnB"}
@@ -1,11 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cancelPendingProjectGraphRequest = cancelPendingProjectGraphRequest;
3
4
  exports.getGraphTimeoutMs = getGraphTimeoutMs;
4
5
  exports.getNxProjectGraphLines = getNxProjectGraphLines;
5
6
  const devkit_1 = require("@nx/devkit");
6
7
  const devkit_internals_1 = require("nx/src/devkit-internals");
7
8
  const exec_gradle_1 = require("../../utils/exec-gradle");
8
9
  const DEFAULT_GRAPH_TIMEOUT_SECONDS = (0, devkit_internals_1.isCI)() ? 600 : 120;
10
+ let currentAbortController;
11
+ /**
12
+ * Cancel any in-flight Gradle project graph process.
13
+ * Safe to call even if nothing is running.
14
+ */
15
+ function cancelPendingProjectGraphRequest() {
16
+ if (currentAbortController) {
17
+ currentAbortController.abort('cancelled');
18
+ currentAbortController = undefined;
19
+ }
20
+ }
9
21
  function getGraphTimeoutMs() {
10
22
  const envTimeout = process.env.NX_GRADLE_PROJECT_GRAPH_TIMEOUT;
11
23
  if (envTimeout) {
@@ -21,7 +33,11 @@ async function getNxProjectGraphLines(gradlewFile, gradleConfigHash, gradlePlugi
21
33
  const gradlePluginOptionsArgs = Object.entries(gradlePluginOptions ?? {})?.map(([key, value]) => `-P${key}=${value}`) ?? [];
22
34
  const timeoutMs = getGraphTimeoutMs();
23
35
  const timeoutSeconds = timeoutMs / 1000;
36
+ // Cancel any in-flight Gradle process from a previous call, then create a fresh controller.
37
+ cancelPendingProjectGraphRequest();
24
38
  const controller = new AbortController();
39
+ currentAbortController = controller;
40
+ const signal = controller.signal;
25
41
  const timer = setTimeout(() => controller.abort(), timeoutMs);
26
42
  try {
27
43
  nxProjectGraphBuffer = await (0, exec_gradle_1.execGradleAsync)(gradlewFile, [
@@ -35,10 +51,14 @@ async function getNxProjectGraphLines(gradlewFile, gradleConfigHash, gradlePlugi
35
51
  ...gradlePluginOptionsArgs,
36
52
  `-PworkspaceRoot=${devkit_1.workspaceRoot}`,
37
53
  process.env.NX_GRADLE_VERBOSE_LOGGING ? '--info' : '',
38
- ], { signal: controller.signal });
54
+ ], { signal });
39
55
  }
40
56
  catch (e) {
41
- if (controller.signal.aborted) {
57
+ // Cancelled by a newer populateProjectGraph call — let the caller handle it
58
+ if (signal.reason === 'cancelled') {
59
+ throw new Error('Gradle project graph generation was cancelled');
60
+ }
61
+ if (signal.aborted) {
42
62
  throw new devkit_1.AggregateCreateNodesError([
43
63
  [
44
64
  gradlewFile,
@@ -1 +1 @@
1
- {"version":3,"file":"exec-gradle.d.ts","sourceRoot":"","sources":["../../../../../packages/gradle/src/utils/exec-gradle.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EAEpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAY,MAAM,oBAAoB,CAAC;AAO/D,eAAO,MAAM,aAAa,QAEb,CAAC;AAEd,eAAO,MAAM,gBAAgB,QAErB,CAAC;AAET;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,WAAW,GAAE,eAAoB,GAChC,OAAO,CAAC,MAAM,CAAC,CAiCjB;AAED,wBAAgB,4CAA4C,CAC1D,MAAM,EAAE,mBAAmB,GAC1B,MAAM,GAAG,SAAS,CAWpB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,EACrB,yBAAyB,CAAC,EAAE,MAAM,GACjC,MAAM,CASR;AAED,wBAAgB,iCAAiC,CAC/C,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,EACrB,iBAAiB,CAAC,EAAE,MAAM,UAoC3B;AAED,wBAAgB,yCAAyC,CACvD,+BAA+B,EAAE,MAAM,EACvC,aAAa,EAAE,MAAM,UAqCtB"}
1
+ {"version":3,"file":"exec-gradle.d.ts","sourceRoot":"","sources":["../../../../../packages/gradle/src/utils/exec-gradle.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EAEpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAY,MAAM,oBAAoB,CAAC;AAQ/D,eAAO,MAAM,aAAa,QAEb,CAAC;AAEd,eAAO,MAAM,gBAAgB,QAErB,CAAC;AAET;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,WAAW,GAAE,eAAoB,GAChC,OAAO,CAAC,MAAM,CAAC,CA+CjB;AAED,wBAAgB,4CAA4C,CAC1D,MAAM,EAAE,mBAAmB,GAC1B,MAAM,GAAG,SAAS,CAWpB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,EACrB,yBAAyB,CAAC,EAAE,MAAM,GACjC,MAAM,CASR;AAED,wBAAgB,iCAAiC,CAC/C,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,EACrB,iBAAiB,CAAC,EAAE,MAAM,UAoC3B;AAED,wBAAgB,yCAAyC,CACvD,+BAA+B,EAAE,MAAM,EACvC,aAAa,EAAE,MAAM,UAqCtB"}
@@ -13,6 +13,7 @@ const node_fs_1 = require("node:fs");
13
13
  const node_path_1 = require("node:path");
14
14
  const run_commands_impl_1 = require("nx/src/executors/run-commands/run-commands.impl");
15
15
  const exit_codes_1 = require("nx/src/utils/exit-codes");
16
+ const treeKill = require("tree-kill");
16
17
  exports.fileSeparator = process.platform.startsWith('win')
17
18
  ? 'file:///'
18
19
  : 'file://';
@@ -34,6 +35,9 @@ function getGradleExecFile() {
34
35
  * @returns promise with the stdout buffer
35
36
  */
36
37
  function execGradleAsync(gradleBinaryPath, args, execOptions = {}) {
38
+ // Extract signal so we can handle cancellation with tree-kill
39
+ // instead of Node's default which only kills the immediate child.
40
+ const { signal, ...restOptions } = execOptions;
37
41
  return new Promise((res, rej) => {
38
42
  const cp = (0, node_child_process_1.execFile)(gradleBinaryPath, args, {
39
43
  cwd: (0, node_path_1.dirname)(gradleBinaryPath),
@@ -41,8 +45,16 @@ function execGradleAsync(gradleBinaryPath, args, execOptions = {}) {
41
45
  windowsHide: true,
42
46
  env: process.env,
43
47
  maxBuffer: run_commands_impl_1.LARGE_BUFFER,
44
- ...execOptions,
48
+ ...restOptions,
45
49
  }, undefined);
50
+ // Use tree-kill on abort to kill the entire process tree
51
+ // (cmd.exe → gradlew.bat → java.exe), not just the shell.
52
+ const onAbort = () => {
53
+ if (cp.pid) {
54
+ treeKill(cp.pid);
55
+ }
56
+ };
57
+ signal?.addEventListener('abort', onAbort, { once: true });
46
58
  let stdout = Buffer.from('');
47
59
  cp.stdout?.on('data', (data) => {
48
60
  stdout += data;
@@ -50,9 +62,10 @@ function execGradleAsync(gradleBinaryPath, args, execOptions = {}) {
50
62
  cp.stderr?.on('data', (data) => {
51
63
  stdout += data;
52
64
  });
53
- cp.on('exit', (code, signal) => {
65
+ cp.on('exit', (code, s) => {
66
+ signal?.removeEventListener('abort', onAbort);
54
67
  if (code === null)
55
- code = (0, exit_codes_1.signalToCode)(signal);
68
+ code = (0, exit_codes_1.signalToCode)(s);
56
69
  if (code === 0) {
57
70
  res(stdout);
58
71
  }