@nx/gradle 19.8.0-canary.20240913-5bbaffb → 19.8.0-canary.20240917-5b34ea5
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/package.json +2 -2
- package/src/generators/init/init.js +0 -7
- package/src/plugin/dependencies.js +4 -2
- package/src/plugin/nodes.js +21 -27
- package/src/utils/exec-gradle.d.ts +21 -2
- package/src/utils/exec-gradle.js +48 -14
- package/src/utils/get-gradle-report.d.ts +11 -7
- package/src/utils/get-gradle-report.js +34 -55
- package/src/utils/get-project-report-lines.d.ts +8 -0
- package/src/utils/get-project-report-lines.js +53 -0
- package/src/utils/split-config-files.d.ts +17 -0
- package/src/utils/split-config-files.js +57 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nx/gradle",
|
3
|
-
"version": "19.8.0-canary.
|
3
|
+
"version": "19.8.0-canary.20240917-5b34ea5",
|
4
4
|
"private": false,
|
5
5
|
"description": "The Nx Plugin for Gradle allows Gradle tasks to be run through Nx",
|
6
6
|
"repository": {
|
@@ -34,7 +34,7 @@
|
|
34
34
|
"migrations": "./migrations.json"
|
35
35
|
},
|
36
36
|
"dependencies": {
|
37
|
-
"@nx/devkit": "19.8.0-canary.
|
37
|
+
"@nx/devkit": "19.8.0-canary.20240917-5b34ea5"
|
38
38
|
},
|
39
39
|
"publishConfig": {
|
40
40
|
"access": "public"
|
@@ -4,18 +4,11 @@ exports.initGenerator = initGenerator;
|
|
4
4
|
exports.addBuildGradleFileNextToSettingsGradle = addBuildGradleFileNextToSettingsGradle;
|
5
5
|
exports.updateNxJsonConfiguration = updateNxJsonConfiguration;
|
6
6
|
const devkit_1 = require("@nx/devkit");
|
7
|
-
const child_process_1 = require("child_process");
|
8
7
|
const versions_1 = require("../../utils/versions");
|
9
8
|
const has_gradle_plugin_1 = require("../../utils/has-gradle-plugin");
|
10
9
|
const path_1 = require("path");
|
11
10
|
async function initGenerator(tree, options) {
|
12
11
|
const tasks = [];
|
13
|
-
if (!tree.exists('settings.gradle') && !tree.exists('settings.gradle.kts')) {
|
14
|
-
devkit_1.logger.warn(`Could not find 'settings.gradle' or 'settings.gradle.kts' file in your gradle workspace.
|
15
|
-
A Gradle build should contain a 'settings.gradle' or 'settings.gradle.kts' file in its root directory. It may also contain a 'build.gradle' or 'build.gradle.kts' file.
|
16
|
-
Running 'gradle init':`);
|
17
|
-
(0, child_process_1.execSync)('gradle init', { stdio: 'inherit' });
|
18
|
-
}
|
19
12
|
if (!options.skipPackageJson && tree.exists('package.json')) {
|
20
13
|
tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
21
14
|
'@nx/gradle': versions_1.nxVersion,
|
@@ -6,6 +6,8 @@ const devkit_1 = require("@nx/devkit");
|
|
6
6
|
const node_fs_1 = require("node:fs");
|
7
7
|
const node_path_1 = require("node:path");
|
8
8
|
const get_gradle_report_1 = require("../utils/get-gradle-report");
|
9
|
+
const split_config_files_1 = require("../utils/split-config-files");
|
10
|
+
const get_project_report_lines_1 = require("../utils/get-project-report-lines");
|
9
11
|
const createDependencies = async (_, context) => {
|
10
12
|
const gradleFiles = findGradleFiles(context.filesToProcess);
|
11
13
|
if (gradleFiles.length === 0) {
|
@@ -43,7 +45,7 @@ function findGradleFiles(fileMap) {
|
|
43
45
|
const gradleFiles = [];
|
44
46
|
for (const [_, files] of Object.entries(fileMap.projectFileMap)) {
|
45
47
|
for (const file of files) {
|
46
|
-
if (
|
48
|
+
if (split_config_files_1.GRADLE_BUILD_FILES.has((0, node_path_1.basename)(file.file))) {
|
47
49
|
gradleFiles.push(file.file);
|
48
50
|
}
|
49
51
|
}
|
@@ -51,7 +53,7 @@ function findGradleFiles(fileMap) {
|
|
51
53
|
return gradleFiles;
|
52
54
|
}
|
53
55
|
function processGradleDependencies(depsFile, gradleProjectNameToProjectRoot, sourceProjectName, gradleFile, context, dependencies) {
|
54
|
-
const lines = (0, node_fs_1.readFileSync)(depsFile).toString().split(
|
56
|
+
const lines = (0, node_fs_1.readFileSync)(depsFile).toString().split(get_project_report_lines_1.newLineSeparator);
|
55
57
|
let inDeps = false;
|
56
58
|
for (const line of lines) {
|
57
59
|
if (line.startsWith('implementationDependenciesMetadata') ||
|
package/src/plugin/nodes.js
CHANGED
@@ -8,9 +8,10 @@ const node_fs_1 = require("node:fs");
|
|
8
8
|
const node_path_1 = require("node:path");
|
9
9
|
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
10
10
|
const devkit_internals_1 = require("nx/src/devkit-internals");
|
11
|
-
const exec_gradle_1 = require("../utils/exec-gradle");
|
12
11
|
const get_gradle_report_1 = require("../utils/get-gradle-report");
|
13
12
|
const file_hasher_1 = require("nx/src/hasher/file-hasher");
|
13
|
+
const split_config_files_1 = require("../utils/split-config-files");
|
14
|
+
const exec_gradle_1 = require("../utils/exec-gradle");
|
14
15
|
const cacheableTaskType = new Set(['Build', 'Verification']);
|
15
16
|
const dependsOnMap = {
|
16
17
|
build: ['^build', 'classes'],
|
@@ -32,17 +33,17 @@ function writeTargetsToCache(cachePath, results) {
|
|
32
33
|
(0, devkit_1.writeJsonFile)(cachePath, results);
|
33
34
|
}
|
34
35
|
exports.createNodesV2 = [
|
35
|
-
|
36
|
+
split_config_files_1.gradleConfigAndTestGlob,
|
36
37
|
async (files, options, context) => {
|
37
|
-
const {
|
38
|
+
const { buildFiles, projectRoots, gradlewFiles, testFiles } = (0, split_config_files_1.splitConfigFiles)(files);
|
38
39
|
const optionsHash = (0, file_hasher_1.hashObject)(options);
|
39
40
|
const cachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `gradle-${optionsHash}.hash`);
|
40
41
|
const targetsCache = readTargetsCache(cachePath);
|
41
|
-
await (0, get_gradle_report_1.populateGradleReport)(context.workspaceRoot);
|
42
|
+
await (0, get_gradle_report_1.populateGradleReport)(context.workspaceRoot, gradlewFiles.map((f) => (0, node_path_1.join)(context.workspaceRoot, f)));
|
42
43
|
const gradleReport = (0, get_gradle_report_1.getCurrentGradleReport)();
|
43
44
|
const gradleProjectRootToTestFilesMap = getGradleProjectRootToTestFilesMap(testFiles, projectRoots);
|
44
45
|
try {
|
45
|
-
return (0, devkit_1.createNodesFromFiles)((0, exports.makeCreateNodesForGradleConfigFile)(gradleReport, targetsCache, gradleProjectRootToTestFilesMap),
|
46
|
+
return (0, devkit_1.createNodesFromFiles)((0, exports.makeCreateNodesForGradleConfigFile)(gradleReport, targetsCache, gradleProjectRootToTestFilesMap), buildFiles, options, context);
|
46
47
|
}
|
47
48
|
finally {
|
48
49
|
writeTargetsToCache(cachePath, targetsCache);
|
@@ -70,13 +71,14 @@ exports.makeCreateNodesForGradleConfigFile = makeCreateNodesForGradleConfigFile;
|
|
70
71
|
This function will change to the v2 function in Nx 20.
|
71
72
|
*/
|
72
73
|
exports.createNodes = [
|
73
|
-
|
74
|
-
async (
|
74
|
+
split_config_files_1.gradleConfigGlob,
|
75
|
+
async (buildFile, options, context) => {
|
75
76
|
devkit_1.logger.warn('`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.');
|
76
|
-
|
77
|
+
const { gradlewFiles } = (0, split_config_files_1.splitConfigFiles)(context.configFiles);
|
78
|
+
await (0, get_gradle_report_1.populateGradleReport)(context.workspaceRoot, gradlewFiles);
|
77
79
|
const gradleReport = (0, get_gradle_report_1.getCurrentGradleReport)();
|
78
80
|
const internalCreateNodes = (0, exports.makeCreateNodesForGradleConfigFile)(gradleReport);
|
79
|
-
return await internalCreateNodes(
|
81
|
+
return await internalCreateNodes(buildFile, options, context);
|
80
82
|
},
|
81
83
|
];
|
82
84
|
async function createGradleProject(gradleReport, gradleFilePath, options, context, testFiles = []) {
|
@@ -112,8 +114,9 @@ async function createGradleProject(gradleReport, gradleFilePath, options, contex
|
|
112
114
|
return undefined;
|
113
115
|
}
|
114
116
|
}
|
115
|
-
async function createGradleTargets(tasks, options, context, outputDirs, gradleProject,
|
117
|
+
async function createGradleTargets(tasks, options, context, outputDirs, gradleProject, gradleBuildFilePath, testFiles = []) {
|
116
118
|
const inputsMap = createInputsMap(context);
|
119
|
+
const gradlewFileDirectory = (0, node_path_1.dirname)((0, exec_gradle_1.findGraldewFile)(gradleBuildFilePath, context.workspaceRoot));
|
117
120
|
const targets = {};
|
118
121
|
const targetGroups = {};
|
119
122
|
for (const task of tasks) {
|
@@ -124,11 +127,14 @@ async function createGradleTargets(tasks, options, context, outputDirs, gradlePr
|
|
124
127
|
outputDirs.get('testReport'),
|
125
128
|
outputDirs.get('testResults'),
|
126
129
|
].filter(Boolean);
|
127
|
-
getTestCiTargets(testFiles, gradleProject, targetName, options.ciTargetName, inputsMap['test'], outputs, task.type, targets, targetGroups);
|
130
|
+
getTestCiTargets(testFiles, gradleProject, targetName, options.ciTargetName, inputsMap['test'], outputs, task.type, targets, targetGroups, gradlewFileDirectory);
|
128
131
|
}
|
129
132
|
const taskCommandToRun = `${gradleProject ? gradleProject + ':' : ''}${task.name}`;
|
130
133
|
targets[targetName] = {
|
131
134
|
command: `${(0, exec_gradle_1.getGradleExecFile)()} ${taskCommandToRun}`,
|
135
|
+
options: {
|
136
|
+
cwd: gradlewFileDirectory,
|
137
|
+
},
|
132
138
|
cache: cacheableTaskType.has(task.type),
|
133
139
|
inputs: inputsMap[task.name],
|
134
140
|
dependsOn: dependsOnMap[task.name],
|
@@ -164,7 +170,7 @@ function createInputsMap(context) {
|
|
164
170
|
: ['default', '^default'],
|
165
171
|
};
|
166
172
|
}
|
167
|
-
function getTestCiTargets(testFiles, gradleProject, testTargetName, ciTargetName, inputs, outputs, targetGroupName, targets, targetGroups) {
|
173
|
+
function getTestCiTargets(testFiles, gradleProject, testTargetName, ciTargetName, inputs, outputs, targetGroupName, targets, targetGroups, gradlewFileDirectory) {
|
168
174
|
if (!testFiles || testFiles.length === 0 || !ciTargetName) {
|
169
175
|
return;
|
170
176
|
}
|
@@ -178,6 +184,9 @@ function getTestCiTargets(testFiles, gradleProject, testTargetName, ciTargetName
|
|
178
184
|
const targetName = ciTargetName + '--' + testName;
|
179
185
|
targets[targetName] = {
|
180
186
|
command: `${(0, exec_gradle_1.getGradleExecFile)()} ${taskCommandToRun} --tests ${testName}`,
|
187
|
+
options: {
|
188
|
+
cwd: gradlewFileDirectory,
|
189
|
+
},
|
181
190
|
cache: true,
|
182
191
|
inputs,
|
183
192
|
dependsOn: dependsOnMap['test'],
|
@@ -224,21 +233,6 @@ function getTestCiTargets(testFiles, gradleProject, testTargetName, ciTargetName
|
|
224
233
|
};
|
225
234
|
targetGroups[targetGroupName].push(ciTargetName);
|
226
235
|
}
|
227
|
-
function splitConfigFiles(files) {
|
228
|
-
const configFiles = [];
|
229
|
-
const testFiles = [];
|
230
|
-
const projectRoots = new Set();
|
231
|
-
files.forEach((file) => {
|
232
|
-
if (get_gradle_report_1.GRADLE_BUILD_FILES.has((0, node_path_1.basename)(file))) {
|
233
|
-
configFiles.push(file);
|
234
|
-
projectRoots.add((0, node_path_1.dirname)(file));
|
235
|
-
}
|
236
|
-
else {
|
237
|
-
testFiles.push(file);
|
238
|
-
}
|
239
|
-
});
|
240
|
-
return { configFiles, testFiles, projectRoots: Array.from(projectRoots) };
|
241
|
-
}
|
242
236
|
function getGradleProjectRootToTestFilesMap(testFiles, projectRoots) {
|
243
237
|
if (testFiles.length === 0 || projectRoots.length === 0) {
|
244
238
|
return;
|
@@ -1,4 +1,23 @@
|
|
1
1
|
import { ExecFileOptions } from 'node:child_process';
|
2
|
-
|
2
|
+
/**
|
3
|
+
* For gradle command, it needs to be run from the directory of the gradle binary
|
4
|
+
* @returns gradle binary file name
|
5
|
+
*/
|
3
6
|
export declare function getGradleExecFile(): string;
|
4
|
-
|
7
|
+
/**
|
8
|
+
* This function executes gradle with the given arguments
|
9
|
+
* @param gradleBinaryPath absolute path to gradle binary
|
10
|
+
* @param args args passed to gradle
|
11
|
+
* @param execOptions exec options
|
12
|
+
* @returns promise with the stdout buffer
|
13
|
+
*/
|
14
|
+
export declare function execGradleAsync(gradleBinaryPath: string, args: ReadonlyArray<string>, execOptions?: ExecFileOptions): Promise<Buffer>;
|
15
|
+
/**
|
16
|
+
* This function recursively finds the nearest gradlew file in the workspace
|
17
|
+
* @param originalFileToSearch the original file to search for
|
18
|
+
* @param wr workspace root
|
19
|
+
* @param currentSearchPath the path to start searching for gradlew file
|
20
|
+
* @returns the relative path of the gradlew file to workspace root, throws an error if gradlew file is not found
|
21
|
+
* It will return gradlew.bat file on windows and gradlew file on other platforms
|
22
|
+
*/
|
23
|
+
export declare function findGraldewFile(originalFileToSearch: string, wr?: string, currentSearchPath?: string): string;
|
package/src/utils/exec-gradle.js
CHANGED
@@ -1,33 +1,34 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.getGradleBinaryPath = getGradleBinaryPath;
|
4
3
|
exports.getGradleExecFile = getGradleExecFile;
|
5
4
|
exports.execGradleAsync = execGradleAsync;
|
5
|
+
exports.findGraldewFile = findGraldewFile;
|
6
6
|
const devkit_1 = require("@nx/devkit");
|
7
7
|
const node_child_process_1 = require("node:child_process");
|
8
8
|
const node_fs_1 = require("node:fs");
|
9
9
|
const node_path_1 = require("node:path");
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
const gradleBinaryPath = (0, node_path_1.join)(devkit_1.workspaceRoot, gradleFile);
|
15
|
-
if (!(0, node_fs_1.existsSync)(gradleBinaryPath)) {
|
16
|
-
throw new Error('Gradle is not setup. Run "gradle init"');
|
17
|
-
}
|
18
|
-
return gradleBinaryPath;
|
19
|
-
}
|
10
|
+
/**
|
11
|
+
* For gradle command, it needs to be run from the directory of the gradle binary
|
12
|
+
* @returns gradle binary file name
|
13
|
+
*/
|
20
14
|
function getGradleExecFile() {
|
21
15
|
return process.platform.startsWith('win') ? '.\\gradlew.bat' : './gradlew';
|
22
16
|
}
|
23
|
-
|
24
|
-
|
17
|
+
/**
|
18
|
+
* This function executes gradle with the given arguments
|
19
|
+
* @param gradleBinaryPath absolute path to gradle binary
|
20
|
+
* @param args args passed to gradle
|
21
|
+
* @param execOptions exec options
|
22
|
+
* @returns promise with the stdout buffer
|
23
|
+
*/
|
24
|
+
function execGradleAsync(gradleBinaryPath, args, execOptions = {}) {
|
25
25
|
return new Promise((res, rej) => {
|
26
26
|
const cp = (0, node_child_process_1.execFile)(gradleBinaryPath, args, {
|
27
|
-
|
27
|
+
cwd: (0, node_path_1.dirname)(gradleBinaryPath),
|
28
28
|
shell: true,
|
29
29
|
windowsHide: true,
|
30
30
|
env: process.env,
|
31
|
+
...execOptions,
|
31
32
|
});
|
32
33
|
let stdout = Buffer.from('');
|
33
34
|
cp.stdout?.on('data', (data) => {
|
@@ -43,3 +44,36 @@ function execGradleAsync(args, execOptions = {}) {
|
|
43
44
|
});
|
44
45
|
});
|
45
46
|
}
|
47
|
+
/**
|
48
|
+
* This function recursively finds the nearest gradlew file in the workspace
|
49
|
+
* @param originalFileToSearch the original file to search for
|
50
|
+
* @param wr workspace root
|
51
|
+
* @param currentSearchPath the path to start searching for gradlew file
|
52
|
+
* @returns the relative path of the gradlew file to workspace root, throws an error if gradlew file is not found
|
53
|
+
* It will return gradlew.bat file on windows and gradlew file on other platforms
|
54
|
+
*/
|
55
|
+
function findGraldewFile(originalFileToSearch, wr = devkit_1.workspaceRoot, currentSearchPath) {
|
56
|
+
currentSearchPath ??= originalFileToSearch;
|
57
|
+
const parent = (0, node_path_1.dirname)(currentSearchPath);
|
58
|
+
if (currentSearchPath === parent) {
|
59
|
+
throw new devkit_1.AggregateCreateNodesError([
|
60
|
+
[
|
61
|
+
originalFileToSearch,
|
62
|
+
new Error('No Gradlew file found. Run "gradle init"'),
|
63
|
+
],
|
64
|
+
], []);
|
65
|
+
}
|
66
|
+
const gradlewPath = (0, node_path_1.join)(parent, 'gradlew');
|
67
|
+
const gradlewBatPath = (0, node_path_1.join)(parent, 'gradlew.bat');
|
68
|
+
if (process.platform.startsWith('win')) {
|
69
|
+
if ((0, node_fs_1.existsSync)((0, node_path_1.join)(wr, gradlewBatPath))) {
|
70
|
+
return gradlewBatPath;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
if ((0, node_fs_1.existsSync)((0, node_path_1.join)(wr, gradlewPath))) {
|
75
|
+
return gradlewPath;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
return findGraldewFile(originalFileToSearch, wr, parent);
|
79
|
+
}
|
@@ -1,5 +1,3 @@
|
|
1
|
-
export declare const fileSeparator: string;
|
2
|
-
export declare const newLineSeparator: string;
|
3
1
|
export interface GradleReport {
|
4
2
|
gradleFileToGradleProjectMap: Map<string, string>;
|
5
3
|
buildFileToDepsMap: Map<string, string>;
|
@@ -9,10 +7,16 @@ export interface GradleReport {
|
|
9
7
|
gradleProjectNameToProjectRootMap: Map<string, string>;
|
10
8
|
gradleProjectToChildProjects: Map<string, string[]>;
|
11
9
|
}
|
12
|
-
export declare const GRADLE_BUILD_FILES: Set<string>;
|
13
|
-
export declare const GRADLE_TEST_FILES: string[];
|
14
|
-
export declare const gradleConfigGlob: string;
|
15
|
-
export declare const gradleConfigAndTestGlob: string;
|
16
10
|
export declare function getCurrentGradleReport(): GradleReport;
|
17
|
-
|
11
|
+
/**
|
12
|
+
* This function populates the gradle report cache.
|
13
|
+
* For each gradlew file, it runs the `projectReportAll` task and processes the output.
|
14
|
+
* If `projectReportAll` fails, it runs the `projectReport` task instead.
|
15
|
+
* It will throw an error if both tasks fail.
|
16
|
+
* It will accumulate the output of all gradlew files.
|
17
|
+
* @param workspaceRoot
|
18
|
+
* @param gradlewFiles absolute paths to all gradlew files in the workspace
|
19
|
+
* @returns Promise<void>
|
20
|
+
*/
|
21
|
+
export declare function populateGradleReport(workspaceRoot: string, gradlewFiles: string[]): Promise<void>;
|
18
22
|
export declare function processProjectReports(projectReportLines: string[]): GradleReport;
|
@@ -1,75 +1,54 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.gradleConfigAndTestGlob = exports.gradleConfigGlob = exports.GRADLE_TEST_FILES = exports.GRADLE_BUILD_FILES = exports.newLineSeparator = exports.fileSeparator = void 0;
|
4
3
|
exports.getCurrentGradleReport = getCurrentGradleReport;
|
5
4
|
exports.populateGradleReport = populateGradleReport;
|
6
5
|
exports.processProjectReports = processProjectReports;
|
7
6
|
const node_fs_1 = require("node:fs");
|
8
7
|
const node_path_1 = require("node:path");
|
9
8
|
const devkit_1 = require("@nx/devkit");
|
10
|
-
const globs_1 = require("nx/src/utils/globs");
|
11
|
-
const exec_gradle_1 = require("./exec-gradle");
|
12
9
|
const workspace_context_1 = require("nx/src/utils/workspace-context");
|
13
10
|
const path_1 = require("path");
|
14
|
-
|
15
|
-
|
16
|
-
: 'file://';
|
17
|
-
exports.newLineSeparator = process.platform.startsWith('win')
|
18
|
-
? '\r\n'
|
19
|
-
: '\n';
|
11
|
+
const split_config_files_1 = require("./split-config-files");
|
12
|
+
const get_project_report_lines_1 = require("./get-project-report-lines");
|
20
13
|
let gradleReportCache;
|
21
14
|
let gradleCurrentConfigHash;
|
22
|
-
exports.GRADLE_BUILD_FILES = new Set(['build.gradle', 'build.gradle.kts']);
|
23
|
-
exports.GRADLE_TEST_FILES = [
|
24
|
-
'**/src/test/java/**/*Test.java',
|
25
|
-
'**/src/test/kotlin/**/*Test.kt',
|
26
|
-
'**/src/test/java/**/*Tests.java',
|
27
|
-
'**/src/test/kotlin/**/*Tests.kt',
|
28
|
-
];
|
29
|
-
exports.gradleConfigGlob = (0, globs_1.combineGlobPatterns)(...Array.from(exports.GRADLE_BUILD_FILES).map((file) => `**/${file}`));
|
30
|
-
exports.gradleConfigAndTestGlob = (0, globs_1.combineGlobPatterns)(...Array.from(exports.GRADLE_BUILD_FILES).map((file) => `**/${file}`), ...exports.GRADLE_TEST_FILES);
|
31
15
|
function getCurrentGradleReport() {
|
32
16
|
if (!gradleReportCache) {
|
33
|
-
throw new
|
17
|
+
throw new devkit_1.AggregateCreateNodesError([
|
18
|
+
[
|
19
|
+
null,
|
20
|
+
new Error(`Expected cached gradle report. Please open an issue at https://github.com/nrwl/nx/issues/new/choose`),
|
21
|
+
],
|
22
|
+
], []);
|
34
23
|
}
|
35
24
|
return gradleReportCache;
|
36
25
|
}
|
37
|
-
|
26
|
+
/**
|
27
|
+
* This function populates the gradle report cache.
|
28
|
+
* For each gradlew file, it runs the `projectReportAll` task and processes the output.
|
29
|
+
* If `projectReportAll` fails, it runs the `projectReport` task instead.
|
30
|
+
* It will throw an error if both tasks fail.
|
31
|
+
* It will accumulate the output of all gradlew files.
|
32
|
+
* @param workspaceRoot
|
33
|
+
* @param gradlewFiles absolute paths to all gradlew files in the workspace
|
34
|
+
* @returns Promise<void>
|
35
|
+
*/
|
36
|
+
async function populateGradleReport(workspaceRoot, gradlewFiles) {
|
38
37
|
const gradleConfigHash = await (0, workspace_context_1.hashWithWorkspaceContext)(workspaceRoot, [
|
39
|
-
|
38
|
+
split_config_files_1.gradleConfigAndTestGlob,
|
40
39
|
]);
|
41
40
|
if (gradleReportCache && gradleConfigHash === gradleCurrentConfigHash) {
|
42
41
|
return;
|
43
42
|
}
|
44
43
|
const gradleProjectReportStart = performance.mark('gradleProjectReport:start');
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
}
|
51
|
-
catch (e) {
|
52
|
-
try {
|
53
|
-
projectReportLines = await (0, exec_gradle_1.execGradleAsync)(['projectReport'], {
|
54
|
-
cwd: workspaceRoot,
|
55
|
-
});
|
56
|
-
devkit_1.logger.warn('Could not run `projectReportAll` task. Ran `projectReport` instead. Please run `nx generate @nx/gradle:init` to generate the necessary tasks.');
|
57
|
-
}
|
58
|
-
catch (e) {
|
59
|
-
throw new devkit_1.AggregateCreateNodesError([
|
60
|
-
[
|
61
|
-
null,
|
62
|
-
new Error('Could not run `projectReportAll` or `projectReport` task. Please run `nx generate @nx/gradle:init` to generate the necessary tasks.'),
|
63
|
-
],
|
64
|
-
], []);
|
65
|
-
}
|
66
|
-
}
|
67
|
-
projectReportLines = projectReportLines
|
68
|
-
.toString()
|
69
|
-
.split(exports.newLineSeparator)
|
70
|
-
.filter((line) => line.trim() !== '');
|
44
|
+
const projectReportLines = await gradlewFiles.reduce(async (projectReportLines, gradlewFile) => {
|
45
|
+
const allLines = await projectReportLines;
|
46
|
+
const currentLines = await (0, get_project_report_lines_1.getProjectReportLines)(gradlewFile);
|
47
|
+
return [...allLines, ...currentLines];
|
48
|
+
}, Promise.resolve([]));
|
71
49
|
const gradleProjectReportEnd = performance.mark('gradleProjectReport:end');
|
72
50
|
performance.measure('gradleProjectReport', gradleProjectReportStart.name, gradleProjectReportEnd.name);
|
51
|
+
gradleCurrentConfigHash = gradleConfigHash;
|
73
52
|
gradleReportCache = processProjectReports(projectReportLines);
|
74
53
|
}
|
75
54
|
function processProjectReports(projectReportLines) {
|
@@ -104,21 +83,21 @@ function processProjectReports(projectReportLines) {
|
|
104
83
|
if (line.endsWith(':dependencyReport')) {
|
105
84
|
const gradleProject = line.substring('> Task '.length, line.length - ':dependencyReport'.length);
|
106
85
|
while (index < projectReportLines.length &&
|
107
|
-
!projectReportLines[index].includes(
|
86
|
+
!projectReportLines[index].includes(get_project_report_lines_1.fileSeparator)) {
|
108
87
|
index++;
|
109
88
|
}
|
110
|
-
const [_, file] = projectReportLines[index].split(
|
89
|
+
const [_, file] = projectReportLines[index].split(get_project_report_lines_1.fileSeparator);
|
111
90
|
dependenciesMap.set(gradleProject, file);
|
112
91
|
}
|
113
92
|
if (line.endsWith('propertyReport')) {
|
114
93
|
const gradleProject = line.substring('> Task '.length, line.length - ':propertyReport'.length);
|
115
94
|
while (index < projectReportLines.length &&
|
116
|
-
!projectReportLines[index].includes(
|
95
|
+
!projectReportLines[index].includes(get_project_report_lines_1.fileSeparator)) {
|
117
96
|
index++;
|
118
97
|
}
|
119
|
-
const [_, file] = projectReportLines[index].split(
|
98
|
+
const [_, file] = projectReportLines[index].split(get_project_report_lines_1.fileSeparator);
|
120
99
|
const propertyReportLines = (0, node_fs_1.existsSync)(file)
|
121
|
-
? (0, node_fs_1.readFileSync)(file).toString().split(
|
100
|
+
? (0, node_fs_1.readFileSync)(file).toString().split(get_project_report_lines_1.newLineSeparator)
|
122
101
|
: [];
|
123
102
|
let projectName, absBuildFilePath, absBuildDirPath;
|
124
103
|
const outputDirMap = new Map();
|
@@ -162,13 +141,13 @@ function processProjectReports(projectReportLines) {
|
|
162
141
|
if (line.endsWith('taskReport')) {
|
163
142
|
const gradleProject = line.substring('> Task '.length, line.length - ':taskReport'.length);
|
164
143
|
while (index < projectReportLines.length &&
|
165
|
-
!projectReportLines[index].includes(
|
144
|
+
!projectReportLines[index].includes(get_project_report_lines_1.fileSeparator)) {
|
166
145
|
index++;
|
167
146
|
}
|
168
|
-
const [_, file] = projectReportLines[index].split(
|
147
|
+
const [_, file] = projectReportLines[index].split(get_project_report_lines_1.fileSeparator);
|
169
148
|
const taskTypeMap = new Map();
|
170
149
|
const tasksFileLines = (0, node_fs_1.existsSync)(file)
|
171
|
-
? (0, node_fs_1.readFileSync)(file).toString().split(
|
150
|
+
? (0, node_fs_1.readFileSync)(file).toString().split(get_project_report_lines_1.newLineSeparator)
|
172
151
|
: [];
|
173
152
|
let i = 0;
|
174
153
|
while (i < tasksFileLines.length) {
|
@@ -0,0 +1,8 @@
|
|
1
|
+
export declare const fileSeparator: string;
|
2
|
+
export declare const newLineSeparator: string;
|
3
|
+
/**
|
4
|
+
* This function executes the gradle projectReportAll task and returns the output as an array of lines.
|
5
|
+
* @param gradlewFile the absolute path to the gradlew file
|
6
|
+
* @returns project report lines
|
7
|
+
*/
|
8
|
+
export declare function getProjectReportLines(gradlewFile: string): Promise<string[]>;
|
@@ -0,0 +1,53 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.newLineSeparator = exports.fileSeparator = void 0;
|
4
|
+
exports.getProjectReportLines = getProjectReportLines;
|
5
|
+
const devkit_1 = require("@nx/devkit");
|
6
|
+
const exec_gradle_1 = require("./exec-gradle");
|
7
|
+
const fs_1 = require("fs");
|
8
|
+
const path_1 = require("path");
|
9
|
+
exports.fileSeparator = process.platform.startsWith('win')
|
10
|
+
? 'file:///'
|
11
|
+
: 'file://';
|
12
|
+
exports.newLineSeparator = process.platform.startsWith('win')
|
13
|
+
? '\r\n'
|
14
|
+
: '\n';
|
15
|
+
/**
|
16
|
+
* This function executes the gradle projectReportAll task and returns the output as an array of lines.
|
17
|
+
* @param gradlewFile the absolute path to the gradlew file
|
18
|
+
* @returns project report lines
|
19
|
+
*/
|
20
|
+
async function getProjectReportLines(gradlewFile) {
|
21
|
+
let projectReportBuffer;
|
22
|
+
// if there is no build.gradle or build.gradle.kts file, we cannot run the projectReport nor projectReportAll task
|
23
|
+
if (!(0, fs_1.existsSync)((0, path_1.join)((0, path_1.dirname)(gradlewFile), 'build.gradle')) &&
|
24
|
+
!(0, fs_1.existsSync)((0, path_1.join)((0, path_1.dirname)(gradlewFile), 'build.gradle.kts'))) {
|
25
|
+
devkit_1.logger.warn(`Could not find build file near ${gradlewFile}. Please run 'nx generate @nx/gradle:init' to generate the necessary tasks.`);
|
26
|
+
return [];
|
27
|
+
}
|
28
|
+
try {
|
29
|
+
projectReportBuffer = await (0, exec_gradle_1.execGradleAsync)(gradlewFile, [
|
30
|
+
'projectReportAll',
|
31
|
+
]);
|
32
|
+
}
|
33
|
+
catch (e) {
|
34
|
+
try {
|
35
|
+
projectReportBuffer = await (0, exec_gradle_1.execGradleAsync)(gradlewFile, [
|
36
|
+
'projectReport',
|
37
|
+
]);
|
38
|
+
devkit_1.logger.warn(`Could not run 'projectReportAll' task. Ran 'projectReport' instead. Please run 'nx generate @nx/gradle:init' to generate the necessary tasks.`);
|
39
|
+
}
|
40
|
+
catch (e) {
|
41
|
+
throw new devkit_1.AggregateCreateNodesError([
|
42
|
+
[
|
43
|
+
gradlewFile,
|
44
|
+
new Error(`Could not run 'projectReportAll' or 'projectReport' task. Please run 'nx generate @nx/gradle:init' to generate the necessary tasks.`),
|
45
|
+
],
|
46
|
+
], []);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
return projectReportBuffer
|
50
|
+
.toString()
|
51
|
+
.split(exports.newLineSeparator)
|
52
|
+
.filter((line) => line.trim() !== '');
|
53
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
export declare const GRADLE_BUILD_FILES: Set<string>;
|
2
|
+
export declare const GRALDEW_FILES: Set<string>;
|
3
|
+
export declare const GRADLE_TEST_FILES: string[];
|
4
|
+
export declare const gradleConfigGlob: string;
|
5
|
+
export declare const gradleConfigAndTestGlob: string;
|
6
|
+
/**
|
7
|
+
* This function split config files into build files, settings files, test files and project roots
|
8
|
+
* @param files list of files to split
|
9
|
+
* @returns object with buildFiles, gradlewFiles, testFiles and projectRoots
|
10
|
+
* For gradlewFiles, it will start with settings files and find the nearest gradlew file in the workspace
|
11
|
+
*/
|
12
|
+
export declare function splitConfigFiles(files: readonly string[]): {
|
13
|
+
buildFiles: string[];
|
14
|
+
gradlewFiles: string[];
|
15
|
+
testFiles: string[];
|
16
|
+
projectRoots: string[];
|
17
|
+
};
|
@@ -0,0 +1,57 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.gradleConfigAndTestGlob = exports.gradleConfigGlob = exports.GRADLE_TEST_FILES = exports.GRALDEW_FILES = exports.GRADLE_BUILD_FILES = void 0;
|
4
|
+
exports.splitConfigFiles = splitConfigFiles;
|
5
|
+
const globs_1 = require("nx/src/utils/globs");
|
6
|
+
const node_path_1 = require("node:path");
|
7
|
+
exports.GRADLE_BUILD_FILES = new Set(['build.gradle', 'build.gradle.kts']);
|
8
|
+
exports.GRALDEW_FILES = new Set(['gradlew', 'gradlew.bat']);
|
9
|
+
exports.GRADLE_TEST_FILES = [
|
10
|
+
'**/src/test/java/**/*Test.java',
|
11
|
+
'**/src/test/kotlin/**/*Test.kt',
|
12
|
+
'**/src/test/java/**/*Tests.java',
|
13
|
+
'**/src/test/kotlin/**/*Tests.kt',
|
14
|
+
];
|
15
|
+
exports.gradleConfigGlob = (0, globs_1.combineGlobPatterns)(...Array.from(exports.GRADLE_BUILD_FILES).map((file) => `**/${file}`));
|
16
|
+
exports.gradleConfigAndTestGlob = (0, globs_1.combineGlobPatterns)(...Array.from(exports.GRADLE_BUILD_FILES).map((file) => `**/${file}`), ...Array.from(exports.GRALDEW_FILES).map((file) => `**/${file}`), ...exports.GRADLE_TEST_FILES);
|
17
|
+
/**
|
18
|
+
* This function split config files into build files, settings files, test files and project roots
|
19
|
+
* @param files list of files to split
|
20
|
+
* @returns object with buildFiles, gradlewFiles, testFiles and projectRoots
|
21
|
+
* For gradlewFiles, it will start with settings files and find the nearest gradlew file in the workspace
|
22
|
+
*/
|
23
|
+
function splitConfigFiles(files) {
|
24
|
+
const buildFiles = [];
|
25
|
+
const testFiles = [];
|
26
|
+
const gradlewFiles = [];
|
27
|
+
const projectRoots = new Set();
|
28
|
+
files.forEach((file) => {
|
29
|
+
const filename = (0, node_path_1.basename)(file);
|
30
|
+
const fileDirectory = (0, node_path_1.dirname)(file);
|
31
|
+
if (exports.GRADLE_BUILD_FILES.has(filename)) {
|
32
|
+
buildFiles.push(file);
|
33
|
+
projectRoots.add(fileDirectory);
|
34
|
+
}
|
35
|
+
else if (exports.GRALDEW_FILES.has(filename)) {
|
36
|
+
if (process.platform.startsWith('win')) {
|
37
|
+
if (filename === 'gradlew.bat') {
|
38
|
+
gradlewFiles.push(file);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
else {
|
42
|
+
if (filename === 'gradlew') {
|
43
|
+
gradlewFiles.push(file);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
testFiles.push(file);
|
49
|
+
}
|
50
|
+
});
|
51
|
+
return {
|
52
|
+
buildFiles,
|
53
|
+
testFiles,
|
54
|
+
gradlewFiles,
|
55
|
+
projectRoots: Array.from(projectRoots),
|
56
|
+
};
|
57
|
+
}
|