@nx/gradle 19.0.0-beta.0 → 19.0.0-beta.10

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/generators.json CHANGED
@@ -6,6 +6,11 @@
6
6
  "factory": "./src/generators/init/init#initGenerator",
7
7
  "schema": "./src/generators/init/schema.json",
8
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"
9
14
  }
10
15
  }
11
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/gradle",
3
- "version": "19.0.0-beta.0",
3
+ "version": "19.0.0-beta.10",
4
4
  "private": false,
5
5
  "description": "The Nx Plugin for Gradle allows Gradle tasks to be run through Nx",
6
6
  "repository": {
@@ -33,7 +33,7 @@
33
33
  "migrations": "./migrations.json"
34
34
  },
35
35
  "dependencies": {
36
- "@nx/devkit": "19.0.0-beta.0"
36
+ "@nx/devkit": "19.0.0-beta.10"
37
37
  },
38
38
  "publishConfig": {
39
39
  "access": "public"
@@ -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,40 @@
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
+ - run: git branch --track main origin/main
38
+ if: ${{ github.event_name == 'pull_request' }}
39
+ <% for (const command of commands) { %>
40
+ - 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,48 @@
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 nxJson = (0, devkit_1.readNxJson)(tree);
21
+ const nxCloudUsed = (0, nx_cloud_utils_1.isNxCloudUsed)(nxJson);
22
+ if (!nxCloudUsed) {
23
+ throw new Error('This workspace is not connected to Nx Cloud.');
24
+ }
25
+ const options = getTemplateData(schema, nxJson);
26
+ (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files', ci), '', options);
27
+ await (0, devkit_1.formatFiles)(tree);
28
+ }
29
+ exports.ciWorkflowGenerator = ciWorkflowGenerator;
30
+ function getTemplateData(options, nxJson) {
31
+ const { name: workflowName, fileName: workflowFileName } = (0, devkit_1.names)(options.name);
32
+ const packageManager = (0, devkit_1.detectPackageManager)();
33
+ const { exec: packageManagerPrefix } = (0, devkit_1.getPackageManagerCommand)(packageManager);
34
+ const nxCloudUrl = (0, nx_cloud_utils_1.getNxCloudUrl)(nxJson);
35
+ const nxCloudHost = new URL(nxCloudUrl).host;
36
+ const mainBranch = (0, default_base_1.deduceDefaultBase)();
37
+ const commands = options.commands ?? getCiCommands(options.ci, mainBranch);
38
+ return {
39
+ workflowName,
40
+ workflowFileName,
41
+ packageManager,
42
+ packageManagerPrefix,
43
+ commands,
44
+ mainBranch,
45
+ nxCloudHost,
46
+ };
47
+ }
48
+ 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
+ }
@@ -1,4 +1,4 @@
1
- import { CreateNodes, TargetConfiguration } from '@nx/devkit';
1
+ import { CreateNodes, ProjectConfiguration, TargetConfiguration } from '@nx/devkit';
2
2
  export interface GradlePluginOptions {
3
3
  testTargetName?: string;
4
4
  classesTargetName?: string;
@@ -8,11 +8,11 @@ export interface GradlePluginOptions {
8
8
  export declare const calculatedTargets: Record<string, {
9
9
  name: string;
10
10
  targets: Record<string, TargetConfiguration>;
11
- targetGroups: Record<string, string[]>;
11
+ metadata: ProjectConfiguration['metadata'];
12
12
  }>;
13
13
  export declare function writeTargetsToCache(targets: Record<string, {
14
14
  name: string;
15
15
  targets: Record<string, TargetConfiguration>;
16
- targetGroups: Record<string, string[]>;
16
+ metadata: ProjectConfiguration['metadata'];
17
17
  }>): void;
18
18
  export declare const createNodes: CreateNodes<GradlePluginOptions>;
@@ -33,12 +33,7 @@ exports.createNodes = [
33
33
  exports.calculatedTargets[hash] = targetsCache[hash];
34
34
  return {
35
35
  projects: {
36
- [projectRoot]: {
37
- ...targetsCache[hash],
38
- metadata: {
39
- technologies: ['gradle'],
40
- },
41
- },
36
+ [projectRoot]: targetsCache[hash],
42
37
  },
43
38
  };
44
39
  }
@@ -58,19 +53,16 @@ exports.createNodes = [
58
53
  });
59
54
  }
60
55
  const outputDirs = gradleFileToOutputDirsMap.get(gradleFilePath);
61
- const { targets, targetGroups } = createGradleTargets(tasks, projectRoot, options, context, outputDirs);
62
- exports.calculatedTargets[hash] = {
63
- name: projectName,
64
- targets,
65
- targetGroups,
66
- };
56
+ const { targets, targetGroups } = createGradleTargets(tasks, options, context, outputDirs, gradleProject);
67
57
  const project = {
68
58
  name: projectName,
69
59
  targets,
70
60
  metadata: {
61
+ targetGroups,
71
62
  technologies: ['gradle'],
72
63
  },
73
64
  };
65
+ exports.calculatedTargets[hash] = project;
74
66
  return {
75
67
  projects: {
76
68
  [projectRoot]: project,
@@ -83,7 +75,7 @@ exports.createNodes = [
83
75
  }
84
76
  },
85
77
  ];
86
- function createGradleTargets(tasks, projectRoot, options, context, outputDirs) {
78
+ function createGradleTargets(tasks, options, context, outputDirs, gradleProject) {
87
79
  const inputsMap = createInputsMap(context);
88
80
  const targets = {};
89
81
  const targetGroups = {};
@@ -91,14 +83,14 @@ function createGradleTargets(tasks, projectRoot, options, context, outputDirs) {
91
83
  const targetName = options?.[`${task.name}TargetName`] ?? task.name;
92
84
  const outputs = outputDirs.get(task.name);
93
85
  targets[targetName] = {
94
- command: `${(0, exec_gradle_1.getGradleBinaryPath)()} ${task.name}`,
95
- options: {
96
- cwd: projectRoot,
97
- },
86
+ command: `${(0, exec_gradle_1.getGradleExecFile)()} ${gradleProject ? gradleProject + ':' : ''}${task.name}`,
98
87
  cache: cacheableTaskType.has(task.type),
99
88
  inputs: inputsMap[task.name],
100
89
  outputs: outputs ? [outputs] : undefined,
101
90
  dependsOn: dependsOnMap[task.name],
91
+ metadata: {
92
+ technologies: ['gradle'],
93
+ },
102
94
  };
103
95
  if (!targetGroups[task.type]) {
104
96
  targetGroups[task.type] = [];
@@ -2,6 +2,7 @@
2
2
  /// <reference types="node" />
3
3
  import { ExecFileOptions } from 'child_process';
4
4
  import { ExecFileSyncOptionsWithBufferEncoding } from 'node:child_process';
5
- export declare function execGradle(args: string[], execOptions: ExecFileSyncOptionsWithBufferEncoding): Buffer;
5
+ export declare function execGradle(args: string[], execOptions?: ExecFileSyncOptionsWithBufferEncoding): Buffer;
6
6
  export declare function getGradleBinaryPath(): string;
7
- export declare function execGradleAsync(args: ReadonlyArray<string>, execOptions: ExecFileOptions): Promise<Buffer>;
7
+ export declare function getGradleExecFile(): string;
8
+ export declare function execGradleAsync(args: ReadonlyArray<string>, execOptions?: ExecFileOptions): Promise<Buffer>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.execGradleAsync = exports.getGradleBinaryPath = exports.execGradle = void 0;
3
+ exports.execGradleAsync = exports.getGradleExecFile = exports.getGradleBinaryPath = exports.execGradle = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const node_child_process_1 = require("node:child_process");
6
6
  const node_fs_1 = require("node:fs");
@@ -21,11 +21,12 @@ function getGradleBinaryPath() {
21
21
  return gradleBinaryPath;
22
22
  }
23
23
  exports.getGradleBinaryPath = getGradleBinaryPath;
24
+ function getGradleExecFile() {
25
+ return process.platform.startsWith('win') ? '.\\gradlew.bat' : './gradlew';
26
+ }
27
+ exports.getGradleExecFile = getGradleExecFile;
24
28
  function execGradleAsync(args, execOptions) {
25
29
  const gradleBinaryPath = getGradleBinaryPath();
26
- if (!(0, node_fs_1.existsSync)(gradleBinaryPath)) {
27
- throw new Error('Gradle is not setup. Run "gradle init"');
28
- }
29
30
  return new Promise((res, rej) => {
30
31
  const cp = (0, node_child_process_1.execFile)(gradleBinaryPath, args, execOptions);
31
32
  let stdout = Buffer.from('');
@@ -1,4 +1,5 @@
1
- interface GradleReport {
1
+ export declare const fileSeparator: string;
2
+ export interface GradleReport {
2
3
  gradleFileToGradleProjectMap: Map<string, string>;
3
4
  buildFileToDepsMap: Map<string, string>;
4
5
  gradleFileToOutputDirsMap: Map<string, Map<string, string>>;
@@ -7,4 +8,4 @@ interface GradleReport {
7
8
  }
8
9
  export declare function invalidateGradleReportCache(): void;
9
10
  export declare function getGradleReport(): GradleReport;
10
- export {};
11
+ export declare function processProjectReports(projectReportLines: string[]): GradleReport;
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getGradleReport = exports.invalidateGradleReportCache = void 0;
3
+ exports.processProjectReports = exports.getGradleReport = exports.invalidateGradleReportCache = exports.fileSeparator = void 0;
4
4
  const node_fs_1 = require("node:fs");
5
5
  const node_path_1 = require("node:path");
6
6
  const devkit_1 = require("@nx/devkit");
7
7
  const exec_gradle_1 = require("./exec-gradle");
8
- const fileSeparator = process.platform.startsWith('win')
8
+ exports.fileSeparator = process.platform.startsWith('win')
9
9
  ? 'file:///'
10
10
  : 'file://';
11
11
  const newLineSeparator = process.platform.startsWith('win') ? '\r\n' : '\n';
@@ -54,20 +54,29 @@ function processProjectReports(projectReportLines) {
54
54
  * e.g. {build.gradle.kts: { projectReportDir: '' testReportDir: '' }}
55
55
  */
56
56
  const gradleFileToOutputDirsMap = new Map();
57
- projectReportLines.forEach((line, index) => {
57
+ let index = 0;
58
+ while (index < projectReportLines.length) {
59
+ const line = projectReportLines[index].trim();
58
60
  if (line.startsWith('> Task ')) {
59
- const nextLine = projectReportLines[index + 1];
60
61
  if (line.endsWith(':dependencyReport')) {
61
62
  const gradleProject = line.substring('> Task '.length, line.length - ':dependencyReport'.length);
62
- const [_, file] = nextLine.split(fileSeparator);
63
+ while (index < projectReportLines.length &&
64
+ !projectReportLines[index].includes(exports.fileSeparator)) {
65
+ index++;
66
+ }
67
+ const [_, file] = projectReportLines[index].split(exports.fileSeparator);
63
68
  dependenciesMap.set(gradleProject, file);
64
69
  }
65
70
  if (line.endsWith('propertyReport')) {
66
71
  const gradleProject = line.substring('> Task '.length, line.length - ':propertyReport'.length);
67
- const [_, file] = nextLine.split(fileSeparator);
68
- const propertyReportLines = (0, node_fs_1.readFileSync)(file)
69
- .toString()
70
- .split(newLineSeparator);
72
+ while (index < projectReportLines.length &&
73
+ !projectReportLines[index].includes(exports.fileSeparator)) {
74
+ index++;
75
+ }
76
+ const [_, file] = projectReportLines[index].split(exports.fileSeparator);
77
+ const propertyReportLines = (0, node_fs_1.existsSync)(file)
78
+ ? (0, node_fs_1.readFileSync)(file).toString().split(newLineSeparator)
79
+ : [];
71
80
  let projectName, absBuildFilePath, absBuildDirPath;
72
81
  const outputDirMap = new Map();
73
82
  for (const line of propertyReportLines) {
@@ -87,7 +96,7 @@ function processProjectReports(projectReportLines) {
87
96
  }
88
97
  }
89
98
  if (!projectName || !absBuildFilePath || !absBuildDirPath) {
90
- return;
99
+ continue;
91
100
  }
92
101
  const buildFile = (0, devkit_1.normalizePath)((0, node_path_1.relative)(devkit_1.workspaceRoot, absBuildFilePath));
93
102
  const buildDir = (0, node_path_1.relative)(devkit_1.workspaceRoot, absBuildDirPath);
@@ -101,11 +110,15 @@ function processProjectReports(projectReportLines) {
101
110
  }
102
111
  if (line.endsWith('taskReport')) {
103
112
  const gradleProject = line.substring('> Task '.length, line.length - ':taskReport'.length);
104
- const [_, file] = nextLine.split(fileSeparator);
113
+ while (index < projectReportLines.length &&
114
+ !projectReportLines[index].includes(exports.fileSeparator)) {
115
+ index++;
116
+ }
117
+ const [_, file] = projectReportLines[index].split(exports.fileSeparator);
105
118
  const taskTypeMap = new Map();
106
- const tasksFileLines = (0, node_fs_1.readFileSync)(file)
107
- .toString()
108
- .split(newLineSeparator);
119
+ const tasksFileLines = (0, node_fs_1.existsSync)(file)
120
+ ? (0, node_fs_1.readFileSync)(file).toString().split(newLineSeparator)
121
+ : [];
109
122
  let i = 0;
110
123
  while (i < tasksFileLines.length) {
111
124
  const line = tasksFileLines[i];
@@ -125,7 +138,8 @@ function processProjectReports(projectReportLines) {
125
138
  gradleProjectToTasksTypeMap.set(gradleProject, taskTypeMap);
126
139
  }
127
140
  }
128
- });
141
+ index++;
142
+ }
129
143
  return {
130
144
  gradleFileToGradleProjectMap,
131
145
  buildFileToDepsMap,
@@ -134,3 +148,4 @@ function processProjectReports(projectReportLines) {
134
148
  gradleProjectToProjectName,
135
149
  };
136
150
  }
151
+ exports.processProjectReports = processProjectReports;