@nx/gradle 23.0.0-beta.3 → 23.0.0-beta.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.
- package/batch-runner/build/libs/gradle-batch-runner-all.jar +0 -0
- package/batch-runner/build/libs/gradle-batch-runner.jar +0 -0
- package/package.json +3 -3
- package/src/executors/gradle/gradle-batch.impl.d.ts +5 -2
- package/src/executors/gradle/gradle-batch.impl.d.ts.map +1 -1
- package/src/executors/gradle/gradle-batch.impl.js +108 -52
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/gradle",
|
|
3
|
-
"version": "23.0.0-beta.
|
|
3
|
+
"version": "23.0.0-beta.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Nx Plugin for Gradle allows Gradle tasks to be run through Nx",
|
|
6
6
|
"repository": {
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"migrations": "./migrations.json"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@nx/devkit": "23.0.0-beta.
|
|
43
|
+
"@nx/devkit": "23.0.0-beta.5",
|
|
44
44
|
"toml-eslint-parser": "^0.10.0",
|
|
45
45
|
"tree-kill": "^1.2.2",
|
|
46
46
|
"tslib": "^2.3.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"nx": "23.0.0-beta.
|
|
49
|
+
"nx": "23.0.0-beta.5"
|
|
50
50
|
},
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"access": "public"
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { ExecutorContext, ProjectGraphProjectNode, TaskGraph } from '@nx/devkit';
|
|
2
2
|
import { RunCommandsOptions } from 'nx/src/executors/run-commands/run-commands.impl';
|
|
3
|
-
import {
|
|
3
|
+
import { TaskResult } from 'nx/src/config/misc-interfaces';
|
|
4
4
|
import { GradleExecutorSchema } from './schema';
|
|
5
5
|
export declare const batchRunnerPath: string;
|
|
6
|
-
export default function gradleBatch(taskGraph: TaskGraph, inputs: Record<string, GradleExecutorSchema>, overrides: RunCommandsOptions, context: ExecutorContext):
|
|
6
|
+
export default function gradleBatch(taskGraph: TaskGraph, inputs: Record<string, GradleExecutorSchema>, overrides: RunCommandsOptions, context: ExecutorContext): AsyncGenerator<{
|
|
7
|
+
task: string;
|
|
8
|
+
result: TaskResult;
|
|
9
|
+
}>;
|
|
7
10
|
export declare function getGradlewTasksToRun(taskIds: string[], taskGraph: TaskGraph, inputs: Record<string, GradleExecutorSchema>, nodes: Record<string, ProjectGraphProjectNode>, fullTaskGraph?: TaskGraph): {
|
|
8
11
|
gradlewTasksToRun: Record<string, GradleExecutorSchema>;
|
|
9
12
|
excludeTasks: Set<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gradle-batch.impl.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/executors/gradle/gradle-batch.impl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEf,uBAAuB,EACvB,SAAS,EAEV,MAAM,YAAY,CAAC;AACpB,OAAO,
|
|
1
|
+
{"version":3,"file":"gradle-batch.impl.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/executors/gradle/gradle-batch.impl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEf,uBAAuB,EACvB,SAAS,EAEV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAahD,eAAO,MAAM,eAAe,QAG3B,CAAC;AAEF,wBAA+B,WAAW,CACxC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAC5C,SAAS,EAAE,kBAAkB,EAC7B,OAAO,EAAE,eAAe,GACvB,cAAc,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CA8EtD;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAC5C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,EAC9C,aAAa,GAAE,SAAqB;;;;EA0DrC"}
|
|
@@ -7,47 +7,60 @@ const devkit_1 = require("@nx/devkit");
|
|
|
7
7
|
const exec_gradle_1 = require("../../utils/exec-gradle");
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const child_process_1 = require("child_process");
|
|
10
|
+
const readline_1 = require("readline");
|
|
10
11
|
const get_exclude_task_1 = require("./get-exclude-task");
|
|
11
12
|
exports.batchRunnerPath = (0, path_1.join)(__dirname, '../../../batch-runner/build/libs/gradle-batch-runner-all.jar');
|
|
12
|
-
async function gradleBatch(taskGraph, inputs, overrides, context) {
|
|
13
|
+
async function* gradleBatch(taskGraph, inputs, overrides, context) {
|
|
14
|
+
const projectName = taskGraph.tasks[taskGraph.roots[0]]?.target?.project;
|
|
15
|
+
const projectRoot = context.projectGraph.nodes[projectName]?.data?.root ?? '';
|
|
16
|
+
const customGradleExecutableDirectory = (0, exec_gradle_1.getCustomGradleExecutableDirectoryFromPlugin)(context.nxJsonConfiguration);
|
|
17
|
+
let gradlewPath = (0, exec_gradle_1.findGradlewFile)((0, path_1.join)(projectRoot, 'project.json'), devkit_1.workspaceRoot, customGradleExecutableDirectory);
|
|
18
|
+
gradlewPath = (0, path_1.join)(context.root, gradlewPath);
|
|
19
|
+
const root = (0, path_1.dirname)(gradlewPath);
|
|
20
|
+
// set args with passed in args and overrides in command line
|
|
21
|
+
const input = inputs[taskGraph.roots[0]];
|
|
22
|
+
const args = typeof input.args === 'string'
|
|
23
|
+
? input.args.trim().split(' ')
|
|
24
|
+
: Array.isArray(input.args)
|
|
25
|
+
? input.args
|
|
26
|
+
: [];
|
|
27
|
+
if (overrides.__overrides_unparsed__.length) {
|
|
28
|
+
args.push(...overrides.__overrides_unparsed__);
|
|
29
|
+
}
|
|
30
|
+
const taskIds = Object.keys(taskGraph.tasks);
|
|
31
|
+
const { gradlewTasksToRun, excludeTasks, excludeTestTasks } = getGradlewTasksToRun(taskIds, taskGraph, inputs, context.projectGraph.nodes, context.taskGraph ?? taskGraph);
|
|
32
|
+
const yielded = new Set();
|
|
13
33
|
try {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
let gradlewPath = (0, exec_gradle_1.findGradlewFile)((0, path_1.join)(projectRoot, 'project.json'), devkit_1.workspaceRoot, customGradleExecutableDirectory);
|
|
18
|
-
gradlewPath = (0, path_1.join)(context.root, gradlewPath);
|
|
19
|
-
const root = (0, path_1.dirname)(gradlewPath);
|
|
20
|
-
const input = inputs[taskGraph.roots[0]];
|
|
21
|
-
let args = typeof input.args === 'string'
|
|
22
|
-
? input.args.trim().split(' ')
|
|
23
|
-
: Array.isArray(input.args)
|
|
24
|
-
? input.args
|
|
25
|
-
: [];
|
|
26
|
-
if (overrides.__overrides_unparsed__.length) {
|
|
27
|
-
args.push(...overrides.__overrides_unparsed__);
|
|
34
|
+
for await (const event of streamTasksInBatch(gradlewTasksToRun, excludeTasks, excludeTestTasks, args, root)) {
|
|
35
|
+
yielded.add(event.task);
|
|
36
|
+
yield event;
|
|
28
37
|
}
|
|
29
|
-
const taskIds = Object.keys(taskGraph.tasks);
|
|
30
|
-
const { gradlewTasksToRun, excludeTasks, excludeTestTasks } = getGradlewTasksToRun(taskIds, taskGraph, inputs, context.projectGraph.nodes, context.taskGraph ?? taskGraph);
|
|
31
|
-
const batchResults = await runTasksInBatch(gradlewTasksToRun, excludeTasks, excludeTestTasks, args, root);
|
|
32
|
-
taskIds.forEach((taskId) => {
|
|
33
|
-
if (!batchResults[taskId]) {
|
|
34
|
-
batchResults[taskId] = {
|
|
35
|
-
success: false,
|
|
36
|
-
terminalOutput: `Gradlew batch failed`,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
return batchResults;
|
|
41
38
|
}
|
|
42
39
|
catch (e) {
|
|
43
40
|
devkit_1.output.error({
|
|
44
41
|
title: `Gradlew batch failed`,
|
|
45
42
|
bodyLines: [e.toString()],
|
|
46
43
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
for (const taskId of taskIds) {
|
|
45
|
+
if (!yielded.has(taskId)) {
|
|
46
|
+
yielded.add(taskId);
|
|
47
|
+
yield {
|
|
48
|
+
task: taskId,
|
|
49
|
+
result: { success: false, terminalOutput: e.toString() },
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Any tasks the batch runner did not report on are treated as failed so Nx
|
|
56
|
+
// does not hang waiting for results.
|
|
57
|
+
for (const taskId of taskIds) {
|
|
58
|
+
if (!yielded.has(taskId)) {
|
|
59
|
+
yield {
|
|
60
|
+
task: taskId,
|
|
61
|
+
result: { success: false, terminalOutput: `Gradlew batch failed` },
|
|
62
|
+
};
|
|
63
|
+
}
|
|
51
64
|
}
|
|
52
65
|
}
|
|
53
66
|
function getGradlewTasksToRun(taskIds, taskGraph, inputs, nodes, fullTaskGraph = taskGraph) {
|
|
@@ -88,7 +101,7 @@ function getGradlewTasksToRun(taskIds, taskGraph, inputs, nodes, fullTaskGraph =
|
|
|
88
101
|
excludeTestTasks,
|
|
89
102
|
};
|
|
90
103
|
}
|
|
91
|
-
async function
|
|
104
|
+
async function* streamTasksInBatch(gradlewTasksToRun, excludeTasks, excludeTestTasks, args, root) {
|
|
92
105
|
const gradlewBatchStart = performance.mark(`gradlew-batch:start`);
|
|
93
106
|
const debugOptions = (process.env.NX_GRADLE_BATCH_DEBUG ?? '').trim();
|
|
94
107
|
const spawnArgs = [
|
|
@@ -102,30 +115,73 @@ async function runTasksInBatch(gradlewTasksToRun, excludeTasks, excludeTestTasks
|
|
|
102
115
|
`--excludeTestTasks=${Array.from(excludeTestTasks).join(',')}`,
|
|
103
116
|
...(process.env.NX_VERBOSE_LOGGING === 'true' ? [] : ['--quiet']),
|
|
104
117
|
];
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
// stdout is piped
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const chunks = [];
|
|
116
|
-
cp.stdout.on('data', (chunk) => chunks.push(chunk));
|
|
118
|
+
// stderr is inherited so Gradle output (tee'd to System.err by TeeOutputStream)
|
|
119
|
+
// and logger output flow to the terminal in real-time.
|
|
120
|
+
// stdout is piped so we can read NX_RESULT lines emitted per task.
|
|
121
|
+
const cp = (0, child_process_1.spawn)('java', spawnArgs, {
|
|
122
|
+
cwd: devkit_1.workspaceRoot,
|
|
123
|
+
windowsHide: true,
|
|
124
|
+
env: process.env,
|
|
125
|
+
stdio: ['pipe', 'pipe', 'inherit'],
|
|
126
|
+
});
|
|
127
|
+
const exit = new Promise((resolve, reject) => {
|
|
117
128
|
cp.on('error', reject);
|
|
118
|
-
cp.on('close', (code) =>
|
|
119
|
-
|
|
120
|
-
|
|
129
|
+
cp.on('close', (code) => resolve(code ?? 0));
|
|
130
|
+
});
|
|
131
|
+
const rl = (0, readline_1.createInterface)({ input: cp.stdout, crlfDelay: Infinity });
|
|
132
|
+
// Drain stdout into a queue eagerly. Yielding inside the readline loop creates
|
|
133
|
+
// back-pressure: if the consumer is slow, `yield` blocks, readline pauses, the
|
|
134
|
+
// OS pipe between Java and Node fills, and Java's NX_RESULT println blocks on
|
|
135
|
+
// a full pipe — the JVM hangs even though all task work is done.
|
|
136
|
+
const queue = [];
|
|
137
|
+
let notifyAvailable = null;
|
|
138
|
+
let readerClosed = false;
|
|
139
|
+
rl.on('line', (line) => {
|
|
140
|
+
if (!line.startsWith('NX_RESULT:'))
|
|
141
|
+
return;
|
|
142
|
+
try {
|
|
143
|
+
const data = JSON.parse(line.slice('NX_RESULT:'.length));
|
|
144
|
+
queue.push({
|
|
145
|
+
task: data.task,
|
|
146
|
+
result: {
|
|
147
|
+
success: data.result.success ?? false,
|
|
148
|
+
terminalOutput: data.result.terminalOutput ?? '',
|
|
149
|
+
startTime: data.result.startTime,
|
|
150
|
+
endTime: data.result.endTime,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
console.error('[Gradle Batch] Failed to parse result line:', line, e);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
notifyAvailable?.();
|
|
159
|
+
notifyAvailable = null;
|
|
160
|
+
});
|
|
161
|
+
rl.on('close', () => {
|
|
162
|
+
readerClosed = true;
|
|
163
|
+
notifyAvailable?.();
|
|
164
|
+
notifyAvailable = null;
|
|
165
|
+
});
|
|
166
|
+
try {
|
|
167
|
+
while (!readerClosed || queue.length > 0) {
|
|
168
|
+
if (queue.length > 0) {
|
|
169
|
+
yield queue.shift();
|
|
121
170
|
}
|
|
122
171
|
else {
|
|
123
|
-
|
|
172
|
+
await new Promise((resolve) => {
|
|
173
|
+
notifyAvailable = resolve;
|
|
174
|
+
});
|
|
124
175
|
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
rl.close();
|
|
180
|
+
}
|
|
181
|
+
const code = await exit;
|
|
127
182
|
const gradlewBatchEnd = performance.mark(`gradlew-batch:end`);
|
|
128
183
|
performance.measure(`gradlew-batch`, gradlewBatchStart.name, gradlewBatchEnd.name);
|
|
129
|
-
|
|
130
|
-
|
|
184
|
+
if (code !== 0) {
|
|
185
|
+
throw new Error(`Gradle batch runner exited with code ${code}`);
|
|
186
|
+
}
|
|
131
187
|
}
|