@nx/gradle 22.7.1 → 22.7.2
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/get-exclude-task.d.ts +3 -17
- package/src/executors/gradle/get-exclude-task.d.ts.map +1 -1
- package/src/executors/gradle/get-exclude-task.js +39 -76
- package/src/executors/gradle/gradle-batch.impl.d.ts +6 -6
- package/src/executors/gradle/gradle-batch.impl.d.ts.map +1 -1
- package/src/executors/gradle/gradle-batch.impl.js +111 -89
- package/src/executors/gradle/gradle.impl.d.ts.map +1 -1
- package/src/executors/gradle/gradle.impl.js +5 -2
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/gradle",
|
|
3
|
-
"version": "22.7.
|
|
3
|
+
"version": "22.7.2",
|
|
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": "22.7.
|
|
43
|
+
"@nx/devkit": "22.7.2",
|
|
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": "22.7.
|
|
49
|
+
"nx": "22.7.2"
|
|
50
50
|
},
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"access": "public"
|
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
import { ProjectGraphProjectNode,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* that are not part of the current execution set.
|
|
5
|
-
*
|
|
6
|
-
* For example, if a project defines `dependsOn: ['lint']` for the `test` target,
|
|
7
|
-
* and only `test` is running, this will return: ['lint']
|
|
8
|
-
*
|
|
9
|
-
* @param tasks - Set of Target to process
|
|
10
|
-
* @param nodes - Project graph nodes
|
|
11
|
-
* @param runningTasks - Set of Target that are currently running (won't be excluded)
|
|
12
|
-
* @param includeDependsOnTasks - Set of Gradle task names that should be included (not excluded)
|
|
13
|
-
* (typically provider-based dependencies that Gradle must resolve)
|
|
14
|
-
*/
|
|
15
|
-
export declare function getExcludeTasks(tasks: Set<Target>, nodes: Record<string, ProjectGraphProjectNode>, runningTasks?: Set<Target>, includeDependsOnTasks?: Set<string>): Set<string>;
|
|
16
|
-
export declare function getGradleTaskName(pt: Target, nodes: Record<string, ProjectGraphProjectNode>): string | null;
|
|
17
|
-
export declare function getAllDependsOn(nodes: Record<string, ProjectGraphProjectNode>, projectName: string, targetName: string): Set<Target>;
|
|
1
|
+
import { ProjectGraphProjectNode, TaskGraph } from '@nx/devkit';
|
|
2
|
+
export declare function getExcludeTasksFromTaskGraph(taskIdsToExcludeDepsOf: Iterable<string>, runningTaskIds: Set<string>, taskGraph: TaskGraph, nodes: Record<string, ProjectGraphProjectNode>, includeDependsOnTasks?: Set<string>): Set<string>;
|
|
3
|
+
export declare function getAllDependsOnFromTaskGraph(startTaskIds: Iterable<string>, taskGraph: TaskGraph): Set<string>;
|
|
18
4
|
//# sourceMappingURL=get-exclude-task.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-exclude-task.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/executors/gradle/get-exclude-task.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"get-exclude-task.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/executors/gradle/get-exclude-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAU,SAAS,EAAE,MAAM,YAAY,CAAC;AAUxE,wBAAgB,4BAA4B,CAC1C,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,EACxC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,EAC3B,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,EAC9C,qBAAqB,GAAE,GAAG,CAAC,MAAM,CAAa,GAC7C,GAAG,CAAC,MAAM,CAAC,CAsBb;AAED,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC9B,SAAS,EAAE,SAAS,GACnB,GAAG,CAAC,MAAM,CAAC,CAiCb"}
|
|
@@ -1,90 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* Resolves a dependsOn entry to a Target.
|
|
9
|
-
* Handles both string format ("target") and object format
|
|
10
|
-
* ({ target: "name", projects?: ["proj1"] }).
|
|
11
|
-
* For same-project object deps (no projects field), uses the owning project name.
|
|
12
|
-
*/
|
|
13
|
-
function resolveDepToTarget(dep, owningProject) {
|
|
14
|
-
if (typeof dep === 'string') {
|
|
15
|
-
return { project: owningProject, target: dep };
|
|
16
|
-
}
|
|
17
|
-
const target = dep?.target;
|
|
18
|
-
if (!target) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
if (dep.projects) {
|
|
22
|
-
const projectList = Array.isArray(dep.projects)
|
|
23
|
-
? dep.projects
|
|
24
|
-
: [dep.projects];
|
|
25
|
-
return {
|
|
26
|
-
project: projectList[0] !== 'self' ? projectList[0] : owningProject,
|
|
27
|
-
target,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
return { project: owningProject, target };
|
|
3
|
+
exports.getExcludeTasksFromTaskGraph = getExcludeTasksFromTaskGraph;
|
|
4
|
+
exports.getAllDependsOnFromTaskGraph = getAllDependsOnFromTaskGraph;
|
|
5
|
+
function getGradleTaskName(target, nodes) {
|
|
6
|
+
return nodes[target.project]?.data?.targets?.[target.target]?.options
|
|
7
|
+
?.taskName;
|
|
31
8
|
}
|
|
32
|
-
|
|
33
|
-
* Returns Gradle CLI arguments to exclude dependent tasks
|
|
34
|
-
* that are not part of the current execution set.
|
|
35
|
-
*
|
|
36
|
-
* For example, if a project defines `dependsOn: ['lint']` for the `test` target,
|
|
37
|
-
* and only `test` is running, this will return: ['lint']
|
|
38
|
-
*
|
|
39
|
-
* @param tasks - Set of Target to process
|
|
40
|
-
* @param nodes - Project graph nodes
|
|
41
|
-
* @param runningTasks - Set of Target that are currently running (won't be excluded)
|
|
42
|
-
* @param includeDependsOnTasks - Set of Gradle task names that should be included (not excluded)
|
|
43
|
-
* (typically provider-based dependencies that Gradle must resolve)
|
|
44
|
-
*/
|
|
45
|
-
function getExcludeTasks(tasks, nodes, runningTasks = new Set(), includeDependsOnTasks = new Set()) {
|
|
9
|
+
function getExcludeTasksFromTaskGraph(taskIdsToExcludeDepsOf, runningTaskIds, taskGraph, nodes, includeDependsOnTasks = new Set()) {
|
|
46
10
|
const excludes = new Set();
|
|
47
|
-
const
|
|
48
|
-
for (const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
11
|
+
const transitiveDepIds = getAllDependsOnFromTaskGraph(taskIdsToExcludeDepsOf, taskGraph);
|
|
12
|
+
for (const depTaskId of transitiveDepIds) {
|
|
13
|
+
if (runningTaskIds.has(depTaskId)) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const task = taskGraph.tasks[depTaskId];
|
|
17
|
+
if (!task) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const gradleTaskName = getGradleTaskName(task.target, nodes);
|
|
21
|
+
if (gradleTaskName && !includeDependsOnTasks.has(gradleTaskName)) {
|
|
22
|
+
excludes.add(gradleTaskName);
|
|
58
23
|
}
|
|
59
24
|
}
|
|
60
25
|
return excludes;
|
|
61
26
|
}
|
|
62
|
-
function
|
|
63
|
-
return nodes[pt.project]?.data?.targets?.[pt.target]?.options?.taskName;
|
|
64
|
-
}
|
|
65
|
-
function getAllDependsOn(nodes, projectName, targetName) {
|
|
66
|
-
const allDependsOn = new Set();
|
|
27
|
+
function getAllDependsOnFromTaskGraph(startTaskIds, taskGraph) {
|
|
67
28
|
const result = new Set();
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
29
|
+
const seen = new Set();
|
|
30
|
+
const stack = [];
|
|
31
|
+
const edges = (id) => [
|
|
32
|
+
...(taskGraph.dependencies[id] ?? []),
|
|
33
|
+
...(taskGraph.continuousDependencies?.[id] ?? []),
|
|
34
|
+
];
|
|
35
|
+
for (const id of startTaskIds) {
|
|
36
|
+
seen.add(id);
|
|
37
|
+
for (const dep of edges(id)) {
|
|
38
|
+
stack.push(dep);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
73
41
|
while (stack.length > 0) {
|
|
74
42
|
const current = stack.pop();
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
for (const dep of directDependencies) {
|
|
84
|
-
const depPt = resolveDepToTarget(dep, current.project);
|
|
85
|
-
if (depPt && !allDependsOn.has((0, devkit_1.targetToTargetString)(depPt))) {
|
|
86
|
-
stack.push(depPt);
|
|
87
|
-
}
|
|
43
|
+
if (seen.has(current)) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
seen.add(current);
|
|
47
|
+
result.add(current);
|
|
48
|
+
for (const dep of edges(current)) {
|
|
49
|
+
if (!seen.has(dep)) {
|
|
50
|
+
stack.push(dep);
|
|
88
51
|
}
|
|
89
52
|
}
|
|
90
53
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
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):
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export declare function getGradlewTasksToRun(taskIds: string[], taskGraph: TaskGraph, inputs: Record<string, GradleExecutorSchema>, nodes: Record<string, ProjectGraphProjectNode
|
|
6
|
+
export default function gradleBatch(taskGraph: TaskGraph, inputs: Record<string, GradleExecutorSchema>, overrides: RunCommandsOptions, context: ExecutorContext): AsyncGenerator<{
|
|
7
|
+
task: string;
|
|
8
|
+
result: TaskResult;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function getGradlewTasksToRun(taskIds: string[], taskGraph: TaskGraph, inputs: Record<string, GradleExecutorSchema>, nodes: Record<string, ProjectGraphProjectNode>, fullTaskGraph?: TaskGraph): {
|
|
11
11
|
gradlewTasksToRun: Record<string, GradleExecutorSchema>;
|
|
12
12
|
excludeTasks: Set<string>;
|
|
13
13
|
excludeTestTasks: 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,
|
|
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,CAkEtD;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,66 +7,59 @@ 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); // find gradlew near project root
|
|
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
|
-
let 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__);
|
|
34
|
+
for await (const event of streamTasksInBatch(gradlewTasksToRun, excludeTasks, excludeTestTasks, args, root)) {
|
|
35
|
+
yielded.add(event.task);
|
|
36
|
+
yield event;
|
|
29
37
|
}
|
|
30
|
-
const taskIds = Object.keys(taskGraph.tasks);
|
|
31
|
-
const { gradlewTasksToRun, excludeTasks, excludeTestTasks } = getGradlewTasksToRun(taskIds, taskGraph, inputs, context.projectGraph.nodes);
|
|
32
|
-
const batchResults = await runTasksInBatch(gradlewTasksToRun, excludeTasks, excludeTestTasks, args, root);
|
|
33
|
-
taskIds.forEach((taskId) => {
|
|
34
|
-
if (!batchResults[taskId]) {
|
|
35
|
-
batchResults[taskId] = {
|
|
36
|
-
success: false,
|
|
37
|
-
terminalOutput: `Gradlew batch failed`,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
return batchResults;
|
|
42
38
|
}
|
|
43
39
|
catch (e) {
|
|
44
40
|
devkit_1.output.error({
|
|
45
41
|
title: `Gradlew batch failed`,
|
|
46
42
|
bodyLines: [e.toString()],
|
|
47
43
|
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
+
}
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const tasksWithExclude = new Set();
|
|
59
|
-
const testTasksWithExclude = new Set();
|
|
60
|
-
const tasksWithoutExclude = new Set();
|
|
55
|
+
function getGradlewTasksToRun(taskIds, taskGraph, inputs, nodes, fullTaskGraph = taskGraph) {
|
|
56
|
+
const tasksWithExcludeIds = new Set();
|
|
57
|
+
const testTasksWithExcludeIds = new Set();
|
|
58
|
+
const tasksWithoutExcludeIds = new Set();
|
|
61
59
|
const gradlewTasksToRun = {};
|
|
62
60
|
const includeDependsOnTasks = new Set();
|
|
63
61
|
for (const taskId of taskIds) {
|
|
64
|
-
const
|
|
65
|
-
const input = inputs[task.id];
|
|
66
|
-
const taskTarget = {
|
|
67
|
-
project: task.target.project,
|
|
68
|
-
target: task.target.target,
|
|
69
|
-
};
|
|
62
|
+
const input = inputs[taskId];
|
|
70
63
|
gradlewTasksToRun[taskId] = input;
|
|
71
64
|
if (input.includeDependsOnTasks) {
|
|
72
65
|
for (const t of input.includeDependsOnTasks) {
|
|
@@ -75,44 +68,29 @@ function getGradlewTasksToRun(taskIds, taskGraph, inputs, nodes) {
|
|
|
75
68
|
}
|
|
76
69
|
if (input.excludeDependsOn) {
|
|
77
70
|
if (input.testClassName) {
|
|
78
|
-
|
|
71
|
+
testTasksWithExcludeIds.add(taskId);
|
|
79
72
|
}
|
|
80
73
|
else {
|
|
81
|
-
|
|
74
|
+
tasksWithExcludeIds.add(taskId);
|
|
82
75
|
}
|
|
83
76
|
}
|
|
84
77
|
else {
|
|
85
|
-
|
|
78
|
+
tasksWithoutExcludeIds.add(taskId);
|
|
86
79
|
}
|
|
87
80
|
}
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
})));
|
|
92
|
-
for (const task of tasksWithoutExclude) {
|
|
93
|
-
const dependencies = (0, get_exclude_task_1.getAllDependsOn)(nodes, task.project, task.target);
|
|
94
|
-
dependencies.forEach((dep) => allRunning.add(dep));
|
|
95
|
-
}
|
|
96
|
-
const excludeTasks = (0, get_exclude_task_1.getExcludeTasks)(tasksWithExclude, nodes, allRunning, includeDependsOnTasks);
|
|
97
|
-
const allTestsDependsOn = new Set();
|
|
98
|
-
for (const task of testTasksWithExclude) {
|
|
99
|
-
const taskDependsOn = (0, get_exclude_task_1.getAllDependsOn)(nodes, task.project, task.target);
|
|
100
|
-
taskDependsOn.forEach((dep) => allTestsDependsOn.add(dep));
|
|
101
|
-
}
|
|
102
|
-
const excludeTestTasks = new Set();
|
|
103
|
-
for (const task of allTestsDependsOn) {
|
|
104
|
-
const gradleTaskName = (0, get_exclude_task_1.getGradleTaskName)(task, nodes);
|
|
105
|
-
if (gradleTaskName) {
|
|
106
|
-
excludeTestTasks.add(gradleTaskName);
|
|
107
|
-
}
|
|
81
|
+
const runningTaskIds = new Set(taskIds);
|
|
82
|
+
for (const depId of (0, get_exclude_task_1.getAllDependsOnFromTaskGraph)(tasksWithoutExcludeIds, fullTaskGraph)) {
|
|
83
|
+
runningTaskIds.add(depId);
|
|
108
84
|
}
|
|
85
|
+
const excludeTasks = (0, get_exclude_task_1.getExcludeTasksFromTaskGraph)(tasksWithExcludeIds, runningTaskIds, fullTaskGraph, nodes, includeDependsOnTasks);
|
|
86
|
+
const excludeTestTasks = (0, get_exclude_task_1.getExcludeTasksFromTaskGraph)(testTasksWithExcludeIds, new Set(), fullTaskGraph, nodes);
|
|
109
87
|
return {
|
|
110
88
|
gradlewTasksToRun,
|
|
111
89
|
excludeTasks,
|
|
112
90
|
excludeTestTasks,
|
|
113
91
|
};
|
|
114
92
|
}
|
|
115
|
-
async function
|
|
93
|
+
async function* streamTasksInBatch(gradlewTasksToRun, excludeTasks, excludeTestTasks, args, root) {
|
|
116
94
|
const gradlewBatchStart = performance.mark(`gradlew-batch:start`);
|
|
117
95
|
const debugOptions = (process.env.NX_GRADLE_BATCH_DEBUG ?? '').trim();
|
|
118
96
|
const spawnArgs = [
|
|
@@ -126,30 +104,74 @@ async function runTasksInBatch(gradlewTasksToRun, excludeTasks, excludeTestTasks
|
|
|
126
104
|
`--excludeTestTasks=${Array.from(excludeTestTasks).join(',')}`,
|
|
127
105
|
...(process.env.NX_VERBOSE_LOGGING === 'true' ? [] : ['--quiet']),
|
|
128
106
|
];
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
// stdout is piped
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const chunks = [];
|
|
140
|
-
cp.stdout.on('data', (chunk) => chunks.push(chunk));
|
|
107
|
+
// stderr is inherited so Gradle output (tee'd to System.err by TeeOutputStream)
|
|
108
|
+
// and logger output flow to the terminal in real-time.
|
|
109
|
+
// stdout is piped so we can read NX_RESULT lines emitted per task.
|
|
110
|
+
const cp = (0, child_process_1.spawn)('java', spawnArgs, {
|
|
111
|
+
cwd: devkit_1.workspaceRoot,
|
|
112
|
+
windowsHide: true,
|
|
113
|
+
env: process.env,
|
|
114
|
+
stdio: ['pipe', 'pipe', 'inherit'],
|
|
115
|
+
});
|
|
116
|
+
const exit = new Promise((resolve, reject) => {
|
|
141
117
|
cp.on('error', reject);
|
|
142
|
-
cp.on('close', (code) =>
|
|
143
|
-
|
|
144
|
-
|
|
118
|
+
cp.on('close', (code) => resolve(code ?? 0));
|
|
119
|
+
});
|
|
120
|
+
const rl = (0, readline_1.createInterface)({ input: cp.stdout, crlfDelay: Infinity });
|
|
121
|
+
// Drain stdout into a queue eagerly. Yielding inside the readline loop creates
|
|
122
|
+
// back-pressure: if the consumer is slow, `yield` blocks, readline pauses, the
|
|
123
|
+
// OS pipe between Java and Node fills, and Java's NX_RESULT println blocks on
|
|
124
|
+
// a full pipe — the JVM hangs even though all task work is done.
|
|
125
|
+
const queue = [];
|
|
126
|
+
let notifyAvailable = null;
|
|
127
|
+
let readerClosed = false;
|
|
128
|
+
rl.on('line', (line) => {
|
|
129
|
+
if (!line.startsWith('NX_RESULT:'))
|
|
130
|
+
return;
|
|
131
|
+
try {
|
|
132
|
+
const data = JSON.parse(line.slice('NX_RESULT:'.length));
|
|
133
|
+
queue.push({
|
|
134
|
+
task: data.task,
|
|
135
|
+
result: {
|
|
136
|
+
success: data.result.success ?? false,
|
|
137
|
+
status: data.result.status,
|
|
138
|
+
terminalOutput: data.result.terminalOutput ?? '',
|
|
139
|
+
startTime: data.result.startTime,
|
|
140
|
+
endTime: data.result.endTime,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
console.error('[Gradle Batch] Failed to parse result line:', line, e);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
notifyAvailable?.();
|
|
149
|
+
notifyAvailable = null;
|
|
150
|
+
});
|
|
151
|
+
rl.on('close', () => {
|
|
152
|
+
readerClosed = true;
|
|
153
|
+
notifyAvailable?.();
|
|
154
|
+
notifyAvailable = null;
|
|
155
|
+
});
|
|
156
|
+
try {
|
|
157
|
+
while (!readerClosed || queue.length > 0) {
|
|
158
|
+
if (queue.length > 0) {
|
|
159
|
+
yield queue.shift();
|
|
145
160
|
}
|
|
146
161
|
else {
|
|
147
|
-
|
|
162
|
+
await new Promise((resolve) => {
|
|
163
|
+
notifyAvailable = resolve;
|
|
164
|
+
});
|
|
148
165
|
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
rl.close();
|
|
170
|
+
}
|
|
171
|
+
const code = await exit;
|
|
151
172
|
const gradlewBatchEnd = performance.mark(`gradlew-batch:end`);
|
|
152
173
|
performance.measure(`gradlew-batch`, gradlewBatchStart.name, gradlewBatchEnd.name);
|
|
153
|
-
|
|
154
|
-
|
|
174
|
+
if (code !== 0) {
|
|
175
|
+
throw new Error(`Gradle batch runner exited with code ${code}`);
|
|
176
|
+
}
|
|
155
177
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gradle.impl.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/executors/gradle/gradle.impl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiB,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAShD,wBAA8B,cAAc,CAC1C,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"gradle.impl.d.ts","sourceRoot":"","sources":["../../../../../../packages/gradle/src/executors/gradle/gradle.impl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiB,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAShD,wBAA8B,cAAc,CAC1C,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAkF/B"}
|
|
@@ -44,9 +44,12 @@ async function gradleExecutor(options, context) {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
|
-
if (options.excludeDependsOn) {
|
|
47
|
+
if (options.excludeDependsOn && context.taskGraph) {
|
|
48
|
+
const taskId = context.configurationName
|
|
49
|
+
? `${context.projectName}:${context.targetName}:${context.configurationName}`
|
|
50
|
+
: `${context.projectName}:${context.targetName}`;
|
|
48
51
|
const includeDependsOnTasks = new Set(options.includeDependsOnTasks ?? []);
|
|
49
|
-
(0, get_exclude_task_1.
|
|
52
|
+
(0, get_exclude_task_1.getExcludeTasksFromTaskGraph)([taskId], new Set([taskId]), context.taskGraph, context.projectGraph.nodes, includeDependsOnTasks).forEach((task) => {
|
|
50
53
|
if (task) {
|
|
51
54
|
args.push('--exclude-task', task);
|
|
52
55
|
}
|