Skip to content

[pull] develop from mikepenz:develop - #15

Merged
pull[bot] merged 8 commits into
wsnchristopher:developfrom
mikepenz:develop
Aug 14, 2026
Merged

[pull] develop from mikepenz:develop#15
pull[bot] merged 8 commits into
wsnchristopher:developfrom
mikepenz:develop

Conversation

@pull

@pull pull Bot commented Aug 14, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

sergeys-opera and others added 8 commits August 13, 2026 11:23
…tions

Each library in the generated metadata can now carry a `variants` array
listing the raw Gradle configuration names it was resolved from, e.g.
`["androidCompileClasspath", "androidRuntimeClasspath"]`.

Enabled via `collect { includeVariants = true }`. It is disabled by
default, and the plugin-side field is nullable so `excludeNulls()` in the
JSON writer omits the key entirely when off — existing metadata files are
unaffected. It can also be dropped per export via
`excludeFields.add("Library.variants")`.

Configuration provenance is gathered before the `uniqueId`-keyed
deduplication that would otherwise discard it. The lookup is derived from
the selected configurations rather than stored on `DependencyData`, since
each coordinate is parsed exactly once and its `DependencyData` instance is
shared by every configuration containing it. Values are sorted to keep the
output byte-for-byte reproducible. Provenance is also unioned across
duplicates collapsed by `DuplicateMode.MERGE` and across config overrides.

The field is exposed on the runtime `Library` entity and read by both the
Android and multiplatform parsers.
…classpaths

- order selected configurations runtime-classpath first, so the version kept
  by `deduplicateDependencies` is the one that actually ships when compile and
  runtime resolve differently
- never materialize `variants` from a config override while `includeVariants`
  is off
- report config-only libraries (not part of any resolved configuration) with an
  empty `variants` set instead of a missing key

Also enables `includeVariants` in `app-test` and regenerates its fixture.
…n names

Renames `collect.includeVariants` to `collect.includeTargets` and the emitted
`variants` array to `targets`, and changes what it holds: Kotlin target names
(`jvm`, `android`, `iosX64`, `wasmJs`) rather than the raw Gradle configuration
names a library happened to resolve from.

Configuration names were the wrong unit. A single jvm target produced four
entries — `jvmCompileClasspath`, `jvmMainCompileClasspath`,
`jvmMainRuntimeClasspath`, `jvmRuntimeClasspath` — none of which a consumer can
match against at runtime. Target names collapse those to `["jvm"]` and make the
intended use possible: narrowing the rendered list to what the running target
actually links against, e.g. `libs.libraries.filter { "iosArm64" in it.targets }`.

Attribution comes from the Kotlin target model — each `KotlinCompilation`'s
`compileDependencyConfigurationName` / `runtimeDependencyConfigurationName` — not
from the `org.jetbrains.kotlin.platform.type` attribute, which is absent on
source-set level configurations (`jvmMainCompileClasspath`) and cannot separate
`wasmJs` from `wasmWasi` nor `iosX64` from `iosArm64`. Configurations the model
does not claim fall back to a prefix match against the known target names, so
source-set configurations fold into their target; an AGP-only build reports its
build variant, and a project with no Kotlin plugin reports nothing rather than
inventing a name no consumer could match.

The Kotlin extension is resolved by name so no KGP class is touched when the
plugin is absent (it is a `compileOnly` dependency).

Rebuilding the `app-test` fixture also refreshes `org.jetbrains:annotations`,
whose upstream LICENSE.txt is no longer plain Apache-2.0 — unrelated to this
change, picked up by `fetchRemoteLicense`.

BREAKING CHANGE: `collect.includeVariants` is now `collect.includeTargets`,
`Library.variants` is now `Library.targets`, and the values are Kotlin target
names rather than Gradle configuration names. Both were introduced on this
branch and have not shipped.
An Android-only module emitted `"targets":[""]` on every library. The
single-target Kotlin extensions (`kotlin("android")`, `kotlin("jvm")`) name
their only target `""` — there is no sibling to disambiguate it from — and that
empty name was passed straight through.

Skips blank target names when building the configuration→target map, and drops
the configuration-name fallback that would otherwise take over and report build
variants (`debug`, `release`) instead. Build variants are not targets, and
`export.variant` already covers splitting an Android build that way.

A single-target project compiles for exactly one target, so every library now
reports an empty `targets` array — nothing to attribute, and nothing a consumer
could filter by. Multiplatform output is unchanged: source-set level
configurations still fold into their target by prefix, so `app-test` still
reports `["jvm"]` / `["jvm","metadata","wasmJs"]`.
Make it possible to trace the library origin in a multiplatform project
…der their root coordinate

Closes #1430

A dependency declared as `com.mikepenz:aboutlibraries-compose-core` can be
reported as `com.mikepenz:aboutlibraries-compose-core-android`, which makes
generated entries hard to match against what the build script declares and breaks
`config` overrides keyed on the declared id.

Gradle's resolution graph contains both the KMP root module — an `available-at`
redirect shell such as `androidx.collection:collection` — and the resolved
platform artifact `androidx.collection:collection-jvm`. Both become entries, and
the default `DuplicateMode.MERGE` then collapses them by graph iteration order,
so which `uniqueId` survives is arbitrary. Note the collapse already happens
today: this option does not introduce it, it makes the survivor deterministic and
names it after the declared coordinate.

    aboutLibraries {
        library {
            mergePlatformArtifacts = true
        }
    }

The redirect shell is dropped and its module name carried onto the platform
artifact. Detection reads `ResolvedComponentResult.variants[].externalVariant`;
only a component whose variants *all* redirect to a single target within the same
group counts as a shell, so nothing is stripped by suffix and a directly declared
`androidx.annotation:annotation-jvm` is untouched. No additional artifact
resolution — configuration-cache and project-isolation safe. Metadata (name,
description, licenses) still comes from the resolved artifact's POM. Independent
of `duplicationMode` / `duplicationRule` and applied before them. Defaults to
`false`, so existing output is unchanged.

`rootModule` is held outside `DependencyCoordinates`' constructor so it takes no
part in `equals`/`hashCode`: it records how an artifact was reached, not which
artifact it is. The same `g:a:v` reached through a redirect in one configuration
and directly in another therefore stays one coordinate, rather than being spread
over two version slots and resolved twice. `cacheKey()` already ignored it.

`LibraryPostProcessor` also deduplicates on an exact variant match, since several
platform artifacts can now collapse onto the same root id within one
configuration, and an exact hit that dedups to empty must not fall through to the
prefix-match branch.

Named `mergePlatformArtifacts` rather than `mergeVariants` because "variant"
already means Android build variant throughout this plugin (`filterVariants`,
`includeTestVariants`, `export.variant`), and to keep it distinct from the
`targets` field.

Tests resolve real `androidx.collection` / `androidx.annotation` coordinates:

- default: root and platform artifact are both reported (unchanged behaviour)
- enabled: only `androidx.collection:collection` remains, metadata preserved
- enabled, suffixed coordinate with no redirect in the graph: `annotation-jvm`
  kept as-is
- enabled, platform artifact reached before its shell: merge is independent of
  graph walk order
- non-multiplatform trees: byte-identical with and without the option
- a two-target (jvm + js) multiplatform consumer with `collect.includeTargets`:
  the merged entry is named for the declared root and carries the union of its
  targets, where without merging the survivor is named for one platform while
  standing for all of them
feat(plugin): add `mergePlatformArtifacts` to report KMP artifacts under their root coordinate
@pull pull Bot locked and limited conversation to collaborators Aug 14, 2026
@pull pull Bot added the ⤵️ pull label Aug 14, 2026
@pull
pull Bot merged commit 2191034 into wsnchristopher:develop Aug 14, 2026
3 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants