Skip to content

Commit cd5c0db

Browse files
Centralize dependency files for the common case.
1 parent 46c0d5e commit cd5c0db

File tree

9 files changed

+73
-19
lines changed

9 files changed

+73
-19
lines changed

src/main/kotlin/com/autonomousapps/internal/OutputPaths.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@
44

55
package com.autonomousapps.internal
66

7+
import com.autonomousapps.internal.OutputPaths.Companion.ROOT_DIR
78
import org.gradle.api.Project
89

9-
internal const val ROOT_DIR = "reports/dependency-analysis"
10-
1110
internal class OutputPaths(
1211
private val project: Project,
13-
variantName: String
12+
variantName: String,
1413
) {
1514

15+
internal companion object {
16+
const val ROOT_DIR = "reports/dependency-analysis"
17+
}
18+
1619
private fun file(path: String) = project.layout.buildDirectory.file(path)
17-
private fun dir(path: String) = project.layout.buildDirectory.dir(path)
1820

1921
private val variantDirectory = "$ROOT_DIR/$variantName"
2022
private val intermediatesDir = "${variantDirectory}/intermediates"
@@ -37,7 +39,7 @@ internal class OutputPaths(
3739
val declaredProcPath = file("${intermediatesDir}/procs-declared.json")
3840
val abiAnalysisPath = file("${intermediatesDir}/abi.json")
3941
val abiDumpPath = file("${variantDirectory}/abi-dump.txt")
40-
val dependenciesDir = dir("${variantDirectory}/dependencies")
42+
val dependencies = file("${variantDirectory}/dependencies.txt")
4143
val explodedSourcePath = file("${intermediatesDir}/exploded-source.json")
4244
val explodingBytecodePath = file("${intermediatesDir}/exploding-bytecode.json")
4345
val syntheticProjectPath = file("${intermediatesDir}/synthetic-project.json")

src/main/kotlin/com/autonomousapps/internal/analyzer/AndroidProjectAnalyzer.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ internal class AndroidLibAnalyzer(
220220
): TaskProvider<AndroidScoreTask> {
221221
return project.tasks.register<AndroidScoreTask>("computeAndroidScore$taskNameSuffix") {
222222
dependencies.set(synthesizeDependenciesTask.flatMap { it.outputDir })
223+
dependenciesList.set(synthesizeDependenciesTask.flatMap { it.output })
223224
syntheticProject.set(synthesizeProjectViewTask.flatMap { it.output })
224225
output.set(outputPaths.androidScorePath)
225226
}

src/main/kotlin/com/autonomousapps/model/ProjectVariant.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.autonomousapps.internal.utils.fromJson
99
import com.autonomousapps.model.CodeSource.Kind
1010
import com.autonomousapps.model.declaration.Variant
1111
import com.squareup.moshi.JsonClass
12+
import com.squareup.moshi.JsonEncodingException
1213
import org.gradle.api.file.Directory
1314

1415
/** Represents a variant-specific view of the project under analysis. */
@@ -22,7 +23,7 @@ data class ProjectVariant(
2223
val sources: Set<Source>,
2324
val classpath: Set<Coordinates>,
2425
val annotationProcessors: Set<Coordinates>,
25-
val testInstrumentationRunner: String?
26+
val testInstrumentationRunner: String?,
2627
) {
2728

2829
val usedClassesBySrc: Set<String> by unsafeLazy {
@@ -93,9 +94,13 @@ data class ProjectVariant(
9394
.map {
9495
val file = dependenciesDir.file(it.toFileName())
9596
if (file.asFile.exists()) {
96-
file.fromJson<Dependency>()
97+
try {
98+
file.fromJson<Dependency>()
99+
} catch (e: JsonEncodingException) {
100+
throw IllegalStateException("Couldn't deserialize '${file.asFile}'", e)
101+
}
97102
} else {
98-
error("No file ${it.toFileName()}")
103+
error("No file '${it.toFileName()}'")
99104
}
100105
}
101106
.toSet()

src/main/kotlin/com/autonomousapps/services/InMemoryCache.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package com.autonomousapps.services
66

77
import com.autonomousapps.Flags.cacheSize
8+
import com.autonomousapps.internal.OutputPaths.Companion.ROOT_DIR
89
import com.autonomousapps.model.InlineMemberCapability
910
import com.autonomousapps.model.intermediates.AnnotationProcessorDependency
1011
import com.autonomousapps.model.intermediates.ExplodingJar
@@ -13,6 +14,7 @@ import com.autonomousapps.tasks.KotlinCapabilities
1314
import com.github.benmanes.caffeine.cache.Cache
1415
import com.github.benmanes.caffeine.cache.Caffeine
1516
import org.gradle.api.Project
17+
import org.gradle.api.file.DirectoryProperty
1618
import org.gradle.api.invocation.Gradle
1719
import org.gradle.api.provider.Property
1820
import org.gradle.api.provider.Provider
@@ -23,6 +25,7 @@ abstract class InMemoryCache : BuildService<InMemoryCache.Params> {
2325

2426
interface Params : BuildServiceParameters {
2527
val cacheSize: Property<Long>
28+
val dependenciesDir: DirectoryProperty
2629
}
2730

2831
private val cacheSize = parameters.cacheSize.get()
@@ -53,7 +56,7 @@ abstract class InMemoryCache : BuildService<InMemoryCache.Params> {
5356
procs.asMap().putIfAbsent(procName, proc)
5457
}
5558

56-
companion object {
59+
internal companion object {
5760
private const val SHARED_SERVICES_IN_MEMORY_CACHE = "inMemoryCache"
5861
private const val DEFAULT_CACHE_VALUE = -1L
5962

@@ -92,6 +95,13 @@ abstract class InMemoryCache : BuildService<InMemoryCache.Params> {
9295
.sharedServices
9396
.registerIfAbsent(SHARED_SERVICES_IN_MEMORY_CACHE, InMemoryCache::class.java) {
9497
parameters.cacheSize.set(project.cacheSize(DEFAULT_CACHE_VALUE))
98+
parameters.dependenciesDir.set(project.layout.buildDirectory.dir("${ROOT_DIR}/dependencies"))
99+
100+
// TODO I wonder how this works in the context of a composite build. Maybe I should create a new service just
101+
// for this, and _not_ share that service across builds?
102+
if (project != project.rootProject) {
103+
project.logger.warn("Creating global dependencies output directory in '${project.path}'")
104+
}
95105
}
96106
}
97107
}

src/main/kotlin/com/autonomousapps/subplugin/ProjectPlugin.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,9 @@ internal class ProjectPlugin(private val project: Project) {
671671

672672
val synthesizeDependenciesTask =
673673
tasks.register<SynthesizeDependenciesTask>("synthesizeDependencies$taskNameSuffix") {
674-
inMemoryCache.set(InMemoryCache.register(project))
674+
val cache = InMemoryCache.register(project)
675+
676+
inMemoryCache.set(cache)
675677
projectPath.set(thisProjectPath)
676678
compileDependencies.set(graphViewTask.flatMap { it.outputNodes })
677679
physicalArtifacts.set(artifactsReport.flatMap { it.output })
@@ -686,7 +688,8 @@ internal class ProjectPlugin(private val project: Project) {
686688
findNativeLibsTask?.let { task -> nativeLibs.set(task.flatMap { it.output }) }
687689
findAndroidAssetsTask?.let { task -> androidAssets.set(task.flatMap { it.output }) }
688690

689-
outputDir.set(outputPaths.dependenciesDir)
691+
outputDir.set(cache.flatMap { it.parameters.dependenciesDir })
692+
output.set(outputPaths.dependencies)
690693
}
691694

692695
/* ******************************
@@ -770,6 +773,7 @@ internal class ProjectPlugin(private val project: Project) {
770773
graph.set(graphViewTask.flatMap { it.output })
771774
declarations.set(findDeclarationsTask.flatMap { it.output })
772775
dependencies.set(synthesizeDependenciesTask.flatMap { it.outputDir })
776+
dependenciesList.set(synthesizeDependenciesTask.flatMap { it.output })
773777
syntheticProject.set(synthesizeProjectViewTask.flatMap { it.output })
774778
kapt.set(isKaptApplied())
775779
output.set(outputPaths.dependencyTraceReportPath)

src/main/kotlin/com/autonomousapps/subplugin/RootPlugin.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.autonomousapps.internal.advice.DslKind
1313
import com.autonomousapps.internal.artifacts.DagpArtifacts
1414
import com.autonomousapps.internal.artifacts.Resolver.Companion.interProjectResolver
1515
import com.autonomousapps.internal.utils.log
16+
import com.autonomousapps.services.InMemoryCache
1617
import com.autonomousapps.tasks.BuildHealthTask
1718
import com.autonomousapps.tasks.ComputeDuplicateDependenciesTask
1819
import com.autonomousapps.tasks.GenerateBuildHealthTask
@@ -23,9 +24,7 @@ import org.gradle.kotlin.dsl.register
2324

2425
internal const val DEPENDENCY_ANALYSIS_PLUGIN = "com.autonomousapps.dependency-analysis"
2526

26-
/**
27-
* This "plugin" is applied to the root project only.
28-
*/
27+
/** This "plugin" is applied to the root project only. */
2928
internal class RootPlugin(private val project: Project) {
3029

3130
init {
@@ -87,6 +86,9 @@ internal class RootPlugin(private val project: Project) {
8786
private fun Project.configureRootProject() {
8887
val paths = RootOutputPaths(this)
8988

89+
// Register this in the root project to centralize dependency synthesis files
90+
InMemoryCache.register(this)
91+
9092
val computeDuplicatesTask = tasks.register<ComputeDuplicateDependenciesTask>("computeDuplicateDependencies") {
9193
resolvedDependenciesReports.setFrom(resolvedDepsResolver.internal)
9294
output.set(paths.duplicateDependenciesPath)

src/main/kotlin/com/autonomousapps/tasks/AndroidScoreTask.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,16 @@ abstract class AndroidScoreTask @Inject constructor(
3131
@get:InputFile
3232
abstract val syntheticProject: RegularFileProperty
3333

34-
@get:PathSensitive(PathSensitivity.NONE)
35-
@get:InputDirectory
34+
/**
35+
* TODO: docs
36+
*/
37+
@get:Internal
3638
abstract val dependencies: DirectoryProperty
3739

40+
@get:PathSensitive(PathSensitivity.NONE)
41+
@get:InputFile
42+
abstract val dependenciesList: RegularFileProperty
43+
3844
@get:OutputFile
3945
abstract val output: RegularFileProperty
4046

src/main/kotlin/com/autonomousapps/tasks/ComputeUsagesTask.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,20 @@ abstract class ComputeUsagesTask @Inject constructor(
4040
@get:InputFile
4141
abstract val declarations: RegularFileProperty
4242

43-
@get:PathSensitive(PathSensitivity.NONE)
44-
@get:InputDirectory
43+
/**
44+
* This contains all of the [Dependencies][Dependency] used by this project. It cannot be a task input because it is
45+
* a globally shared directory that many tasks write to and read from. See also [dependenciesList].
46+
*/
47+
@get:Internal
4548
abstract val dependencies: DirectoryProperty
4649

50+
/**
51+
* Only for task snapshotting. A simplified representation of [dependencies].
52+
*/
53+
@get:PathSensitive(PathSensitivity.NONE)
54+
@get:InputFile
55+
abstract val dependenciesList: RegularFileProperty
56+
4757
@get:PathSensitive(PathSensitivity.NONE)
4858
@get:InputFile
4959
abstract val syntheticProject: RegularFileProperty

src/main/kotlin/com/autonomousapps/tasks/SynthesizeDependenciesTask.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,14 @@ abstract class SynthesizeDependenciesTask @Inject constructor(
8787
@get:InputFile
8888
abstract val androidAssets: RegularFileProperty
8989

90+
// TODO: Maybe this should not be an OutputDirectory anymore, but just Internal? Since multiple tasks will write to it
9091
@get:OutputDirectory
9192
abstract val outputDir: DirectoryProperty
9293

94+
/** A simplified representation of [outputDir] for task snapshotting purposes only. */
95+
@get:OutputFile
96+
abstract val output: RegularFileProperty
97+
9398
@TaskAction fun action() {
9499
workerExecutor.noIsolation().submit(SynthesizeDependenciesWorkAction::class.java) {
95100
inMemoryCache.set(this@SynthesizeDependenciesTask.inMemoryCache)
@@ -105,6 +110,7 @@ abstract class SynthesizeDependenciesTask @Inject constructor(
105110
nativeLibs.set(this@SynthesizeDependenciesTask.nativeLibs)
106111
androidAssets.set(this@SynthesizeDependenciesTask.androidAssets)
107112
outputDir.set(this@SynthesizeDependenciesTask.outputDir)
113+
output.set(this@SynthesizeDependenciesTask.output)
108114
}
109115
}
110116

@@ -125,6 +131,7 @@ abstract class SynthesizeDependenciesTask @Inject constructor(
125131
val androidAssets: RegularFileProperty
126132

127133
val outputDir: DirectoryProperty
134+
val output: RegularFileProperty
128135
}
129136

130137
abstract class SynthesizeDependenciesWorkAction : WorkAction<SynthesizeDependenciesParameters> {
@@ -133,6 +140,7 @@ abstract class SynthesizeDependenciesTask @Inject constructor(
133140

134141
override fun execute() {
135142
val outputDir = parameters.outputDir
143+
val output = parameters.output.getAndDelete()
136144

137145
val dependencies = parameters.compileDependencies.fromJson<CoordinatesContainer>().coordinates
138146
val physicalArtifacts = parameters.physicalArtifacts.fromJsonSet<PhysicalArtifact>()
@@ -192,7 +200,13 @@ abstract class SynthesizeDependenciesTask @Inject constructor(
192200
.map { it.build() }
193201
.forEach { dependency ->
194202
val coordinates = dependency.coordinates
195-
outputDir.file(coordinates.toFileName()).get().asFile.bufferWriteJson(dependency)
203+
val file = outputDir.file(coordinates.toFileName()).get().asFile
204+
if (!file.exists()) {
205+
file.bufferWriteJson(dependency)
206+
}
207+
208+
// This is the task output for snapshotting purposes
209+
output.appendText("${coordinates.gav()}\n")
196210
}
197211
}
198212

0 commit comments

Comments
 (0)