Skip to content

Commit

Permalink
Merge main into branch and fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanalvarado committed May 14, 2024
2 parents 3c6b55e + 71cf517 commit 3cd104e
Show file tree
Hide file tree
Showing 103 changed files with 1,428 additions and 606 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
Dependency Analysis Plugin Changelog

# Version 1.31.0
* [Fix] support Isolated Projects.
* [Fix] only use new configurations factories from Gradle 8.5.
* [Fix] Do not suggest to move dependencies between feature variants
* [Fix] Reason explanation id ambiguity
* [Fix] Use a hash in file name for dependencies with capabilities
* [Fix] make file relativizing work properly on Windows
* [Fix] try/catch to workaround AGP issue.
* [Fix] enhance logging when ConstantPoolParser throws exception.
* [Chore] no group for 'internal' tasks.

# Version 1.30.0
* [Fix] Don't pass in android res (incl layouts) to XmlSourceExploderTask.
* [Fix] Use AGP-blessed API for getting compiled class files instead of bundleTask.
Expand Down
20 changes: 20 additions & 0 deletions README.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,26 @@ For a quick start, just run the following:
./gradlew buildHealth
----

You will probably see output like the following:

----
> Task :buildHealth FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':buildHealth'.
> There were dependency violations. See report at file:///path/to/project/build/reports/dependency-analysis/build-health-report.txt
----

If you wish to have this (potentially very long) report printed to console, add this to your `gradle.properties` file:

.gradle.properties
[source]
----
dependency.analysis.print.build.health=true
----

== More advanced usage

=== Project Health
Expand Down
2 changes: 1 addition & 1 deletion build-logic/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pluginManagement {
mavenCentral()
}
plugins {
id("org.jetbrains.kotlin.jvm") version "1.9.10"
id("org.jetbrains.kotlin.jvm") version "1.9.22"
}
}

Expand Down
7 changes: 7 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ gradleTestKitSupport {

dependencies {
implementation(platform(libs.kotlin.bom))
implementation(platform(libs.okio.bom))

api(libs.guava) {
because("Graphs")
Expand Down Expand Up @@ -317,6 +318,12 @@ dependencyAnalysis {
includeDependency("org.jetbrains.kotlin:kotlin-gradle-plugin")
includeDependency("org.jetbrains.kotlin:kotlin-gradle-plugin-api")
}
bundle("truth") {
includeDependency(libs.truth)
// Truth's Subject class makes use of the @Nullable annotation from this library when creating `Factory`s. It ends
// up in the bytecode, but I don't really have any control over that.
includeDependency("org.checkerframework:checker-qual")
}
}

abi {
Expand Down
7 changes: 5 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# Copyright (c) 2024. Tony Robalik.
# SPDX-License-Identifier: Apache-2.0
org.gradle.jvmargs=-Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:MaxMetaspaceSize=1024m
org.gradle.jvmargs=-Xmx6G \
-Dfile.encoding=UTF-8 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:MaxMetaspaceSize=1024m
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.configuration-cache=true

VERSION=1.30.1-SNAPSHOT
VERSION=1.31.1-SNAPSHOT

dependency.analysis.autoapply=false
dependency.analysis.print.build.health=true
Expand Down
47 changes: 28 additions & 19 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
[versions]
antlr-shadowed = "4.10.1.6"
asm-relocated = "9.6.0.1"
caffeine = "3.1.8"
commons-io = "2.16.0"
dagp = "1.31.0"
error-prone = "2.26.1"
gradle-publish-plugin = "1.1.0"
grammar = "0.3"
guava = "33.1.0-jre"
java = "11"
junit = "5.8.2"
kotlin = "1.9.10"
moshi = "1.14.0"
moshix = "0.19.0"
okio = "2.10.0"
retrofit = "2.9.0"
junit = "5.10.2"
kotlin = "1.9.22"
kotlinx-metadata = "0.9.0"
moshi = "1.15.1"
moshix = "0.25.1"
okhttp = "4.12.0"
okio = "3.9.0"
retrofit = "2.11.0"
spock = "2.3-groovy-3.0"
truth = "1.4.2"

agp = "8.0.2"
#agp = "8.1.4
Expand All @@ -20,32 +30,32 @@ agp-common = "31.2.0"
agp = { module = "com.android.tools.build:gradle", version.ref = "agp" }
android-tools-common = { module = "com.android.tools:common", version.ref = "agp-common" }

caffeine = "com.github.ben-manes.caffeine:caffeine:3.1.0"
commons-io = "commons-io:commons-io:2.11.0"
errorProne = "com.google.errorprone:error_prone_annotations:2.11.0"
gradle-publish-plugin = "com.gradle.plugin-publish:com.gradle.plugin-publish.gradle.plugin:1.1.0"
caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" }
commons-io = { module = "commons-io:commons-io", version.ref = "commons-io" }
errorProne = { module = "com.google.errorprone:error_prone_annotations", version.ref = "error-prone" }
gradle-publish-plugin = { module = "com.gradle.plugin-publish:com.gradle.plugin-publish.gradle.plugin", version.ref = "gradle-publish-plugin" }
grammar = { module = "com.autonomousapps:gradle-script-grammar", version.ref = "grammar" }
guava = "com.google.guava:guava:31.1-jre"
guava = { module ="com.google.guava:guava", version.ref = "guava" }

javax-inject = "javax.inject:javax.inject:1"

kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
kotlin-dokka = { module = "org.jetbrains.dokka:kotlin-as-java-plugin", version.ref = "kotlin" }
kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
kotlin-stdlib-core = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
kotlinx-metadata-jvm = "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.8.0"
kotlinx-metadata-jvm = { module = "org.jetbrains.kotlinx:kotlinx-metadata-jvm", version.ref = "kotlinx-metadata" }

moshi-core = { module = "com.squareup.moshi:moshi", version.ref = "moshi" }
moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" }
moshi-adapters = { module = "com.squareup.moshi:moshi-adapters", version.ref = "moshi" }

moshix-ksp = { module = "dev.zacsweers.moshix:moshi-ksp", version.ref = "moshix" }
moshix-sealed-reflect = { module = "dev.zacsweers.moshix:moshi-sealed-reflect", version.ref = "moshix" }
moshix-sealed-runtime = { module = "dev.zacsweers.moshix:moshi-sealed-runtime", version.ref = "moshix" }

okhttp3 = "com.squareup.okhttp3:okhttp:4.9.0"
okhttp3 = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
okio = { module = "com.squareup.okio:okio", version.ref = "okio" }
okio-bom = { module = "com.squareup.okio:okio-bom", version.ref = "okio" }

relocated-antlr = { module = "com.autonomousapps:antlr", version.ref = "antlr-shadowed" }
relocated-asm = { module = "com.autonomousapps:asm-relocated", version.ref = "asm-relocated" }
Expand All @@ -58,9 +68,8 @@ junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "jun
junit-bom = { module = "org.junit:junit-bom", version.ref = "junit" }
junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
junit-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" }
mockito-kotlin = "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
spock = "org.spockframework:spock-core:2.1-groovy-3.0"
truth = "com.google.truth:truth:1.1.3"
spock = { module = "org.spockframework:spock-core", version.ref = "spock" }
truth = { module = "com.google.truth:truth", version.ref = "truth" }

[plugins]
dependencyAnalysis = { id = "com.autonomousapps.dependency-analysis", version = "1.29.0" }
dependencyAnalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dagp" }
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2024. Tony Robalik.
// SPDX-License-Identifier: Apache-2.0
package com.autonomousapps.graph

import com.autonomousapps.graph.DominanceTreeWriter.NodeWriter

public class DominanceTreeDataWriter<N : Any>(
private val root: N,
private val tree: DominanceTree<N>,
private val nodeWriter: NodeWriter<N>,
) {

public val sizeTree: DependencySizeTree<N> by lazy { dfs(root) }

private fun dfs(node: N): DependencySizeTree<N> {
return DependencySizeTree(
self = node,
size = nodeWriter.getSize(node),
totalSize = nodeWriter.getTreeSize(node),
dependencies = tree.dominanceGraph.successors(node)
.run { nodeWriter.comparator()?.let { sortedWith(it) } ?: this }
.map { dfs(it) }
)
}
}

public data class DependencySizeTree<N>(
val self: N,
val size: Long?,
val totalSize: Long?,
val dependencies: List<DependencySizeTree<N>>
) {
public fun <M> map(f: (N) -> M): DependencySizeTree<M> = DependencySizeTree(
self = f(self),
size = size,
totalSize = totalSize,
dependencies = dependencies.map { it.map(f) }
)
}

Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ public class DominanceTreeWriter<N : Any>(

/** String representation of [node] that will be printed to console. */
public fun toString(node: N): String

/** Total size of the node */
public fun getTreeSize(node: N): Long?

/** The size of the node itself */
public fun getSize(node: N): Long?
}

private companion object {
Expand Down
5 changes: 3 additions & 2 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ pluginManagement {
id("com.github.johnrengelman.shadow") version "8.1.1"
id("com.gradle.enterprise") version "3.15.1"
id("com.gradle.plugin-publish") version "1.1.0"
id("org.jetbrains.kotlin.jvm") version "1.9.10"
id("org.jetbrains.dokka") version "1.9.0"
id("org.jetbrains.kotlin.jvm") version "1.9.22"
id("org.jetbrains.dokka") version "1.9.20"
}
}

plugins {
id("com.gradle.enterprise")
id("org.gradle.toolchains.foojay-resolver-convention") version("0.8.0")
}

// Yes, this is also in pluginManagement above. This is required for normal dependencies.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ abstract class AbstractFunctionalSpec extends Specification {
protected static final GRADLE_8_4 = GradleVersion.version('8.4')
protected static final GRADLE_8_5 = GradleVersion.version('8.5')
protected static final GRADLE_8_6 = GradleVersion.version('8.6')
protected static final GRADLE_8_7 = GradleVersion.version('8.7-rc-2')
protected static final GRADLE_8_7 = GradleVersion.version('8.7')

// For faster CI times, we only test min + max. Testing all would be preferable, but we don't have till the heat death
// of the universe.
protected static final SUPPORTED_GRADLE_VERSIONS = [
GradleVersions.minGradleVersion,
GRADLE_8_6,
GRADLE_8_7,
]

protected GradleProject gradleProject = null
Expand Down Expand Up @@ -87,7 +87,7 @@ abstract class AbstractFunctionalSpec extends Specification {
}
}

// TODO only needed due to some CC issues in 7.4, remove an replace with above, once 7.5 becomes the minimum.
// TODO only needed due to some CC issues in 7.4, remove and replace with above, once 7.5 becomes the minimum.
protected static List<GradleVersion> gradleVersionsCC() {
return gradleVersions().collect { it == GradleVersions.minGradleVersion ? GRADLE_7_5 : it }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,23 @@ abstract class AbstractProject extends AbstractGradleProject {

private static final String NO_AUTO_APPLY = "dependency.analysis.autoapply=false"
private static final String PRINT_ADVICE = "dependency.analysis.print.build.health=true"
protected static final String ADDITIONAL_PROPERTIES = GradleProperties.of(PRINT_ADVICE, NO_AUTO_APPLY)
protected static final GradleProperties ADDITIONAL_PROPERTIES = GradleProperties.of(PRINT_ADVICE, NO_AUTO_APPLY)

/** Applies the 'org.jetbrains.kotlin.jvm' plugin. */
protected static final List<Plugin> kotlinOnly = [Plugins.kotlinNoVersion]

/** Applies the 'org.jetbrains.kotlin.jvm' and 'com.autonomousapps.dependency-analysis' plugins. */
protected static final List<Plugin> kotlin = [Plugins.kotlinNoVersion, Plugins.dependencyAnalysisNoVersion]

/** Applies the 'java-library' and 'com.autonomousapps.dependency-analysis' plugins. */
protected static final List<Plugin> javaLibrary = [Plugin.javaLibrary, Plugins.dependencyAnalysisNoVersion]

@Override
protected GradleProject.Builder newGradleProjectBuilder(
GradleProject.DslKind dslKind = GradleProject.DslKind.GROOVY
) {
def additionalProperties = ADDITIONAL_PROPERTIES
// There is a Gradle bug that makes tests break when the test uses CC and we're also debugging
// There is a Gradle bug that makes tests break when the test uses CC/IP and we're also debugging
if (!DebugAware.debug) {
additionalProperties += GradleProperties.enableConfigurationCache()
}
Expand Down
31 changes: 31 additions & 0 deletions src/functionalTest/groovy/com/autonomousapps/AdviceHelper.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import com.autonomousapps.advice.PluginAdvice
import com.autonomousapps.kit.GradleProject
import com.autonomousapps.model.*

import static com.autonomousapps.kit.gradle.dependencies.Dependencies.kotlinStdLib

/**
* Helps specs find advice output in test projects.
*/
Expand Down Expand Up @@ -93,6 +95,35 @@ final class AdviceHelper {
return new ProjectAdvice(projectPath, advice, pluginAdvice, moduleAdvice, shouldFail)
}

/**
* This is a workaround for a deficiency in the algorithm. KGP adds the stdlib to the `api` configuration. If Kotlin
* is only used as an implementation detail, then the algo will suggest moving stdlib from api -> implementation.
* This advice cannot be followed. We still don't have a good solution for default dependencies added by plugins.
*/
static Set<Advice> downgradeKotlinStdlib() {
return downgradeKotlinStdlib('main')
}

/**
* This is a workaround for a deficiency in the algorithm. KGP adds the stdlib to the `api` configuration. If Kotlin
* is only used as an implementation detail, then the algo will suggest moving stdlib from api -> implementation.
* This advice cannot be followed. We still don't have a good solution for default dependencies added by plugins.
*/
static Set<Advice> downgradeKotlinStdlib(String sourceSetName) {
def from = sourceSetName == 'main' ? 'api' : "${sourceSetName}Api"
def to = sourceSetName == 'main' ? 'implementation' : "${sourceSetName}Implementation"
return [Advice.ofChange(moduleCoordinates(kotlinStdLib(from)), from, to)]
}

/**
* This is a workaround for a deficiency in the algorithm. KGP adds the stdlib to the `api` configuration. If Kotlin
* is only used as an implementation detail, then the algo will suggest moving stdlib from api -> implementation.
* This advice cannot be followed. We still don't have a good solution for default dependencies added by plugins.
*/
static Set<Advice> removeKotlinStdlib() {
return [Advice.ofRemove(moduleCoordinates(kotlinStdLib('api')), 'api')]
}

private static GradleVariantIdentification defaultGVI(String capability) {
new GradleVariantIdentification(capability ? [capability] as Set : [] as Set, [:])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.autonomousapps.android

import com.autonomousapps.android.projects.AndroidTestSourceProject
import com.autonomousapps.android.projects.AndroidTestsAreIgnorableProject
import org.gradle.util.GradleVersion

import static com.autonomousapps.advice.truth.BuildHealthSubject.buildHealth
Expand Down Expand Up @@ -45,4 +46,22 @@ final class AndroidTestSourceSpec extends AbstractAndroidSpec {
where:
[gradleVersion, agpVersion] << gradleAgpMatrix()
}
// https://github.com/autonomousapps/dependency-analysis-gradle-plugin/issues/1079
def "can ignore androidTest source set (#gradleVersion AGP #agpVersion)"() {
given:
def project = new AndroidTestsAreIgnorableProject(agpVersion as String)
gradleProject = project.gradleProject
when:
build(gradleVersion as GradleVersion, gradleProject.rootDir, 'buildHealth')
then:
assertAbout(buildHealth())
.that(project.actualBuildHealth())
.isEquivalentIgnoringModuleAdvice(project.expectedBuildHealth)
where:
[gradleVersion, agpVersion] << gradleAgpMatrix()
}
}
Loading

0 comments on commit 3cd104e

Please sign in to comment.