Skip to content

Commit

Permalink
Merge pull request #24118 Clear root metadata when extending configur…
Browse files Browse the repository at this point in the history
…ations

The hierarchy is saved as an instance variable in configuration metadata. The mutation type for configuration extension
was DEPENDENCIES, which only caused the cached metadata to be reevaluated. This is not sufficient. We add a new mutation
type for HIERARCHY which completely discards the metadata, allowing it to be recalculated and the new hierarchy value
to be passed to the configuration metadata

Fixes #24109

Co-authored-by: Justin Van Dort <jvandort@gradle.com>
  • Loading branch information
bot-gradle and jvandort committed Mar 2, 2023
2 parents 038ae59 + 8fcba91 commit 79a3a14
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 3 deletions.
Expand Up @@ -104,4 +104,35 @@ task checkResolveParentThenChild {
succeeds "checkResolveChild"
succeeds "checkResolveParentThenChild"
}

@Issue("https://github.com/gradle/gradle/issues/24109")
def "can resolve configuration after extending a resolved configuration"() {
given:
mavenRepo.module("org", "foo").publish()

buildFile << """
repositories {
maven { url "${mavenRepo.uri}" }
}
configurations {
superConfiguration
subConfiguration
}
dependencies {
superConfiguration 'org:foo:1.0'
}
task resolve {
println configurations.superConfiguration.files.collect { it.name }
configurations.subConfiguration.extendsFrom(configurations.superConfiguration)
println configurations.subConfiguration.files.collect { it.name }
}
"""

when:
succeeds("resolve")

then:
output.contains("[foo-1.0.jar]\n[foo-1.0.jar]")
}
}
Expand Up @@ -381,7 +381,7 @@ public Set<Configuration> getExtendsFrom() {

@Override
public Configuration setExtendsFrom(Iterable<Configuration> extendsFrom) {
validateMutation(MutationType.DEPENDENCIES);
validateMutation(MutationType.HIERARCHY);
for (Configuration configuration : this.extendsFrom) {
if (inheritedArtifacts != null) {
inheritedArtifacts.removeCollection(configuration.getAllArtifacts());
Expand All @@ -403,7 +403,7 @@ public Configuration setExtendsFrom(Iterable<Configuration> extendsFrom) {

@Override
public Configuration extendsFrom(Configuration... extendsFrom) {
validateMutation(MutationType.DEPENDENCIES);
validateMutation(MutationType.HIERARCHY);
for (Configuration configuration : extendsFrom) {
if (configuration.getHierarchy().contains(this)) {
throw new InvalidUserDataException(String.format(
Expand Down
Expand Up @@ -46,7 +46,12 @@ enum MutationType {
/**
* The mutation of the role of the configuration (can be queries, resolved, ...)
*/
ROLE("role");
ROLE("role"),

/**
* The mutation of the hierarchy of the configuration, i.e. which configurations this configuration extends from.
*/
HIERARCHY("hierarchy");

private final String displayName;

Expand Down
Expand Up @@ -156,6 +156,11 @@ public void validateMutation(MutationType type) {
cachedValue.reevaluate();
}
}
} else if (type == MutationType.HIERARCHY) {
// The hierarchy is provided to the configuration metadata on construction. Since it is not
// computed lazily, there is no lazy value to invalidate. Thus, we need to recompute the
// entire component in order to reconstruct new configuration metadatas with new hierarchy values.
cachedValue = null;
}
}

Expand Down
Expand Up @@ -137,6 +137,28 @@ class DefaultRootComponentMetadataBuilderTest extends Specification {
]
}

def "discards component metadata when hierarchy changes"() {
componentIdentifierFactory.createComponentIdentifier(_) >> {
new DefaultModuleComponentIdentifier(mid, '1.0')
}
def root = builder.toRootComponentMetaData()

def conf = root.getConfiguration("conf")
assert conf.needsReevaluate()
conf.realizeDependencies()
assert !conf.needsReevaluate()

when:
builder.validator.validateMutation(MutationValidator.MutationType.HIERARCHY)
def otherRoot = builder.toRootComponentMetaData()
def otherConf = otherRoot.getConfiguration("conf")

then:
root != otherRoot
conf != otherConf
otherConf.needsReevaluate()
}

def "does not reevaluate component metadata when #mutationType change"() {
componentIdentifierFactory.createComponentIdentifier(_) >> {
new DefaultModuleComponentIdentifier(mid, '1.0')
Expand Down

0 comments on commit 79a3a14

Please sign in to comment.