Skip to content

Commit

Permalink
feat(gradle): add batch mode
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongemi committed Mar 7, 2025
1 parent 442f301 commit 0cee615
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 45 deletions.
17 changes: 17 additions & 0 deletions docs/generated/manifests/menus.json
Original file line number Diff line number Diff line change
Expand Up @@ -8128,6 +8128,23 @@
"isExternal": false,
"disableCollapsible": false
},
{
"id": "executors",
"path": "/nx-api/gradle/executors",
"name": "executors",
"children": [
{
"id": "gradlew",
"path": "/nx-api/gradle/executors/gradlew",
"name": "gradlew",
"children": [],
"isExternal": false,
"disableCollapsible": false
}
],
"isExternal": false,
"disableCollapsible": false
},
{
"id": "generators",
"path": "/nx-api/gradle/generators",
Expand Down
12 changes: 11 additions & 1 deletion docs/generated/manifests/nx-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -2294,7 +2294,17 @@
},
"root": "/packages/gradle",
"source": "/packages/gradle/src",
"executors": {},
"executors": {
"/nx-api/gradle/executors/gradlew": {
"description": "gradlew.impl executor",
"file": "generated/packages/gradle/executors/gradlew.json",
"hidden": false,
"name": "gradlew",
"originalFilePath": "/packages/gradle/src/executors/gradlew/schema.json",
"path": "/nx-api/gradle/executors/gradlew",
"type": "executor"
}
},
"generators": {
"/nx-api/gradle/generators/init": {
"description": "Initializes a Gradle project in the current workspace",
Expand Down
12 changes: 11 additions & 1 deletion docs/generated/packages-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2278,7 +2278,17 @@
"originalFilePath": "shared/packages/gradle/gradle-plugin"
}
],
"executors": [],
"executors": [
{
"description": "gradlew.impl executor",
"file": "generated/packages/gradle/executors/gradlew.json",
"hidden": false,
"name": "gradlew",
"originalFilePath": "/packages/gradle/src/executors/gradlew/schema.json",
"path": "gradle/executors/gradlew",
"type": "executor"
}
],
"generators": [
{
"description": "Initializes a Gradle project in the current workspace",
Expand Down
20 changes: 20 additions & 0 deletions docs/generated/packages/gradle/executors/gradlew.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "gradlew",
"batchImplementation": "./src/executors/gradlew/gradlew.impl#batchGradlew",
"implementation": "/packages/gradle/src/executors/gradlew/gradlew.impl.ts",
"schema": {
"$schema": "https://json-schema.org/schema",
"version": 2,
"title": "GradlewImpl executor",
"description": "The GradlewImpl executor is used to run Gradle tasks.",
"type": "object",
"properties": {},
"required": [],
"presets": []
},
"description": "gradlew.impl executor",
"aliases": [],
"hidden": false,
"path": "/packages/gradle/src/executors/gradlew/schema.json",
"type": "executor"
}
2 changes: 2 additions & 0 deletions docs/shared/reference/sitemap.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,8 @@
- [gradle](/nx-api/gradle)
- [documents](/nx-api/gradle/documents)
- [Overview](/nx-api/gradle/documents/overview)
- [executors](/nx-api/gradle/executors)
- [gradlew](/nx-api/gradle/executors/gradlew)
- [generators](/nx-api/gradle/generators)
- [init](/nx-api/gradle/generators/init)
- [ci-workflow](/nx-api/gradle/generators/ci-workflow)
Expand Down
7 changes: 6 additions & 1 deletion packages/gradle/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@
}
},
{
"files": ["./package.json"],
"files": [
"./package.json",
"./generators.json",
"./executors.json",
"./migrations.json"
],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/nx-plugin-checks": "error"
Expand Down
10 changes: 10 additions & 0 deletions packages/gradle/executors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"executors": {
"gradlew": {
"batchImplementation": "./src/executors/gradlew/gradlew.impl#batchGradlew",
"implementation": "./src/executors/gradlew/gradlew.impl",
"schema": "./src/executors/gradlew/schema.json",
"description": "gradlew.impl executor"
}
}
}
3 changes: 2 additions & 1 deletion packages/gradle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
},
"publishConfig": {
"access": "public"
}
},
"executors": "./executors.json"
}
4 changes: 2 additions & 2 deletions packages/gradle/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/gradle/src",
"projectType": "library",
"tags": [],
"targets": {
"nx-release-publish": {
"dependsOn": ["^nx-release-publish"],
Expand Down Expand Up @@ -62,6 +63,5 @@
"command": "node ./scripts/copy-readme.js gradle"
}
}
},
"tags": []
}
}
67 changes: 67 additions & 0 deletions packages/gradle/src/executors/gradlew/gradlew.impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { ExecutorContext, TaskGraph } from '@nx/devkit';
import runCommandsImpl, {
RunCommandsOptions,
} from 'nx/src/executors/run-commands/run-commands.impl';
import { BatchResults } from 'nx/src/tasks-runner/batch/batch-messages';

const MAX_PROJECTS_IN_BATCH = 10;

export async function graldewExecutor(
options: RunCommandsOptions,
context: ExecutorContext
): Promise<{ success: boolean }> {
const results = await runCommandsImpl(options, context);
return { success: results.success };
}

export default graldewExecutor;

export async function batchGradlew(
taskGraph: TaskGraph,
inputs: Record<string, RunCommandsOptions>,
overrides: RunCommandsOptions,
context: ExecutorContext
): Promise<BatchResults> {
const regex = /[./\\]*gradlew[\w.-]*/;

let gradlewCommand: string | undefined;
const roots = taskGraph.roots.slice(0, MAX_PROJECTS_IN_BATCH);
const tasksRan = [];
const results: BatchResults = {};

const gradlewTasks = roots.flatMap((task) => {
const gradlewTask = inputs[task].command;
if (typeof gradlewTask !== 'string') return [];

const match = gradlewTask.match(regex);
if (!match) return [];
results[task] = { success: false, terminalOutput: '' };

tasksRan.push(task);

gradlewCommand = match[0]; // Store the first found gradlewCommand
return gradlewTask.replace(gradlewCommand, '').trim();
});

const startTime = Date.now();
const { success, terminalOutput } = await runCommandsImpl(
{
command: `${gradlewCommand} ${gradlewTasks.join(' ')} --parallel`,
__unparsed__: [],
...(overrides ?? {}),
},
context
);
const endTime = Date.now();

tasksRan.forEach((task) => {
results[task] = {
success,
terminalOutput,
startTime,
endTime,
};
});

return results;
}
9 changes: 9 additions & 0 deletions packages/gradle/src/executors/gradlew/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://json-schema.org/schema",
"version": 2,
"title": "GradlewImpl executor",
"description": "The GradlewImpl executor is used to run Gradle tasks.",
"type": "object",
"properties": {},
"required": []
}
Original file line number Diff line number Diff line change
Expand Up @@ -1668,13 +1668,6 @@ exports[`create ci targets replaceTargetNameWithOptions should replace test in d
"gradle",
],
},
"options": {
"__unparsed__": [],
"args": [
"--exclude-task",
"test",
],
},
"parallelism": false,
},
"test-ci--LinkedList2Test": {
Expand All @@ -1698,13 +1691,6 @@ exports[`create ci targets replaceTargetNameWithOptions should replace test in d
"gradle",
],
},
"options": {
"__unparsed__": [],
"args": [
"--exclude-task",
"test",
],
},
"outputs": [
"{projectRoot}/build/test-results/test/binary",
"{projectRoot}/build/reports/tests/test",
Expand Down Expand Up @@ -1733,13 +1719,6 @@ exports[`create ci targets replaceTargetNameWithOptions should replace test in d
"gradle",
],
},
"options": {
"__unparsed__": [],
"args": [
"--exclude-task",
"test",
],
},
"outputs": [
"{projectRoot}/build/test-results/test/binary",
"{projectRoot}/build/reports/tests/test",
Expand Down
57 changes: 39 additions & 18 deletions packages/gradle/src/plugin/utils/create-ci-targets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,7 @@ export function replaceTargetNameWithOptions(
// rename target name if it is provided
Object.entries(targets).forEach(([taskName, target]) => {
let targetName = options?.[`${taskName}TargetName`] as string;
if (taskName.startsWith('ci')) {
if (options.ciTargetName) {
targetName = taskName.replace('ci', options.ciTargetName);
targetsWithReplacedName[targetName] = target;
if (targetName === options.ciTargetName) {
target.metadata.nonAtomizedTarget = options.testTargetName;
target.dependsOn.forEach((dep) => {
if (typeof dep !== 'string' && dep.target.startsWith('ci')) {
dep.target = dep.target.replace('ci', options.ciTargetName);
}
});
}
}
} else if (targetName) {
targetsWithReplacedName[targetName] = target;
} else {
targetsWithReplacedName[taskName] = target;
}

// if is it CI, replace target test with ci in dependsOn and exclude test in each command
if (
isCI() &&
Expand Down Expand Up @@ -68,6 +51,44 @@ export function replaceTargetNameWithOptions(
target.options.args = ['--exclude-task', 'test'];
}
}

// change executor to gradlew if it is batch mode
if (
process.env.NX_BATCH_MODE === 'true' &&
target.command?.includes('gradlew')
) {
target = {
executor: '@nx/gradle:gradlew',
options: {
...target,
__unparsed__: [],
},
dependsOn: [...(target.dependsOn ?? [])],
metadata: { ...target.metadata },
inputs: target.inputs,
outputs: target.outputs,
cache: true,
};
}

if (taskName.startsWith('ci')) {
if (options.ciTargetName) {
targetName = taskName.replace('ci', options.ciTargetName);
targetsWithReplacedName[targetName] = target;
if (targetName === options.ciTargetName) {
target.metadata.nonAtomizedTarget = options.testTargetName;
target.dependsOn.forEach((dep) => {
if (typeof dep !== 'string' && dep.target.startsWith('ci')) {
dep.target = dep.target.replace('ci', options.ciTargetName);
}
});
}
}
} else if (targetName) {
targetsWithReplacedName[targetName] = target;
} else {
targetsWithReplacedName[taskName] = target;
}
});
return targetsWithReplacedName;
}
Expand Down

0 comments on commit 0cee615

Please sign in to comment.