Skip to content

Commit

Permalink
Guard against new Spring modules in ApiDiff task
Browse files Browse the repository at this point in the history
Prior to this commit, the ApiDiff Gradle task would be configured for
all submodules of the Spring Framework project and would assume that
they all existed for the baseline version considered for the API diff.

This would cause issues when:
* the sub-project is not published as it's not an official "spring-*"
  module
* the "spring-*" module is new and did not exist for the baseline
  version

This commit ensures that only "spring-*" modules are considered for this
task and that we trigger an early resolution of the baseline version -
if the version doesn't exist, a warn message is logged and we assume
that this is a new module, to be compared with an empty configuration.

This commit also renames the "spring-core-graalvm" project to
"graalvm-feature", since this sub-project is not an official module
published to Maven Central, but rather an internal dependency.

Fixes spring-projectsgh-28818
  • Loading branch information
bclozel committed Jul 28, 2022
1 parent d33c2b5 commit 10e4965
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,22 @@

import me.champeau.gradle.japicmp.JapicmpPlugin;
import me.champeau.gradle.japicmp.JapicmpTask;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.repositories.ArtifactRepository;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
import org.gradle.api.artifacts.repositories.RepositoryContentDescriptor;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.jvm.tasks.Jar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* {@link Plugin} that applies the {@code "japicmp-gradle-plugin"}
* and create tasks for all subprojects, diffing the public API one by one
* and create tasks for all subprojects named {@code "spring-*"}, diffing the public API one by one
* and creating the reports in {@code "build/reports/api-diff/$OLDVERSION_to_$NEWVERSION/"}.
* <p>{@code "./gradlew apiDiff -PbaselineVersion=5.1.0.RELEASE"} will output the
* reports for the API diff between the baseline version and the current one for all modules.
Expand All @@ -51,6 +50,8 @@
*/
public class ApiDiffPlugin implements Plugin<Project> {

private static final Logger logger = LoggerFactory.getLogger(ApiDiffPlugin.class);

public static final String TASK_NAME = "apiDiff";

private static final String BASELINE_VERSION_PROPERTY = "baselineVersion";
Expand All @@ -70,7 +71,11 @@ public void apply(Project project) {

private void applyApiDiffConventions(Project project) {
String baselineVersion = project.property(BASELINE_VERSION_PROPERTY).toString();
project.subprojects(subProject -> createApiDiffTask(baselineVersion, subProject));
project.subprojects(subProject -> {
if (subProject.getName().startsWith("spring-")) {
createApiDiffTask(baselineVersion, subProject);
}
});
}

private void createApiDiffTask(String baselineVersion, Project project) {
Expand All @@ -83,7 +88,7 @@ private void createApiDiffTask(String baselineVersion, Project project) {
apiDiff.setDescription("Generates an API diff report with japicmp");
apiDiff.setGroup(JavaBasePlugin.DOCUMENTATION_GROUP);

apiDiff.setOldClasspath(project.files(createBaselineConfiguration(baselineVersion, project)));
apiDiff.setOldClasspath(createBaselineConfiguration(baselineVersion, project));
TaskProvider<Jar> jar = project.getTasks().withType(Jar.class).named("jar");
apiDiff.setNewArchives(project.getLayout().files(jar.get().getArchiveFile().get().getAsFile()));
apiDiff.setNewClasspath(getRuntimeClassPath(project));
Expand All @@ -109,7 +114,16 @@ private Configuration createBaselineConfiguration(String baselineVersion, Projec
String baseline = String.join(":",
project.getGroup().toString(), project.getName(), baselineVersion);
Dependency baselineDependency = project.getDependencies().create(baseline + "@jar");
return project.getRootProject().getConfigurations().detachedConfiguration(baselineDependency);
Configuration baselineConfiguration = project.getRootProject().getConfigurations().detachedConfiguration(baselineDependency);
try {
// eagerly resolve the baseline configuration to check whether this is a new Spring module
baselineConfiguration.resolve();
return baselineConfiguration;
}
catch (GradleException exception) {
logger.warn("Could not resolve {} - assuming this is a new Spring module.", baseline);
}
return project.getRootProject().getConfigurations().detachedConfiguration();
}

private Configuration getRuntimeClassPath(Project project) {
Expand Down
2 changes: 1 addition & 1 deletion framework-bom/framework-bom.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ group = "org.springframework"

dependencies {
constraints {
parent.moduleProjects.findAll{ it.name != 'spring-core-graalvm' }.sort { "$it.name" }.each {
parent.moduleProjects.sort { "$it.name" }.each {
api it
}
}
Expand Down
16 changes: 6 additions & 10 deletions gradle/docs.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
ext {
documentedProjects = moduleProjects.findAll { it.name != 'spring-core-graalvm' }
}

configurations {
asciidoctorExt
}
Expand All @@ -28,7 +24,7 @@ task api(type: Javadoc) {
title = "${rootProject.description} ${version} API"

dependsOn {
documentedProjects.collect {
moduleProjects.collect {
it.tasks.getByName("jar")
}
}
Expand All @@ -37,7 +33,7 @@ task api(type: Javadoc) {
// ensure the javadoc process can resolve types compiled from .aj sources
project(":spring-aspects").sourceSets.main.output
)
classpath += files(documentedProjects.collect { it.sourceSets.main.compileClasspath })
classpath += files(moduleProjects.collect { it.sourceSets.main.compileClasspath })
}

options {
Expand All @@ -52,7 +48,7 @@ task api(type: Javadoc) {
addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
addBooleanOption('Werror', true) // fail build on Javadoc warnings
}
source documentedProjects.collect { project ->
source moduleProjects.collect { project ->
project.sourceSets.main.allJava
}
maxMemory = "1024m"
Expand Down Expand Up @@ -184,7 +180,7 @@ task schemaZip(type: Zip) {
description = "Builds -${archiveClassifier} archive containing all " +
"XSDs for deployment at https://springframework.org/schema."
duplicatesStrategy DuplicatesStrategy.EXCLUDE
documentedProjects.each { module ->
moduleProjects.each { module ->
def Properties schemas = new Properties();

module.sourceSets.main.resources.find {
Expand Down Expand Up @@ -234,7 +230,7 @@ task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
into "${baseDir}/schema"
}

documentedProjects.each { module ->
moduleProjects.each { module ->
into ("${baseDir}/libs") {
from module.jar
if (module.tasks.findByPath("sourcesJar")) {
Expand All @@ -247,4 +243,4 @@ task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
}
}

distZip.mustRunAfter documentedProjects.check
distZip.mustRunAfter moduleProjects.check
4 changes: 2 additions & 2 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ include "spring-context"
include "spring-context-indexer"
include "spring-context-support"
include "spring-core"
include "spring-core-graalvm"
project(':spring-core-graalvm').projectDir = file('spring-core/graalvm')
include "graalvm-feature"
project(':graalvm-feature').projectDir = file('spring-core/graalvm')
include "spring-core-test"
include "spring-expression"
include "spring-instrument"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,3 @@ eclipse.classpath.file {
dependencies {
compileOnly("org.graalvm.nativeimage:svm")
}

tasks.withType(PublishToMavenRepository) {
enabled = false
}

tasks.withType(PublishToMavenLocal) {
enabled = false
}

tasks.withType(Javadoc) {
enabled = false
}
2 changes: 1 addition & 1 deletion spring-core/spring-core.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ dependencies {
cglib("cglib:cglib:${cglibVersion}@jar")
javapoet("com.squareup:javapoet:${javapoetVersion}@jar")
objenesis("org.objenesis:objenesis:${objenesisVersion}@jar")
graalvm(project(path: ":spring-core-graalvm", configuration: 'classesOnlyElements'))
graalvm(project(path: ":graalvm-feature", configuration: 'classesOnlyElements'))
api(files(cglibRepackJar))
api(files(javapoetRepackJar))
api(files(objenesisRepackJar))
Expand Down

0 comments on commit 10e4965

Please sign in to comment.