@nx/gradle 21.1.2 → 21.2.0-beta.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/README.md +4 -4
- package/batch-runner/build/libs/batch-runner-all.jar +0 -0
- package/batch-runner/build/libs/batch-runner.jar +0 -0
- package/migrations.json +6 -0
- package/package.json +2 -2
- package/src/executors/gradle/get-exclude-task.d.ts +14 -0
- package/src/executors/gradle/get-exclude-task.js +46 -0
- package/src/executors/gradle/gradle-batch.impl.d.ts +2 -2
- package/src/executors/gradle/gradle-batch.impl.js +74 -40
- package/src/executors/gradle/gradle.impl.d.ts +2 -2
- package/src/executors/gradle/gradle.impl.js +12 -0
- package/src/executors/gradle/schema.d.ts +2 -1
- package/src/executors/gradle/schema.json +6 -0
- package/src/generators/init/gradle-project-graph-plugin-utils.d.ts +21 -0
- package/src/generators/init/gradle-project-graph-plugin-utils.js +149 -0
- package/src/generators/init/init.d.ts +0 -4
- package/src/generators/init/init.js +2 -67
- package/src/migrations/21-1-2/change-plugin-version-0-1-0.d.ts +2 -0
- package/src/migrations/21-1-2/change-plugin-version-0-1-0.js +18 -0
- package/src/plugin/utils/get-project-graph-lines.js +1 -3
package/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
<p style="text-align: center;">
|
2
2
|
<picture>
|
3
3
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
|
4
|
-
<img alt="Nx - Smart
|
4
|
+
<img alt="Nx - Smart Repos · Fast Builds" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
|
5
5
|
</picture>
|
6
6
|
</p>
|
7
7
|
|
@@ -22,9 +22,9 @@
|
|
22
22
|
|
23
23
|
> Note: this plugin is currently experimental.
|
24
24
|
|
25
|
-
# Nx: Smart
|
25
|
+
# Nx: Smart Repos · Fast Builds
|
26
26
|
|
27
|
-
|
27
|
+
An AI-first build platform that connects everything from your editor to CI. Helping you deliver fast, without breaking things.
|
28
28
|
|
29
29
|
This package is a [Gradle plugin for Nx](https://nx.dev/gradle/overview).
|
30
30
|
|
@@ -66,5 +66,5 @@ npx nx@latest init
|
|
66
66
|
- [Blog Posts About Nx](https://nx.dev/blog)
|
67
67
|
|
68
68
|
<p style="text-align: center;"><a href="https://nx.dev/#learning-materials" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-courses-and-videos.svg"
|
69
|
-
width="100%" alt="Nx - Smart
|
69
|
+
width="100%" alt="Nx - Smart Repos · Fast Builds"></a></p>
|
70
70
|
|
Binary file
|
Binary file
|
package/migrations.json
CHANGED
@@ -29,6 +29,12 @@
|
|
29
29
|
"cli": "nx",
|
30
30
|
"description": "Change @nx/gradle option from ciTargetName to ciTestTargetName",
|
31
31
|
"factory": "./src/migrations/21-0-0/change-ciTargetName-to-ciTestTargetName"
|
32
|
+
},
|
33
|
+
"change-plugin-version-0-1-0": {
|
34
|
+
"version": "21.1.2-beta.1",
|
35
|
+
"cli": "nx",
|
36
|
+
"description": "Change dev.nx.gradle.project-graph to version 0.1.0 in build file",
|
37
|
+
"factory": "./src/migrations/21-1-2/change-plugin-version-0-1-0"
|
32
38
|
}
|
33
39
|
},
|
34
40
|
"packageJsonUpdates": {}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nx/gradle",
|
3
|
-
"version": "21.
|
3
|
+
"version": "21.2.0-beta.2",
|
4
4
|
"private": false,
|
5
5
|
"description": "The Nx Plugin for Gradle allows Gradle tasks to be run through Nx",
|
6
6
|
"repository": {
|
@@ -35,7 +35,7 @@
|
|
35
35
|
"migrations": "./migrations.json"
|
36
36
|
},
|
37
37
|
"dependencies": {
|
38
|
-
"@nx/devkit": "21.
|
38
|
+
"@nx/devkit": "21.2.0-beta.2"
|
39
39
|
},
|
40
40
|
"publishConfig": {
|
41
41
|
"access": "public"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { ProjectGraph } from 'nx/src/config/project-graph';
|
2
|
+
/**
|
3
|
+
* Returns Gradle CLI arguments to exclude dependent tasks
|
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
|
+
export declare function getExcludeTasks(projectGraph: ProjectGraph, targets: {
|
10
|
+
project: string;
|
11
|
+
target: string;
|
12
|
+
excludeDependsOn: boolean;
|
13
|
+
}[], runningTaskIds?: Set<string>): Set<string>;
|
14
|
+
export declare function getAllDependsOn(projectGraph: ProjectGraph, projectName: string, targetName: string, visited?: Set<string>): string[];
|
@@ -0,0 +1,46 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getExcludeTasks = getExcludeTasks;
|
4
|
+
exports.getAllDependsOn = getAllDependsOn;
|
5
|
+
/**
|
6
|
+
* Returns Gradle CLI arguments to exclude dependent tasks
|
7
|
+
* that are not part of the current execution set.
|
8
|
+
*
|
9
|
+
* For example, if a project defines `dependsOn: ['lint']` for the `test` target,
|
10
|
+
* and only `test` is running, this will return: ['lint']
|
11
|
+
*/
|
12
|
+
function getExcludeTasks(projectGraph, targets, runningTaskIds = new Set()) {
|
13
|
+
const excludes = new Set();
|
14
|
+
for (const { project, target, excludeDependsOn } of targets) {
|
15
|
+
if (!excludeDependsOn) {
|
16
|
+
continue;
|
17
|
+
}
|
18
|
+
const taskDeps = projectGraph.nodes[project]?.data?.targets?.[target]?.dependsOn ?? [];
|
19
|
+
for (const dep of taskDeps) {
|
20
|
+
const taskId = typeof dep === 'string' ? dep : dep?.target;
|
21
|
+
if (taskId && !runningTaskIds.has(taskId)) {
|
22
|
+
const [projectName, targetName] = taskId.split(':');
|
23
|
+
const taskName = projectGraph.nodes[projectName]?.data?.targets?.[targetName]?.options
|
24
|
+
?.taskName;
|
25
|
+
if (taskName) {
|
26
|
+
excludes.add(taskName);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
return excludes;
|
32
|
+
}
|
33
|
+
function getAllDependsOn(projectGraph, projectName, targetName, visited = new Set()) {
|
34
|
+
const dependsOn = projectGraph[projectName]?.data?.targets?.[targetName]?.dependsOn ?? [];
|
35
|
+
const allDependsOn = [];
|
36
|
+
for (const dependency of dependsOn) {
|
37
|
+
if (!visited.has(dependency)) {
|
38
|
+
visited.add(dependency);
|
39
|
+
const [depProjectName, depTargetName] = dependency.split(':');
|
40
|
+
allDependsOn.push(dependency);
|
41
|
+
// Recursively get dependencies of the current dependency
|
42
|
+
allDependsOn.push(...getAllDependsOn(projectGraph, depProjectName, depTargetName, visited));
|
43
|
+
}
|
44
|
+
}
|
45
|
+
return allDependsOn;
|
46
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { ExecutorContext, TaskGraph } from '@nx/devkit';
|
2
2
|
import { RunCommandsOptions } from 'nx/src/executors/run-commands/run-commands.impl';
|
3
3
|
import { BatchResults } from 'nx/src/tasks-runner/batch/batch-messages';
|
4
|
-
import {
|
4
|
+
import { GradleExecutorSchema } from './schema';
|
5
5
|
export declare const batchRunnerPath: string;
|
6
|
-
export default function gradleBatch(taskGraph: TaskGraph, inputs: Record<string,
|
6
|
+
export default function gradleBatch(taskGraph: TaskGraph, inputs: Record<string, GradleExecutorSchema>, overrides: RunCommandsOptions, context: ExecutorContext): Promise<BatchResults>;
|
@@ -8,13 +8,15 @@ 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
10
|
const pseudo_terminal_1 = require("nx/src/tasks-runner/pseudo-terminal");
|
11
|
+
const get_exclude_task_1 = require("./get-exclude-task");
|
11
12
|
exports.batchRunnerPath = (0, path_1.join)(__dirname, '../../../batch-runner/build/libs/batch-runner-all.jar');
|
12
13
|
async function gradleBatch(taskGraph, inputs, overrides, context) {
|
13
14
|
try {
|
14
15
|
const projectName = taskGraph.tasks[taskGraph.roots[0]]?.target?.project;
|
15
16
|
let projectRoot = context.projectGraph.nodes[projectName]?.data?.root ?? '';
|
16
|
-
|
17
|
-
|
17
|
+
let gradlewPath = (0, exec_gradle_1.findGradlewFile)((0, path_1.join)(projectRoot, 'project.json')); // find gradlew near project root
|
18
|
+
gradlewPath = (0, path_1.join)(context.root, gradlewPath);
|
19
|
+
const root = (0, path_1.dirname)(gradlewPath);
|
18
20
|
// set args with passed in args and overrides in command line
|
19
21
|
const input = inputs[taskGraph.roots[0]];
|
20
22
|
let args = typeof input.args === 'string'
|
@@ -25,7 +27,25 @@ async function gradleBatch(taskGraph, inputs, overrides, context) {
|
|
25
27
|
if (overrides.__overrides_unparsed__.length) {
|
26
28
|
args.push(...overrides.__overrides_unparsed__);
|
27
29
|
}
|
28
|
-
const
|
30
|
+
const taskIdsWithExclude = [];
|
31
|
+
const taskIdsWithoutExclude = [];
|
32
|
+
const taskIds = Object.keys(taskGraph.tasks);
|
33
|
+
for (const taskId of taskIds) {
|
34
|
+
if (inputs[taskId].excludeDependsOn) {
|
35
|
+
taskIdsWithExclude.push(taskId);
|
36
|
+
}
|
37
|
+
else {
|
38
|
+
taskIdsWithoutExclude.push(taskId);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
const allDependsOn = new Set(taskIds);
|
42
|
+
taskIdsWithoutExclude.forEach((taskId) => {
|
43
|
+
const [projectName, targetName] = taskId.split(':');
|
44
|
+
const dependencies = (0, get_exclude_task_1.getAllDependsOn)(context.projectGraph, projectName, targetName);
|
45
|
+
dependencies.forEach((dep) => allDependsOn.add(dep));
|
46
|
+
});
|
47
|
+
const gradlewTasksToRun = taskIds.reduce((gradlewTasksToRun, taskId) => {
|
48
|
+
const task = taskGraph.tasks[taskId];
|
29
49
|
const gradlewTaskName = inputs[task.id].taskName;
|
30
50
|
const testClassName = inputs[task.id].testClassName;
|
31
51
|
gradlewTasksToRun[taskId] = {
|
@@ -34,48 +54,24 @@ async function gradleBatch(taskGraph, inputs, overrides, context) {
|
|
34
54
|
};
|
35
55
|
return gradlewTasksToRun;
|
36
56
|
}, {});
|
37
|
-
const
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
jsEnv: process.env,
|
50
|
-
quiet: process.env.NX_VERBOSE_LOGGING !== 'true',
|
51
|
-
});
|
52
|
-
const results = await cp.getResults();
|
53
|
-
batchResults = results.terminalOutput;
|
54
|
-
batchResults = batchResults.replace(command, '');
|
55
|
-
const startIndex = batchResults.indexOf('{');
|
56
|
-
const endIndex = batchResults.lastIndexOf('}');
|
57
|
-
batchResults = batchResults.substring(startIndex, endIndex + 1);
|
58
|
-
}
|
59
|
-
else {
|
60
|
-
batchResults = (0, child_process_1.execSync)(command, {
|
61
|
-
cwd: devkit_1.workspaceRoot,
|
62
|
-
windowsHide: true,
|
63
|
-
env: process.env,
|
64
|
-
maxBuffer: run_commands_impl_1.LARGE_BUFFER,
|
65
|
-
}).toString();
|
66
|
-
}
|
67
|
-
const gradlewBatchEnd = performance.mark(`gradlew-batch:end`);
|
68
|
-
performance.measure(`gradlew-batch`, gradlewBatchStart.name, gradlewBatchEnd.name);
|
69
|
-
const gradlewBatchResults = JSON.parse(batchResults.toString());
|
70
|
-
Object.keys(taskGraph.tasks).forEach((taskId) => {
|
71
|
-
if (!gradlewBatchResults[taskId]) {
|
72
|
-
gradlewBatchResults[taskId] = {
|
57
|
+
const excludeTasks = (0, get_exclude_task_1.getExcludeTasks)(context.projectGraph, taskIdsWithExclude.map((taskId) => {
|
58
|
+
const task = taskGraph.tasks[taskId];
|
59
|
+
return {
|
60
|
+
project: task?.target?.project,
|
61
|
+
target: task?.target?.target,
|
62
|
+
excludeDependsOn: inputs[taskId]?.excludeDependsOn,
|
63
|
+
};
|
64
|
+
}), allDependsOn);
|
65
|
+
const batchResults = await runTasksInBatch(gradlewTasksToRun, excludeTasks, args, root);
|
66
|
+
taskIds.forEach((taskId) => {
|
67
|
+
if (!batchResults[taskId]) {
|
68
|
+
batchResults[taskId] = {
|
73
69
|
success: false,
|
74
70
|
terminalOutput: `Gradlew batch failed`,
|
75
71
|
};
|
76
72
|
}
|
77
73
|
});
|
78
|
-
return
|
74
|
+
return batchResults;
|
79
75
|
}
|
80
76
|
catch (e) {
|
81
77
|
devkit_1.output.error({
|
@@ -88,3 +84,41 @@ async function gradleBatch(taskGraph, inputs, overrides, context) {
|
|
88
84
|
}, {});
|
89
85
|
}
|
90
86
|
}
|
87
|
+
async function runTasksInBatch(gradlewTasksToRun, excludeTasks, args, root) {
|
88
|
+
const gradlewBatchStart = performance.mark(`gradlew-batch:start`);
|
89
|
+
const usePseudoTerminal = process.env.NX_NATIVE_COMMAND_RUNNER !== 'false' &&
|
90
|
+
pseudo_terminal_1.PseudoTerminal.isSupported();
|
91
|
+
const command = `java -jar ${exports.batchRunnerPath} --tasks='${JSON.stringify(gradlewTasksToRun)}' --workspaceRoot=${root} --args='${args
|
92
|
+
.join(' ')
|
93
|
+
.replaceAll("'", '"')}' --excludeTasks='${Array.from(excludeTasks).join(',')}' ${process.env.NX_VERBOSE_LOGGING === 'true' ? '' : '--quiet'}`;
|
94
|
+
let batchResults;
|
95
|
+
if (usePseudoTerminal && process.env.NX_VERBOSE_LOGGING !== 'true') {
|
96
|
+
const terminal = (0, pseudo_terminal_1.createPseudoTerminal)();
|
97
|
+
await terminal.init();
|
98
|
+
const cp = terminal.runCommand(command, {
|
99
|
+
cwd: devkit_1.workspaceRoot,
|
100
|
+
jsEnv: process.env,
|
101
|
+
quiet: true,
|
102
|
+
});
|
103
|
+
const results = await cp.getResults();
|
104
|
+
terminal.shutdown(0);
|
105
|
+
batchResults = results.terminalOutput;
|
106
|
+
batchResults = batchResults.replace(command, '');
|
107
|
+
const startIndex = batchResults.indexOf('{');
|
108
|
+
const endIndex = batchResults.lastIndexOf('}');
|
109
|
+
// only keep the json part
|
110
|
+
batchResults = batchResults.substring(startIndex, endIndex + 1);
|
111
|
+
}
|
112
|
+
else {
|
113
|
+
batchResults = (0, child_process_1.execSync)(command, {
|
114
|
+
cwd: devkit_1.workspaceRoot,
|
115
|
+
windowsHide: true,
|
116
|
+
env: process.env,
|
117
|
+
maxBuffer: run_commands_impl_1.LARGE_BUFFER,
|
118
|
+
}).toString();
|
119
|
+
}
|
120
|
+
const gradlewBatchEnd = performance.mark(`gradlew-batch:end`);
|
121
|
+
performance.measure(`gradlew-batch`, gradlewBatchStart.name, gradlewBatchEnd.name);
|
122
|
+
const gradlewBatchResults = JSON.parse(batchResults);
|
123
|
+
return gradlewBatchResults;
|
124
|
+
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { ExecutorContext } from '@nx/devkit';
|
2
|
-
import {
|
3
|
-
export default function gradleExecutor(options:
|
2
|
+
import { GradleExecutorSchema } from './schema';
|
3
|
+
export default function gradleExecutor(options: GradleExecutorSchema, context: ExecutorContext): Promise<{
|
4
4
|
success: boolean;
|
5
5
|
}>;
|
@@ -4,6 +4,7 @@ exports.default = gradleExecutor;
|
|
4
4
|
const exec_gradle_1 = require("../../utils/exec-gradle");
|
5
5
|
const node_path_1 = require("node:path");
|
6
6
|
const run_commands_impl_1 = require("nx/src/executors/run-commands/run-commands.impl");
|
7
|
+
const get_exclude_task_1 = require("./get-exclude-task");
|
7
8
|
async function gradleExecutor(options, context) {
|
8
9
|
let projectRoot = context.projectGraph.nodes[context.projectName]?.data?.root ?? context.root;
|
9
10
|
let gradlewPath = (0, exec_gradle_1.findGradlewFile)((0, node_path_1.join)(projectRoot, 'project.json')); // find gradlew near project root
|
@@ -16,6 +17,17 @@ async function gradleExecutor(options, context) {
|
|
16
17
|
if (options.testClassName) {
|
17
18
|
args.push(`--tests`, options.testClassName);
|
18
19
|
}
|
20
|
+
(0, get_exclude_task_1.getExcludeTasks)(context.projectGraph, [
|
21
|
+
{
|
22
|
+
project: context.projectName,
|
23
|
+
target: context.targetName,
|
24
|
+
excludeDependsOn: options.excludeDependsOn,
|
25
|
+
},
|
26
|
+
]).forEach((task) => {
|
27
|
+
if (task) {
|
28
|
+
args.push('--exclude-task', task);
|
29
|
+
}
|
30
|
+
});
|
19
31
|
try {
|
20
32
|
const { success } = await (0, run_commands_impl_1.default)({
|
21
33
|
command: `${gradlewPath} ${options.taskName}`,
|
@@ -27,6 +27,12 @@
|
|
27
27
|
],
|
28
28
|
"description": "The arguments to pass to the Gradle task.",
|
29
29
|
"examples": [["--warning-mode", "all"], "--stracktrace"]
|
30
|
+
},
|
31
|
+
"excludeDependsOn": {
|
32
|
+
"type": "boolean",
|
33
|
+
"description": "If true, the tasks will not execute its dependsOn tasks (e.g. pass --exclude-task args to gradle command). If false, the task will execute its dependsOn tasks.",
|
34
|
+
"default": true,
|
35
|
+
"x-priority": "internal"
|
30
36
|
}
|
31
37
|
},
|
32
38
|
"required": ["taskName"]
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { Tree } from '@nx/devkit';
|
2
|
+
/**
|
3
|
+
* Adds a `build.gradle(.kts)` file next to each `settings.gradle(.kts)` file found in the workspace.
|
4
|
+
* If the build.gradle file already exists, it reads its contents.
|
5
|
+
*/
|
6
|
+
export declare function addBuildGradleFileNextToSettingsGradle(tree: Tree): Promise<{
|
7
|
+
filePath: string;
|
8
|
+
content: string;
|
9
|
+
}[]>;
|
10
|
+
/**
|
11
|
+
* Extract gradle plugin version from build.gradle file
|
12
|
+
*/
|
13
|
+
export declare function extractNxPluginVersion(gradleFilePath: string, gradleContent: string): Promise<string | null>;
|
14
|
+
/**
|
15
|
+
* Updates the plugin version in the given Gradle file content.
|
16
|
+
*/
|
17
|
+
export declare function updateNxPluginVersion(content: string, newVersion: string): string;
|
18
|
+
/**
|
19
|
+
* Ensures all build.gradle(.kts) files use the expected version of dev.nx.gradle.project-graph.
|
20
|
+
*/
|
21
|
+
export declare function addNxProjectGraphPlugin(tree: Tree, expectedVersion?: string): Promise<void>;
|
@@ -0,0 +1,149 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.addBuildGradleFileNextToSettingsGradle = addBuildGradleFileNextToSettingsGradle;
|
4
|
+
exports.extractNxPluginVersion = extractNxPluginVersion;
|
5
|
+
exports.updateNxPluginVersion = updateNxPluginVersion;
|
6
|
+
exports.addNxProjectGraphPlugin = addNxProjectGraphPlugin;
|
7
|
+
const devkit_1 = require("@nx/devkit");
|
8
|
+
const versions_1 = require("../../utils/versions");
|
9
|
+
const path_1 = require("path");
|
10
|
+
const exec_gradle_1 = require("../../utils/exec-gradle");
|
11
|
+
/**
|
12
|
+
* Adds a `build.gradle(.kts)` file next to each `settings.gradle(.kts)` file found in the workspace.
|
13
|
+
* If the build.gradle file already exists, it reads its contents.
|
14
|
+
*/
|
15
|
+
async function addBuildGradleFileNextToSettingsGradle(tree) {
|
16
|
+
const settingsGradleFiles = await (0, devkit_1.globAsync)(tree, [
|
17
|
+
'**/settings.gradle',
|
18
|
+
'**/settings.gradle.kts',
|
19
|
+
]);
|
20
|
+
return settingsGradleFiles.map((settingsGradlePath) => {
|
21
|
+
return ensureBuildGradleFile(tree, settingsGradlePath);
|
22
|
+
});
|
23
|
+
}
|
24
|
+
/**
|
25
|
+
* Determines the appropriate build.gradle file path based on the settings file
|
26
|
+
* and ensures it exists in the tree. Returns the path and contents.
|
27
|
+
*/
|
28
|
+
function ensureBuildGradleFile(tree, settingsGradlePath) {
|
29
|
+
const isKotlinDsl = settingsGradlePath.endsWith('.kts');
|
30
|
+
const buildGradleFile = (0, path_1.join)((0, path_1.dirname)(settingsGradlePath), isKotlinDsl ? 'build.gradle.kts' : 'build.gradle');
|
31
|
+
let content = '';
|
32
|
+
if (tree.exists(buildGradleFile)) {
|
33
|
+
content = tree.read(buildGradleFile, 'utf-8');
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
tree.write(buildGradleFile, content);
|
37
|
+
}
|
38
|
+
return { filePath: buildGradleFile, content };
|
39
|
+
}
|
40
|
+
// a regex to get the version in build file in format `id "dev.nx.gradle.project-graph" version "x"`
|
41
|
+
const regex = /(id\s*\(?["']dev\.nx\.gradle\.project-graph["']\)?\s*version\s*\(?["'])([^"']+)(["']\)?)/;
|
42
|
+
/**
|
43
|
+
* Extract gradle plugin version from build.gradle file
|
44
|
+
*/
|
45
|
+
async function extractNxPluginVersion(gradleFilePath, gradleContent) {
|
46
|
+
const match = gradleContent.match(regex);
|
47
|
+
let version = match ? match[2] : null;
|
48
|
+
if (!version) {
|
49
|
+
try {
|
50
|
+
const gradlewFile = (0, exec_gradle_1.findGradlewFile)(gradleFilePath, devkit_1.workspaceRoot);
|
51
|
+
const buildEnvironment = (await (0, exec_gradle_1.execGradleAsync)((0, path_1.join)(devkit_1.workspaceRoot, gradlewFile), [
|
52
|
+
'buildEnvironment',
|
53
|
+
'--quiet',
|
54
|
+
])).toString();
|
55
|
+
version = getPluginVersion(buildEnvironment);
|
56
|
+
}
|
57
|
+
catch (e) { } // Silently ignore error, fallback remains null
|
58
|
+
}
|
59
|
+
return version;
|
60
|
+
}
|
61
|
+
function getPluginVersion(dependencyTree) {
|
62
|
+
const lines = dependencyTree.split('\n');
|
63
|
+
for (const line of lines) {
|
64
|
+
// line is dev.nx.gradle.project-graph:dev.nx.gradle.project-graph.gradle.plugin:version
|
65
|
+
const match = line.match(/dev\.nx\.gradle\.project-graph:dev\.nx\.gradle\.project-graph\.gradle\.plugin:([^\s\\]+)/);
|
66
|
+
if (match) {
|
67
|
+
return match[1]; // returns the version part
|
68
|
+
}
|
69
|
+
}
|
70
|
+
return null; // not found
|
71
|
+
}
|
72
|
+
/**
|
73
|
+
* Updates the plugin version in the given Gradle file content.
|
74
|
+
*/
|
75
|
+
function updateNxPluginVersion(content, newVersion) {
|
76
|
+
if (regex.test(content)) {
|
77
|
+
return content.replace(regex, `$1${newVersion}$3`);
|
78
|
+
}
|
79
|
+
else {
|
80
|
+
devkit_1.logger.warn(`Please update plugin dev.nx.gradle.project-graph to ${newVersion}`);
|
81
|
+
}
|
82
|
+
return content;
|
83
|
+
}
|
84
|
+
/**
|
85
|
+
* Ensures all build.gradle(.kts) files use the expected version of dev.nx.gradle.project-graph.
|
86
|
+
*/
|
87
|
+
async function addNxProjectGraphPlugin(tree, expectedVersion = versions_1.gradleProjectGraphVersion) {
|
88
|
+
const files = await addBuildGradleFileNextToSettingsGradle(tree);
|
89
|
+
files.forEach(({ filePath, content }) => {
|
90
|
+
addNxProjectGraphPluginToBuildGradle(filePath, content, expectedVersion, tree);
|
91
|
+
});
|
92
|
+
}
|
93
|
+
/**
|
94
|
+
* Adds or updates the Nx Project Graph plugin in the build.gradle(.kts) file.
|
95
|
+
* Ensures the correct version and applies the plugin to all projects.
|
96
|
+
* Returns the updated build.gradle content.
|
97
|
+
*/
|
98
|
+
async function addNxProjectGraphPluginToBuildGradle(gradleFilePath, buildGradleContent, expectedVersion = versions_1.gradleProjectGraphVersion, tree) {
|
99
|
+
const isKotlinDsl = gradleFilePath.endsWith('.kts');
|
100
|
+
const nxProjectGraphReportPlugin = isKotlinDsl
|
101
|
+
? `id(\"${versions_1.gradleProjectGraphPluginName}\") version(\"${expectedVersion}\")`
|
102
|
+
: `id \"${versions_1.gradleProjectGraphPluginName}\" version \"${expectedVersion}\"`;
|
103
|
+
// Helper to add plugin to plugins block
|
104
|
+
function addPluginToPluginsBlock(content) {
|
105
|
+
return content.replace(/plugins\s*\{/, `plugins {\n ${nxProjectGraphReportPlugin}`);
|
106
|
+
}
|
107
|
+
// Helper to add plugins block if missing
|
108
|
+
function addPluginsBlock(content) {
|
109
|
+
return `plugins {\n ${nxProjectGraphReportPlugin}\n}\n${content}`;
|
110
|
+
}
|
111
|
+
// Helper to add plugin application to allprojects
|
112
|
+
function addPluginToAllProjects(content) {
|
113
|
+
const applyPlugin = isKotlinDsl
|
114
|
+
? `plugin(\"${versions_1.gradleProjectGraphPluginName}\")`
|
115
|
+
: `plugin(\"${versions_1.gradleProjectGraphPluginName}\")`;
|
116
|
+
return `${content}\nallprojects {\n apply {\n ${applyPlugin}\n }\n}`;
|
117
|
+
}
|
118
|
+
// 1. Ensure plugins block and correct plugin version
|
119
|
+
if (buildGradleContent.includes('plugins {')) {
|
120
|
+
if (buildGradleContent.includes(versions_1.gradleProjectGraphPluginName)) {
|
121
|
+
// Update version if needed
|
122
|
+
const currentVersion = await extractNxPluginVersion(gradleFilePath, buildGradleContent);
|
123
|
+
if (currentVersion && currentVersion !== expectedVersion) {
|
124
|
+
buildGradleContent = updateNxPluginVersion(buildGradleContent, expectedVersion);
|
125
|
+
}
|
126
|
+
}
|
127
|
+
else {
|
128
|
+
// Add plugin to plugins block
|
129
|
+
buildGradleContent = addPluginToPluginsBlock(buildGradleContent);
|
130
|
+
}
|
131
|
+
}
|
132
|
+
else {
|
133
|
+
// Add plugins block if missing
|
134
|
+
buildGradleContent = addPluginsBlock(buildGradleContent);
|
135
|
+
}
|
136
|
+
// 2. Ensure plugin is applied to all projects
|
137
|
+
const applyPluginPattern = new RegExp(`\\s*plugin\\(["']${versions_1.gradleProjectGraphPluginName}["']\\)`);
|
138
|
+
if (buildGradleContent.includes('allprojects {')) {
|
139
|
+
if (!applyPluginPattern.test(buildGradleContent)) {
|
140
|
+
devkit_1.logger.warn(`Please add the ${versions_1.gradleProjectGraphPluginName} plugin to your ${gradleFilePath}:\nallprojects {\n apply {\n plugin(\"${versions_1.gradleProjectGraphPluginName}\")\n }\n}`);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
else {
|
144
|
+
buildGradleContent = addPluginToAllProjects(buildGradleContent);
|
145
|
+
}
|
146
|
+
// 3. Write and return updated content
|
147
|
+
tree.write(gradleFilePath, buildGradleContent);
|
148
|
+
return buildGradleContent;
|
149
|
+
}
|
@@ -1,9 +1,5 @@
|
|
1
1
|
import { GeneratorCallback, Tree } from '@nx/devkit';
|
2
2
|
import { InitGeneratorSchema } from './schema';
|
3
3
|
export declare function initGenerator(tree: Tree, options: InitGeneratorSchema): Promise<GeneratorCallback>;
|
4
|
-
/**
|
5
|
-
* This function creates and populate build.gradle file next to the settings.gradle file.
|
6
|
-
*/
|
7
|
-
export declare function addBuildGradleFileNextToSettingsGradle(tree: Tree): Promise<void>;
|
8
4
|
export declare function updateNxJsonConfiguration(tree: Tree): void;
|
9
5
|
export default initGenerator;
|
@@ -1,12 +1,11 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.initGenerator = initGenerator;
|
4
|
-
exports.addBuildGradleFileNextToSettingsGradle = addBuildGradleFileNextToSettingsGradle;
|
5
4
|
exports.updateNxJsonConfiguration = updateNxJsonConfiguration;
|
6
5
|
const devkit_1 = require("@nx/devkit");
|
7
6
|
const versions_1 = require("../../utils/versions");
|
8
7
|
const has_gradle_plugin_1 = require("../../utils/has-gradle-plugin");
|
9
|
-
const
|
8
|
+
const gradle_project_graph_plugin_utils_1 = require("./gradle-project-graph-plugin-utils");
|
10
9
|
async function initGenerator(tree, options) {
|
11
10
|
const tasks = [];
|
12
11
|
if (!options.skipPackageJson && tree.exists('package.json')) {
|
@@ -14,7 +13,7 @@ async function initGenerator(tree, options) {
|
|
14
13
|
'@nx/gradle': versions_1.nxVersion,
|
15
14
|
}, undefined, options.keepExistingVersions));
|
16
15
|
}
|
17
|
-
await
|
16
|
+
await (0, gradle_project_graph_plugin_utils_1.addNxProjectGraphPlugin)(tree);
|
18
17
|
addPlugin(tree);
|
19
18
|
updateNxJsonConfiguration(tree);
|
20
19
|
if (!options.skipFormat) {
|
@@ -37,70 +36,6 @@ function addPlugin(tree) {
|
|
37
36
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
38
37
|
}
|
39
38
|
}
|
40
|
-
/**
|
41
|
-
* This function creates and populate build.gradle file next to the settings.gradle file.
|
42
|
-
*/
|
43
|
-
async function addBuildGradleFileNextToSettingsGradle(tree) {
|
44
|
-
const settingsGradleFiles = await (0, devkit_1.globAsync)(tree, [
|
45
|
-
'**/settings.gradle?(.kts)',
|
46
|
-
]);
|
47
|
-
settingsGradleFiles.forEach((settingsGradleFile) => {
|
48
|
-
addNxProjectGraphPluginToBuildGradle(settingsGradleFile, tree);
|
49
|
-
});
|
50
|
-
}
|
51
|
-
/**
|
52
|
-
* - creates a build.gradle file next to the settings.gradle file if it does not exist.
|
53
|
-
* - adds the NxProjectGraphPlugin plugin to the build.gradle file if it does not exist.
|
54
|
-
*/
|
55
|
-
function addNxProjectGraphPluginToBuildGradle(settingsGradleFile, tree) {
|
56
|
-
const filename = (0, path_1.basename)(settingsGradleFile);
|
57
|
-
let gradleFilePath = 'build.gradle';
|
58
|
-
if (filename.endsWith('.kts')) {
|
59
|
-
gradleFilePath = 'build.gradle.kts';
|
60
|
-
}
|
61
|
-
gradleFilePath = (0, path_1.join)((0, path_1.dirname)(settingsGradleFile), gradleFilePath);
|
62
|
-
let buildGradleContent = '';
|
63
|
-
if (!tree.exists(gradleFilePath)) {
|
64
|
-
tree.write(gradleFilePath, buildGradleContent); // create a build.gradle file near settings.gradle file if it does not exist
|
65
|
-
}
|
66
|
-
else {
|
67
|
-
buildGradleContent = tree.read(gradleFilePath).toString();
|
68
|
-
}
|
69
|
-
const nxProjectGraphReportPlugin = filename.endsWith('.kts')
|
70
|
-
? `id("${versions_1.gradleProjectGraphPluginName}") version("${versions_1.gradleProjectGraphVersion}")`
|
71
|
-
: `id "${versions_1.gradleProjectGraphPluginName}" version "${versions_1.gradleProjectGraphVersion}"`;
|
72
|
-
if (buildGradleContent.includes('plugins {')) {
|
73
|
-
if (!buildGradleContent.includes(versions_1.gradleProjectGraphPluginName)) {
|
74
|
-
buildGradleContent = buildGradleContent.replace('plugins {', `plugins {
|
75
|
-
${nxProjectGraphReportPlugin}`);
|
76
|
-
}
|
77
|
-
}
|
78
|
-
else {
|
79
|
-
buildGradleContent = `plugins {
|
80
|
-
${nxProjectGraphReportPlugin}
|
81
|
-
}\n\r${buildGradleContent}`;
|
82
|
-
}
|
83
|
-
const applyNxProjectGraphReportPlugin = `plugin("${versions_1.gradleProjectGraphPluginName}")`;
|
84
|
-
if (buildGradleContent.includes('allprojects {')) {
|
85
|
-
if (!buildGradleContent.includes(`plugin("${versions_1.gradleProjectGraphPluginName}")`) &&
|
86
|
-
!buildGradleContent.includes(`plugin('${versions_1.gradleProjectGraphPluginName}')`)) {
|
87
|
-
devkit_1.logger.warn(`Please add the ${versions_1.gradleProjectGraphPluginName} plugin to your ${gradleFilePath}:
|
88
|
-
allprojects {
|
89
|
-
apply {
|
90
|
-
${applyNxProjectGraphReportPlugin}
|
91
|
-
}
|
92
|
-
}`);
|
93
|
-
}
|
94
|
-
}
|
95
|
-
else {
|
96
|
-
buildGradleContent = `${buildGradleContent}\n\rallprojects {
|
97
|
-
apply {
|
98
|
-
${applyNxProjectGraphReportPlugin}
|
99
|
-
}
|
100
|
-
}`;
|
101
|
-
}
|
102
|
-
tree.write(gradleFilePath, buildGradleContent);
|
103
|
-
}
|
104
39
|
function updateNxJsonConfiguration(tree) {
|
105
40
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
106
41
|
if (!nxJson.namedInputs) {
|
@@ -0,0 +1,18 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.default = update;
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
5
|
+
const has_gradle_plugin_1 = require("../../utils/has-gradle-plugin");
|
6
|
+
const gradle_project_graph_plugin_utils_1 = require("../../generators/init/gradle-project-graph-plugin-utils");
|
7
|
+
/* Change the plugin version to 0.1.0
|
8
|
+
*/
|
9
|
+
async function update(tree) {
|
10
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
11
|
+
if (!nxJson) {
|
12
|
+
return;
|
13
|
+
}
|
14
|
+
if (!(0, has_gradle_plugin_1.hasGradlePlugin)(tree)) {
|
15
|
+
return;
|
16
|
+
}
|
17
|
+
await (0, gradle_project_graph_plugin_utils_1.addNxProjectGraphPlugin)(tree, '0.1.0');
|
18
|
+
}
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getNxProjectGraphLines = getNxProjectGraphLines;
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
5
5
|
const exec_gradle_1 = require("../../utils/exec-gradle");
|
6
|
-
const node_path_1 = require("node:path");
|
7
6
|
async function getNxProjectGraphLines(gradlewFile, gradleConfigHash, gradlePluginOptions) {
|
8
7
|
if (process.env.VERCEL) {
|
9
8
|
// skip on Vercel
|
@@ -21,7 +20,6 @@ async function getNxProjectGraphLines(gradlewFile, gradleConfigHash, gradlePlugi
|
|
21
20
|
'--warning-mode',
|
22
21
|
'none',
|
23
22
|
...gradlePluginOptionsArgs,
|
24
|
-
`-Pcwd=${(0, node_path_1.dirname)(gradlewFile)}`,
|
25
23
|
`-PworkspaceRoot=${devkit_1.workspaceRoot}`,
|
26
24
|
process.env.NX_VERBOSE_LOGGING ? '--info' : '',
|
27
25
|
]);
|
@@ -39,7 +37,7 @@ async function getNxProjectGraphLines(gradlewFile, gradleConfigHash, gradlePlugi
|
|
39
37
|
throw new devkit_1.AggregateCreateNodesError([
|
40
38
|
[
|
41
39
|
gradlewFile,
|
42
|
-
new Error(`Could not run 'nxProjectGraph' task. Please run 'nx generate @nx/gradle:init' to
|
40
|
+
new Error(`Could not run 'nxProjectGraph' task. Please run 'nx generate @nx/gradle:init' to add the necessary plugin dev.nx.gradle.project-graph.\n\r${e.toString()}`),
|
43
41
|
],
|
44
42
|
], []);
|
45
43
|
}
|