From 9754d4e2603236123d0fc63bd4a38bdbc0207722 Mon Sep 17 00:00:00 2001 From: Justin Van Dort Date: Tue, 21 Feb 2023 16:48:00 -0500 Subject: [PATCH] Clear root metadata when adding or removing configurations This ensures when a configuration is removed and added between resolutions, we can clear and subsequently re-calculate updated metadata --- .../AddingConfigurationIntegrationTest.groovy | 26 ++++++++++++++++++- .../DefaultConfigurationContainer.java | 2 ++ .../DefaultRootComponentMetadataBuilder.java | 4 +++ .../DefaultConfigurationContainerSpec.groovy | 4 ++- .../DefaultConfigurationContainerTest.groovy | 5 +++- 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/AddingConfigurationIntegrationTest.groovy b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/AddingConfigurationIntegrationTest.groovy index 932968ab9932..ac695f39919a 100644 --- a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/AddingConfigurationIntegrationTest.groovy +++ b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/AddingConfigurationIntegrationTest.groovy @@ -18,7 +18,6 @@ package org.gradle.integtests.resolve.api import org.gradle.integtests.fixtures.AbstractIntegrationSpec - class AddingConfigurationIntegrationTest extends AbstractIntegrationSpec { def "can add configurations" () { buildFile << """ @@ -79,4 +78,29 @@ class AddingConfigurationIntegrationTest extends AbstractIntegrationSpec { expect: succeeds "addConfigs" } + + def "can remove and add configurations between resolutions"() { + given: + mavenRepo.module("org", "foo", "1.0").publish() + + buildFile << """ + repositories { + maven { url '$mavenRepo.uri' } + } + + task resolve { + def conf = configurations.create("conf") + conf.dependencies.add(project.dependencies.create("org:foo:1.0")) + conf.files + configurations.remove(conf) + + def conf2 = configurations.create("conf2") + conf2.dependencies.add(project.dependencies.create("org:foo:1.0")) + conf2.files + } + """ + + expect: + succeeds("resolve") + } } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainer.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainer.java index 1c504416e074..d6aff4d59c62 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainer.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainer.java @@ -81,6 +81,8 @@ public DefaultConfigurationContainer( }; this.rootComponentMetadataBuilder = rootComponentMetadataBuilderFactory.create(this); this.defaultConfigurationFactory = defaultConfigurationFactory; + this.getEventRegister().registerLazyAddAction(x -> rootComponentMetadataBuilder.discardAll()); + this.whenObjectRemoved(x -> rootComponentMetadataBuilder.discardAll()); } @Override diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/ivyservice/moduleconverter/DefaultRootComponentMetadataBuilder.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/ivyservice/moduleconverter/DefaultRootComponentMetadataBuilder.java index 4b7ff0a261d9..74df735dccf9 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/ivyservice/moduleconverter/DefaultRootComponentMetadataBuilder.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/ivyservice/moduleconverter/DefaultRootComponentMetadataBuilder.java @@ -131,6 +131,10 @@ public MutationValidator getValidator() { return holder; } + public void discardAll() { + holder.cachedValue = null; + } + private static class MetadataHolder implements MutationValidator { private DefaultLocalComponentMetadata cachedValue; private final ConfigurationsProvider configurationsProvider; diff --git a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainerSpec.groovy b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainerSpec.groovy index 60889891e399..74c60d51a944 100644 --- a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainerSpec.groovy +++ b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainerSpec.groovy @@ -15,6 +15,7 @@ */ package org.gradle.api.internal.artifacts.configurations +import org.gradle.api.Action import org.gradle.api.artifacts.UnknownConfigurationException import org.gradle.api.internal.CollectionCallbackActionDecorator import org.gradle.api.internal.DocumentationRegistry @@ -72,8 +73,9 @@ class DefaultConfigurationContainerSpec extends Specification { private UserCodeApplicationContext userCodeApplicationContext = Mock() private CalculatedValueContainerFactory calculatedValueContainerFactory = Mock() - private CollectionCallbackActionDecorator domainObjectCollectionCallbackActionDecorator = Mock() { + private CollectionCallbackActionDecorator domainObjectCollectionCallbackActionDecorator = Mock(CollectionCallbackActionDecorator) { decorateSpec(_) >> { Spec spec -> spec } + decorate(_ as Action) >> { it[0] } } def immutableAttributesFactory = AttributeTestUtil.attributesFactory() private DefaultRootComponentMetadataBuilder.Factory rootComponentMetadataBuilderFactory = Mock(DefaultRootComponentMetadataBuilder.Factory) { diff --git a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainerTest.groovy b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainerTest.groovy index f1860561bdeb..e8bc9d217c12 100644 --- a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainerTest.groovy +++ b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainerTest.groovy @@ -17,6 +17,7 @@ package org.gradle.api.internal.artifacts.configurations import groovy.test.NotYetImplemented +import org.gradle.api.Action import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.UnknownConfigurationException import org.gradle.api.internal.CollectionCallbackActionDecorator @@ -63,7 +64,9 @@ class DefaultConfigurationContainerTest extends Specification { private DependencyLockingProvider lockingProvider = Mock(DependencyLockingProvider) private ProjectStateRegistry projectStateRegistry = Mock(ProjectStateRegistry) private DocumentationRegistry documentationRegistry = Mock(DocumentationRegistry) - private CollectionCallbackActionDecorator callbackActionDecorator = Mock() + private CollectionCallbackActionDecorator callbackActionDecorator = Mock(CollectionCallbackActionDecorator) { + decorate(_ as Action) >> { it[0] } + } private UserCodeApplicationContext userCodeApplicationContext = Mock() private CalculatedValueContainerFactory calculatedValueContainerFactory = Mock() private Instantiator instantiator = TestUtil.instantiatorFactory().decorateLenient()