diff --git a/src/main/java/org/hibernate/search/develocity/GoalMetadataProvider.java b/src/main/java/org/hibernate/search/develocity/GoalMetadataProvider.java new file mode 100644 index 0000000..7b54d8b --- /dev/null +++ b/src/main/java/org/hibernate/search/develocity/GoalMetadataProvider.java @@ -0,0 +1,55 @@ +/* + * + * * Hibernate Search, full-text search for your domain model + * * + * * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * * See the lgpl.txt file in the root directory or . + * + */ +package org.hibernate.search.develocity; + +import org.hibernate.search.develocity.util.MavenMojoExecutionConfig; +import org.hibernate.search.develocity.util.MavenProperties; + +import com.gradle.maven.extension.api.cache.MojoMetadataProvider; +import com.gradle.maven.extension.api.scan.BuildScanApi; + +@FunctionalInterface +public interface GoalMetadataProvider { + void configure(Context context); + + class Context { + private final BuildScanApi buildScanApi; + private final MojoMetadataProvider.Context metadataContext; + private final MavenProperties properties; + private final MavenMojoExecutionConfig configuration; + + + public Context(BuildScanApi buildScanApi, MojoMetadataProvider.Context metadataContext) { + this.buildScanApi = buildScanApi; + this.metadataContext = metadataContext; + this.properties = new MavenProperties( metadataContext.getSession(), metadataContext.getMojoExecution() ); + this.configuration = new MavenMojoExecutionConfig( metadataContext.getMojoExecution() ); + } + + public BuildScanApi buildScan() { + return buildScanApi; + } + + public MojoMetadataProvider.Context metadata() { + return metadataContext; + } + + public MavenProperties properties() { + return properties; + } + + public MavenMojoExecutionConfig configuration() { + return configuration; + } + + public void buildScanDeduplicatedValue(String key, String value) { + buildScanApi.executeOnce( key + value, ignored -> buildScanApi.value( key, value ) ); + } + } +} diff --git a/src/main/java/org/hibernate/search/develocity/HibernateSearchProjectDevelocityListener.java b/src/main/java/org/hibernate/search/develocity/HibernateSearchProjectDevelocityListener.java index a606a2b..98845d3 100644 --- a/src/main/java/org/hibernate/search/develocity/HibernateSearchProjectDevelocityListener.java +++ b/src/main/java/org/hibernate/search/develocity/HibernateSearchProjectDevelocityListener.java @@ -26,10 +26,11 @@ public class HibernateSearchProjectDevelocityListener implements GradleEnterpris @Override - public void configure(GradleEnterpriseApi gradleEnterpriseApi, MavenSession mavenSession) throws Exception { + public void configure(GradleEnterpriseApi gradleEnterpriseApi, MavenSession mavenSession) { gradleEnterpriseApi.getBuildScan().publishAlways(); ((BuildScanApiInternal) gradleEnterpriseApi.getBuildScan()).publishIfAuthenticated(); - BuildScanMetadata.addMetadataToBuildScan(gradleEnterpriseApi.getBuildScan(), mavenSession); + + BuildScanMetadata.addMainMetadata(gradleEnterpriseApi.getBuildScan()); Normalization.configureNormalization(gradleEnterpriseApi.getBuildCache()); diff --git a/src/main/java/org/hibernate/search/develocity/SimpleConfiguredPlugin.java b/src/main/java/org/hibernate/search/develocity/SimpleConfiguredPlugin.java index 6f6c6f9..4fb8c85 100644 --- a/src/main/java/org/hibernate/search/develocity/SimpleConfiguredPlugin.java +++ b/src/main/java/org/hibernate/search/develocity/SimpleConfiguredPlugin.java @@ -5,13 +5,11 @@ import java.util.Map.Entry; import java.util.function.Function; +import org.hibernate.search.develocity.scan.BuildScanMetadata; import org.hibernate.search.develocity.util.JavaVersions; -import org.hibernate.search.develocity.util.MavenConfigs; import com.gradle.maven.extension.api.GradleEnterpriseApi; import com.gradle.maven.extension.api.cache.MojoMetadataProvider; -import com.gradle.maven.extension.api.cache.NormalizationProvider; -import com.gradle.maven.extension.api.scan.BuildScanApi; import org.apache.maven.execution.MavenSession; import org.apache.maven.project.MavenProject; @@ -27,16 +25,17 @@ public void configureBuildCache(GradleEnterpriseApi gradleEnterpriseApi, MavenSe return; } - Map goalMetadataProviders = Collections.unmodifiableMap(getGoalMetadataProviders(gradleEnterpriseApi.getBuildScan())); + Map goalMetadataProviders = Collections.unmodifiableMap(getGoalMetadataProviders()); Log.debug(getPluginName(), "Build cache is enabled. Configuring metadata providers."); Log.debug(getPluginName(), "Configuring metadata for goals: " + goalMetadataProviders.keySet()); - for (Entry goalMetadataProviderEntry : goalMetadataProviders.entrySet()) { - if (goalMetadataProviderEntry.getKey().equalsIgnoreCase(context.getMojoExecution().getGoal())) { - goalMetadataProviderEntry.getValue().configure(context); - } - } + for ( Entry goalMetadataProviderEntry : goalMetadataProviders.entrySet() ) { + if ( goalMetadataProviderEntry.getKey().equalsIgnoreCase( context.getMojoExecution().getGoal() ) ) { + goalMetadataProviderEntry.getValue() + .configure( new GoalMetadataProvider.Context( gradleEnterpriseApi.getBuildScan(), context ) ); + } + } }); }); } @@ -47,10 +46,11 @@ protected boolean isBuildCacheEnabled(MavenProject project) { return true; } - protected abstract Map getGoalMetadataProviders(BuildScanApi buildScanApi); + protected abstract Map getGoalMetadataProviders(); - protected static void dependsOnGav(MojoMetadataProvider.Context.Inputs inputs, MojoMetadataProvider.Context context) { - inputs.property("_internal_gav", context.getProject().getGroupId() + ":" + context.getProject().getArtifactId() + ":" + context.getProject().getVersion()); + protected static void dependsOnGav(MojoMetadataProvider.Context.Inputs inputs, GoalMetadataProvider.Context context) { + var project = context.metadata().getProject(); + inputs.property("_internal_gav", project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion()); } @@ -65,31 +65,24 @@ protected static void dependsOnMavenJavaVersion(MojoMetadataProvider.Context.Inp } protected static void dependsOnConfigurableJavaExecutable(MojoMetadataProvider.Context.Inputs inputs, - MojoMetadataProvider.Context context, String configChildName, + GoalMetadataProvider.Context context, String configChildName, Boolean skipped, Function executableToVersion) { - var configChild = context.getMojoExecution().getConfiguration().getChild( configChildName ); - String javaExecutable = configChild == null ? null : configChild.getValue(); + String javaExecutable = context.configuration().getString( configChildName ); String javaVersion = executableToVersion.apply( javaExecutable ); + boolean canCacheExactVersion = context.properties().cacheExactJavaVersion(); inputs.property( "_internal_" + configChildName + "_java_version", - MavenConfigs.cacheExactJavaVersion( context.getSession() ) + canCacheExactVersion ? javaVersion : JavaVersions.toJdkMajor( javaVersion, javaVersion ) ); - Log.info( - context.getMojoExecution().getPlugin().getArtifactId(), - "Using %s at path '%s'; resolved version: %s" - .formatted( configChildName, javaExecutable, javaVersion.replace( '\n', ' ' ).trim() ) - ); - } - - @FunctionalInterface - public interface PluginNormalizationProvider { - void configure(NormalizationProvider.Context context); + if ( skipped == null || !skipped ) { + BuildScanMetadata.addJavaExecutableVersion( context, javaExecutable, javaVersion, canCacheExactVersion ); + Log.info( + context.metadata().getMojoExecution().getPlugin().getArtifactId(), + "Using %s at path '%s'; resolved version: %s" + .formatted( configChildName, javaExecutable, javaVersion.replace( '\n', ' ' ).trim() ) + ); + } } - @FunctionalInterface - public interface GoalMetadataProvider { - - void configure(MojoMetadataProvider.Context context); - } } diff --git a/src/main/java/org/hibernate/search/develocity/plugins/CompilerConfiguredPlugin.java b/src/main/java/org/hibernate/search/develocity/plugins/CompilerConfiguredPlugin.java index 75ddeb9..e21eac7 100644 --- a/src/main/java/org/hibernate/search/develocity/plugins/CompilerConfiguredPlugin.java +++ b/src/main/java/org/hibernate/search/develocity/plugins/CompilerConfiguredPlugin.java @@ -2,12 +2,10 @@ import java.util.Map; +import org.hibernate.search.develocity.GoalMetadataProvider; import org.hibernate.search.develocity.SimpleConfiguredPlugin; import org.hibernate.search.develocity.util.JavaVersions; -import com.gradle.maven.extension.api.cache.MojoMetadataProvider; -import com.gradle.maven.extension.api.scan.BuildScanApi; - public class CompilerConfiguredPlugin extends SimpleConfiguredPlugin { @Override @@ -16,16 +14,19 @@ protected String getPluginName() { } @Override - protected Map getGoalMetadataProviders(BuildScanApi buildScanApi) { + protected Map getGoalMetadataProviders() { return Map.of( "compile", CompilerConfiguredPlugin::configureCompile, "testCompile", CompilerConfiguredPlugin::configureCompile ); } - private static void configureCompile(MojoMetadataProvider.Context context) { - context.inputs( inputs -> { - dependsOnConfigurableJavaExecutable( inputs, context, "executable", JavaVersions::forJavacExecutable ); + private static void configureCompile(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + metadata.inputs( inputs -> { + dependsOnConfigurableJavaExecutable( inputs, context, "executable", + context.configuration().getBoolean( "skip" ), + JavaVersions::forJavacExecutable ); } ); } } diff --git a/src/main/java/org/hibernate/search/develocity/plugins/EnforcerConfiguredPlugin.java b/src/main/java/org/hibernate/search/develocity/plugins/EnforcerConfiguredPlugin.java index 2ab25ca..2db0455 100644 --- a/src/main/java/org/hibernate/search/develocity/plugins/EnforcerConfiguredPlugin.java +++ b/src/main/java/org/hibernate/search/develocity/plugins/EnforcerConfiguredPlugin.java @@ -3,11 +3,9 @@ import java.util.Map; import java.util.stream.Collectors; +import org.hibernate.search.develocity.GoalMetadataProvider; import org.hibernate.search.develocity.SimpleConfiguredPlugin; -import com.gradle.maven.extension.api.cache.MojoMetadataProvider; -import com.gradle.maven.extension.api.scan.BuildScanApi; - public class EnforcerConfiguredPlugin extends SimpleConfiguredPlugin { @Override @@ -16,20 +14,21 @@ protected String getPluginName() { } @Override - protected Map getGoalMetadataProviders(BuildScanApi buildScanApi) { + protected Map getGoalMetadataProviders() { return Map.of( "enforce", EnforcerConfiguredPlugin::configureEnforce); } - private static void configureEnforce(MojoMetadataProvider.Context context) { - context.inputs(inputs -> { + private static void configureEnforce(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + metadata.inputs(inputs -> { dependsOnGav(inputs, context); inputs.properties("skip", "fail", "failFast", "failIfNoRules", "rules", "rulesToExecute", "rulesToSkip", "ignoreCache"); dependsOnOs(inputs); dependsOnMavenJavaVersion(inputs); - String dependencies = context.getProject().getArtifacts().stream() + String dependencies = metadata.getProject().getArtifacts().stream() .map(a -> a.getGroupId() + ":" + a.getArtifactId() + ":" + a.getVersion() + ":" + a.getClassifier()) .sorted() .collect(Collectors.joining("\n")); @@ -39,7 +38,7 @@ private static void configureEnforce(MojoMetadataProvider.Context context) { inputs.ignore("project", "mojoExecution", "session"); }); - context.outputs(outputs -> { + metadata.outputs(outputs -> { outputs.cacheable("If the inputs and dependencies are identical, we should have the same output"); }); } diff --git a/src/main/java/org/hibernate/search/develocity/plugins/FailsafeConfiguredPlugin.java b/src/main/java/org/hibernate/search/develocity/plugins/FailsafeConfiguredPlugin.java index 30920e1..0d34693 100644 --- a/src/main/java/org/hibernate/search/develocity/plugins/FailsafeConfiguredPlugin.java +++ b/src/main/java/org/hibernate/search/develocity/plugins/FailsafeConfiguredPlugin.java @@ -2,13 +2,10 @@ import java.util.Map; +import org.hibernate.search.develocity.GoalMetadataProvider; import org.hibernate.search.develocity.scan.BuildScanMetadata; -import org.hibernate.search.develocity.util.MavenConfigs; import com.gradle.maven.extension.api.cache.MojoMetadataProvider; -import com.gradle.maven.extension.api.scan.BuildScanApi; - -import org.apache.maven.plugin.MojoExecution; public class FailsafeConfiguredPlugin extends SurefireConfiguredPlugin { @@ -18,22 +15,22 @@ protected String getPluginName() { } @Override - protected Map getGoalMetadataProviders(BuildScanApi buildScanApi) { + protected Map getGoalMetadataProviders() { return Map.of( - "integration-test", context -> configureIntegrationTest( context, buildScanApi ) + "integration-test", this::configureIntegrationTest ); } - private static void configureIntegrationTest(MojoMetadataProvider.Context context, BuildScanApi buildScanApi) { + private void configureIntegrationTest(GoalMetadataProvider.Context context) { configureTest( context ); - context.inputs( inputs -> { + context.metadata().inputs( inputs -> { // We try to be smart about which container is used for the build scan, // because an error would be of little consequence there, // but here it could lead to missing important regressions. // So we just consider all Dockerfiles are used in all integration tests, // and invalidate all integration test caches as soon as one Dockerfile changes. - var containersPath = MavenConfigs.getFailsafeSystemProperty( context.getMojoExecution(), - "org.hibernate.search.integrationtest.container.directory" ); + var containersPath = context.configuration() + .getFailsafeSystemProperty( "org.hibernate.search.integrationtest.container.directory" ); if ( containersPath != null ) { inputs.fileSet( "containers", containersPath, fileSet -> { fileSet.normalizationStrategy( @@ -41,8 +38,8 @@ private static void configureIntegrationTest(MojoMetadataProvider.Context contex } ); } - var repackagedJarPath = MavenConfigs.getFailsafeSystemProperty( context.getMojoExecution(), - "test.repackaged-jar-path" ); + var repackagedJarPath = context.configuration() + .getFailsafeSystemProperty( "test.repackaged-jar-path" ); if ( repackagedJarPath != null ) { inputs.fileSet( "repackaged-jar", repackagedJarPath, fileSet -> { fileSet.normalizationStrategy( @@ -50,15 +47,22 @@ private static void configureIntegrationTest(MojoMetadataProvider.Context contex } ); } } ); - if ( !isSkipped( context.getMojoExecution() ) ) { - BuildScanMetadata.addFailsafeMetadataToBuildScan( buildScanApi, context.getSession(), context.getMojoExecution() ); + + if ( !isSkipped( context ) ) { + BuildScanMetadata.addFailsafeMetadata( context ); } } - private static boolean isSkipped(MojoExecution mojoExecution) { - return MavenConfigs.getBooleanConfig( mojoExecution, "skip" ) - || MavenConfigs.getBooleanConfig( mojoExecution, "skipITs" ) - || MavenConfigs.getBooleanConfig( mojoExecution, "skipExec" ); + @Override + protected boolean isSkipped(GoalMetadataProvider.Context context) { + return context.configuration().getBoolean( "skip" ) + || context.properties().getBoolean( "maven.test.skip" ) + || context.configuration().getBoolean( "skipITs" ) + || context.properties().getBoolean( "skipITs" ) + || context.configuration().getBoolean( "skipTests" ) + || context.properties().getBoolean( "skipTests" ) + || context.configuration().getBoolean( "skipExec" ) + || context.properties().getBoolean( "maven.test.skip.exec" ); } } diff --git a/src/main/java/org/hibernate/search/develocity/plugins/ForbiddenApisConfiguredPlugin.java b/src/main/java/org/hibernate/search/develocity/plugins/ForbiddenApisConfiguredPlugin.java index cedf3cc..67167ec 100644 --- a/src/main/java/org/hibernate/search/develocity/plugins/ForbiddenApisConfiguredPlugin.java +++ b/src/main/java/org/hibernate/search/develocity/plugins/ForbiddenApisConfiguredPlugin.java @@ -3,14 +3,14 @@ import java.io.File; import java.util.Map; -import com.gradle.maven.extension.api.scan.BuildScanApi; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.DefaultArtifact; +import org.hibernate.search.develocity.GoalMetadataProvider; import org.hibernate.search.develocity.SimpleConfiguredPlugin; -import com.gradle.maven.extension.api.cache.MojoMetadataProvider; import com.gradle.maven.extension.api.cache.MojoMetadataProvider.Context.FileSet.NormalizationStrategy; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; + public class ForbiddenApisConfiguredPlugin extends SimpleConfiguredPlugin { @Override @@ -19,14 +19,16 @@ protected String getPluginName() { } @Override - protected Map getGoalMetadataProviders(BuildScanApi buildScanApi) { + protected Map getGoalMetadataProviders() { return Map.of( "check", ForbiddenApisConfiguredPlugin::configureCheck, "testCheck", ForbiddenApisConfiguredPlugin::configureTestCheck); } - private static void configureCheck(MojoMetadataProvider.Context context) { - context.inputs(inputs -> { + private static void configureCheck(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + + metadata.inputs(inputs -> { dependsOnGav(inputs, context); inputs.properties("signatures", "bundledSignatures", "failOnUnsupportedJava", "failOnMissingClasses", "failOnUnresolvableSignatures", "ignoreSignaturesOfMissingClasses", @@ -46,27 +48,29 @@ private static void configureCheck(MojoMetadataProvider.Context context) { inputs.ignore("signaturesArtifacts", "projectRepos", "repoSession"); }); - context.outputs(outputs -> { + metadata.outputs(outputs -> { outputs.cacheable("If the inputs and signatures are identical, we should have the same output"); }); } - private static void configureTestCheck(MojoMetadataProvider.Context context) { + private static void configureTestCheck(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + configureCheck(context); - context.inputs(inputs -> { + metadata.inputs(inputs -> { inputs.properties("testTargetVersion", "testReleaseVersion"); }); } - private static File resolveHibernateSearchBuildConfigArtifact(MojoMetadataProvider.Context context) { + private static File resolveHibernateSearchBuildConfigArtifact(GoalMetadataProvider.Context context) { Artifact hibernateSearchBuildConfigArtifact = new DefaultArtifact("org.hibernate.search", "hibernate-search-build-config", "jar", - context.getProject().getVersion()); - File hibernateSearchBuildConfigArtifactFile = context.getSession().getRepositorySession().getWorkspaceReader() + context.metadata().getProject().getVersion()); + File hibernateSearchBuildConfigArtifactFile = context.metadata().getSession().getRepositorySession().getWorkspaceReader() .findArtifact(hibernateSearchBuildConfigArtifact); if (hibernateSearchBuildConfigArtifactFile == null) { - hibernateSearchBuildConfigArtifactFile = new File(context.getSession().getRepositorySession() + hibernateSearchBuildConfigArtifactFile = new File(context.metadata().getSession().getRepositorySession() .getLocalRepositoryManager().getPathForLocalArtifact(hibernateSearchBuildConfigArtifact)); } return hibernateSearchBuildConfigArtifactFile; diff --git a/src/main/java/org/hibernate/search/develocity/plugins/FormatterConfiguredPlugin.java b/src/main/java/org/hibernate/search/develocity/plugins/FormatterConfiguredPlugin.java index 2da96b9..479eaf3 100644 --- a/src/main/java/org/hibernate/search/develocity/plugins/FormatterConfiguredPlugin.java +++ b/src/main/java/org/hibernate/search/develocity/plugins/FormatterConfiguredPlugin.java @@ -2,12 +2,11 @@ import java.util.Map; +import org.hibernate.search.develocity.GoalMetadataProvider; import org.hibernate.search.develocity.SimpleConfiguredPlugin; -import com.gradle.maven.extension.api.cache.MojoMetadataProvider; import com.gradle.maven.extension.api.cache.MojoMetadataProvider.Context.FileSet.EmptyDirectoryHandling; import com.gradle.maven.extension.api.cache.MojoMetadataProvider.Context.FileSet.NormalizationStrategy; -import com.gradle.maven.extension.api.scan.BuildScanApi; public class FormatterConfiguredPlugin extends SimpleConfiguredPlugin { @@ -17,7 +16,7 @@ protected String getPluginName() { } @Override - protected Map getGoalMetadataProviders(BuildScanApi buildScanApi) { + protected Map getGoalMetadataProviders() { return Map.of( "format", FormatterConfiguredPlugin::configureFormat, "validate", FormatterConfiguredPlugin::configureValidate); @@ -25,8 +24,10 @@ protected Map getGoalMetadataProviders(BuildScanAp // This is for FormatterMojo, extended by ValidateMojo // See https://github.com/revelc/formatter-maven-plugin/tree/main/src/main/java/net/revelc/code/formatter - private static void configureCommon(MojoMetadataProvider.Context context) { - context.inputs(inputs -> { + private static void configureCommon(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + + metadata.inputs(inputs -> { dependsOnGav(inputs, context); inputs.properties("includes", "excludes", "compilerSource", "compilerCompliance", "compilerTargetPlatform", "lineEnding", "configFile", @@ -44,21 +45,25 @@ private static void configureCommon(MojoMetadataProvider.Context context) { inputs.ignore("project", "targetDirectory", "basedir", "cachedir"); }); - context.nested("encoding", c -> c.inputs(inputs -> inputs.properties("displayName"))); + metadata.nested("encoding", c -> c.inputs(inputs -> inputs.properties("displayName"))); } - private static void configureFormat(MojoMetadataProvider.Context context) { + private static void configureFormat(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + configureCommon(context); - context.outputs(outputs -> { + metadata.outputs(outputs -> { outputs.cacheable("If the inputs and dependencies are identical, we should have the same output"); }); } - private static void configureValidate(MojoMetadataProvider.Context context) { + private static void configureValidate(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + configureCommon(context); - context.inputs( inputs -> { + metadata.inputs( inputs -> { inputs.properties( "aggregator", "executionRoot"); // We already depend on the GAV. inputs.ignore( "mojoGroupId", "mojoArtifactId", "mojoVersion" ); @@ -66,7 +71,7 @@ private static void configureValidate(MojoMetadataProvider.Context context) { inputs.ignore( "mavenProject", "mavenSession" ); } ); - context.outputs(outputs -> { + metadata.outputs(outputs -> { outputs.cacheable("If the inputs and dependencies are identical, validation should give the same result (success/failure)"); }); } diff --git a/src/main/java/org/hibernate/search/develocity/plugins/ImpsortConfiguredPlugin.java b/src/main/java/org/hibernate/search/develocity/plugins/ImpsortConfiguredPlugin.java index f09eb61..24d1213 100644 --- a/src/main/java/org/hibernate/search/develocity/plugins/ImpsortConfiguredPlugin.java +++ b/src/main/java/org/hibernate/search/develocity/plugins/ImpsortConfiguredPlugin.java @@ -2,12 +2,11 @@ import java.util.Map; +import org.hibernate.search.develocity.GoalMetadataProvider; import org.hibernate.search.develocity.SimpleConfiguredPlugin; -import com.gradle.maven.extension.api.cache.MojoMetadataProvider; import com.gradle.maven.extension.api.cache.MojoMetadataProvider.Context.FileSet.EmptyDirectoryHandling; import com.gradle.maven.extension.api.cache.MojoMetadataProvider.Context.FileSet.NormalizationStrategy; -import com.gradle.maven.extension.api.scan.BuildScanApi; public class ImpsortConfiguredPlugin extends SimpleConfiguredPlugin { @@ -17,7 +16,7 @@ protected String getPluginName() { } @Override - protected Map getGoalMetadataProviders(BuildScanApi buildScanApi) { + protected Map getGoalMetadataProviders() { return Map.of( "sort", ImpsortConfiguredPlugin::configureSort, "check", ImpsortConfiguredPlugin::configureValidate); @@ -25,8 +24,10 @@ protected Map getGoalMetadataProviders(BuildScanAp // This is for AbstractImpSortMojo, extended by CheckMojo and SortMojo // See https://github.com/revelc/impsort-maven-plugin/tree/main/src/main/java/net/revelc/code/impsort/maven/plugin - private static void configureCommon(MojoMetadataProvider.Context context) { - context.inputs(inputs -> { + private static void configureCommon(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + + metadata.inputs(inputs -> { dependsOnGav(inputs, context); inputs.properties("sourceEncoding", "skip", "staticGroups", "groups", "staticAfter", "joinStaticWithNonStatic", @@ -43,26 +44,32 @@ private static void configureCommon(MojoMetadataProvider.Context context) { inputs.ignore("project", "plugin", // For now, we need to ignore the cachedir until we can declare it as an output. See below. "cachedir"); - - context.outputs(outputs -> { - // For now we don't want to output the cachedir as it contains absolute paths - // See https://github.com/revelc/impsort-maven-plugin/pull/87 - //outputs.directory("cachedir"); - }); }); - } - private static void configureSort(MojoMetadataProvider.Context context) { - configureCommon(context); - context.outputs(outputs -> { - outputs.cacheable("If the inputs and dependencies are identical, we should have the same output"); + metadata.outputs(outputs -> { + // For now we don't want to output the cachedir as it contains absolute paths + // See https://github.com/revelc/impsort-maven-plugin/pull/87 + //outputs.directory("cachedir"); }); } - private static void configureValidate(MojoMetadataProvider.Context context) { - configureCommon(context); - context.outputs(outputs -> { - outputs.cacheable("If the inputs and dependencies are identical, we should have the same output"); - }); - } + private static void configureSort(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + + configureCommon( context ); + + metadata.outputs( outputs -> { + outputs.cacheable( "If the inputs and dependencies are identical, we should have the same output" ); + } ); + } + + private static void configureValidate(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + + configureCommon( context ); + + metadata.outputs( outputs -> { + outputs.cacheable( "If the inputs and dependencies are identical, we should have the same output" ); + } ); + } } diff --git a/src/main/java/org/hibernate/search/develocity/plugins/SourceConfiguredPlugin.java b/src/main/java/org/hibernate/search/develocity/plugins/SourceConfiguredPlugin.java index 7fb4efa..5974018 100644 --- a/src/main/java/org/hibernate/search/develocity/plugins/SourceConfiguredPlugin.java +++ b/src/main/java/org/hibernate/search/develocity/plugins/SourceConfiguredPlugin.java @@ -3,11 +3,10 @@ import java.util.Map; import java.util.stream.Collectors; +import org.hibernate.search.develocity.GoalMetadataProvider; import org.hibernate.search.develocity.SimpleConfiguredPlugin; -import com.gradle.maven.extension.api.cache.MojoMetadataProvider; import com.gradle.maven.extension.api.cache.MojoMetadataProvider.Context.FileSet.NormalizationStrategy; -import com.gradle.maven.extension.api.scan.BuildScanApi; /** * TODO discuss this more in depth with Alexey, especially to make sure the output directory is not shared with other plugins. @@ -20,32 +19,35 @@ protected String getPluginName() { } @Override - protected Map getGoalMetadataProviders(BuildScanApi buildScanApi) { + protected Map getGoalMetadataProviders() { return Map.of( "jar-no-fork", SourceConfiguredPlugin::jarNoFork); } - private static void jarNoFork(MojoMetadataProvider.Context context) { - context.inputs(inputs -> { + private static void jarNoFork(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + var project = metadata.getProject(); + + metadata.inputs(inputs -> { dependsOnGav(inputs, context); inputs.properties("classifier", "includes", "excludes", "useDefaultExcludes", "useDefaultManifestFile", "attach", "excludeResources", "includePom", "finalName", "forceCreation", "skipSource", "outputTimestamp"); inputs.fileSet("defaultManifestFile", fileSet -> fileSet.normalizationStrategy(NormalizationStrategy.RELATIVE_PATH)); - inputs.fileSet("resources", context.getProject().getResources().stream().map(r -> r.getDirectory()) + inputs.fileSet("resources", project.getResources().stream().map(r -> r.getDirectory()) .collect(Collectors.toList()), fileSet -> fileSet.normalizationStrategy(NormalizationStrategy.RELATIVE_PATH)); - inputs.fileSet("sources", context.getProject().getCompileSourceRoots(), + inputs.fileSet("sources", project.getCompileSourceRoots(), fileSet -> fileSet.normalizationStrategy(NormalizationStrategy.RELATIVE_PATH)); inputs.ignore("project", "jarArchiver", "archive", "outputDirectory", "reactorProjects", "session"); }); - context.outputs(outputs -> { + metadata.outputs(outputs -> { outputs.cacheable("If the inputs are identical, we should have the same output"); - outputs.file("source-jar", context.getProject().getBuild().getDirectory() + "/" - + context.getProject().getBuild().getFinalName() + "-sources.jar"); + outputs.file("source-jar", project.getBuild().getDirectory() + "/" + + project.getBuild().getFinalName() + "-sources.jar"); }); } } diff --git a/src/main/java/org/hibernate/search/develocity/plugins/SurefireConfiguredPlugin.java b/src/main/java/org/hibernate/search/develocity/plugins/SurefireConfiguredPlugin.java index 90358ec..62483d3 100644 --- a/src/main/java/org/hibernate/search/develocity/plugins/SurefireConfiguredPlugin.java +++ b/src/main/java/org/hibernate/search/develocity/plugins/SurefireConfiguredPlugin.java @@ -2,12 +2,10 @@ import java.util.Map; +import org.hibernate.search.develocity.GoalMetadataProvider; import org.hibernate.search.develocity.SimpleConfiguredPlugin; import org.hibernate.search.develocity.util.JavaVersions; -import com.gradle.maven.extension.api.cache.MojoMetadataProvider; -import com.gradle.maven.extension.api.scan.BuildScanApi; - public class SurefireConfiguredPlugin extends SimpleConfiguredPlugin { @Override @@ -16,15 +14,26 @@ protected String getPluginName() { } @Override - protected Map getGoalMetadataProviders(BuildScanApi buildScanApi) { + protected Map getGoalMetadataProviders() { return Map.of( - "test", SurefireConfiguredPlugin::configureTest + "test", this::configureTest ); } - protected static void configureTest(MojoMetadataProvider.Context context) { - context.inputs( inputs -> { - dependsOnConfigurableJavaExecutable( inputs, context, "jvm", JavaVersions::forJavaExecutable ); + protected void configureTest(GoalMetadataProvider.Context context) { + var metadata = context.metadata(); + metadata.inputs( inputs -> { + dependsOnConfigurableJavaExecutable( inputs, context, "jvm", isSkipped( context ), + JavaVersions::forJavaExecutable ); } ); } + + protected boolean isSkipped(GoalMetadataProvider.Context context) { + return context.configuration().getBoolean( "skip" ) + || context.properties().getBoolean( "maven.test.skip" ) + || context.configuration().getBoolean( "skipTests" ) + || context.properties().getBoolean( "skipTests" ) + || context.configuration().getBoolean( "skipExec" ) + || context.properties().getBoolean( "maven.test.skip.exec" ); + } } diff --git a/src/main/java/org/hibernate/search/develocity/scan/BuildScanMetadata.java b/src/main/java/org/hibernate/search/develocity/scan/BuildScanMetadata.java index 54527ac..0fe850f 100644 --- a/src/main/java/org/hibernate/search/develocity/scan/BuildScanMetadata.java +++ b/src/main/java/org/hibernate/search/develocity/scan/BuildScanMetadata.java @@ -6,19 +6,16 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Objects; -import java.util.function.Function; import java.util.regex.Pattern; +import org.hibernate.search.develocity.GoalMetadataProvider; import org.hibernate.search.develocity.Log; import org.hibernate.search.develocity.util.JavaVersions; -import org.hibernate.search.develocity.util.MavenConfigs; +import org.hibernate.search.develocity.util.MavenProperties; import org.hibernate.search.develocity.util.Strings; import com.gradle.maven.extension.api.scan.BuildScanApi; -import org.apache.maven.execution.MavenSession; -import org.apache.maven.plugin.MojoExecution; - public final class BuildScanMetadata { private static final Pattern DOCKERFILE_FROM_PATTERN = Pattern.compile( "FROM (.+)" ); @@ -28,7 +25,7 @@ public final class BuildScanMetadata { private BuildScanMetadata() { } - public static void addMetadataToBuildScan(BuildScanApi buildScanApi, MavenSession mavenSession) { + public static void addMainMetadata(BuildScanApi buildScanApi) { // Add mvn command line final String mavenCommandLine = System.getenv( "MAVEN_CMD_LINE_ARGS" ) != null ? "mvn " + System.getenv( @@ -39,25 +36,31 @@ public static void addMetadataToBuildScan(BuildScanApi buildScanApi, MavenSessio } buildScanApi.tag( "hibernate-search" ); + } - buildScanApi.value( MavenConfigs.BUILD_CACHE_JAVA_VERSION_EXACT, - String.valueOf( MavenConfigs.cacheExactJavaVersion( mavenSession ) ) ); + public static void addJavaExecutableVersion(GoalMetadataProvider.Context context, + String javaExecutable, String javaVersion, + boolean canCacheExactVersion) { + context.buildScanDeduplicatedValue( MavenProperties.BUILD_CACHE_JAVA_VERSION_EXACT, + String.valueOf( canCacheExactVersion ) ); + var buildScanApi = context.buildScan(); + String plugin = context.metadata().getMojoExecution().getArtifactId(); + if ( plugin.equals( "maven-surefire-plugin" ) || plugin.equals( "maven-failsafe-plugin" ) ) { + buildScanApi.tag( "jdk-%s".formatted( JavaVersions.toJdkMajor( javaVersion, "unknown" ) ) ); + } - recordExecutableVersion( buildScanApi, mavenSession, "java-version.main.compiler", false, - JavaVersions::forJavacExecutable ); - recordExecutableVersion( buildScanApi, mavenSession, "java-version.test.compiler", false, - JavaVersions::forJavacExecutable ); - recordExecutableVersion( buildScanApi, mavenSession, "java-version.test.launcher", true, - JavaVersions::forJavaExecutable ); + String goal = context.metadata().getMojoExecution().getGoal(); + context.buildScanDeduplicatedValue( "%s.%s.jdk".formatted( plugin, goal ), "Path: %s\nResolved version: %s".formatted( javaExecutable, javaVersion ) ); } - public static void addFailsafeMetadataToBuildScan(BuildScanApi buildScanApi, MavenSession mavenSession, - MojoExecution mojoExecution) { - var project = mavenSession.getCurrentProject(); + public static void addFailsafeMetadata(GoalMetadataProvider.Context context) { + var buildScanApi = context.buildScan(); + + var project = context.metadata().getProject(); boolean dependsOnOrm = false; boolean dependsOnLucene = false; boolean dependsOnElasticsearch = false; - var artifactFilter = MavenConfigs.getFailsafeClasspathFilter( mojoExecution ); + var artifactFilter = context.configuration().getFailsafeClasspathFilter(); for ( var dependency : project.getArtifacts() ) { if ( !artifactFilter.include( dependency ) ) { continue; @@ -69,44 +72,46 @@ public static void addFailsafeMetadataToBuildScan(BuildScanApi buildScanApi, Mav } if ( dependsOnOrm ) { - var dbKind = MavenConfigs.getStringProperty( mavenSession, "test.database.run.kind" ); + var dbKind = context.properties().getString( "test.database.run.kind" ); if ( !Strings.isBlank( dbKind ) ) { if ( dbKind.equals( "h2" ) ) { // H2 doesn't use containers buildScanApi.tag( "h2" ); } else { - tagDockerfileShortImageRef( buildScanApi, mavenSession, + addDockerfileShortImageRef( context, "database/%s.Dockerfile".formatted( dbKind ), null ); } } } - String explicitBackend = - MavenConfigs.getFailsafeSystemProperty( mojoExecution, "org.hibernate.search.integrationtest.backend.type" ); + String explicitBackend = context.configuration() + .getFailsafeSystemProperty( "org.hibernate.search.integrationtest.backend.type" ); if ( Strings.isBlank( explicitBackend ) ) { explicitBackend = null; } if ( dependsOnLucene && ( explicitBackend == null || "lucene".equals( explicitBackend ) ) - && !MavenConfigs.getBooleanProperty( project, "test.lucene.skip" ) ) { + && !context.properties().getBoolean( "test.lucene.skip" ) ) { buildScanApi.tag( "lucene" ); } if ( dependsOnElasticsearch && ( explicitBackend == null || "elasticsearch".equals( explicitBackend ) ) - && !MavenConfigs.getBooleanProperty( project, "test.elasticsearch.skip" ) ) { - var distribution = MavenConfigs.getStringProperty( mavenSession, "test.elasticsearch.distribution" ); - tagDockerfileShortImageRef( buildScanApi, mavenSession, + && !context.properties().getBoolean( "test.elasticsearch.skip" ) ) { + var distribution = context.properties().getString( "test.elasticsearch.distribution" ); + addDockerfileShortImageRef( context, "search-backend/%s.Dockerfile".formatted( distribution ), - MavenConfigs.getStringProperty( mavenSession, "test.elasticsearch.version" ) ); + context.properties().getString( "test.elasticsearch.version" ) ); } } - private static void tagDockerfileShortImageRef(BuildScanApi buildScanApi, MavenSession mavenSession, + private static void addDockerfileShortImageRef(GoalMetadataProvider.Context context, String dockerfileRelativePath, String versionOverride) { - var path = Path.of( mavenSession.getExecutionRootDirectory(), "build/container", dockerfileRelativePath ); + var buildScanApi = context.buildScan(); + var path = Path.of( context.metadata().getSession().getExecutionRootDirectory(), + "build/container", dockerfileRelativePath ); try { String ref; try ( var stream = Files.lines( path ) ) { @@ -148,14 +153,4 @@ static String toShortImageRef(String ref) { } } - private static void recordExecutableVersion(BuildScanApi buildScanApi, MavenSession mavenSession, - String propertyName, boolean tag, Function executableToVersion) { - String javaExecutable = MavenConfigs.getStringProperty( mavenSession, propertyName ); - String javaVersion = executableToVersion.apply( javaExecutable ); - if ( tag ) { - buildScanApi.tag( "jdk-%s".formatted( JavaVersions.toJdkMajor( javaVersion, "unknown" ) ) ); - } - buildScanApi.value( propertyName, "Path: %s\nResolved version: %s".formatted( javaExecutable, javaVersion ) ); - } - } diff --git a/src/main/java/org/hibernate/search/develocity/util/MavenConfigs.java b/src/main/java/org/hibernate/search/develocity/util/MavenMojoExecutionConfig.java similarity index 56% rename from src/main/java/org/hibernate/search/develocity/util/MavenConfigs.java rename to src/main/java/org/hibernate/search/develocity/util/MavenMojoExecutionConfig.java index c23f477..60a1471 100644 --- a/src/main/java/org/hibernate/search/develocity/util/MavenConfigs.java +++ b/src/main/java/org/hibernate/search/develocity/util/MavenMojoExecutionConfig.java @@ -13,40 +13,25 @@ import org.hibernate.search.develocity.Log; -import com.gradle.maven.extension.api.cache.MojoMetadataProvider; import org.apache.maven.artifact.resolver.filter.AndArtifactFilter; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; -import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.project.MavenProject; import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter; import org.codehaus.plexus.util.xml.Xpp3Dom; -public final class MavenConfigs { +public final class MavenMojoExecutionConfig { + private final MojoExecution mojoExecution; - public static final String BUILD_CACHE_JAVA_VERSION_EXACT = "build-cache.java-version.exact"; - - private MavenConfigs() { - } - - public static String getStringProperty(MavenSession mavenSession, String key) { - return getStringProperty( mavenSession.getResult().getProject(), key ); - } - - public static String getStringProperty(MavenProject project, String key) { - return (String) project.getProperties().get( key ); + public MavenMojoExecutionConfig(MojoExecution mojoExecution) { + this.mojoExecution = mojoExecution; } - public static boolean getBooleanProperty(MavenProject project, String key) { - return Boolean.parseBoolean( getStringProperty( project, key ) ); + public Boolean getBoolean(String key) { + return Boolean.parseBoolean( getString( key ) ); } - public static boolean getBooleanConfig(MojoExecution mojoExecution, String key) { - return Boolean.parseBoolean( getStringConfig( mojoExecution, key ) ); - } - - public static String getStringConfig(MojoExecution mojoExecution, String key) { + public String getString(String key) { var configElement = mojoExecution.getConfiguration().getChild( key ); if ( configElement == null ) { return null; @@ -58,7 +43,7 @@ public static String getStringConfig(MojoExecution mojoExecution, String key) { return value.trim(); } - public static List getStringListConfig(MojoExecution mojoExecution, String key) { + public List getStringList(String key) { var configElement = mojoExecution.getConfiguration().getChild( key ); if ( configElement == null ) { return List.of(); @@ -73,8 +58,8 @@ public static List getStringListConfig(MojoExecution mojoExecution, Stri return children; } - public static String getFailsafeSystemProperty(MojoExecution failsafeIntegrationTestExecution, String key) { - var systemPropertyVariables = failsafeIntegrationTestExecution.getConfiguration() + public String getFailsafeSystemProperty(String key) { + var systemPropertyVariables = mojoExecution.getConfiguration() .getChild( "systemPropertyVariables" ); if ( systemPropertyVariables == null ) { return null; @@ -86,13 +71,11 @@ public static String getFailsafeSystemProperty(MojoExecution failsafeIntegration return child.getValue(); } - public static ArtifactFilter getFailsafeClasspathFilter(MojoExecution mojoExecution) { + public ArtifactFilter getFailsafeClasspathFilter() { List filters = new ArrayList<>(); try { - String classpathDependencyScopeExclude = getStringConfig( - mojoExecution, "classpathDependencyScopeExclude" ); - List classpathDependencyExcludes = getStringListConfig( - mojoExecution, "classpathDependencyExcludes" ); + String classpathDependencyScopeExclude = getString( "classpathDependencyScopeExclude" ); + List classpathDependencyExcludes = getStringList( "classpathDependencyExcludes" ); if ( classpathDependencyScopeExclude != null && !classpathDependencyScopeExclude.isEmpty() ) { var scopeIncludeFilter = new ScopeArtifactFilter( classpathDependencyScopeExclude ); filters.add( artifact -> !scopeIncludeFilter.include( artifact ) ); @@ -109,8 +92,4 @@ public static ArtifactFilter getFailsafeClasspathFilter(MojoExecution mojoExecut } return new AndArtifactFilter( filters ); } - - public static boolean cacheExactJavaVersion(MavenSession mavenSession) { - return Boolean.parseBoolean( (String) mavenSession.getUserProperties().get( BUILD_CACHE_JAVA_VERSION_EXACT ) ); - } } diff --git a/src/main/java/org/hibernate/search/develocity/util/MavenProperties.java b/src/main/java/org/hibernate/search/develocity/util/MavenProperties.java new file mode 100644 index 0000000..860e1c1 --- /dev/null +++ b/src/main/java/org/hibernate/search/develocity/util/MavenProperties.java @@ -0,0 +1,46 @@ +/* + * + * * Hibernate Search, full-text search for your domain model + * * + * * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * * See the lgpl.txt file in the root directory or . + * + */ +package org.hibernate.search.develocity.util; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.plugin.PluginParameterExpressionEvaluator; +import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; + +public final class MavenProperties { + + public static final String BUILD_CACHE_JAVA_VERSION_EXACT = "build-cache.java-version.exact"; + + private final PluginParameterExpressionEvaluator evaluator; + + public MavenProperties(MavenSession session, MojoExecution mojoExecution) { + this.evaluator = new PluginParameterExpressionEvaluator( session, mojoExecution ); + } + + public Boolean getBoolean(String key) { + return Boolean.parseBoolean( getString( key ) ); + } + + public String getString(String key) { + return (String) get( key ); + } + + public Object get(String key) { + try { + return evaluator.evaluate( "${" + key + "}" ); + } + catch (ExpressionEvaluationException e) { + throw new RuntimeException( "Could not get value for %s: %s".formatted( key, e.getMessage() ), e ); + } + } + + public boolean cacheExactJavaVersion() { + return getBoolean( BUILD_CACHE_JAVA_VERSION_EXACT ); + } +}