Skip to content

Commit

Permalink
HHH-18644 - New and improved hibernate-maven-plugin
Browse files Browse the repository at this point in the history
Signed-off-by: Koen Aers <[email protected]>
  • Loading branch information
koentsje authored and sebersole committed Nov 19, 2024
1 parent 817355f commit 707c3a7
Show file tree
Hide file tree
Showing 17 changed files with 1,586 additions and 9 deletions.
1 change: 1 addition & 0 deletions local-build-plugins/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ dependencies {
implementation "org.apache.maven:maven-compat:3.9.9"
implementation "org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18"
implementation "org.apache.maven.resolver:maven-resolver-transport-http:1.9.18"
implementation "org.slf4j:slf4j-simple:1.7.36"
}

tasks.compileJava {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskProvider;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
* Plugin for integrating Maven Embedder into the Gradle build to execute
* some Maven tasks/goals/mojos.
Expand All @@ -29,23 +33,43 @@ public void apply(Project project) {
MavenEmbedderConfig.class
);

final Provider<Directory> workingDirectory = project.getLayout().getBuildDirectory().dir("maven-embedder/workspace");

// add the MavenEmbedderService shared-build-service
final Provider<MavenEmbedderService> embedderServiceProvider = sharedServices.registerIfAbsent(
"maven-embedder",
MavenEmbedderService.class, (spec) -> {
spec.getParameters().getProjectVersion().set( project.getVersion().toString() );
spec.getParameters().getWorkingDirectory().set( project.getLayout().getProjectDirectory() );
spec.getParameters().getWorkingDirectory().set( workingDirectory );
spec.getParameters().getMavenLocalDirectory().set( dsl.getLocalRepositoryDirectory() );
}
);

project.getTasks().register(
"installHibernateCore",
RunMavenTask.class,
(task) -> {
configureInstallHibernateCoreTask(
configureInstallTask( configureRunMavenTask( task, embedderServiceProvider ) ) );
});

project.getTasks().register(
"installHibernateScanJandex",
RunMavenTask.class,
(task) -> {
configureInstallHibernateScanJandexTask(
configureInstallTask( configureRunMavenTask( task, embedderServiceProvider ) ));
} );

// Via the plugin's POM, we tell Maven to generate the descriptors into
// `target/generated/sources/plugin-descriptors/META-INF/maven`.
// `META-INF/maven` is the relative path we need inside the jar, so we
// configure the "resource directory" in Gradle to be just the
// `target/generated/sources/plugin-descriptors` part.
final Provider<Directory> descriptorsDir = project.getLayout().getBuildDirectory().dir( "generated/sources/plugin-descriptors" );



// create the "mirror" task which calls the appropriate Maven tasks/goals/mojos behind the scenes using the embedder service
final TaskProvider<MavenPluginDescriptorTask> generatePluginDescriptorTask = project.getTasks().register( "generatePluginDescriptor", MavenPluginDescriptorTask.class, (task) -> {
task.setGroup( "maven embedder" );
Expand All @@ -61,11 +85,160 @@ public void apply(Project project) {
final SourceSet mainSourceSet = sourceSets.getByName( "main" );
mainSourceSet.getResources().srcDir( task.getDescriptorDirectory() );

// the hibernate-core jar needs to be present in the local repository
// we need compilation to happen before we generate the descriptors
task.dependsOn( "compileJava" );
task.dependsOn( "prepareWorkspace", "installHibernateCore", "installHibernateScanJandex");
} );

project.getTasks().register(
"createMavenWrapper",
RunMavenTask.class,
(task) -> {
configuraCreateMavenWrapperTask(
configureRunMavenTask( task, embedderServiceProvider ));
} );

project.getTasks().register(
"installHibernateMavenPlugin",
RunMavenTask.class,
(task) -> {
configureInstallHibernateMavenPluginTask(
configureInstallTask(
configureRunMavenTask( task, embedderServiceProvider )));
} );

project.getTasks().register(
"integrationTest",
RunMavenTask.class,
(task) -> {
configureIntegrationTestTask(
configureRunMavenTask( task, embedderServiceProvider ));
} );

// we need the descriptor generation to happen before we jar
project.getTasks().named( "jar", (jarTask) -> jarTask.dependsOn( generatePluginDescriptorTask ) );
project.getTasks().named( "check" , (checkTask) -> checkTask.dependsOn( "integrationTest", generatePluginDescriptorTask ) );
}

private void configureInstallHibernateMavenPluginTask(RunMavenTask task) {
List<String> arguments = new ArrayList<String>(task.getArguments().get());
arguments.add("-Dfile=" + getHibernateMavenPluginArtifactFilePath( task.getProject() ));
arguments.add("-DartifactId=hibernate-maven-plugin");
arguments.add( "-DpomFile=" + getHibernateMavenPluginPomFilePath( task.getProject() ) );
task.getArguments().set( arguments );
task.dependsOn("jar", "generatePluginDescriptor");
}

private void configureInstallHibernateCoreTask(RunMavenTask task) {
List<String> arguments = new ArrayList<String>(task.getArguments().get());
arguments.add("-Dfile=" + getHibernateCoreArtifactFilePath( task.getProject() ));
arguments.add("-DartifactId=hibernate-core");
arguments.add( "-DpomFile=" + getHibernateCorePomFilePath( task.getProject() ) );
task.getArguments().set( arguments );
task.dependsOn(":hibernate-core:generatePomFileForPublishedArtifactsPublication", ":hibernate-core:jar");
}

private void configureInstallHibernateScanJandexTask(RunMavenTask task) {
List<String> arguments = new ArrayList<String>(task.getArguments().get());
arguments.add("-Dfile=" + getHibernateScanJandexArtifactFilePath( task.getProject() ));
arguments.add("-DartifactId=hibernate-scan-jandex");
task.getArguments().set( arguments );
task.dependsOn(":hibernate-scan-jandex:jar");
}

private void configureIntegrationTestTask(RunMavenTask task) {
task.getGoals().set( "invoker:run" );
task.dependsOn("createMavenWrapper", "installHibernateMavenPlugin");
}

private void configuraCreateMavenWrapperTask(RunMavenTask task) {
task.getGoals().set("wrapper:wrapper");
task.getArguments().set( List.of("-f" + getIntegrationTestFolderPath( task.getProject() ) ));
task.dependsOn( "prepareWorkspace" );
}

private String getHibernateMavenPluginPomFilePath(Project project) {
return project
.getLayout()
.getBuildDirectory()
.file( "publications/publishedArtifacts/pom-default.xml")
.get()
.getAsFile()
.getAbsolutePath();
}

private String getHibernateMavenPluginArtifactFilePath(Project project) {
final String artifactName = "hibernate-maven-plugin-" + project.getVersion() + ".jar";
final File libsFolder = project.getLayout().getBuildDirectory().dir("libs" ).get().getAsFile();
return new File(libsFolder, artifactName).getAbsolutePath();
}

private RunMavenTask configureRunMavenTask(
RunMavenTask task,
Provider<MavenEmbedderService> embedderServiceProvider) {
task.setGroup( "maven embedder" );
task.getMavenEmbedderService().set( embedderServiceProvider );
task.usesService( embedderServiceProvider );
return task;
}

private Directory getWorkingDirectory(Project project) {
return project.getLayout().getBuildDirectory().dir("maven-embedder/workspace").get();
}

private String getIntegrationTestFolderPath(Project project) {
return getWorkingDirectory( project).dir( "src/it/enhance" ).getAsFile().getAbsolutePath();
}

private RunMavenTask configureInstallTask(RunMavenTask task) {
task.getGoals().set( "install:install-file" );
ArrayList<String> arguments = new ArrayList<String>();
arguments.add("-DgroupId=" + task.getProject().getGroup().toString());
arguments.add("-Dversion=" + task.getProject().getVersion());
arguments.add("-Dpackaging=jar");
task.getArguments().set( arguments );
return task;
}

private String getHibernateCoreArtifactFilePath(Project project) {
final String artifactName = "hibernate-core-" + project.getVersion() + ".jar";
final File hibernateCoreLibsFolder = getHibernateCoreBuildDirectory( project )
.dir( "libs" )
.getAsFile();
return new File(hibernateCoreLibsFolder, artifactName).getAbsolutePath();
}

private String getHibernateCorePomFilePath(Project project) {
return getHibernateCoreBuildDirectory( project )
.file( "publications/publishedArtifacts/pom-default.xml" )
.getAsFile()
.getAbsolutePath();
}

private String getHibernateScanJandexArtifactFilePath(Project project) {
final String artifactName = "hibernate-scan-jandex-" + project.getVersion() + ".jar";
final File hibernateScanJandexLibsFolder = getHibernateScanJandexBuildDirectory( project )
.dir( "libs" )
.getAsFile();
return new File(hibernateScanJandexLibsFolder, artifactName).getAbsolutePath();
}

private Directory getHibernateCoreBuildDirectory(Project project) {
return project
.getRootProject()
.project( "hibernate-core" )
.getLayout()
.getBuildDirectory()
.get();
}

private Directory getHibernateScanJandexBuildDirectory(Project project) {
return project
.getRootProject()
.project( "hibernate-scan-jandex" )
.getLayout()
.getBuildDirectory()
.get();
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.hibernate.build.maven.embedder;

import org.apache.maven.cli.MavenCli;
import org.gradle.api.GradleException;
import org.gradle.api.file.Directory;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.Property;
Expand Down Expand Up @@ -37,7 +38,7 @@ public void execute(String... tasksAndArgs) {
Collections.addAll( cml, tasksAndArgs );

final Directory mavenLocalDirectory = getParameters().getMavenLocalDirectory().get();
cml.add( "-Dmaven.repo.local=\"" + mavenLocalDirectory.getAsFile().getAbsolutePath() + "\"" );
cml.add( "-Dmaven.repo.local=" + mavenLocalDirectory.getAsFile().getAbsolutePath() );
cml.add( "-Dorm.project.version=" + getParameters().getProjectVersion().get() );

final Directory workingDirectory = getParameters().getWorkingDirectory().get();
Expand All @@ -46,6 +47,12 @@ public void execute(String... tasksAndArgs) {
// todo : consider bridging Maven out/err to Gradle logging

final int resultCode = embedder.doMain( cml.toArray(new String[0]), workingDirectoryPath, System.out, System.err );
// todo : do something with result-code
if (resultCode != 0) {
StringBuilder sb = new StringBuilder();
for (String s : tasksAndArgs) {
sb.append( s );
}
throw new GradleException("Maven execution has failed: " + sb);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ public MavenPluginDescriptorTask() {

@TaskAction
public void generateDescriptor() {
performDescriptorGeneration();
}

private void performDescriptorGeneration() {
getMavenEmbedderService().get().execute( "plugin:descriptor" );
// todo : anything else? e.g.
//getMavenEmbedderService().get().execute( "plugin:addPluginArtifactMetadata" );
//getMavenEmbedderService().get().execute( "plugin:helpmojo" );
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.hibernate.build.maven.embedder;

import org.gradle.api.DefaultTask;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.services.ServiceReference;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;

import java.util.ArrayList;
import java.util.List;

public abstract class RunMavenTask extends DefaultTask {

@ServiceReference
abstract Property<MavenEmbedderService> getMavenEmbedderService();

@Input
abstract Property<String> getGoals();

@Input
abstract ListProperty<String> getArguments();

@TaskAction
public void run() {
getMavenEmbedderService().get().execute( constructTaskAndArgs() );
}

private String[] constructTaskAndArgs() {
List<String> args = new ArrayList<String>();
args.add( getGoals().get() );
args.addAll( getArguments().get() );
return args.toArray(new String[0]);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.hibernate.build.maven.embedder.logging;

import org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.MavenSlf4jSimpleFriend;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Slf4jConfiguration extends Slf4jSimpleConfiguration {
@Override
public void activate() {
resetLoggerFactory();
initMavenSlf4jSimpleFriend();
}

private void resetLoggerFactory() {
try {
Method m = LoggerFactory.class.getDeclaredMethod("reset", new Class[]{});
m.setAccessible(true);
m.invoke(null);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}

private void initMavenSlf4jSimpleFriend() {
MavenSlf4jSimpleFriend.init();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.gradle.internal.logging.slf4j.OutputEventListenerBackedLoggerContext org.hibernate.build.maven.embedder.logging.Slf4jConfiguration
Loading

0 comments on commit 707c3a7

Please sign in to comment.