Skip to content

Commit

Permalink
add node-gradle generator/conventions plugin (#25594)
Browse files Browse the repository at this point in the history
add node-gradle generator/conventions plugin
  • Loading branch information
mshima authored Mar 22, 2024
1 parent 790a4b9 commit 9e94544
Show file tree
Hide file tree
Showing 16 changed files with 295 additions and 154 deletions.
12 changes: 12 additions & 0 deletions generators/base-application/support/task-type-inference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,20 @@
* limitations under the License.
*/
import CoreGenerator from '../../base-core/generator.js';
import { WriteFileSection, WriteFileBlock } from '../../base/api.js';
import { GeneratorDefinition } from '../generator.js';

export function asWriteFilesSection<Data = GeneratorDefinition['writingTaskParam']['application']>(
section: WriteFileSection<CoreGenerator, Data>,
) {
return section;
}
export function asWriteFilesBlock<Data = GeneratorDefinition['writingTaskParam']['application']>(
section: WriteFileBlock<CoreGenerator, Data>,
) {
return section;
}

export function asInitializingTask(task: (this: CoreGenerator, params: GeneratorDefinition['initializingTaskParam']) => void) {
return task;
}
Expand Down
36 changes: 25 additions & 11 deletions generators/gradle/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ import {
addGradlePluginCallback,
addGradlePluginManagementCallback,
addGradlePropertyCallback,
addGradleBuildSrcDependencyCallback,
addGradleDependenciesCatalogVersionCallback,
addGradleBuildSrcDependencyCatalogVersionCallback,
addGradleDependencyCatalogLibrariesCallback,
addGradleDependencyCatalogPluginsCallback,
addGradleDependencyFromCatalogCallback,
Expand Down Expand Up @@ -75,7 +73,11 @@ export default class GradleGenerator extends BaseApplicationGenerator {
async verify({ application }) {
assert.equal(application.buildTool, GRADLE);
},
addSourceNeddles({ source }) {
prepareConventionsPlugins({ application }) {
application.gradleBuildSrc = GRADLE_BUILD_SRC_DIR;
},
addSourceNeddles({ application, source }) {
const { gradleBuildSrc } = application;
source.applyFromGradle = script => this.editFile('build.gradle', applyFromGradleCallback(script));
source.addGradleDependencies = (dependencies, { gradleFile = 'build.gradle' } = {}) => {
dependencies = [...dependencies].sort(sortDependencies);
Expand All @@ -86,14 +88,15 @@ export default class GradleGenerator extends BaseApplicationGenerator {
source.addGradleMavenRepository = repository => this.editFile('build.gradle', addGradleMavenRepositoryCallback(repository));
source.addGradlePluginManagement = plugin => this.editFile('settings.gradle', addGradlePluginManagementCallback(plugin));
source.addGradleProperty = property => this.editFile('gradle.properties', addGradlePropertyCallback(property));
source.addGradleBuildSrcDependency = dependency =>
this.editFile(`${GRADLE_BUILD_SRC_DIR}/build.gradle`, addGradleBuildSrcDependencyCallback(dependency));
source.addGradleDependencyCatalogVersions = versions =>
this.editFile('gradle/libs.versions.toml', addGradleDependenciesCatalogVersionCallback(versions));
source.addGradleDependencyCatalogVersion = version => source.addGradleDependencyCatalogVersions!([version]);
source.addGradleDependencyCatalogLibraries = (libs, { gradleFile = 'build.gradle' } = {}) => {
source.addGradleDependencyCatalogVersions = (versions, { gradleVersionCatalogFile = 'gradle/libs.versions.toml' } = {}) =>
this.editFile(gradleVersionCatalogFile, addGradleDependenciesCatalogVersionCallback(versions));
source.addGradleDependencyCatalogVersion = (version, options) => source.addGradleDependencyCatalogVersions!([version], options);
source.addGradleDependencyCatalogLibraries = (
libs,
{ gradleFile = 'build.gradle', gradleVersionCatalogFile = 'gradle/libs.versions.toml' } = {},
) => {
libs = [...libs].sort((a, b) => a.libraryName.localeCompare(b.libraryName));
this.editFile('gradle/libs.versions.toml', addGradleDependencyCatalogLibrariesCallback(libs));
this.editFile(gradleVersionCatalogFile, addGradleDependencyCatalogLibrariesCallback(libs));
this.editFile(gradleFile, addGradleDependencyFromCatalogCallback(libs));
};
source.addGradleDependencyCatalogLibrary = (lib, options) => source.addGradleDependencyCatalogLibraries!([lib], options);
Expand All @@ -102,8 +105,19 @@ export default class GradleGenerator extends BaseApplicationGenerator {
this.editFile('build.gradle', addGradlePluginFromCatalogCallback(plugins));
};
source.addGradleDependencyCatalogPlugin = plugin => source.addGradleDependencyCatalogPlugins!([plugin]);

source.addGradleBuildSrcDependency = dependency =>
source.addGradleDependencies!([dependency], { gradleFile: `${gradleBuildSrc}/build.gradle` });
source.addGradleBuildSrcDependencyCatalogVersion = version =>
this.editFile(`${GRADLE_BUILD_SRC_DIR}/gradle/libs.versions.toml`, addGradleBuildSrcDependencyCatalogVersionCallback(version));
source.addGradleDependencyCatalogVersions!([version], {
gradleVersionCatalogFile: `${gradleBuildSrc}/gradle/libs.versions.toml`,
});
source.addGradleBuildSrcDependencyCatalogVersions = versions => source.addGradleDependencyCatalogVersions!(versions);
source.addGradleBuildSrcDependencyCatalogLibraries = libs =>
source.addGradleDependencyCatalogLibraries!(libs, {
gradleFile: `${gradleBuildSrc}/build.gradle`,
gradleVersionCatalogFile: `${gradleBuildSrc}/gradle/libs.versions.toml`,
});
},
});
}
Expand Down
72 changes: 72 additions & 0 deletions generators/gradle/generators/node-gradle/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Copyright 2013-2024 the original author or authors from the JHipster project.
*
* This file is part of the JHipster project, see https://www.jhipster.tech/
* for more information.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import BaseApplicationGenerator from '../../../base-application/index.js';
import { GRADLE_BUILD_SRC_MAIN_DIR } from '../../../generator-constants.js';
import { GENERATOR_GRADLE } from '../../../generator-list.js';

export default class NodeGradleGenerator extends BaseApplicationGenerator {
async beforeQueue() {
if (!this.fromBlueprint) {
await this.composeWithBlueprints();
}

if (!this.delegateToBlueprint) {
await this.dependsOnBootstrapAplication();
await this.dependsOnJHipster(GENERATOR_GRADLE);
}
}

get writing() {
return this.asWritingTaskGroup({
async writing({ application }) {
await this.writeFiles({
blocks: [{ templates: [`${GRADLE_BUILD_SRC_MAIN_DIR}/jhipster.node-gradle-conventions.gradle`] }],
context: application,
});
},
});
}

get [BaseApplicationGenerator.WRITING]() {
return this.delegateTasksToBlueprint(() => this.writing);
}

get postWriting() {
return this.asPostWritingTaskGroup({
customize({ application, source }) {
source.addGradlePlugin!({ id: 'jhipster.node-gradle-conventions' });
source.addGradleBuildSrcDependencyCatalogLibraries!([
{
libraryName: 'node-gradle',
module: 'com.github.node-gradle:gradle-node-plugin',
version: application.javaDependencies!['node-gradle'],
scope: 'implementation',
},
]);

source.addGradleProperty!({ property: 'nodeInstall', comment: 'Install and use a local version of node and npm.' });
},
});
}

get [BaseApplicationGenerator.POST_WRITING]() {
return this.delegateTasksToBlueprint(() => this.postWriting);
}
}
19 changes: 19 additions & 0 deletions generators/gradle/generators/node-gradle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright 2013-2024 the original author or authors from the JHipster project.
*
* This file is part of the JHipster project, see https://www.jhipster.tech/
* for more information.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { default } from './generator.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
plugins {
id "com.github.node-gradle.node"
}

if (project.hasProperty("nodeInstall")) {
node {
version = "<%= nodeVersion %>"
npmVersion = "<%= nodeDependencies.npm %>"
download = true
}

// Copy local node and npm to a fixed location for npmw
def deleteOldNpm = tasks.register("deleteOldNpm", Delete) {
delete '<%= temporaryDir %>node/lib/node_modules/npm'
}
def fixedNode = tasks.register("fixedNode", Copy) {
from nodeSetup
into '<%= temporaryDir %>node'
finalizedBy deleteOldNpm
}
tasks.named("nodeSetup").configure { finalizedBy fixedNode }

def fixedNpm = tasks.register("fixedNpm", Copy) {
from npmSetup
into '<%= temporaryDir %>node'
}
tasks.named("npmSetup").configure { finalizedBy fixedNpm }
}

<%_ if (!skipClient) { _%>
task webapp_test(type: NpmTask) {
inputs.property('appVersion', project.version)
inputs.files("package-lock.json")
.withPropertyName('package-lock')
.withPathSensitivity(PathSensitivity.RELATIVE)
inputs.files("build.gradle")
.withPropertyName('build.gradle')
.withPathSensitivity(PathSensitivity.RELATIVE)
<%_ if (clientFrameworkAngular) { _%>
inputs.files("angular.json")
.withPropertyName('angular.json')
.withPathSensitivity(PathSensitivity.RELATIVE)
inputs.files("tsconfig.json", "tsconfig.app.json")
.withPropertyName("tsconfig")
.withPathSensitivity(PathSensitivity.RELATIVE)
inputs.dir("<%= CLIENT_WEBPACK_DIR %>")
.withPropertyName("<%= CLIENT_WEBPACK_DIR %>")
.withPathSensitivity(PathSensitivity.RELATIVE)
<%_ } _%>
inputs.dir("<%= clientSrcDir %>")
.withPropertyName("webapp-source-dir")
.withPathSensitivity(PathSensitivity.RELATIVE)
<%_ if (clientFrameworkReact) { _%>
inputs.files("tsconfig.json")
.withPropertyName("tsconfig")
.withPathSensitivity(PathSensitivity.RELATIVE)
def webpackDevFiles = fileTree("<%= CLIENT_WEBPACK_DIR %>")
webpackDevFiles.exclude("webpack.prod.js")
inputs.files(webpackDevFiles)
.withPropertyName("webpack-dir")
.withPathSensitivity(PathSensitivity.RELATIVE)
<%_ } _%>
<%_ if (clientFrameworkVue) { _%>
inputs.files("tsconfig.json", "tsconfig.app.json")
.withPropertyName("tsconfig")
.withPathSensitivity(PathSensitivity.RELATIVE)
<%_ if (microfrontend) { _%>
def webpackDevFiles = fileTree("<%= CLIENT_WEBPACK_DIR %>")
webpackDevFiles.exclude("webpack.prod.js")
inputs.files(webpackDevFiles)
.withPropertyName("webpack-dir")
.withPathSensitivity(PathSensitivity.RELATIVE)
<%_ } else { _%>
inputs.files("vite.config.ts")
.withPropertyName("vite")
.withPathSensitivity(PathSensitivity.RELATIVE)
<%_ } _%>
inputs.files(".postcssrc")
.withPropertyName("postcssrc")
.withPathSensitivity(PathSensitivity.RELATIVE)
<%_ } _%>
outputs.dir("build/test-results/jest/")
.withPropertyName("jest-result-dir")
outputs.file("build/test-results/TESTS-results-jest.xml")
.withPropertyName("jest-result")
outputs.file("build/test-results/clover.xml")
.withPropertyName("clover-result")
dependsOn npmInstall,compileTestJava
args = ["run", "webapp:test"]
}
test.dependsOn webapp_test
<%_ } _%>
9 changes: 6 additions & 3 deletions generators/gradle/internal/needles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import type {
GradleTomlVersion,
GradleLibrary,
GradleTomlPlugin,
GradleComment,
} from '../types.js';

const tomlItemToString = (item: Record<string, string | undefined>) =>
Expand Down Expand Up @@ -78,6 +79,7 @@ export const addGradleDependenciesCallback = (dependencies: GradleDependency[])
),
});

/** @deprecated use addGradleDependenciesCallback */
export const addGradleBuildSrcDependencyCallback = ({ groupId, artifactId, version, scope }: GradleDependency) =>
createNeedleCallback({
needle: 'gradle-build-src-dependency',
Expand Down Expand Up @@ -126,6 +128,7 @@ export const addGradlePluginFromCatalogCallback = (plugins: GradleTomlPlugin[])
.map(({ pluginName }) => `alias(libs.plugins.${gradleNameToReference(pluginName)})`),
});

/** @deprecated use addGradleDependenciesCatalogVersionCallback */
export const addGradleBuildSrcDependencyCatalogVersionCallback = ({ name, version }: GradleTomlVersion) =>
createNeedleCallback({
needle: 'gradle-build-src-dependency-catalog-version',
Expand All @@ -144,11 +147,11 @@ export const addGradlePluginManagementCallback = ({ id, version }: GradlePlugin)
contentToAdd: `id "${id}" version "${version}"`,
});

export const addGradlePropertyCallback = ({ property, value }: GradleProperty) =>
export const addGradlePropertyCallback = ({ comment, property, value }: GradleProperty & GradleComment) =>
createNeedleCallback({
needle: 'gradle-property',
contentToAdd: `${property}=${value}`,
contentToCheck: new RegExp(`\n${property}=`),
contentToAdd: `${typeof comment === 'string' ? `## ${comment}\n` : ''}${property}${typeof value === 'string' ? `=${value}` : ''}`,
contentToCheck: new RegExp(`\n${property}${typeof value === 'string' ? '=' : '\n'}`),
autoIndent: false,
});

Expand Down
5 changes: 3 additions & 2 deletions generators/gradle/templates/buildSrc/build.gradle.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ repositories {
}

dependencies {
// jhipster-needle-gradle-build-src-dependency - JHipster will add additional dependencies for convention plugins here
}
// jhipster-needle-gradle-dependency - JHipster will add additional dependencies for convention plugins here
// jhipster-needle-gradle-build-src-dependency - Deprecated: JHipster will add additional dependencies for convention plugins here
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
[versions]
# jhipster-needle-gradle-build-src-dependency-catalog-version - JHipster will add additional versions for convention plugins here
# jhipster-needle-gradle-dependency-catalog-version - JHipster will add additional versions for convention plugins heref
# jhipster-needle-gradle-build-src-dependency-catalog-version - Deprecated: JHipster will add additional versions for convention plugins here

[libraries]
# jhipster-needle-gradle-dependency-catalog-libraries - JHipster will add additional libraries versions

[plugins]
# jhipster-needle-gradle-dependency-catalog-plugins - JHipster will add additional plugins versions
27 changes: 20 additions & 7 deletions generators/gradle/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { RequireOneOrNone } from 'type-fest';

export type GradleComment = { comment?: string };

export type GradleScript = { script: string };

export type GradleDependency = { groupId: string; artifactId: string; version?: string; scope: string; classifier?: string };

export type GradlePlugin = { id: string; version?: string };

export type GradleProperty = { property: string; value: string };
export type GradleProperty = { property: string; value?: string };

export type GradleRepository = { url: string; username?: string; password?: string };

Expand All @@ -26,22 +28,33 @@ export type GradleTomlPlugin = { pluginName: string; addToBuild?: boolean } & (
| ({ id: string } & GradleTomlAnyItemVersion)
);

export type GradleNeedleOptions = { gradleFile?: string };
export type GradleFileNeedleOptions = { gradleFile?: string };
export type GradleCatalogNeedleOptions = { gradleVersionCatalogFile?: string };

export type GradleNeedleOptions = GradleFileNeedleOptions & GradleCatalogNeedleOptions;

export type GradleSourceType = {
applyFromGradle?(script: GradleScript): void;
addGradleDependency?(dependency: GradleDependency, options?: GradleNeedleOptions): void;
addGradleDependencies?(dependency: GradleDependency[], options?: GradleNeedleOptions): void;
addGradleDependency?(dependency: GradleDependency, options?: GradleFileNeedleOptions): void;
addGradleDependencies?(dependency: GradleDependency[], options?: GradleFileNeedleOptions): void;
addGradlePlugin?(plugin: GradlePlugin): void;
addGradlePluginManagement?(pluginManagement: GradlePlugin): void;
addGradleProperty?(property: GradleProperty): void;
addGradleProperty?(property: GradleProperty & GradleComment): void;
addGradleMavenRepository?(repository: GradleRepository): void;
addGradleBuildSrcDependency?(dependency: GradleDependency): void;
addGradleDependencyCatalogVersion?(catalogVersion: GradleTomlVersion): void;
addGradleDependencyCatalogVersions?(catalogVersion: GradleTomlVersion[]): void;

addGradleDependencyCatalogVersion?(catalogVersion: GradleTomlVersion, options?: GradleCatalogNeedleOptions): void;
addGradleDependencyCatalogVersions?(catalogVersion: GradleTomlVersion[], options?: GradleCatalogNeedleOptions): void;
addGradleDependencyCatalogLibrary?(catalogVersion: GradleLibrary, options?: GradleNeedleOptions): void;
addGradleDependencyCatalogLibraries?(catalogVersion: GradleLibrary[], options?: GradleNeedleOptions): void;
addGradleDependencyCatalogPlugin?(catalogVersion: GradleTomlPlugin): void;
addGradleDependencyCatalogPlugins?(catalogVersion: GradleTomlPlugin[]): void;

addGradleBuildSrcDependencyCatalogVersion?(catalogVersion: GradleTomlVersion): void;
addGradleBuildSrcDependencyCatalogVersions?(catalogVersion: GradleTomlVersion[]): void;
addGradleBuildSrcDependencyCatalogLibraries?(catalogVersion: GradleLibrary[]): void;
};

export type GradleApplication = {
gradleBuildSrc?: string;
};
Loading

0 comments on commit 9e94544

Please sign in to comment.