Skip to content

Commit

Permalink
feat(gradle): add gradle kotlin plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongemi committed Mar 5, 2025
1 parent 2c0b5d3 commit ce11848
Show file tree
Hide file tree
Showing 74 changed files with 6,372 additions and 1,109 deletions.
File renamed without changes.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,7 @@ target
/wasi-sdk*

vite.config.*.timestamp*

# Ignore Gradle project-specific cache directory
.gradle
.kotlin
24 changes: 24 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
plugins {
id("dev.nx.gradle.native") version("+")
}

group = "dev.nx.gradle"

allprojects {
apply {
plugin("project-report")
plugin("dev.nx.gradle.native")
}
}

tasks.register("projectReportAll") {
// All project reports of subprojects
allprojects.forEach {
dependsOn(it.tasks.get("projectReport"))
}

// All projectReportAll of included builds
gradle.includedBuilds.forEach {
dependsOn(it.task(":projectReportAll"))
}
}
2 changes: 0 additions & 2 deletions e2e/gradle/gradle/libs.versions.toml

This file was deleted.

117 changes: 117 additions & 0 deletions e2e/gradle/src/gradle-plugin-v1.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import {
checkFilesExist,
cleanupProject,
createFile,
newProject,
runCLI,
uniq,
updateFile,
updateJson,
} from '@nx/e2e/utils';

import { createGradleProject } from './utils/create-gradle-project';
import { updateProjectFiles } from 'nx/src/utils/workspace-context';

describe('Gradle Plugin V1', () => {
describe.each([{ type: 'kotlin' }, { type: 'groovy' }])(
'$type',
({ type }: { type: 'kotlin' | 'groovy' }) => {
let gradleProjectName = uniq('my-gradle-project');
beforeAll(() => {
newProject();
createGradleProject(gradleProjectName, type);
runCLI(`add @nx/gradle`);
updateJson('nx.json', (json) => {
json.plugins.find((p) => p.plugin === '@nx/gradle').plugin =
'@nx/gradle-plugin-v1';
return json;
});
});
afterAll(() => cleanupProject());

it('should build', () => {
const projects = runCLI(`show projects`);
expect(projects).toContain('app');
expect(projects).toContain('list');
expect(projects).toContain('utilities');
expect(projects).toContain(gradleProjectName);

const buildOutput = runCLI('build app', { verbose: true });
expect(buildOutput).toContain('nx run list:');
expect(buildOutput).toContain(':list:classes');
expect(buildOutput).toContain('nx run utilities:');
expect(buildOutput).toContain(':utilities:classes');

checkFilesExist(
`app/build/libs/app.jar`,
`list/build/libs/list.jar`,
`utilities/build/libs/utilities.jar`
);
});

it('should track dependencies for new app', () => {
if (type === 'groovy') {
createFile(
`app2/build.gradle`,
`plugins {
id 'buildlogic.groovy-application-conventions'
}
dependencies {
implementation project(':app')
}`
);
} else {
createFile(
`app2/build.gradle.kts`,
`plugins {
id("buildlogic.kotlin-application-conventions")
}
dependencies {
implementation(project(":app"))
}`
);
updateFile(`app/build.gradle.kts`, (content) => {
content += `\r\ntasks.register("task1"){
println("REGISTER TASK1: This is executed during the configuration phase")
}`;
return content;
});
}
updateFile(
`settings.gradle${type === 'kotlin' ? '.kts' : ''}`,
(content) => {
content += `\r\ninclude("app2")`;
return content;
}
);

let buildOutput = runCLI('build app2', { verbose: true });
// app2 depends on app
expect(buildOutput).toContain('nx run app:');
expect(buildOutput).toContain(':app:classes');
expect(buildOutput).toContain('nx run list:');
expect(buildOutput).toContain(':list:classes');
expect(buildOutput).toContain('nx run utilities:');
expect(buildOutput).toContain(':utilities:classes');

checkFilesExist(`app2/build/libs/app2.jar`);
});

it('should run atomized test target', () => {
updateJson('nx.json', (json) => {
json.plugins.find((p) => p.plugin === '@nx/gradle').options[
'ciTargetName'
] = 'test-ci';
return json;
});

expect(() => {
runCLI('run app:test-ci--MessageUtilsTest', { verbose: true });
runCLI('run list:test-ci--LinkedListTest', { verbose: true });
}).not.toThrow();
});
}
);
});
27 changes: 24 additions & 3 deletions e2e/gradle/src/gradle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
runCLI,
uniq,
updateFile,
updateJson,
} from '@nx/e2e/utils';

import { createGradleProject } from './utils/create-gradle-project';
Expand All @@ -30,9 +31,9 @@ describe('Gradle', () => {
expect(projects).toContain(gradleProjectName);

const buildOutput = runCLI('build app', { verbose: true });
expect(buildOutput).toContain('nx run list:build');
expect(buildOutput).toContain('nx run list:');
expect(buildOutput).toContain(':list:classes');
expect(buildOutput).toContain('nx run utilities:build');
expect(buildOutput).toContain('nx run utilities:');
expect(buildOutput).toContain(':utilities:classes');

checkFilesExist(
Expand Down Expand Up @@ -82,8 +83,28 @@ dependencies {

let buildOutput = runCLI('build app2', { verbose: true });
// app2 depends on app
expect(buildOutput).toContain('nx run app:build');
expect(buildOutput).toContain('nx run app:');
expect(buildOutput).toContain(':app:classes');
expect(buildOutput).toContain('nx run list:');
expect(buildOutput).toContain(':list:classes');
expect(buildOutput).toContain('nx run utilities:');
expect(buildOutput).toContain(':utilities:classes');

checkFilesExist(`app2/build/libs/app2.jar`);
});

it('should run atomized test target', () => {
updateJson('nx.json', (json) => {
json.plugins.find((p) => p.plugin === '@nx/gradle').options[
'ciTargetName'
] = 'test-ci';
return json;
});

expect(() => {
runCLI('run app:test-ci--MessageUtilsTest', { verbose: true });
runCLI('run list:test-ci--LinkedListTest', { verbose: true });
}).not.toThrow();
});
}
);
Expand Down
41 changes: 33 additions & 8 deletions e2e/gradle/src/utils/create-gradle-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
tmpProjPath,
} from '@nx/e2e/utils';
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
import { createFileSync, writeFileSync } from 'fs-extra';
import { join, resolve } from 'path';

Expand All @@ -15,14 +16,10 @@ export function createGradleProject(
packageName: string = 'gradleProject',
addProjectJsonNamePrefix: string = ''
) {
e2eConsoleLogger(
`Using java version: ${execSync('java -version')} ${execSync(
'echo $JAVA_HOME'
)}`
);
e2eConsoleLogger(`Using java version: ${execSync('java -version')}`);
const gradleCommand = isWindows()
? resolve(`${__dirname}/../../gradlew.bat`)
: resolve(`${__dirname}/../../gradlew`);
? resolve(`${__dirname}/../../../../gradlew.bat`)
: resolve(`${__dirname}/../../../../gradlew`);
e2eConsoleLogger(
'Using gradle version: ' +
execSync(`${gradleCommand} --version`, {
Expand All @@ -36,7 +33,7 @@ export function createGradleProject(
);
e2eConsoleLogger(
runCommand(
`${gradleCommand} init --type ${type}-application --dsl ${type} --project-name ${projectName} --package ${packageName} --no-incubating --split-project`,
`${gradleCommand} init --type ${type}-application --dsl ${type} --project-name ${projectName} --package ${packageName} --no-incubating --split-project --overwrite`,
{
cwd,
}
Expand All @@ -60,4 +57,32 @@ export function createGradleProject(
`{"name": "${addProjectJsonNamePrefix}utilities"}`
);
}

addLocalPluginManagement(
join(cwd, `settings.gradle${type === 'kotlin' ? '.kts' : ''}`)
);
addLocalPluginManagement(
join(cwd, `buildSrc/settings.gradle${type === 'kotlin' ? '.kts' : ''}`)
);

e2eConsoleLogger(
execSync(`${gradleCommand} publishToMavenLocal`, {
cwd: `${__dirname}/../../../../packages/gradle/native`,
}).toString()
);
}

function addLocalPluginManagement(filePath: string) {
let content = readFileSync(filePath).toString();
content =
`pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
mavenCentral()
// Add other repositories if needed
}
}
` + content;
writeFileSync(filePath, content);
}
11 changes: 11 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# This file was generated by the Gradle 'init' task.
# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format

[plugins]
jvm = { id = "org.jetbrains.kotlin.jvm", version = "1.9.20" }

[versions]
kotlin-gradle-plugin = "2.0.21"

[libraries]
kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-gradle-plugin" }
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
validateDistributionUrl=false
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
6 changes: 4 additions & 2 deletions e2e/gradle/gradlew → gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

##############################################################################
#
Expand Down Expand Up @@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
Expand Down Expand Up @@ -84,7 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down
22 changes: 12 additions & 10 deletions e2e/gradle/gradlew.bat → gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem

@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
Expand Down Expand Up @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

Expand All @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

Expand Down
3 changes: 3 additions & 0 deletions packages/gradle/native/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ignore Gradle project-specific cache directory
bin
build
Loading

0 comments on commit ce11848

Please sign in to comment.