@nx/gradle 0.0.0-pr-26515-856ef7f

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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2017-2024 Narwhal Technologies Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ <p style="text-align: center;">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
4
+ <img alt="Nx - Smart Monorepos · Fast CI" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
5
+ </picture>
6
+ </p>
7
+
8
+ <div style="text-align: center;">
9
+
10
+ [![CircleCI](https://circleci.com/gh/nrwl/nx.svg?style=svg)](https://circleci.com/gh/nrwl/nx)
11
+ [![License](https://img.shields.io/npm/l/@nx/workspace.svg?style=flat-square)]()
12
+ [![NPM Version](https://badge.fury.io/js/%40nrwl%2Fworkspace.svg)](https://www.npmjs.com/@nx/workspace)
13
+ [![Semantic Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)]()
14
+ [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
15
+ [![Join the chat at https://gitter.im/nrwl-nx/community](https://badges.gitter.im/nrwl-nx/community.svg)](https://gitter.im/nrwl-nx/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
16
+ [![Join us on the Official Nx Discord Server](https://img.shields.io/discord/1143497901675401286?label=discord)](https://go.nx.dev/community)
17
+
18
+ </div>
19
+
20
+
21
+ <hr>
22
+
23
+ > Note: this plugin is currently experimental.
24
+
25
+ # Nx: Smart Monorepos · Fast CI
26
+
27
+ Nx is a build system with built-in tooling and advanced CI capabilities. It helps you maintain and scale monorepos, both locally and on CI.
28
+
29
+ This package is a [Gradle plugin for Nx](https://nx.dev/gradle/overview).
30
+
31
+ ## Getting Started
32
+
33
+ ### Creating an Nx Workspace
34
+
35
+ **Using `npx`**
36
+
37
+ ```bash
38
+ npx create-nx-workspace
39
+ ```
40
+
41
+ **Using `npm init`**
42
+
43
+ ```bash
44
+ npm init nx-workspace
45
+ ```
46
+
47
+ **Using `yarn create`**
48
+
49
+ ```bash
50
+ yarn create nx-workspace
51
+ ```
52
+
53
+ ### Adding Nx to an Existing Repository
54
+
55
+ Run:
56
+
57
+ ```bash
58
+ npx nx@latest init
59
+ ```
60
+
61
+ ## Documentation & Resources
62
+
63
+ - [Nx.Dev: Documentation, Guides, Tutorials](https://nx.dev)
64
+ - [Intro to Nx](https://nx.dev/getting-started/intro)
65
+ - [Official Nx YouTube Channel](https://www.youtube.com/@NxDevtools)
66
+ - [Blog Posts About Nx](https://blog.nrwl.io/nx/home)
67
+
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 Monorepos · Fast CI"></a></p>
70
+
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "Nx Gradle",
3
+ "version": "0.1",
4
+ "generators": {
5
+ "init": {
6
+ "factory": "./src/generators/init/init#initGenerator",
7
+ "schema": "./src/generators/init/schema.json",
8
+ "description": "Initializes a Gradle project in the current workspace"
9
+ },
10
+ "ci-workflow": {
11
+ "factory": "./src/generators/ci-workflow/generator",
12
+ "schema": "./src/generators/ci-workflow/schema.json",
13
+ "description": "Setup a CI Workflow to run Nx in CI"
14
+ }
15
+ }
16
+ }
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './plugin';
package/index.js ADDED
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./plugin"), exports);
@@ -0,0 +1,4 @@
1
+ {
2
+ "generators": {},
3
+ "packageJsonUpdates": {}
4
+ }
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@nx/gradle",
3
+ "version": "0.0.0-pr-26515-856ef7f",
4
+ "private": false,
5
+ "description": "The Nx Plugin for Gradle allows Gradle tasks to be run through Nx",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/nrwl/nx.git",
9
+ "directory": "packages/gradle"
10
+ },
11
+ "keywords": [
12
+ "Monorepo",
13
+ "Java",
14
+ "Gradle",
15
+ "CLI",
16
+ "Backend"
17
+ ],
18
+ "main": "./index",
19
+ "typings": "./index.d.ts",
20
+ "author": "Victor Savkin",
21
+ "license": "MIT",
22
+ "bugs": {
23
+ "url": "https://github.com/nrwl/nx/issues"
24
+ },
25
+ "homepage": "https://nx.dev",
26
+ "generators": "./generators.json",
27
+ "exports": {
28
+ ".": "./index.js",
29
+ "./package.json": "./package.json",
30
+ "./migrations.json": "./migrations.json",
31
+ "./generators.json": "./generators.json"
32
+ },
33
+ "nx-migrate": {
34
+ "migrations": "./migrations.json"
35
+ },
36
+ "dependencies": {
37
+ "@nx/devkit": "0.0.0-pr-26515-856ef7f"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "type": "commonjs"
43
+ }
package/plugin.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { createDependencies } from './src/plugin/dependencies';
2
+ export { createNodes, createNodesV2 } from './src/plugin/nodes';
package/plugin.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodesV2 = exports.createNodes = exports.createDependencies = void 0;
4
+ var dependencies_1 = require("./src/plugin/dependencies");
5
+ Object.defineProperty(exports, "createDependencies", { enumerable: true, get: function () { return dependencies_1.createDependencies; } });
6
+ var nodes_1 = require("./src/plugin/nodes");
7
+ Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return nodes_1.createNodes; } });
8
+ Object.defineProperty(exports, "createNodesV2", { enumerable: true, get: function () { return nodes_1.createNodesV2; } });
@@ -0,0 +1,32 @@
1
+ version: 2.1
2
+
3
+ orbs:
4
+ nx: nrwl/nx@1.6.2
5
+
6
+ jobs:
7
+ main:
8
+ environment:
9
+ # Configure the JVM and Gradle to avoid OOM errors
10
+ _JAVA_OPTIONS: "-Xmx3g"
11
+ GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2"
12
+ docker:
13
+ - image: cimg/openjdk:17.0-node
14
+ steps:
15
+ - checkout
16
+
17
+ # Connect your workspace on <%= nxCloudHost %> and uncomment this to enable task distribution.
18
+ # The "--stop-agents-after" is optional, but allows idle agents to shut down once the "build" targets have been requested
19
+ # - run: <%= packageManagerPrefix %> nx-cloud start-ci-run --distribute-on="5 linux-medium-jvm" --stop-agents-after="build"
20
+
21
+ - nx/set-shas:
22
+ main-branch-name: '<%= mainBranch %>'
23
+
24
+ <% for (const command of commands) { %>
25
+ - run: <%= command %><% } %>
26
+
27
+ workflows:
28
+ version: 2
29
+
30
+ <%= workflowFileName %>:
31
+ jobs:
32
+ - main
@@ -0,0 +1,38 @@
1
+ name: <%= workflowName %>
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - <%= mainBranch %>
7
+ pull_request:
8
+
9
+ permissions:
10
+ actions: read
11
+ contents: read
12
+
13
+ jobs:
14
+ main:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+
21
+ # Connect your workspace on <%= nxCloudHost %> and uncomment this to enable task distribution.
22
+ # The "--stop-agents-after" is optional, but allows idle agents to shut down once the "build" targets have been requested
23
+ # - run: <%= packageManagerPrefix %> nx-cloud start-ci-run --distribute-on="5 linux-medium-jvm" --stop-agents-after="build"
24
+
25
+ - name: Set up JDK 17 for x64
26
+ uses: actions/setup-java@v4
27
+ with:
28
+ java-version: '17'
29
+ distribution: 'temurin'
30
+ architecture: x64
31
+
32
+ - name: Setup Gradle
33
+ uses: gradle/gradle-build-action@v2
34
+
35
+ - uses: nrwl/nx-set-shas@v4
36
+
37
+ <% for (const command of commands) { %>
38
+ - run: <%= command %><% } %>
@@ -0,0 +1,9 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export interface Schema {
3
+ name: string;
4
+ ci: 'github' | 'circleci';
5
+ packageManager?: null;
6
+ commands?: string[];
7
+ }
8
+ export declare function ciWorkflowGenerator(tree: Tree, schema: Schema): Promise<void>;
9
+ export default ciWorkflowGenerator;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ciWorkflowGenerator = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const path_1 = require("path");
6
+ const nx_cloud_utils_1 = require("nx/src/utils/nx-cloud-utils");
7
+ const default_base_1 = require("nx/src/utils/default-base");
8
+ function getCiCommands(ci, mainBranch) {
9
+ switch (ci) {
10
+ case 'circleci': {
11
+ return [`./nx affected --base=$NX_BASE --head=$NX_HEAD -t test build`];
12
+ }
13
+ default: {
14
+ return [`./nx affected -t test build`];
15
+ }
16
+ }
17
+ }
18
+ async function ciWorkflowGenerator(tree, schema) {
19
+ const ci = schema.ci;
20
+ const options = getTemplateData(tree, schema);
21
+ (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files', ci), '', options);
22
+ await (0, devkit_1.formatFiles)(tree);
23
+ }
24
+ exports.ciWorkflowGenerator = ciWorkflowGenerator;
25
+ function getTemplateData(tree, options) {
26
+ const { name: workflowName, fileName: workflowFileName } = (0, devkit_1.names)(options.name);
27
+ const packageManager = (0, devkit_1.detectPackageManager)();
28
+ const { exec: packageManagerPrefix } = (0, devkit_1.getPackageManagerCommand)(packageManager);
29
+ let nxCloudHost = 'nx.app';
30
+ try {
31
+ const nxCloudUrl = (0, nx_cloud_utils_1.getNxCloudUrl)((0, devkit_1.readJson)(tree, 'nx.json'));
32
+ nxCloudHost = new URL(nxCloudUrl).host;
33
+ }
34
+ catch { }
35
+ const mainBranch = (0, default_base_1.deduceDefaultBase)();
36
+ const commands = options.commands ?? getCiCommands(options.ci, mainBranch);
37
+ return {
38
+ workflowName,
39
+ workflowFileName,
40
+ packageManager,
41
+ packageManagerPrefix,
42
+ commands,
43
+ mainBranch,
44
+ nxCloudHost,
45
+ };
46
+ }
47
+ exports.default = ciWorkflowGenerator;
@@ -0,0 +1,40 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NxGradleCiWorkflowSchema",
4
+ "title": "Gradle CI Workflow Generator",
5
+ "description": "Setup a CI Workflow to run Nx in CI.",
6
+ "type": "object",
7
+ "properties": {
8
+ "ci": {
9
+ "type": "string",
10
+ "description": "CI provider.",
11
+ "enum": ["github", "circleci"],
12
+ "x-prompt": {
13
+ "message": "What is your target CI provider?",
14
+ "type": "list",
15
+ "items": [
16
+ {
17
+ "value": "github",
18
+ "label": "GitHub Actions"
19
+ },
20
+ {
21
+ "value": "circleci",
22
+ "label": "Circle CI"
23
+ }
24
+ ]
25
+ }
26
+ },
27
+ "name": {
28
+ "type": "string",
29
+ "description": "Workflow name.",
30
+ "$default": {
31
+ "$source": "argv",
32
+ "index": 0
33
+ },
34
+ "default": "CI",
35
+ "x-prompt": "How should we name your workflow?",
36
+ "pattern": "^[a-zA-Z].*$"
37
+ }
38
+ },
39
+ "required": ["ci", "name"]
40
+ }
@@ -0,0 +1,4 @@
1
+ import { GeneratorCallback, Tree } from '@nx/devkit';
2
+ import { InitGeneratorSchema } from './schema';
3
+ export declare function initGenerator(tree: Tree, options: InitGeneratorSchema): Promise<GeneratorCallback>;
4
+ export default initGenerator;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initGenerator = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const child_process_1 = require("child_process");
6
+ const versions_1 = require("../../utils/versions");
7
+ const has_gradle_plugin_1 = require("../../utils/has-gradle-plugin");
8
+ async function initGenerator(tree, options) {
9
+ const tasks = [];
10
+ if (!tree.exists('settings.gradle') && !tree.exists('settings.gradle.kts')) {
11
+ devkit_1.logger.warn(`Could not find 'settings.gradle' or 'settings.gradle.kts' file in your gradle workspace.
12
+ 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.
13
+ Running 'gradle init':`);
14
+ (0, child_process_1.execSync)('gradle init', { stdio: 'inherit' });
15
+ }
16
+ if (!options.skipPackageJson && tree.exists('package.json')) {
17
+ tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
18
+ '@nx/gradle': versions_1.nxVersion,
19
+ }, undefined, options.keepExistingVersions));
20
+ }
21
+ addPlugin(tree);
22
+ updateNxJsonConfiguration(tree);
23
+ addProjectReportToBuildGradle(tree);
24
+ if (!options.skipFormat) {
25
+ await (0, devkit_1.formatFiles)(tree);
26
+ }
27
+ return (0, devkit_1.runTasksInSerial)(...tasks);
28
+ }
29
+ exports.initGenerator = initGenerator;
30
+ function addPlugin(tree) {
31
+ const nxJson = (0, devkit_1.readNxJson)(tree);
32
+ if (!(0, has_gradle_plugin_1.hasGradlePlugin)(tree)) {
33
+ nxJson.plugins ??= [];
34
+ nxJson.plugins.push({
35
+ plugin: '@nx/gradle',
36
+ options: {
37
+ testTargetName: 'test',
38
+ classesTargetName: 'classes',
39
+ buildTargetName: 'build',
40
+ },
41
+ });
42
+ (0, devkit_1.updateNxJson)(tree, nxJson);
43
+ }
44
+ }
45
+ /**
46
+ * This function adds the project-report plugin to the build.gradle or build.gradle.kts file
47
+ */
48
+ function addProjectReportToBuildGradle(tree) {
49
+ let buildGradleFile;
50
+ if (tree.exists('settings.gradle.kts')) {
51
+ buildGradleFile = 'build.gradle.kts';
52
+ }
53
+ else if (tree.exists('settings.gradle')) {
54
+ buildGradleFile = 'build.gradle';
55
+ }
56
+ let buildGradleContent = '';
57
+ if (tree.exists(buildGradleFile)) {
58
+ buildGradleContent = tree.read(buildGradleFile).toString();
59
+ }
60
+ if (buildGradleContent.includes('allprojects')) {
61
+ if (!buildGradleContent.includes('"project-report')) {
62
+ devkit_1.logger.warn(`Please add the project-report plugin to your ${buildGradleFile}:
63
+ allprojects {
64
+ apply {
65
+ plugin("project-report")
66
+ }
67
+ }`);
68
+ }
69
+ }
70
+ else {
71
+ buildGradleContent += `\n\rallprojects {
72
+ apply {
73
+ plugin("project-report")
74
+ }
75
+ }`;
76
+ tree.write(buildGradleFile, buildGradleContent);
77
+ }
78
+ }
79
+ function updateNxJsonConfiguration(tree) {
80
+ const nxJson = (0, devkit_1.readNxJson)(tree);
81
+ if (!nxJson.namedInputs) {
82
+ nxJson.namedInputs = {};
83
+ }
84
+ const defaultFilesSet = nxJson.namedInputs.default ?? [];
85
+ nxJson.namedInputs.default = Array.from(new Set([...defaultFilesSet, '{projectRoot}/**/*']));
86
+ const productionFileSet = nxJson.namedInputs.production ?? [];
87
+ nxJson.namedInputs.production = Array.from(new Set([...productionFileSet, 'default', '!{projectRoot}/test/**/*']));
88
+ (0, devkit_1.updateNxJson)(tree, nxJson);
89
+ }
90
+ exports.default = initGenerator;
@@ -0,0 +1,6 @@
1
+ export interface InitGeneratorSchema {
2
+ skipFormat?: boolean;
3
+ skipPackageJson?: boolean;
4
+ keepExistingVersions?: boolean;
5
+ updatePackageScripts?: boolean;
6
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NxGradleInitSchema",
4
+ "title": "Gradle Init Generator",
5
+ "description": "Initializes a Gradle project in the current workspace.",
6
+ "type": "object",
7
+ "properties": {
8
+ "skipFormat": {
9
+ "description": "Skip formatting files.",
10
+ "type": "boolean",
11
+ "default": false,
12
+ "x-priority": "internal"
13
+ },
14
+ "skipPackageJson": {
15
+ "type": "boolean",
16
+ "default": false,
17
+ "description": "Do not add dependencies to `package.json`.",
18
+ "x-priority": "internal"
19
+ },
20
+ "keepExistingVersions": {
21
+ "type": "boolean",
22
+ "x-priority": "internal",
23
+ "description": "Keep existing dependencies versions",
24
+ "default": false
25
+ },
26
+ "updatePackageScripts": {
27
+ "type": "boolean",
28
+ "x-priority": "internal",
29
+ "description": "Update `package.json` scripts with inferred targets",
30
+ "default": false
31
+ }
32
+ },
33
+ "required": []
34
+ }
@@ -0,0 +1,2 @@
1
+ import { CreateDependencies } from '@nx/devkit';
2
+ export declare const createDependencies: CreateDependencies;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDependencies = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const get_gradle_report_1 = require("../utils/get-gradle-report");
8
+ const createDependencies = async (_, context) => {
9
+ const gradleFiles = findGradleFiles(context.filesToProcess);
10
+ if (gradleFiles.length === 0) {
11
+ return [];
12
+ }
13
+ let dependencies = [];
14
+ const gradleDependenciesStart = performance.mark('gradleDependencies:start');
15
+ const { gradleFileToGradleProjectMap, gradleProjectToProjectName, buildFileToDepsMap, } = (0, get_gradle_report_1.getCurrentGradleReport)();
16
+ for (const gradleFile of gradleFiles) {
17
+ const gradleProject = gradleFileToGradleProjectMap.get(gradleFile);
18
+ const projectName = gradleProjectToProjectName.get(gradleProject);
19
+ const depsFile = buildFileToDepsMap.get(gradleFile);
20
+ if (projectName && depsFile) {
21
+ dependencies = dependencies.concat(Array.from(processGradleDependencies(depsFile, gradleProjectToProjectName, projectName, gradleFile, context)));
22
+ }
23
+ }
24
+ const gradleDependenciesEnd = performance.mark('gradleDependencies:end');
25
+ performance.measure('gradleDependencies', gradleDependenciesStart.name, gradleDependenciesEnd.name);
26
+ return dependencies;
27
+ };
28
+ exports.createDependencies = createDependencies;
29
+ const gradleConfigFileNames = new Set(['build.gradle', 'build.gradle.kts']);
30
+ function findGradleFiles(fileMap) {
31
+ const gradleFiles = [];
32
+ for (const [_, files] of Object.entries(fileMap.projectFileMap)) {
33
+ for (const file of files) {
34
+ if (gradleConfigFileNames.has((0, node_path_1.basename)(file.file))) {
35
+ gradleFiles.push(file.file);
36
+ }
37
+ }
38
+ }
39
+ return gradleFiles;
40
+ }
41
+ function processGradleDependencies(depsFile, gradleProjectToProjectName, sourceProjectName, gradleFile, context) {
42
+ const dependencies = new Set();
43
+ const lines = (0, node_fs_1.readFileSync)(depsFile).toString().split(get_gradle_report_1.newLineSeparator);
44
+ let inDeps = false;
45
+ for (const line of lines) {
46
+ if (line.startsWith('implementationDependenciesMetadata') ||
47
+ line.startsWith('compileClasspath')) {
48
+ inDeps = true;
49
+ continue;
50
+ }
51
+ if (inDeps) {
52
+ if (line === '') {
53
+ inDeps = false;
54
+ continue;
55
+ }
56
+ const [indents, dep] = line.split('--- ');
57
+ if ((indents === '\\' || indents === '+') && dep.startsWith('project ')) {
58
+ const gradleProjectName = dep
59
+ .substring('project '.length)
60
+ .replace(/ \(n\)$/, '')
61
+ .trim();
62
+ const target = gradleProjectToProjectName.get(gradleProjectName);
63
+ const dependency = {
64
+ source: sourceProjectName,
65
+ target,
66
+ type: devkit_1.DependencyType.static,
67
+ sourceFile: gradleFile,
68
+ };
69
+ (0, devkit_1.validateDependency)(dependency, context);
70
+ dependencies.add(dependency);
71
+ }
72
+ }
73
+ }
74
+ return dependencies;
75
+ }
@@ -0,0 +1,22 @@
1
+ import { CreateNodes, CreateNodesV2, ProjectConfiguration, TargetConfiguration, CreateNodesFunction } from '@nx/devkit';
2
+ import { GradleReport } from '../utils/get-gradle-report';
3
+ export interface GradlePluginOptions {
4
+ testTargetName?: string;
5
+ classesTargetName?: string;
6
+ buildTargetName?: string;
7
+ [taskTargetName: string]: string | undefined;
8
+ }
9
+ type GradleTargets = Record<string, {
10
+ name: string;
11
+ targets: Record<string, TargetConfiguration>;
12
+ metadata: ProjectConfiguration['metadata'];
13
+ }>;
14
+ export declare function writeTargetsToCache(cachePath: string, results: GradleTargets): void;
15
+ export declare const createNodesV2: CreateNodesV2<GradlePluginOptions>;
16
+ export declare const makeCreateNodes: (gradleReport: GradleReport, targetsCache: GradleTargets) => CreateNodesFunction;
17
+ /**
18
+ @deprecated This is replaced with {@link createNodesV2}. Update your plugin to export its own `createNodesV2` function that wraps this one instead.
19
+ This function will change to the v2 function in Nx 20.
20
+ */
21
+ export declare const createNodes: CreateNodes<GradlePluginOptions>;
22
+ export {};
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodes = exports.makeCreateNodes = exports.createNodesV2 = exports.writeTargetsToCache = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const cache_directory_1 = require("nx/src/utils/cache-directory");
9
+ const exec_gradle_1 = require("../utils/exec-gradle");
10
+ const get_gradle_report_1 = require("../utils/get-gradle-report");
11
+ const file_hasher_1 = require("nx/src/hasher/file-hasher");
12
+ const cacheableTaskType = new Set(['Build', 'Verification']);
13
+ const dependsOnMap = {
14
+ build: ['^build', 'classes'],
15
+ test: ['classes'],
16
+ classes: ['^classes'],
17
+ };
18
+ function readTargetsCache(cachePath) {
19
+ return (0, node_fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {};
20
+ }
21
+ function writeTargetsToCache(cachePath, results) {
22
+ (0, devkit_1.writeJsonFile)(cachePath, results);
23
+ }
24
+ exports.writeTargetsToCache = writeTargetsToCache;
25
+ exports.createNodesV2 = [
26
+ get_gradle_report_1.gradleConfigGlob,
27
+ async (configFiles, options, context) => {
28
+ const optionsHash = (0, file_hasher_1.hashObject)(options);
29
+ const cachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `gradle-${optionsHash}.hash`);
30
+ const targetsCache = readTargetsCache(cachePath);
31
+ await (0, get_gradle_report_1.populateGradleReport)(context.workspaceRoot);
32
+ const gradleReport = (0, get_gradle_report_1.getCurrentGradleReport)();
33
+ try {
34
+ return await (0, devkit_1.createNodesFromFiles)((0, exports.makeCreateNodes)(gradleReport, targetsCache), configFiles, options, context);
35
+ }
36
+ finally {
37
+ writeTargetsToCache(cachePath, targetsCache);
38
+ }
39
+ },
40
+ ];
41
+ const makeCreateNodes = (gradleReport, targetsCache) => async (gradleFilePath, options, context) => {
42
+ const projectRoot = (0, node_path_1.dirname)(gradleFilePath);
43
+ const hash = await (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options ?? {}, context);
44
+ targetsCache[hash] ??= createGradleProject(gradleReport, gradleFilePath, options, context);
45
+ const project = targetsCache[hash];
46
+ if (!project) {
47
+ return {};
48
+ }
49
+ return {
50
+ projects: {
51
+ [projectRoot]: project,
52
+ },
53
+ };
54
+ };
55
+ exports.makeCreateNodes = makeCreateNodes;
56
+ /**
57
+ @deprecated This is replaced with {@link createNodesV2}. Update your plugin to export its own `createNodesV2` function that wraps this one instead.
58
+ This function will change to the v2 function in Nx 20.
59
+ */
60
+ exports.createNodes = [
61
+ get_gradle_report_1.gradleConfigGlob,
62
+ async (configFile, options, context) => {
63
+ devkit_1.logger.warn('`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.');
64
+ await (0, get_gradle_report_1.populateGradleReport)(context.workspaceRoot);
65
+ const gradleReport = (0, get_gradle_report_1.getCurrentGradleReport)();
66
+ const internalCreateNodes = (0, exports.makeCreateNodes)(gradleReport, {});
67
+ return await internalCreateNodes(configFile, options, context);
68
+ },
69
+ ];
70
+ function createGradleProject(gradleReport, gradleFilePath, options, context) {
71
+ try {
72
+ const { gradleProjectToTasksTypeMap, gradleFileToOutputDirsMap, gradleFileToGradleProjectMap, gradleProjectToProjectName, } = gradleReport;
73
+ const gradleProject = gradleFileToGradleProjectMap.get(gradleFilePath);
74
+ const projectName = gradleProjectToProjectName.get(gradleProject);
75
+ if (!projectName) {
76
+ return;
77
+ }
78
+ const tasksTypeMap = gradleProjectToTasksTypeMap.get(gradleProject);
79
+ let tasks = [];
80
+ for (let [taskName, taskType] of tasksTypeMap.entries()) {
81
+ tasks.push({
82
+ type: taskType,
83
+ name: taskName,
84
+ });
85
+ }
86
+ const outputDirs = gradleFileToOutputDirsMap.get(gradleFilePath);
87
+ const { targets, targetGroups } = createGradleTargets(tasks, options, context, outputDirs, gradleProject);
88
+ const project = {
89
+ name: projectName,
90
+ targets,
91
+ metadata: {
92
+ targetGroups,
93
+ technologies: ['gradle'],
94
+ },
95
+ };
96
+ return project;
97
+ }
98
+ catch (e) {
99
+ console.error(e);
100
+ return undefined;
101
+ }
102
+ }
103
+ function createGradleTargets(tasks, options, context, outputDirs, gradleProject) {
104
+ const inputsMap = createInputsMap(context);
105
+ const targets = {};
106
+ const targetGroups = {};
107
+ for (const task of tasks) {
108
+ const targetName = options?.[`${task.name}TargetName`] ?? task.name;
109
+ const outputs = outputDirs.get(task.name);
110
+ targets[targetName] = {
111
+ command: `${(0, exec_gradle_1.getGradleExecFile)()} ${gradleProject ? gradleProject + ':' : ''}${task.name}`,
112
+ cache: cacheableTaskType.has(task.type),
113
+ inputs: inputsMap[task.name],
114
+ dependsOn: dependsOnMap[task.name],
115
+ metadata: {
116
+ technologies: ['gradle'],
117
+ },
118
+ };
119
+ if (outputs) {
120
+ targets[targetName].outputs = [outputs];
121
+ }
122
+ if (!targetGroups[task.type]) {
123
+ targetGroups[task.type] = [];
124
+ }
125
+ targetGroups[task.type].push(task.name);
126
+ }
127
+ return { targetGroups, targets };
128
+ }
129
+ function createInputsMap(context) {
130
+ const namedInputs = context.nxJsonConfiguration.namedInputs;
131
+ return {
132
+ build: namedInputs?.production
133
+ ? ['production', '^production']
134
+ : ['default', '^default'],
135
+ test: ['default', namedInputs?.production ? '^production' : '^default'],
136
+ classes: namedInputs?.production
137
+ ? ['production', '^production']
138
+ : ['default', '^default'],
139
+ };
140
+ }
@@ -0,0 +1,6 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { ExecFileOptions } from 'node:child_process';
4
+ export declare function getGradleBinaryPath(): string;
5
+ export declare function getGradleExecFile(): string;
6
+ export declare function execGradleAsync(args: ReadonlyArray<string>, execOptions?: ExecFileOptions): Promise<Buffer>;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.execGradleAsync = exports.getGradleExecFile = exports.getGradleBinaryPath = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const node_child_process_1 = require("node:child_process");
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ function getGradleBinaryPath() {
9
+ const gradleFile = process.platform.startsWith('win')
10
+ ? 'gradlew.bat'
11
+ : 'gradlew';
12
+ const gradleBinaryPath = (0, node_path_1.join)(devkit_1.workspaceRoot, gradleFile);
13
+ if (!(0, node_fs_1.existsSync)(gradleBinaryPath)) {
14
+ throw new Error('Gradle is not setup. Run "gradle init"');
15
+ }
16
+ return gradleBinaryPath;
17
+ }
18
+ exports.getGradleBinaryPath = getGradleBinaryPath;
19
+ function getGradleExecFile() {
20
+ return process.platform.startsWith('win') ? '.\\gradlew.bat' : './gradlew';
21
+ }
22
+ exports.getGradleExecFile = getGradleExecFile;
23
+ function execGradleAsync(args, execOptions = {}) {
24
+ const gradleBinaryPath = getGradleBinaryPath();
25
+ return new Promise((res, rej) => {
26
+ const cp = (0, node_child_process_1.execFile)(gradleBinaryPath, args, {
27
+ ...execOptions,
28
+ shell: true,
29
+ windowsHide: true,
30
+ });
31
+ let stdout = Buffer.from('');
32
+ cp.stdout?.on('data', (data) => {
33
+ stdout += data;
34
+ });
35
+ cp.on('exit', (code) => {
36
+ if (code === 0) {
37
+ res(stdout);
38
+ }
39
+ else {
40
+ rej(new Error(`Executing Gradle with ${args.join(' ')} failed with code: ${code}. \nLogs: ${stdout}`));
41
+ }
42
+ });
43
+ });
44
+ }
45
+ exports.execGradleAsync = execGradleAsync;
@@ -0,0 +1,13 @@
1
+ export declare const fileSeparator: string;
2
+ export declare const newLineSeparator: string;
3
+ export interface GradleReport {
4
+ gradleFileToGradleProjectMap: Map<string, string>;
5
+ buildFileToDepsMap: Map<string, string>;
6
+ gradleFileToOutputDirsMap: Map<string, Map<string, string>>;
7
+ gradleProjectToTasksTypeMap: Map<string, Map<string, string>>;
8
+ gradleProjectToProjectName: Map<string, string>;
9
+ }
10
+ export declare const gradleConfigGlob = "**/build.{gradle.kts,gradle}";
11
+ export declare function getCurrentGradleReport(): GradleReport;
12
+ export declare function populateGradleReport(workspaceRoot: string): Promise<void>;
13
+ export declare function processProjectReports(projectReportLines: string[]): GradleReport;
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processProjectReports = exports.populateGradleReport = exports.getCurrentGradleReport = exports.gradleConfigGlob = exports.newLineSeparator = exports.fileSeparator = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const devkit_1 = require("@nx/devkit");
7
+ const exec_gradle_1 = require("./exec-gradle");
8
+ const workspace_context_1 = require("nx/src/utils/workspace-context");
9
+ exports.fileSeparator = process.platform.startsWith('win')
10
+ ? 'file:///'
11
+ : 'file://';
12
+ exports.newLineSeparator = process.platform.startsWith('win')
13
+ ? '\r\n'
14
+ : '\n';
15
+ let gradleReportCache;
16
+ let gradleCurrentConfigHash;
17
+ exports.gradleConfigGlob = '**/build.{gradle.kts,gradle}';
18
+ function getCurrentGradleReport() {
19
+ if (!gradleReportCache) {
20
+ throw new Error('Expected cached gradle report. Please open an issue at https://github.com/nrwl/nx/issues/new/choose');
21
+ }
22
+ return gradleReportCache;
23
+ }
24
+ exports.getCurrentGradleReport = getCurrentGradleReport;
25
+ async function populateGradleReport(workspaceRoot) {
26
+ const gradleConfigHash = await (0, workspace_context_1.hashWithWorkspaceContext)(workspaceRoot, [
27
+ exports.gradleConfigGlob,
28
+ ]);
29
+ if (gradleReportCache && gradleConfigHash === gradleCurrentConfigHash) {
30
+ return;
31
+ }
32
+ const gradleProjectReportStart = performance.mark('gradleProjectReport:start');
33
+ const projectReportLines = (await (0, exec_gradle_1.execGradleAsync)(['projectReport'], {
34
+ cwd: workspaceRoot,
35
+ }))
36
+ .toString()
37
+ .split(exports.newLineSeparator);
38
+ const gradleProjectReportEnd = performance.mark('gradleProjectReport:end');
39
+ performance.measure('gradleProjectReport', gradleProjectReportStart.name, gradleProjectReportEnd.name);
40
+ gradleReportCache = processProjectReports(projectReportLines);
41
+ }
42
+ exports.populateGradleReport = populateGradleReport;
43
+ function processProjectReports(projectReportLines) {
44
+ /**
45
+ * Map of Gradle File path to Gradle Project Name
46
+ */
47
+ const gradleFileToGradleProjectMap = new Map();
48
+ /**
49
+ * Map of Gradle Project Name to Gradle File
50
+ */
51
+ const gradleProjectToGradleFileMap = new Map();
52
+ const dependenciesMap = new Map();
53
+ /**
54
+ * Map of Gradle Build File to tasks type map
55
+ */
56
+ const gradleProjectToTasksTypeMap = new Map();
57
+ const gradleProjectToProjectName = new Map();
58
+ /**
59
+ * Map of buildFile to dependencies report path
60
+ */
61
+ const buildFileToDepsMap = new Map();
62
+ /**
63
+ * Map fo possible output files of each gradle file
64
+ * e.g. {build.gradle.kts: { projectReportDir: '' testReportDir: '' }}
65
+ */
66
+ const gradleFileToOutputDirsMap = new Map();
67
+ let index = 0;
68
+ while (index < projectReportLines.length) {
69
+ const line = projectReportLines[index].trim();
70
+ if (line.startsWith('> Task ')) {
71
+ if (line.endsWith(':dependencyReport')) {
72
+ const gradleProject = line.substring('> Task '.length, line.length - ':dependencyReport'.length);
73
+ while (index < projectReportLines.length &&
74
+ !projectReportLines[index].includes(exports.fileSeparator)) {
75
+ index++;
76
+ }
77
+ const [_, file] = projectReportLines[index].split(exports.fileSeparator);
78
+ dependenciesMap.set(gradleProject, file);
79
+ }
80
+ if (line.endsWith('propertyReport')) {
81
+ const gradleProject = line.substring('> Task '.length, line.length - ':propertyReport'.length);
82
+ while (index < projectReportLines.length &&
83
+ !projectReportLines[index].includes(exports.fileSeparator)) {
84
+ index++;
85
+ }
86
+ const [_, file] = projectReportLines[index].split(exports.fileSeparator);
87
+ const propertyReportLines = (0, node_fs_1.existsSync)(file)
88
+ ? (0, node_fs_1.readFileSync)(file).toString().split(exports.newLineSeparator)
89
+ : [];
90
+ let projectName, absBuildFilePath, absBuildDirPath;
91
+ const outputDirMap = new Map();
92
+ for (const line of propertyReportLines) {
93
+ if (line.startsWith('name: ')) {
94
+ projectName = line.substring('name: '.length);
95
+ }
96
+ if (line.startsWith('buildFile: ')) {
97
+ absBuildFilePath = line.substring('buildFile: '.length);
98
+ }
99
+ if (line.startsWith('buildDir: ')) {
100
+ absBuildDirPath = line.substring('buildDir: '.length);
101
+ }
102
+ if (line.includes('Dir: ')) {
103
+ const [dirName, dirPath] = line.split(': ');
104
+ const taskName = dirName.replace('Dir', '');
105
+ outputDirMap.set(taskName, `{workspaceRoot}/${(0, node_path_1.relative)(devkit_1.workspaceRoot, dirPath)}`);
106
+ }
107
+ }
108
+ if (!projectName || !absBuildFilePath || !absBuildDirPath) {
109
+ continue;
110
+ }
111
+ const buildFile = (0, devkit_1.normalizePath)((0, node_path_1.relative)(devkit_1.workspaceRoot, absBuildFilePath));
112
+ const buildDir = (0, node_path_1.relative)(devkit_1.workspaceRoot, absBuildDirPath);
113
+ buildFileToDepsMap.set(buildFile, dependenciesMap.get(gradleProject));
114
+ outputDirMap.set('build', `{workspaceRoot}/${buildDir}`);
115
+ outputDirMap.set('classes', `{workspaceRoot}/${(0, node_path_1.join)(buildDir, 'classes')}`);
116
+ gradleFileToOutputDirsMap.set(buildFile, outputDirMap);
117
+ gradleFileToGradleProjectMap.set(buildFile, gradleProject);
118
+ gradleProjectToGradleFileMap.set(gradleProject, buildFile);
119
+ gradleProjectToProjectName.set(gradleProject, projectName);
120
+ }
121
+ if (line.endsWith('taskReport')) {
122
+ const gradleProject = line.substring('> Task '.length, line.length - ':taskReport'.length);
123
+ while (index < projectReportLines.length &&
124
+ !projectReportLines[index].includes(exports.fileSeparator)) {
125
+ index++;
126
+ }
127
+ const [_, file] = projectReportLines[index].split(exports.fileSeparator);
128
+ const taskTypeMap = new Map();
129
+ const tasksFileLines = (0, node_fs_1.existsSync)(file)
130
+ ? (0, node_fs_1.readFileSync)(file).toString().split(exports.newLineSeparator)
131
+ : [];
132
+ let i = 0;
133
+ while (i < tasksFileLines.length) {
134
+ const line = tasksFileLines[i];
135
+ if (line.endsWith('tasks')) {
136
+ const dashes = new Array(line.length + 1).join('-');
137
+ if (tasksFileLines[i + 1] === dashes) {
138
+ const type = line.substring(0, line.length - ' tasks'.length);
139
+ i++;
140
+ while (tasksFileLines[++i] !== '') {
141
+ const [taskName] = tasksFileLines[i].split(' - ');
142
+ taskTypeMap.set(taskName, type);
143
+ }
144
+ }
145
+ }
146
+ i++;
147
+ }
148
+ gradleProjectToTasksTypeMap.set(gradleProject, taskTypeMap);
149
+ }
150
+ }
151
+ index++;
152
+ }
153
+ return {
154
+ gradleFileToGradleProjectMap,
155
+ buildFileToDepsMap,
156
+ gradleFileToOutputDirsMap,
157
+ gradleProjectToTasksTypeMap,
158
+ gradleProjectToProjectName,
159
+ };
160
+ }
161
+ exports.processProjectReports = processProjectReports;
@@ -0,0 +1,2 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export declare function hasGradlePlugin(tree: Tree): boolean;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasGradlePlugin = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ function hasGradlePlugin(tree) {
6
+ const nxJson = (0, devkit_1.readNxJson)(tree);
7
+ return !!nxJson.plugins?.some((p) => typeof p === 'string' ? p === '@nx/gradle' : p.plugin === '@nx/gradle');
8
+ }
9
+ exports.hasGradlePlugin = hasGradlePlugin;
@@ -0,0 +1 @@
1
+ export declare const nxVersion: any;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nxVersion = void 0;
4
+ exports.nxVersion = require('../../package.json').version;