Skip to content

Commit

Permalink
feat(gradle): gradle atomizer
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongemi committed Jun 13, 2024
1 parent c8c3ebd commit 3a64075
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 10 deletions.
80 changes: 70 additions & 10 deletions packages/gradle/src/plugin/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
CreateNodes,
CreateNodesV2,
CreateNodesContext,
CreateNodesContextV2,
ProjectConfiguration,
TargetConfiguration,
createNodesFromFiles,
Expand All @@ -24,6 +23,7 @@ import {
gradleConfigGlob,
} from '../utils/get-gradle-report';
import { hashObject } from 'nx/src/hasher/file-hasher';
import { getTestsForProject } from '../utils/get-tests-for-project';

const cacheableTaskType = new Set(['Build', 'Verification']);
const dependsOnMap = {
Expand Down Expand Up @@ -104,7 +104,7 @@ export const makeCreateNodes =
options ?? {},
context
);
targetsCache[hash] ??= createGradleProject(
targetsCache[hash] ??= await createGradleProject(
gradleReport,
gradleFilePath,
options,
Expand Down Expand Up @@ -138,7 +138,7 @@ export const createNodes: CreateNodes<GradlePluginOptions> = [
},
];

function createGradleProject(
async function createGradleProject(
gradleReport: GradleReport,
gradleFilePath: string,
options: GradlePluginOptions | undefined,
Expand Down Expand Up @@ -177,7 +177,7 @@ function createGradleProject(
string
>;

const { targets, targetGroups } = createGradleTargets(
const { targets, targetGroups } = await createGradleTargets(
tasks,
options,
context,
Expand All @@ -200,19 +200,19 @@ function createGradleProject(
}
}

function createGradleTargets(
async function createGradleTargets(
tasks: GradleTask[],
options: GradlePluginOptions | undefined,
context: CreateNodesContext,
outputDirs: Map<string, string>,
gradleProject: string
): {
): Promise<{
targetGroups: Record<string, string[]>;
targets: Record<string, TargetConfiguration>;
} {
}> {
const inputsMap = createInputsMap(context);

const targets: Record<string, TargetConfiguration> = {};
let targets: Record<string, TargetConfiguration> = {};
const targetGroups: Record<string, string[]> = {};
for (const task of tasks) {
const targetName = options?.[`${task.name}TargetName`] ?? task.name;
Expand All @@ -229,10 +229,22 @@ function createGradleTargets(
metadata: {
technologies: ['gradle'],
},
outputs: outputs ? [outputs] : undefined,
};

if (outputs) {
targets[targetName].outputs = [outputs];
if (task.name === 'test') {
const testTargets = await getTestTargets(
gradleProject,
targetName,
targetGroups,
inputsMap,
outputDirs,
task.type
);
if (testTargets) {
targets = { ...targets, ...testTargets };
continue;
}
}

if (!targetGroups[task.type]) {
Expand All @@ -243,6 +255,54 @@ function createGradleTargets(
return { targetGroups, targets };
}

async function getTestTargets(
gradleProject: string,
testTargetName: string,
targetGroups: Record<string, string[]>,
inputsMap: Record<string, TargetConfiguration['inputs']>,
outputDirs: Map<string, string>,
taskType: string
): Promise<Record<string, TargetConfiguration>> {
const tests: string[] | undefined = await getTestsForProject(gradleProject);
const taskCommandToRun = `${gradleProject ? gradleProject + ':' : ''}test`;

const targets: Record<string, TargetConfiguration> = {
[testTargetName]: {
command: `${getGradleExecFile()} ${taskCommandToRun}`,
cache: true,
inputs: inputsMap['test'],
dependsOn: dependsOnMap['test'],
metadata: {
technologies: ['gradle'],
},
outputs: [outputDirs.get('testReport'), outputDirs.get('testResults')],
},
};

if (!tests || tests.length === 0) {
targetGroups[taskType].push(testTargetName);
return targets;
}

const targetGroupName = 'Tests';
tests?.forEach((test) => {
const targetName = testTargetName + '--' + test;
targetGroups[targetGroupName].push(targetName);
targets[targetName] = {
command: `${getGradleExecFile()} ${taskCommandToRun} --tests ${test}`,
cache: true,
inputs: inputsMap['test'],
dependsOn: dependsOnMap['test'],
metadata: {
technologies: ['gradle'],
},
outputs: [outputDirs.get('testReport'), outputDirs.get('testResults')],
};
targetGroups;
});
return targets;
}

function createInputsMap(
context: CreateNodesContext
): Record<string, TargetConfiguration['inputs']> {
Expand Down
32 changes: 32 additions & 0 deletions packages/gradle/src/utils/get-tests-for-project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { execGradleAsync } from './exec-gradle';
import { newLineSeparator } from './get-gradle-report';

export async function getTestsForProject(
gradleProject: string
): Promise<string[] | undefined> {
try {
const task = `${gradleProject ? gradleProject + ':' : ''}test`;
const testLines = (
await execGradleAsync([task, `--info`, `--test-dry-run`, `--rerun`])
)
.toString()
.split(newLineSeparator)
.filter((line) => line.trim() !== '' && line.includes('SKIPPED'))
.map((line) => line.split('>')?.[0]?.trim())
.filter(Boolean);
const tests = new Set([]);
for (const line of testLines) {
try {
await execGradleAsync([
task,
`--test-dry-run`,
`--rerun`,
`--tests`,
line,
]);
tests.add(line);
} catch (e) {}
}
return Array.from(tests);
} catch (e) {}
}

0 comments on commit 3a64075

Please sign in to comment.