com.palantir.baseline.plugins.javaversions.BaselineJavaVersions Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-baseline-java Show documentation
Show all versions of gradle-baseline-java Show documentation
A Gradle plugin for applying Baseline-recommended build and IDE settings
/*
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.palantir.baseline.plugins.javaversions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.Objects;
import org.gradle.api.GradleException;
import org.gradle.api.Named;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.publish.Publication;
import org.gradle.api.publish.PublishingExtension;
import org.gradle.api.publish.ivy.IvyPublication;
import org.gradle.api.publish.maven.MavenPublication;
import org.gradle.util.GradleVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class BaselineJavaVersions implements Plugin {
private static final Logger log = LoggerFactory.getLogger(BaselineJavaVersions.class);
public static final String EXTENSION_NAME = "javaVersions";
public static final GradleVersion MIN_GRADLE_VERSION = GradleVersion.version("7.0");
private static final ImmutableSet LIBRARY_PLUGINS =
ImmutableSet.of("com.palantir.external-publish-jar", "com.palantir.publish-jar");
private static final ImmutableSet DISTRIBUTION_PLUGINS = ImmutableSet.of(
"com.palantir.external-publish-dist",
"com.palantir.publish-dist",
"com.palantir.sls-java-service-distribution");
@Override
public void apply(Project project) {
if (!Objects.equals(project, project.getRootProject())) {
throw new GradleException("BaselineJavaVersions may only be applied to the root project");
}
GradleVersion currentGradleVersion = GradleVersion.current();
if (currentGradleVersion.compareTo(MIN_GRADLE_VERSION) < 0) {
throw new GradleException(String.format(
"BaselineJavaVersions requires %s. %s is not supported", MIN_GRADLE_VERSION, currentGradleVersion));
}
BaselineJavaVersionsExtension rootExtension =
project.getExtensions().create(EXTENSION_NAME, BaselineJavaVersionsExtension.class, project);
project.subprojects(proj ->
proj.getExtensions().create(EXTENSION_NAME, SubprojectBaselineJavaVersionsExtension.class, proj));
project.allprojects(proj -> proj.getPluginManager().withPlugin("java", unused -> {
proj.getPluginManager().apply(BaselineJavaVersion.class);
BaselineJavaVersionExtension projectVersions =
proj.getExtensions().getByType(BaselineJavaVersionExtension.class);
Provider suggestedTarget = proj.provider(() -> isLibrary(proj, projectVersions)
? ChosenJavaVersion.of(rootExtension.libraryTarget().get())
: rootExtension.distributionTarget().get());
projectVersions.target().convention(suggestedTarget);
projectVersions.runtime().convention(rootExtension.runtime());
}));
}
private static boolean isLibrary(Project project, BaselineJavaVersionExtension projectVersions) {
if (GradleVersion.current().compareTo(GradleVersion.version("8.6")) >= 0) {
return newIsLibrary(project, projectVersions);
} else {
return oldIsLibrary(project, projectVersions);
}
}
private static boolean newIsLibrary(Project project, BaselineJavaVersionExtension projectVersions) {
Property libraryOverride = projectVersions.overrideLibraryAutoDetection();
if (libraryOverride.isPresent()) {
log.debug(
"Project '{}' is considered a library because it has been overridden with library = true",
project.getDisplayName());
return libraryOverride.get();
}
for (String plugin : LIBRARY_PLUGINS) {
if (project.getPluginManager().hasPlugin(plugin)) {
log.debug(
"Project '{}' is considered a library because the '{}' plugin is applied",
project.getDisplayName(),
plugin);
return true;
}
}
for (String plugin : DISTRIBUTION_PLUGINS) {
if (project.getPluginManager().hasPlugin(plugin)) {
log.debug(
"Project '{}' is considered a distribution because the '{}' plugin is applied",
project.getDisplayName(),
plugin);
return false;
}
}
PublishingExtension publishing = project.getExtensions().findByType(PublishingExtension.class);
if (publishing == null) {
log.debug(
"Project '{}' is considered a distribution, not a library, because "
+ "it doesn't define any publishing extensions",
project.getDisplayName());
return false;
}
// Better to be conservative with the java version rather than release something that is too high to be used.
log.debug("Project '{}' is considered a library as no other conditions matched", project.getDisplayName());
return true;
}
/**
* This only exists for rollout of the new Gradle 8.6+ behaviour. It should be deleted shortly once we have upgraded
* repos past 8.6 and verified that the new behaviour is correct.
*/
private static boolean oldIsLibrary(Project project, BaselineJavaVersionExtension projectVersions) {
Property libraryOverride = projectVersions.overrideLibraryAutoDetection();
if (libraryOverride.isPresent()) {
log.debug(
"Project '{}' is considered a library because it has been overridden with library = true",
project.getDisplayName());
return libraryOverride.get();
}
for (String plugin :
new String[] {"nebula.maven-publish", "com.palantir.shadow-jar", "com.palantir.external-publish-jar"}) {
if (project.getPluginManager().hasPlugin(plugin)) {
log.debug(
"Project '{}' is considered a library because the '{}' plugin is applied",
project.getDisplayName(),
plugin);
return true;
}
}
PublishingExtension publishing = project.getExtensions().findByType(PublishingExtension.class);
if (publishing == null) {
log.debug(
"Project '{}' is considered a distribution, not a library, because "
+ "it doesn't define any publishing extensions",
project.getDisplayName());
return false;
}
ImmutableList jarPublications = publishing.getPublications().stream()
.filter(pub -> isLibraryPublication(project, pub))
.map(Named::getName)
.collect(ImmutableList.toImmutableList());
if (jarPublications.isEmpty()) {
log.debug(
"Project '{}' is considered a distribution because it does not publish jars",
project.getDisplayName());
return false;
}
log.debug(
"Project '{}' is considered a library because it publishes jars: {}",
project.getDisplayName(),
jarPublications);
return true;
}
private static boolean isLibraryPublication(Project project, Publication publication) {
if (publication instanceof MavenPublication) {
MavenPublication mavenPublication = (MavenPublication) publication;
return mavenPublication.getArtifacts().stream().anyMatch(artifact -> "jar".equals(artifact.getExtension()));
}
if (publication instanceof IvyPublication) {
IvyPublication ivyPublication = (IvyPublication) publication;
return ivyPublication.getArtifacts().stream().anyMatch(artifact -> "jar".equals(artifact.getExtension()));
}
// Default to true for unknown publication types to avoid setting higher jvm targets than necessary
log.warn(
"Unknown publication '{}' of type '{}'. Assuming project {} is a library",
publication,
publication.getClass().getName(),
project.getName());
return true;
}
}