From 6c2f4ad28c5efeef5c8ec1e5454ddde8d9f5ae4f Mon Sep 17 00:00:00 2001 From: Roberto Perez Alcolea Date: Fri, 17 Nov 2023 16:51:04 -0800 Subject: [PATCH] PublishVerificationPlugin: replace VerificationViolationsCollectorHolderExtension with VerificationViolationsCollectorService build service --- .../PublishVerificationPlugin.groovy | 29 +++++++------------ .../VerificationReportTask.groovy | 9 +++--- ...ificationViolationsCollectorService.groovy | 27 +++++++++++++++++ .../verification/VerifyPublicationTask.groovy | 5 ++-- ...shVerificationPluginIntegrationSpec.groovy | 2 ++ .../VerificationReportTaskSpec.groovy | 15 ++++++---- .../VerifyPublicationTaskSpec.groovy | 19 ++++++++---- 7 files changed, 70 insertions(+), 36 deletions(-) create mode 100644 src/main/groovy/nebula/plugin/publishing/verification/VerificationViolationsCollectorService.groovy diff --git a/src/main/groovy/nebula/plugin/publishing/verification/PublishVerificationPlugin.groovy b/src/main/groovy/nebula/plugin/publishing/verification/PublishVerificationPlugin.groovy index 935fd12..bfa3519 100644 --- a/src/main/groovy/nebula/plugin/publishing/verification/PublishVerificationPlugin.groovy +++ b/src/main/groovy/nebula/plugin/publishing/verification/PublishVerificationPlugin.groovy @@ -14,6 +14,7 @@ import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency import org.gradle.api.attributes.Attribute import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.provider.Provider import org.gradle.api.publish.ivy.tasks.PublishToIvyRepository import org.gradle.api.publish.maven.tasks.PublishToMavenRepository import org.gradle.api.tasks.SourceSet @@ -44,23 +45,25 @@ class PublishVerificationPlugin implements Plugin { @CompileDynamic private void setupPlugin(Project project, PublishVerificationExtension extension) { - createVerificationViolationsCollector(project) + Provider serviceProvider = project.getGradle().getSharedServices().registerIfAbsent("verificationViolationsCollectorService", VerificationViolationsCollectorService.class, spec -> { + }) + generateStatusSchemeAttribute(project) project.afterEvaluate { SourceSet sourceSet = project.sourceSets.find { it.name == SourceSet.MAIN_SOURCE_SET_NAME } if (!sourceSet) return TaskProvider verificationTask = project.tasks.register("verifyPublication", VerifyPublicationTask) - TaskProvider reportTask = getOrCreateReportTask(project, verificationTask) - VerificationViolationsCollectorHolderExtension verificationViolationsCollectorHolderExtension = project.rootProject.extensions.findByType(VerificationViolationsCollectorHolderExtension) + TaskProvider reportTask = getOrCreateReportTask(project, verificationTask, serviceProvider) verificationTask.configure(new Action() { @Override void execute(VerifyPublicationTask verifyPublicationTask) { + verifyPublicationTask.verificationViolationsCollectorService.set(serviceProvider) + verifyPublicationTask.usesService(serviceProvider) verifyPublicationTask.projectName.set(project.name) verifyPublicationTask.targetStatus.set(project.status.toString()) verifyPublicationTask.resolvedComponentResultProvider = project.configurations.named(sourceSet.getRuntimeClasspathConfigurationName()).get().incoming.resolutionResult.rootComponent verifyPublicationTask.ignore.set(extension.ignore) verifyPublicationTask.ignoreGroups.set(extension.ignoreGroups) - verifyPublicationTask.verificationViolationsCollectorHolderExtension.set(verificationViolationsCollectorHolderExtension) verifyPublicationTask.definedDependencies.set(project.configurations.collect { Configuration configuration -> configuration.dependencies }.flatten().collect { Dependency dependency -> new DeclaredDependency(dependency.group, dependency.name, dependency.version) } as List) @@ -72,14 +75,6 @@ class PublishVerificationPlugin implements Plugin { } } - void createVerificationViolationsCollector(Project project) { - //root project doesn't have to fulfil condition for plugin setup so first submodule will create extension if it not created - VerificationViolationsCollectorHolderExtension violationCollector = project.rootProject.extensions.findByType(VerificationViolationsCollectorHolderExtension) - if (violationCollector == null) { - project.rootProject.extensions.create('verificationViolationsCollectorHolderExtension', VerificationViolationsCollectorHolderExtension) - } - } - @CompileDynamic private void generateStatusSchemeAttribute(Project p) { if(GradleKt.versionLessThan(p.gradle, "5.0")) { @@ -96,7 +91,7 @@ class PublishVerificationPlugin implements Plugin { } - private TaskProvider getOrCreateReportTask(Project project, TaskProvider verificationTask) { + private TaskProvider getOrCreateReportTask(Project project, TaskProvider verificationTask, Provider verificationViolationsCollectorServiceProvider) { //root project doesn't have to fulfil condition for plugin setup so first submodule will create report task if it not created TaskCollection verificationReports = project.rootProject.tasks.withType(VerificationReportTask) TaskProvider verificationReportTask @@ -105,12 +100,12 @@ class PublishVerificationPlugin implements Plugin { } else { verificationReportTask = project.rootProject.tasks.named('verifyPublicationReport', VerificationReportTask) } - VerificationViolationsCollectorHolderExtension verificationViolationsCollectorHolderExtension = project.rootProject.extensions.findByType(VerificationViolationsCollectorHolderExtension) verificationReportTask.configure(new Action() { @Override void execute(VerificationReportTask reportTask) { + reportTask.verificationViolationsCollectorService.set(verificationViolationsCollectorServiceProvider) + reportTask.usesService(verificationViolationsCollectorServiceProvider) reportTask.targetStatus.set(project.status.toString()) - reportTask.verificationViolationsCollectorHolderExtension.set(verificationViolationsCollectorHolderExtension) reportTask.dependsOn(verificationTask) } }) @@ -125,8 +120,4 @@ class PublishVerificationPlugin implements Plugin { task.dependsOn(reportTask) } } - - static class VerificationViolationsCollectorHolderExtension { - Map collector = new ConcurrentHashMap<>() - } } diff --git a/src/main/groovy/nebula/plugin/publishing/verification/VerificationReportTask.groovy b/src/main/groovy/nebula/plugin/publishing/verification/VerificationReportTask.groovy index b69fdba..59d5b6e 100644 --- a/src/main/groovy/nebula/plugin/publishing/verification/VerificationReportTask.groovy +++ b/src/main/groovy/nebula/plugin/publishing/verification/VerificationReportTask.groovy @@ -13,16 +13,17 @@ abstract class VerificationReportTask extends DefaultTask { protected VerificationReportGenerator verificationReportGenerator = new VerificationReportGenerator() - @Internal - abstract Property getVerificationViolationsCollectorHolderExtension() - @Input abstract Property getTargetStatus() + @Internal + abstract Property getVerificationViolationsCollectorService() + + @TaskAction void reportViolatingDependencies() { if (project.rootProject == project) { - reportErrors(verificationViolationsCollectorHolderExtension.get().collector) + reportErrors(verificationViolationsCollectorService.get().collector) } } diff --git a/src/main/groovy/nebula/plugin/publishing/verification/VerificationViolationsCollectorService.groovy b/src/main/groovy/nebula/plugin/publishing/verification/VerificationViolationsCollectorService.groovy new file mode 100644 index 0000000..e401d86 --- /dev/null +++ b/src/main/groovy/nebula/plugin/publishing/verification/VerificationViolationsCollectorService.groovy @@ -0,0 +1,27 @@ +package nebula.plugin.publishing.verification + +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters + +import java.util.concurrent.ConcurrentHashMap + +abstract class VerificationViolationsCollectorService implements BuildService, AutoCloseable { + private final Map collector + + VerificationViolationsCollectorService() { + this.collector = new ConcurrentHashMap<>() + } + + void addProject(String projectName, ViolationsContainer violationsContainer) { + collector.put(projectName, violationsContainer) + } + + Map getCollector() { + return collector + } + + @Override + void close() { + collector.clear() + } +} diff --git a/src/main/groovy/nebula/plugin/publishing/verification/VerifyPublicationTask.groovy b/src/main/groovy/nebula/plugin/publishing/verification/VerifyPublicationTask.groovy index 8028ee9..c72d552 100644 --- a/src/main/groovy/nebula/plugin/publishing/verification/VerifyPublicationTask.groovy +++ b/src/main/groovy/nebula/plugin/publishing/verification/VerifyPublicationTask.groovy @@ -38,7 +38,8 @@ abstract class VerifyPublicationTask extends DefaultTask { abstract ListProperty getDefinedDependencies() @Internal - abstract Property getVerificationViolationsCollectorHolderExtension() + abstract Property getVerificationViolationsCollectorService() + @TaskAction void verifyDependencies() { @@ -47,7 +48,7 @@ abstract class VerifyPublicationTask extends DefaultTask { List versionViolations = new VersionSelectorVerification(ignore.get(), ignoreGroups.get()).verify(definedDependencies.get()) - verificationViolationsCollectorHolderExtension.get().collector.put(projectName.get(), new ViolationsContainer(statusViolations: violations, versionSelectorViolations: versionViolations)) + verificationViolationsCollectorService.get().addProject(projectName.get(), new ViolationsContainer(statusViolations: violations, versionSelectorViolations: versionViolations)) } private static Set getNonProjectDependencies(ResolvedComponentResult resolvedComponentResult) { diff --git a/src/test/groovy/nebula/plugin/publishing/verification/PublishVerificationPluginIntegrationSpec.groovy b/src/test/groovy/nebula/plugin/publishing/verification/PublishVerificationPluginIntegrationSpec.groovy index 9483531..8f5fbd8 100644 --- a/src/test/groovy/nebula/plugin/publishing/verification/PublishVerificationPluginIntegrationSpec.groovy +++ b/src/test/groovy/nebula/plugin/publishing/verification/PublishVerificationPluginIntegrationSpec.groovy @@ -23,6 +23,8 @@ class PublishVerificationPluginIntegrationSpec extends IntegrationSpec { rootProject.name='testhello' ''' gradleVersion = null + // Enable configuration cache :) + // new File(projectDir, 'gradle.properties') << '''org.gradle.configuration-cache=true'''.stripIndent() } def 'should successful pass through verification'() { diff --git a/src/test/groovy/nebula/plugin/publishing/verification/VerificationReportTaskSpec.groovy b/src/test/groovy/nebula/plugin/publishing/verification/VerificationReportTaskSpec.groovy index f077456..ef5caf2 100644 --- a/src/test/groovy/nebula/plugin/publishing/verification/VerificationReportTaskSpec.groovy +++ b/src/test/groovy/nebula/plugin/publishing/verification/VerificationReportTaskSpec.groovy @@ -4,6 +4,7 @@ import org.gradle.api.BuildCancelledException import org.gradle.api.Project import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.ModuleVersionIdentifier +import org.gradle.api.provider.Provider import org.gradle.testfixtures.ProjectBuilder import spock.lang.Specification @@ -12,12 +13,14 @@ class VerificationReportTaskSpec extends Specification { def 'build is unaffected when there is no violation'() { given: Project project = ProjectBuilder.builder().build() - PublishVerificationPlugin.VerificationViolationsCollectorHolderExtension extension = project.extensions.create('collectorExtension', PublishVerificationPlugin.VerificationViolationsCollectorHolderExtension) + Provider verificationViolationsCollectorServiceProvider = project.getGradle().getSharedServices().registerIfAbsent("verificationViolationsCollectorService", VerificationViolationsCollectorService.class, spec -> { + }) VerificationReportTask task = project.tasks.create('report', VerificationReportTask) def generator = Mock(VerificationReportGenerator) task.verificationReportGenerator = generator task.targetStatus.set(project.status.toString()) - task.verificationViolationsCollectorHolderExtension.set(extension) + task.verificationViolationsCollectorService.set(verificationViolationsCollectorServiceProvider) + task.usesService(verificationViolationsCollectorServiceProvider) when: task.reportViolatingDependencies() @@ -34,13 +37,15 @@ class VerificationReportTaskSpec extends Specification { given: Project project = ProjectBuilder.builder().build() project.status = 'release' - def extension = project.extensions.create('collectorExtension', PublishVerificationPlugin.VerificationViolationsCollectorHolderExtension) - extension.collector.put(project, container) + Provider verificationViolationsCollectorServiceProvider = project.getGradle().getSharedServices().registerIfAbsent("verificationViolationsCollectorService", VerificationViolationsCollectorService.class, spec -> { + }) + verificationViolationsCollectorServiceProvider.get().addProject(project.name, container) VerificationReportTask task = project.tasks.create('report', VerificationReportTask) def generator = Mock(VerificationReportGenerator) task.verificationReportGenerator = generator task.targetStatus.set(project.status.toString()) - task.verificationViolationsCollectorHolderExtension.set(extension) + task.verificationViolationsCollectorService.set(verificationViolationsCollectorServiceProvider) + task.usesService(verificationViolationsCollectorServiceProvider) when: task.reportViolatingDependencies() diff --git a/src/test/groovy/nebula/plugin/publishing/verification/VerifyPublicationTaskSpec.groovy b/src/test/groovy/nebula/plugin/publishing/verification/VerifyPublicationTaskSpec.groovy index e982579..68fe5ad 100644 --- a/src/test/groovy/nebula/plugin/publishing/verification/VerifyPublicationTaskSpec.groovy +++ b/src/test/groovy/nebula/plugin/publishing/verification/VerifyPublicationTaskSpec.groovy @@ -10,6 +10,7 @@ import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency import org.gradle.api.internal.artifacts.DefaultModuleIdentifier import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.provider.Provider import org.gradle.testfixtures.ProjectBuilder import spock.lang.Specification import spock.lang.Unroll @@ -29,7 +30,8 @@ class VerifyPublicationTaskSpec extends Specification { then: noExceptionThrown() - def holderExtension = project.extensions.findByType(PublishVerificationPlugin.VerificationViolationsCollectorHolderExtension) + def holderExtension = project.getGradle().getSharedServices().registerIfAbsent("verificationViolationsCollectorService", VerificationViolationsCollectorService.class, spec -> { + }).get() holderExtension.collector.size() == 1 def violations = holderExtension.collector[project.name] violations.statusViolations.size() == 0 @@ -56,7 +58,8 @@ class VerifyPublicationTaskSpec extends Specification { then: noExceptionThrown() - def holderExtension = project.extensions.findByType(PublishVerificationPlugin.VerificationViolationsCollectorHolderExtension) + def holderExtension = project.getGradle().getSharedServices().registerIfAbsent("verificationViolationsCollectorService", VerificationViolationsCollectorService.class, spec -> { + }).get() holderExtension.collector.size() == 1 def violations = holderExtension.collector[project.name] violations.statusViolations.size() == 1 @@ -88,7 +91,8 @@ class VerifyPublicationTaskSpec extends Specification { then: noExceptionThrown() - def holderExtension = project.extensions.findByType(PublishVerificationPlugin.VerificationViolationsCollectorHolderExtension) + def holderExtension = project.getGradle().getSharedServices().registerIfAbsent("verificationViolationsCollectorService", VerificationViolationsCollectorService.class, spec -> { + }).get() holderExtension.collector.size() == 1 def violations = holderExtension.collector[project.name] violations.statusViolations.size() == 0 @@ -111,7 +115,8 @@ class VerifyPublicationTaskSpec extends Specification { then: noExceptionThrown() - def holderExtension = project.extensions.findByType(PublishVerificationPlugin.VerificationViolationsCollectorHolderExtension) + def holderExtension = project.getGradle().getSharedServices().registerIfAbsent("verificationViolationsCollectorService", VerificationViolationsCollectorService.class, spec -> { + }).get() holderExtension.collector.size() == 1 def violations = holderExtension.collector[project.name] violations.statusViolations.size() == 0 @@ -119,7 +124,8 @@ class VerifyPublicationTaskSpec extends Specification { } Task setupProjectAndTask(Project project, String libraryStatus, String projectStatus) { - def extension = project.extensions.create('collectorExtension', PublishVerificationPlugin.VerificationViolationsCollectorHolderExtension) + Provider verificationViolationsCollectorServiceProvider = project.getGradle().getSharedServices().registerIfAbsent("verificationViolationsCollectorService", VerificationViolationsCollectorService.class, spec -> { + }) project.plugins.apply(JavaPlugin) project.status = projectStatus @@ -128,6 +134,8 @@ class VerifyPublicationTaskSpec extends Specification { def task = project.task('verify', type: VerifyPublicationTask) task.configure { + verificationViolationsCollectorService.set(verificationViolationsCollectorServiceProvider) + usesService(verificationViolationsCollectorServiceProvider) ignore.set(Collections.emptySet()) ignoreGroups.set(Collections.emptySet()) resolvedComponentResultProvider = project.configurations.named(project.sourceSets.main.getRuntimeClasspathConfigurationName()).get().incoming.resolutionResult.rootComponent @@ -136,7 +144,6 @@ class VerifyPublicationTaskSpec extends Specification { }.flatten().collect { Dependency dependency -> new DeclaredDependency(dependency.group, dependency.name, dependency.version) } as List) projectName.set(project.name) targetStatus.set(project.status.toString()) - verificationViolationsCollectorHolderExtension.set(extension) } }