org.gradle.internal.component.AmbiguousConfigurationSelectionException Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2016 the original author or authors.
*
* 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 org.gradle.internal.component;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.gradle.api.attributes.Attribute;
import org.gradle.api.internal.attributes.AttributeContainerInternal;
import org.gradle.api.internal.attributes.AttributeValue;
import org.gradle.api.internal.attributes.AttributeDescriber;
import org.gradle.api.internal.attributes.ImmutableAttributes;
import org.gradle.internal.Cast;
import org.gradle.internal.component.model.AttributeMatcher;
import org.gradle.internal.component.model.ComponentResolveMetadata;
import org.gradle.internal.component.model.ConfigurationMetadata;
import org.gradle.internal.exceptions.StyledException;
import org.gradle.internal.logging.text.StyledTextOutput;
import org.gradle.internal.logging.text.TreeFormatter;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class AmbiguousConfigurationSelectionException extends StyledException {
public AmbiguousConfigurationSelectionException(AttributeDescriber describer, AttributeContainerInternal fromConfigurationAttributes,
AttributeMatcher attributeMatcher,
List extends ConfigurationMetadata> matches,
ComponentResolveMetadata targetComponent,
boolean variantAware,
Set discarded) {
super(generateMessage(new StyledDescriber(describer), fromConfigurationAttributes, attributeMatcher, matches, discarded, targetComponent, variantAware));
}
private static String generateMessage(AttributeDescriber describer, AttributeContainerInternal fromConfigurationAttributes, AttributeMatcher attributeMatcher, List extends ConfigurationMetadata> matches, Set discarded, ComponentResolveMetadata targetComponent, boolean variantAware) {
Map ambiguousConfigurations = new TreeMap<>();
for (ConfigurationMetadata match : matches) {
ambiguousConfigurations.put(match.getName(), match);
}
TreeFormatter formatter = new TreeFormatter();
String configTerm = variantAware ? "variants" : "configurations";
if (fromConfigurationAttributes.isEmpty()) {
formatter.node("Cannot choose between the following " + configTerm + " of ");
} else {
formatter.node("The consumer was configured to find " + describer.describeAttributeSet(fromConfigurationAttributes.asMap()) + ". However we cannot choose between the following " + configTerm + " of ");
}
formatter.append(style(StyledTextOutput.Style.Info, targetComponent.getId().getDisplayName()));
formatter.startChildren();
for (String configuration : ambiguousConfigurations.keySet()) {
formatter.node(configuration);
}
formatter.endChildren();
formatter.node("All of them match the consumer attributes");
// We're sorting the names of the configurations and later attributes
// to make sure the output is consistently the same between invocations
formatter.startChildren();
for (ConfigurationMetadata ambiguousConf : ambiguousConfigurations.values()) {
formatConfiguration(formatter, targetComponent, fromConfigurationAttributes, attributeMatcher, ambiguousConf, variantAware, true, describer);
}
formatter.endChildren();
if (!discarded.isEmpty()) {
formatter.node("The following " + configTerm + " were also considered but didn't match the requested attributes:");
formatter.startChildren();
discarded.stream()
.sorted(Comparator.comparing(ConfigurationMetadata::getName))
.forEach(discardedConf -> formatConfiguration(formatter, targetComponent, fromConfigurationAttributes, attributeMatcher, discardedConf, variantAware, false, describer));
formatter.endChildren();
}
return formatter.toString();
}
static void formatConfiguration(TreeFormatter formatter,
ComponentResolveMetadata targetComponent,
AttributeContainerInternal consumerAttributes,
AttributeMatcher attributeMatcher,
ConfigurationMetadata configuration,
boolean variantAware,
boolean ambiguous,
AttributeDescriber describer) {
AttributeContainerInternal producerAttributes = configuration.getAttributes();
if (variantAware) {
formatter.node("Variant '");
} else {
formatter.node("Configuration '");
}
formatter.append(configuration.getName());
formatter.append("'");
if (variantAware) {
formatter.append(" " + CapabilitiesSupport.prettifyCapabilities(targetComponent, configuration.getCapabilities().getCapabilities()));
}
if (ambiguous) {
formatAttributeMatchesForAmbiguity(formatter, consumerAttributes.asImmutable(), attributeMatcher, producerAttributes.asImmutable(), describer);
} else {
formatAttributeMatchesForIncompatibility(formatter, consumerAttributes.asImmutable(), attributeMatcher, producerAttributes.asImmutable(), describer);
}
}
static void formatAttributeMatchesForIncompatibility(TreeFormatter formatter,
ImmutableAttributes immutableConsumer,
AttributeMatcher attributeMatcher,
ImmutableAttributes immutableProducer,
AttributeDescriber describer) {
Map> allAttributes = collectAttributes(immutableConsumer, immutableProducer);
List otherValues = Lists.newArrayListWithExpectedSize(allAttributes.size());
Map, ?> compatibleAttrs = Maps.newLinkedHashMap();
Map, ?> incompatibleAttrs = Maps.newLinkedHashMap();
Map, ?> incompatibleConsumerAttrs = Maps.newLinkedHashMap();
for (Attribute> attribute : allAttributes.values()) {
Attribute
© 2015 - 2025 Weber Informatics LLC | Privacy Policy