From 5cf5f5adbda7a06559459e234314f6a907c90ef7 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 18 Oct 2022 09:18:19 -0500 Subject: [PATCH] HHH-15558 - Hibernate's Gradle plugin does not work with three-part source set names --- .../tooling/gradle/HibernateOrmPlugin.java | 45 ++--- .../orm/tooling/gradle/HibernateOrmSpec.java | 21 +++ .../orm/tooling/gradle/JavaProjectTests.java | 144 +++------------- .../tooling/gradle/KotlinProjectTests.java | 146 ++++------------ .../tooling/gradle/MultiPartNameTests.java | 53 ++++++ .../orm/tooling/gradle/TestHelper.java | 12 -- .../orm/tooling/gradle/TestsBase.java | 160 ++++++++++++++++++ .../multi-part-source-set-name/build.gradle | 49 ++++++ .../settings.gradle | 0 .../java/TheEmbeddable.java | 29 ++++ .../mySpecialSourceSet/java/TheEntity.java | 88 ++++++++++ .../projects/simple-kotlin/build.gradle | 4 +- .../src/main/kotlin/TheEmbeddable.kt | 13 ++ .../src/main/kotlin/TheEntity.kt | 19 ++- .../resources/projects/simple/build.gradle | 5 +- 15 files changed, 514 insertions(+), 274 deletions(-) create mode 100644 tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/MultiPartNameTests.java create mode 100644 tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/TestsBase.java create mode 100644 tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/build.gradle create mode 100644 tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/settings.gradle create mode 100644 tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/src/mySpecialSourceSet/java/TheEmbeddable.java create mode 100644 tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/src/mySpecialSourceSet/java/TheEntity.java create mode 100644 tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/src/main/kotlin/TheEmbeddable.kt diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java index cf52ee3f42..4edb22c26a 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java @@ -6,6 +6,8 @@ */ package org.hibernate.orm.tooling.gradle; +import java.util.Set; + import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Project; @@ -22,7 +24,6 @@ import org.gradle.api.tasks.compile.JavaCompile; import org.hibernate.orm.tooling.gradle.enhance.EnhancementHelper; import org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask; -import static org.hibernate.orm.tooling.gradle.Helper.determineCompileSourceSetName; import static org.hibernate.orm.tooling.gradle.HibernateOrmSpec.HIBERNATE; import static org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask.COMPILE_META_TASK_NAME; import static org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask.GEN_TASK_NAME; @@ -60,28 +61,30 @@ public class HibernateOrmPlugin implements Plugin { return; } - graph.getAllTasks().forEach( (task) -> { - if ( task instanceof AbstractCompile ) { - final SourceSet sourceSetLocal = ormDsl.getSourceSet().get(); + final SourceSet sourceSet = ormDsl.getSourceSet().get(); + final Set languages = ormDsl.getLanguages().getOrNull(); + if ( languages == null ) { + return; + } - final String compiledSourceSetName = determineCompileSourceSetName( task.getName() ); - if ( !sourceSetLocal.getName().equals( compiledSourceSetName ) ) { - return; - } - - final AbstractCompile compileTask = (AbstractCompile) task; - //noinspection Convert2Lambda,NullableProblems - task.doLast( new Action<>() { - @Override - public void execute(Task t) { - final DirectoryProperty classesDirectory = compileTask.getDestinationDirectory(); - final ClassLoader classLoader = Helper.toClassLoader( sourceSetLocal.getOutput().getClassesDirs() ); - - EnhancementHelper.enhance( classesDirectory, classLoader, ormDsl, project ); - } - } ); + for ( String language : languages ) { + final String languageCompileTaskName = sourceSet.getCompileTaskName( language ); + final AbstractCompile languageCompileTask = (AbstractCompile) project.getTasks().findByName( languageCompileTaskName ); + if ( languageCompileTask == null ) { + continue; } - } ); + + //noinspection Convert2Lambda + languageCompileTask.doLast( new Action<>() { + @Override + public void execute(Task t) { + final DirectoryProperty classesDirectory = languageCompileTask.getDestinationDirectory(); + final ClassLoader classLoader = Helper.toClassLoader( sourceSet.getOutput().getClassesDirs() ); + + EnhancementHelper.enhance( classesDirectory, classLoader, ormDsl, project ); + } + } ); + } } ); } diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmSpec.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmSpec.java index f235a9c8d1..76034d23ec 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmSpec.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmSpec.java @@ -6,6 +6,7 @@ */ package org.hibernate.orm.tooling.gradle; +import java.util.Arrays; import javax.inject.Inject; import org.gradle.api.Action; @@ -15,6 +16,7 @@ import org.gradle.api.plugins.ExtensionContainer; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; +import org.gradle.api.provider.SetProperty; import org.gradle.api.tasks.SourceSet; import org.hibernate.orm.tooling.gradle.enhance.EnhancementSpec; @@ -35,6 +37,7 @@ public abstract class HibernateOrmSpec implements ExtensionAware { private final Property useSameVersion; private final Property sourceSet; + private final SetProperty languages; private final Provider enhancementDslAccess; private final Provider jpaMetamodelDslAccess; @@ -50,6 +53,9 @@ public abstract class HibernateOrmSpec implements ExtensionAware { sourceSet = project.getObjects().property( SourceSet.class ); sourceSet.convention( mainSourceSet( project ) ); + languages = project.getObjects().setProperty( String.class ); + languages.convention( Arrays.asList( "java", "kotlin" ) ); + enhancementDslAccess = project.provider( () -> enhancementDsl ); jpaMetamodelDslAccess = project.provider( () -> jpaMetamodelDsl ); } @@ -125,6 +131,21 @@ public abstract class HibernateOrmSpec implements ExtensionAware { setSourceSet( sourceSet ); } + /** + * The languages used in the project + */ + public SetProperty getLanguages() { + return languages; + } + + public void setLanguages(Iterable languages) { + this.languages.set( languages ); + } + + public void languages(String language) { + this.languages.add( language ); + } + /** * DSL extension for configuring bytecode enhancement. Also acts as the trigger for * opting into bytecode enhancement diff --git a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/JavaProjectTests.java b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/JavaProjectTests.java index 16b07d2c46..fe60357c17 100644 --- a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/JavaProjectTests.java +++ b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/JavaProjectTests.java @@ -6,147 +6,59 @@ */ package org.hibernate.orm.tooling.gradle; -import java.io.File; import java.nio.file.Path; -import org.gradle.testkit.runner.BuildResult; -import org.gradle.testkit.runner.BuildTask; -import org.gradle.testkit.runner.GradleRunner; -import org.gradle.testkit.runner.TaskOutcome; - import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - /** * Basic functional tests * * @author Steve Ebersole */ -class JavaProjectTests { +class JavaProjectTests extends TestsBase { + + @Override + protected String getProjectName() { + return "simple"; + } + + @Override + protected String getSourceSetName() { + return "main"; + } + + @Override + protected String getLanguageName() { + return "java"; + } + + @Override + protected String getCompileTaskName() { + return "compileJava"; + } @Test + @Override public void testEnhancement(@TempDir Path projectDir) throws Exception { - Copier.copyProject( "simple/build.gradle", projectDir ); - - System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "clean", "compileJava", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":compileJava" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); - - // make sure the class is enhanced - final File classesDir = new File( projectDir.toFile(), "build/classes/java/main" ); - final ClassLoader classLoader = Helper.toClassLoader( classesDir ); - TestHelper.verifyEnhanced( classLoader, "TheEmbeddable" ); - TestHelper.verifyEnhanced( classLoader, "TheEntity" ); + super.testEnhancement( projectDir ); } @Test + @Override public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception { - Copier.copyProject( "simple/build.gradle", projectDir ); - - { - System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "clean", "compileJava", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":compileJava" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); - - // make sure the class is enhanced - final File classesDir = new File( projectDir.toFile(), "build/classes/java/main" ); - final ClassLoader classLoader = Helper.toClassLoader( classesDir ); - TestHelper.verifyEnhanced( classLoader, "TheEntity" ); - } - - { - System.out.println( "Second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "compileJava", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":compileJava" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE ); - - // and again - final File classesDir = new File( projectDir.toFile(), "build/classes/java/main" ); - final ClassLoader classLoader = Helper.toClassLoader( classesDir ); - TestHelper.verifyEnhanced( classLoader, "TheEntity" ); - } + super.testEnhancementUpToDate( projectDir ); } @Test + @Override public void testJpaMetamodelGen(@TempDir Path projectDir) { - Copier.copyProject( "simple/build.gradle", projectDir ); - - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":generateJpaMetamodel" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); - assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists(); + super.testJpaMetamodelGen( projectDir ); } @Test public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) { - Copier.copyProject( "simple/build.gradle", projectDir ); - - { - System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":generateJpaMetamodel" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); - assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists(); - } - - { - System.out.println( "Second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - final GradleRunner gradleRunner2 = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result2 = gradleRunner2.build(); - final BuildTask task2 = result2.task( ":generateJpaMetamodel" ); - assertThat( task2 ).isNotNull(); - assertThat( task2.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE ); - assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists(); - } + super.testJpaMetamodelGenUpToDate( projectDir ); } } diff --git a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/KotlinProjectTests.java b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/KotlinProjectTests.java index 4574c529a3..1d04398495 100644 --- a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/KotlinProjectTests.java +++ b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/KotlinProjectTests.java @@ -6,145 +6,57 @@ */ package org.hibernate.orm.tooling.gradle; -import java.io.File; import java.nio.file.Path; -import org.gradle.testkit.runner.BuildResult; -import org.gradle.testkit.runner.BuildTask; -import org.gradle.testkit.runner.GradleRunner; -import org.gradle.testkit.runner.TaskOutcome; - import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.hibernate.orm.tooling.gradle.TestHelper.verifyEnhanced; - /** * @author Steve Ebersole */ -public class KotlinProjectTests { +public class KotlinProjectTests extends TestsBase { - @Test - public void testEnhanceModel(@TempDir Path projectDir) throws Exception { - Copier.copyProject( "simple-kotlin/build.gradle", projectDir ); + @Override + protected String getProjectName() { + return "simple-kotlin"; + } - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "clean", "compileKotlin", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); + @Override + protected String getSourceSetName() { + return "main"; + } - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":compileKotlin" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); + @Override + protected String getLanguageName() { + return "kotlin"; + } - // make sure the class is enhanced - final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" ); - final ClassLoader classLoader = Helper.toClassLoader( classesDir ); - verifyEnhanced( classLoader, "TheEntity" ); + @Override + protected String getCompileTaskName() { + return "compileKotlin"; } @Test - public void testEnhanceModelUpToDate(@TempDir Path projectDir) throws Exception { - Copier.copyProject( "simple-kotlin/build.gradle", projectDir ); - - { - System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "clean", "compileKotlin", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":compileKotlin" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); - - // make sure the class is enhanced - final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" ); - final ClassLoader classLoader = Helper.toClassLoader( classesDir ); - verifyEnhanced( classLoader, "TheEntity" ); - } - { - System.out.println( "Second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "compileKotlin", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":compileKotlin" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE ); - - // make sure the class is enhanced - final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" ); - final ClassLoader classLoader = Helper.toClassLoader( classesDir ); - verifyEnhanced( classLoader, "TheEntity" ); - } + @Override + public void testEnhancement(@TempDir Path projectDir) throws Exception { + super.testEnhancement( projectDir ); } @Test + @Override + public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception { + super.testEnhancementUpToDate( projectDir ); + } + + @Test + @Override public void testJpaMetamodelGen(@TempDir Path projectDir) { - Copier.copyProject( "simple-kotlin/build.gradle", projectDir ); - - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":generateJpaMetamodel" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); - assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists(); + super.testJpaMetamodelGen( projectDir ); } @Test + @Override public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) { - Copier.copyProject( "simple-kotlin/build.gradle", projectDir ); - - { - System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":generateJpaMetamodel" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); - assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists(); - } - - { - System.out.println( "Second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - final GradleRunner gradleRunner2 = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result2 = gradleRunner2.build(); - final BuildTask task2 = result2.task( ":generateJpaMetamodel" ); - assertThat( task2 ).isNotNull(); - assertThat( task2.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE ); - assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists(); - } + super.testJpaMetamodelGenUpToDate( projectDir ); } } diff --git a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/MultiPartNameTests.java b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/MultiPartNameTests.java new file mode 100644 index 0000000000..94a912ba21 --- /dev/null +++ b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/MultiPartNameTests.java @@ -0,0 +1,53 @@ +package org.hibernate.orm.tooling.gradle; + +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +/** + * @author Steve Ebersole + */ +public class MultiPartNameTests extends TestsBase { + + @Override + protected String getProjectName() { + return "multi-part-source-set-name"; + } + + @Override + protected String getSourceSetName() { + return "mySpecialSourceSet"; + } + + @Override + protected String getLanguageName() { + return "java"; + } + + @Override + protected String getCompileTaskName() { + return "compileMySpecialSourceSetJava"; + } + + @Test + @Override + public void testEnhancement(@TempDir Path projectDir) throws Exception { + super.testEnhancement( projectDir ); + } + + @Test + public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception { + super.testEnhancementUpToDate( projectDir ); + } + + @Test + public void testJpaMetamodelGen(@TempDir Path projectDir) { + super.testJpaMetamodelGen( projectDir ); + } + + @Test + public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) { + super.testJpaMetamodelGenUpToDate( projectDir ); + } +} diff --git a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/TestHelper.java b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/TestHelper.java index 093767e83e..ef6fecb953 100644 --- a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/TestHelper.java +++ b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/TestHelper.java @@ -6,26 +6,14 @@ */ package org.hibernate.orm.tooling.gradle; -import org.gradle.testkit.runner.TaskOutcome; - import org.hibernate.engine.spi.Managed; -import org.assertj.core.api.Condition; - import static org.assertj.core.api.AssertionsForClassTypes.assertThat; /** * @author Steve Ebersole */ public class TestHelper { - private static final Condition SUCCESS = new Condition<>( - (taskOutcome) -> taskOutcome == TaskOutcome.SUCCESS, - "task succeeded" - ); - private static final Condition UP_TO_DATE = new Condition<>( - (taskOutcome) -> taskOutcome == TaskOutcome.UP_TO_DATE, - "task up-to-date" - ); public static void verifyEnhanced(ClassLoader classLoader, String className) throws Exception { final Class loadedClass = classLoader.loadClass( className ); diff --git a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/TestsBase.java b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/TestsBase.java new file mode 100644 index 0000000000..43fd5d0408 --- /dev/null +++ b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/TestsBase.java @@ -0,0 +1,160 @@ +package org.hibernate.orm.tooling.gradle; + +import java.io.File; +import java.nio.file.Path; + +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.BuildTask; +import org.gradle.testkit.runner.GradleRunner; +import org.gradle.testkit.runner.TaskOutcome; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +/** + * @author Steve Ebersole + */ +public abstract class TestsBase { + protected abstract String getProjectName(); + protected abstract String getSourceSetName(); + protected abstract String getLanguageName(); + protected abstract String getCompileTaskName(); + + public void testEnhancement(Path projectDir) throws Exception { + final String buildFilePath = getProjectName() + "/build.gradle"; + final String sourceSetName = getSourceSetName(); + final String compileTaskName = getCompileTaskName(); + + final File classesDir = new File( projectDir.toFile(), "build/classes/" + getLanguageName() + "/" + sourceSetName ); + + Copier.copyProject( buildFilePath, projectDir ); + + System.out.println( "Starting execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); + final GradleRunner gradleRunner = GradleRunner.create() + .withProjectDir( projectDir.toFile() ) + .withPluginClasspath() + .withDebug( true ) + .withArguments( "clean", compileTaskName, "--stacktrace", "--no-build-cache" ) + .forwardOutput(); + + final BuildResult result = gradleRunner.build(); + final BuildTask task = result.task( ":" + compileTaskName ); + assertThat( task ).isNotNull(); + assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); + + // make sure the class is enhanced + final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + TestHelper.verifyEnhanced( classLoader, "TheEmbeddable" ); + TestHelper.verifyEnhanced( classLoader, "TheEntity" ); + } + + @Test + public void testEnhancementUpToDate(Path projectDir) throws Exception { + final String buildFilePath = getProjectName() + "/build.gradle"; + final String sourceSetName = getSourceSetName(); + final String compileTaskName = getCompileTaskName(); + + final File classesDir = new File( projectDir.toFile(), "build/classes/" + getLanguageName() + "/" + sourceSetName ); + + Copier.copyProject( buildFilePath, projectDir ); + + { + System.out.println( "Starting first execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); + final GradleRunner gradleRunner = GradleRunner.create() + .withProjectDir( projectDir.toFile() ) + .withPluginClasspath() + .withDebug( true ) + .withArguments( "clean", compileTaskName, "--stacktrace", "--no-build-cache" ) + .forwardOutput(); + + final BuildResult result = gradleRunner.build(); + final BuildTask task = result.task( ":" + compileTaskName ); + assertThat( task ).isNotNull(); + assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); + + // make sure the class is enhanced + final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + TestHelper.verifyEnhanced( classLoader, "TheEntity" ); + } + + { + System.out.println( "Starting second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); + final GradleRunner gradleRunner = GradleRunner.create() + .withProjectDir( projectDir.toFile() ) + .withPluginClasspath() + .withDebug( true ) + .withArguments( compileTaskName, "--stacktrace", "--no-build-cache" ) + .forwardOutput(); + final BuildResult result = gradleRunner.build(); + final BuildTask task = result.task( ":" + compileTaskName ); + assertThat( task ).isNotNull(); + assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE ); + + // and again + final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + TestHelper.verifyEnhanced( classLoader, "TheEntity" ); + } + } + + @Test + public void testJpaMetamodelGen(@TempDir Path projectDir) { + final String buildFilePath = getProjectName() + "/build.gradle"; + Copier.copyProject( buildFilePath, projectDir ); + + System.out.println( "Starting execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); + + final GradleRunner gradleRunner = GradleRunner.create() + .withProjectDir( projectDir.toFile() ) + .withPluginClasspath() + .withDebug( true ) + .withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) + .forwardOutput(); + + final BuildResult result = gradleRunner.build(); + final BuildTask task = result.task( ":generateJpaMetamodel" ); + assertThat( task ).isNotNull(); + assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); + assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists(); + } + + @Test + public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) { + final String buildFilePath = getProjectName() + "/build.gradle"; + Copier.copyProject( buildFilePath, projectDir ); + + { + System.out.println( "Starting first execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); + final GradleRunner gradleRunner = GradleRunner.create() + .withProjectDir( projectDir.toFile() ) + .withPluginClasspath() + .withDebug( true ) + .withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) + .forwardOutput(); + + final BuildResult result = gradleRunner.build(); + final BuildTask task = result.task( ":generateJpaMetamodel" ); + assertThat( task ).isNotNull(); + assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); + assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists(); + } + + { + System.out.println( "Starting second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); + final GradleRunner gradleRunner2 = GradleRunner.create() + .withProjectDir( projectDir.toFile() ) + .withPluginClasspath() + .withDebug( true ) + .withArguments( "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) + .forwardOutput(); + + final BuildResult result2 = gradleRunner2.build(); + final BuildTask task2 = result2.task( ":generateJpaMetamodel" ); + assertThat( task2 ).isNotNull(); + assertThat( task2.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE ); + assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists(); + } + } + +} diff --git a/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/build.gradle b/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/build.gradle new file mode 100644 index 0000000000..67e0058d29 --- /dev/null +++ b/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/build.gradle @@ -0,0 +1,49 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ + +plugins { + id 'java' + id 'org.hibernate.orm' +} + +repositories { + mavenCentral() + + maven { + name 'jboss-snapshots-repository' + url 'https://repository.jboss.org/nexus/content/repositories/snapshots' + } +} + +dependencies { + // NOTE : The version used here is irrelevant in terms of testing the plugin. + // We just need a resolvable version + implementation 'org.hibernate.orm:hibernate-core:6.1.0.Final' +} + +sourceSets { + mySpecialSourceSet { + java { + srcDirs "src/mySpecialSourceSet/java" + } + } +} + +hibernate { + useSameVersion = false + sourceSet = 'mySpecialSourceSet' + enhancement { + lazyInitialization( true ) + dirtyTracking = true + } + jpaMetamodel { + } +} + +tasks.withType(JavaCompile).forEach { + logger.lifecycle " - compile task : " + it.name +} diff --git a/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/settings.gradle b/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/settings.gradle new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/src/mySpecialSourceSet/java/TheEmbeddable.java b/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/src/mySpecialSourceSet/java/TheEmbeddable.java new file mode 100644 index 0000000000..25b8849aac --- /dev/null +++ b/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/src/mySpecialSourceSet/java/TheEmbeddable.java @@ -0,0 +1,29 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +import jakarta.persistence.Embeddable; + +@Embeddable +public class TheEmbeddable { + private String valueOne; + private String valueTwo; + + public String getValueOne() { + return valueOne; + } + + public void setValueOne(String valueOne) { + this.valueOne = valueOne; + } + + public String getValueTwo() { + return valueTwo; + } + + public void setValueTwo(String valueTwo) { + this.valueTwo = valueTwo; + } +} diff --git a/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/src/mySpecialSourceSet/java/TheEntity.java b/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/src/mySpecialSourceSet/java/TheEntity.java new file mode 100644 index 0000000000..b5d9eb5eea --- /dev/null +++ b/tooling/hibernate-gradle-plugin/src/test/resources/projects/multi-part-source-set-name/src/mySpecialSourceSet/java/TheEntity.java @@ -0,0 +1,88 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; + +import org.hibernate.annotations.BatchSize; + +import java.util.Set; + +@Entity +@BatchSize( size = 20 ) +public class TheEntity { + @Id + private Integer id; + private String name; + + @Embedded + private TheEmbeddable theEmbeddable; + + @ManyToOne + @JoinColumn + private TheEntity theManyToOne; + + @OneToMany( mappedBy = "theManyToOne" ) + private Set theOneToMany; + + @ElementCollection + @JoinColumn( name = "owner_id" ) + private Set theEmbeddableCollection; + + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public TheEmbeddable getTheEmbeddable() { + return theEmbeddable; + } + + public void setTheEmbeddable(TheEmbeddable theEmbeddable) { + this.theEmbeddable = theEmbeddable; + } + + public TheEntity getTheManyToOne() { + return theManyToOne; + } + + public void setTheManyToOne(TheEntity theManyToOne) { + this.theManyToOne = theManyToOne; + } + + public Set getTheOneToMany() { + return theOneToMany; + } + + public void setTheOneToMany(Set theOneToMany) { + this.theOneToMany = theOneToMany; + } + + public Set getTheEmbeddableCollection() { + return theEmbeddableCollection; + } + + public void setTheEmbeddableCollection(Set theEmbeddableCollection) { + this.theEmbeddableCollection = theEmbeddableCollection; + } +} diff --git a/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/build.gradle b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/build.gradle index 7e19c6dfe7..d4a5fd6308 100644 --- a/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/build.gradle +++ b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/build.gradle @@ -20,12 +20,12 @@ repositories { } dependencies { + // NOTE : The version used here is irrelevant in terms of testing the plugin. + // We just need a resolvable version implementation 'org.hibernate.orm:hibernate-core:6.1.0.Final' } hibernate { - // to get using the same version to work, we'd have to install hibernate-core into maven local prior to running these. - // suck we won't be able to adequately test this part, but useSameVersion = false enhancement { lazyInitialization( true ) diff --git a/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/src/main/kotlin/TheEmbeddable.kt b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/src/main/kotlin/TheEmbeddable.kt new file mode 100644 index 0000000000..f664f3116b --- /dev/null +++ b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/src/main/kotlin/TheEmbeddable.kt @@ -0,0 +1,13 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +import jakarta.persistence.Embeddable; + +@Embeddable +class TheEmbeddable { + var valueOne: String? = null + var valueTwo: String? = null +} diff --git a/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/src/main/kotlin/TheEntity.kt b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/src/main/kotlin/TheEntity.kt index 1a5d539003..959fad018f 100644 --- a/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/src/main/kotlin/TheEntity.kt +++ b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple-kotlin/src/main/kotlin/TheEntity.kt @@ -1,5 +1,4 @@ -import jakarta.persistence.Entity; -import jakarta.persistence.Id; +import jakarta.persistence.* import org.hibernate.annotations.BatchSize @Entity @@ -8,4 +7,18 @@ class TheEntity ( @Id var id: Long? = null, var name: String? = null, -) \ No newline at end of file + + @Embedded + var theEmbeddable: TheEmbeddable? = null, + + @ManyToOne + @JoinColumn + val theManyToOne: TheEntity? = null, + + @OneToMany(mappedBy = "theManyToOne") + val theOneToMany: Set? = null, + + @ElementCollection + @JoinColumn(name = "owner_id") + val theEmbeddableCollection: Set? = null +) diff --git a/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple/build.gradle b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple/build.gradle index 20bc5d3281..c5886befc6 100644 --- a/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple/build.gradle +++ b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple/build.gradle @@ -20,13 +20,12 @@ repositories { } dependencies { - implementation 'jakarta.persistence:jakarta.persistence-api:3.0.0' + // NOTE : The version used here is irrelevant in terms of testing the plugin. + // We just need a resolvable version implementation 'org.hibernate.orm:hibernate-core:6.1.0.Final' } hibernate { - // to get using the same version to work, we'd have to install hibernate-core into maven local prior to running these. - // suck we won't be able to adequately test this part, but useSameVersion = false enhancement { lazyInitialization( true )