StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy

Clone Tools
  • last updated a few seconds ago
Constraints
Constraints: committers
 
Constraints: files
Constraints: dates
Reshuffle some tests into subpackages

This is just a refactoring of tests, to make it clearer: the base

package started to grow significantly.

    • -1363
    • +0
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 79 more files in changeset.
Make AbstractArchiveTask.destinationDir mandatory

Prior to this commit the working directory was used when the

`destinationDir` was not set. Since this behavior does not play nice

with reproducible builds, it will now fail instead. However, it should

rarely happen because the `base` plugin provides a convention.

    • -0
    • +12
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 26 more files in changeset.
Make AbstractArchiveTask.destinationDir mandatory

Prior to this commit the working directory was used when the

`destinationDir` was not set. Since this behavior does not play nice

with reproducible builds, it will now fail instead. However, it should

rarely happen because the `base` plugin provides a convention.

    • -0
    • +12
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 26 more files in changeset.
Consistently use component level attributes

Component-level attributes were only used if the component metadata was using Gradle

metadata. This was particularly confusing, as it was possible to define a component-

level attribute in a component-metadata rule, but it would be ignored during matching.

It was possible, however, to add attributes on variants of Ivy or Maven metadata,

but then the error messages in case there wasn't any match was even more confusing:

"Because there are no configurations with attributes"

This commit modifies the resolution engine so that it's possible to use component

level attributes independently of whether the underlying component metadata was

constructed from Ivy, Maven or Gradle metadata. It also changes the error messages

to mention either "configuration" or "variant" depending on whether the matching

strategy was using variant-aware dependency management *or* legacy configurations.

It was confusing because we have the `IMPROVED_POM_SUPPORT` flag which activates

variant construction from Maven metadata. This meant that in practice, if the flag

was active, we were using variants, but still the component level attributes were

not taken into account. If the flag wasn't active, then we would fail with the

error above, despite the fact we had rules on "configuration backed variants".

The separation of configuration/variant in error messages makes it easier for

us to understand in which case we are, since this wasn't always obvious. If we

see "variant", then now we know that the selection failed using the variant-aware

matching. If we see "configuration", then we know it's using the legacy mode.

This commit also needed to make the difference between "this component has no

variant" and "this component doesn't provide any mapping to variants", therefore

the introduction of the `Optional` on `getVariantsForTraversal`. This gives us

the opportunity to give the correct error message in case of failure using

the legacy mode.

Last but not least, this introduces a change in the attributes visible on variants

**and** artifacts. Before this commit, dependending on whether metadata was

Gradle metadata, the "status" attribute would be found or not. Now, the component

level attributes are _always_ merged to variant and artifact attributes, which

means that it's consistent independently of the format. This can be a breaking

change, but a low risk one.

    • -3
    • +3
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 39 more files in changeset.
Revert "Revert "Speed up attribute matching""

    • -8
    • +8
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 14 more files in changeset.
Revert "Speed up attribute matching"

    • -8
    • +8
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 14 more files in changeset.
Make ImmutableAttributes more efficient

Keep the mapping from attribute to value in a map

instead of going up the parent chain on every request.

This is faster since attributes are queried much more

often than they are created and creation is de-duplicated,

so there are only a few such attribute containers in the

whole build.

    • -8
    • +8
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 8 more files in changeset.
Construct matching table more efficiently

To make attribute matching more efficient, we just assume

that all attributes in the schema will be involved in matching

instead of computing the superset of attributes for all candidates.

This avoids filling a LinkedHashSet on every match and we can instead

reuse the already allocated keyset of the schema.

This requires that all attributes are actually declared in the

schema. Until now this was unfortunately not enforced and the Android

plugin uses some attributes without declaring them. To work around this,

this change adds a wrapper around the attribute factory to catch any

undeclared attributes. This wrapper could later be changed to throw

an error instead.

    • -2
    • +2
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 7 more files in changeset.
Make attribute matching more efficient

Replace the many nested objects, sets and maps

with a single array of matching values and a BitSet

tracking which candidates are still "alive".

This significantly reduces memory usage of attribute

matching and makes it run much faster.

    • -3
    • +3
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 7 more files in changeset.
Some restructuring so that variant aware dependency management works regardless of the path via which a particular component is reachable in the graph. Previously, the consumer's attributes were retained only for local components reachable via other local components. This meant, for example, that variant aware dependency management would not work for an included build reachable only via external components.

    • -0
    • +1
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 20 more files in changeset.
Changed attribute matching to consider two attributes with the same name as the _same_ attribute, failing if the producer and consumer values have types that are not compatible. Previously, two attributes with the same name and different types would be considered distinct attributes, leading to some confusing behaviour when types are mismatched.

    • -11
    • +5
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 2 more files in changeset.
Limit the type of attributes to types we can make immutable

This commit restricts the possibilities of custom types for attributes. Since attributes are used in various

places, potentially different classloaders or even different process, we need a stable way to make them

both snapshottable and serializable. This commit is the first step, by making it impossible to create attributes

with arbitrary types.

Types that we support include:

- scalar types, which are primitive types (and their wrappers), `File` or `String` (aka, known immutables)

- a type extending `Named`, in which case it is expected to create values using the `ObjectFactory`

- an enum

- an array of the above (arrays are not immutable, but we can create immutable values out of arrays)

Some tests had to be adjusted, because they didn't match those constraints. Future work will include possibilities

to include richer types.

    • -39
    • +36
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 5 more files in changeset.
Remove `assumeCompatibleWhenMissing` from `CompatibilityRuleChain`

This method was already a no-op. Now is time for removal.

    • -8
    • +2
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 10 more files in changeset.
Fixed test expectation for change to error message.

    • -2
    • +2
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
Changed the way that the target configuration for a project dependency is calculated, to always select only from the configurations of the target project that have attributes attached, regardless of whether the consumer has defined any attributes or not. Fall back to `default` only when the target project has no configurations with attributes defined.

This introduces a breaking change when consuming the output of a project with the Java plugin applied from a project that does not have the Java plugin applied. Previously, the `default` configuration would be selected, now the `runtimeElements` configuration is selected. However, this is consistent with the case where the consuming project is also using the Java plugin or is using the Android plugin. It also means that custom configurations in these projects will select the same thing as the runtime classpath configuration.

    • -0
    • +57
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 13 more files in changeset.
Added `MultipleCandidatesDetails.getConsumerValue()` to allow an attribute disambiguation rule to select the best match based on the consumer's value, if any.

    • -0
    • +86
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 7 more files in changeset.
Treat various kinds of dependency resolution failures in more consistent ways.

- When a non-lenient view is used as a task input, then propagate any failure to select a configuration in the dependency graph during task graph calculation, rather than suppressing these kinds of failures and propagating later when the files happen to be queried. This now happens consistently whether fluid dependencies are used or not. The only difference between these is how much of the graph is traversed at task graph calculation time.

- When a lenient view is used as a task input, suppress configuration selection failures during task graph calculation and instead present them in `ArtifactCollection.failures`. Do this consistently regardless of whether fluid dependencies are used or not. Previously this kind of failure was propagated during task graph calculation for lenient views.

Also changed the error message on resolution failure to include what kind of query was being performed at the time to trigger the failure.

From an implementation point of view, separated the handling of selection failures from the code that produces the legacy resolution result so that this handling can be reused when the legacy result is not required (such as, say, when calculating the task graph).

    • -27
    • +8
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 34 more files in changeset.
Do not treat a failure to select the target configurations for a particular dependency edge as a fatal error, and instead treat this kind of failure in the same way as other kinds of failures and continue with dependency graph resolution.

    • -4
    • +26
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 3 more files in changeset.
Tweaked the error message when attempting to create an instance of an object with a private constructor that is not annotated with `@Inject`.

    • -2
    • +2
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 2 more files in changeset.
Changed variant attribute matching to prefer variants whose value for a particular attribute is the same as the consumer value, over those variants whose value is different to but compatible with the consumer value. That is, added a hard-coded rule to say "prefer the requested value over all others" when disambiguating matches.

    • -24
    • +93
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 6 more files in changeset.
Improved the 'no matching variant' and 'too many matching variant' error messages to use a better description of each of the variants, such as which project/module and configuration the variant belongs to.

Made a bunch of changes to forward the display name of the variant from where the variant originates from through to the variant selection logic so it can construct the error messages, using `Describable` to represent the display name.

    • -3
    • +3
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 34 more files in changeset.
Changed attribute matching so that a missing attribute is always considered compatible.

`CompatibilityRuleChange.assumeCompatibleWhenMissing()` is now a no-op and will be removed shortly.

    • -4
    • +10
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 11 more files in changeset.
Some fixes for timeout in int test: switched to using Java for unit tests in the test build, and compile everything prior to starting the test build.

    • -0
    • +1
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 8 more files in changeset.
Treat a failure to resolve the dependencies of a configuration as a failure to calculate task dependencies, when using dependency substitution, so that execution fails early. Previously these were ignored, usually to be rethrown later when the files of the configuration were queried.

This is a potential breaking change.

    • -4
    • +8
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 26 more files in changeset.
Fail when no compatible variant can be selected for a component. Continue to ignore components with no compatible variant when using an `ArtifactView` with additional attributes defined, whose implicit contract is to ignore these (this should be an explicit contract).

Made some changes to error messages so that failure to select a variant shows the same useful details as a failure to select a configuration.

    • -3
    • +7
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 24 more files in changeset.
Decoupled the interfaces that are used for attribute matching from the public APIs for defining the compatibility and disambiguation rules. Also changed matching so that we short-circuit evaluation of the rules when the consumer and producer values are equal, rather than doing this at the end of the chain. This means a compatibility rule cannot mark 2 equals values as incompatible, which is probably a good thing.

    • -11
    • +9
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 14 more files in changeset.
Changed attribute matching to chain the producer's rules after the consumer's rules, rather than stopping at the end of the consumer's rules. This allows the consumer to reuse the producer's rules but override certain decisions, and it allows the producer to add new values for an attribute that the consumer knows about which are compatible with the consumer value.

    • -28
    • +210
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 23 more files in changeset.
Consider the attributes attached to the configuration when selecting a variant.

    • -5
    • +5
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 6 more files in changeset.
Use the same instantiation infrastructure for attribute rules as is used for artifact transforms and other types. This change means that attribute rule constructors now need to be annotated with `@Inject`.

    • -2
    • +4
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 14 more files in changeset.
Allow configuration to be injected into attribute compatibility rules and disambiguation rules, using the same pattern as worker actions and artifact transforms.

    • -3
    • +97
    ./StronglyTypedConfigurationAttributesResolveIntegrationTest.groovy
  1. … 12 more files in changeset.