Skip to content

Commit 9daa0ae

Browse files
danysantiagoDagger Team
authored and
Dagger Team
committed
Wire resource configuration while keeping the Bazel project structure.
RELNOTES=N/A PiperOrigin-RevId: 712608237
1 parent 3418609 commit 9daa0ae

File tree

3 files changed

+162
-10
lines changed

3 files changed

+162
-10
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (C) 2025 The Dagger Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package dagger.gradle.build
18+
19+
import org.gradle.api.DefaultTask
20+
import org.gradle.api.file.DirectoryProperty
21+
import org.gradle.api.file.RegularFile
22+
import org.gradle.api.provider.ListProperty
23+
import org.gradle.api.provider.MapProperty
24+
import org.gradle.api.tasks.Input
25+
import org.gradle.api.tasks.InputFiles
26+
import org.gradle.api.tasks.OutputDirectory
27+
import org.gradle.api.tasks.PathSensitive
28+
import org.gradle.api.tasks.PathSensitivity
29+
import org.gradle.api.tasks.TaskAction
30+
import org.gradle.work.DisableCachingByDefault
31+
32+
/**
33+
* A task for copying JAR resources files located in the repository structure into a generated resource source set
34+
* that matches the JAR's resources structure. This is necessary due to the repository's structure not being the
35+
* standard Gradle source set structure.
36+
*/
37+
@DisableCachingByDefault(because = "Not worth caching")
38+
abstract class ResourceCopyTask : DefaultTask() {
39+
40+
/**
41+
* Specifications of resource files to copy and their destination directory within the JAR.
42+
*/
43+
@get:Input
44+
abstract val resourceSpecs: MapProperty<String, String>
45+
46+
@get:InputFiles
47+
@get:PathSensitive(PathSensitivity.RELATIVE)
48+
abstract val inputFiles: ListProperty<RegularFile>
49+
50+
@get:OutputDirectory
51+
abstract val outputDirectory: DirectoryProperty
52+
53+
@TaskAction
54+
fun execute() {
55+
val specMap = resourceSpecs.get()
56+
inputFiles.get().forEach { resourceFile ->
57+
val inputFile = resourceFile.asFile
58+
check(inputFile.exists()) {
59+
"Resource file does not exist: $inputFile"
60+
}
61+
check(inputFile.isFile) {
62+
"Resource file must be a file not a directory: $inputFile"
63+
}
64+
val jarOutputDir = specMap.getValue(inputFile.path)
65+
val outputFile = outputDirectory.get().dir(jarOutputDir).file(inputFile.name).asFile
66+
inputFile.copyTo(outputFile, overwrite = true)
67+
}
68+
}
69+
}

buildSrc/src/main/kotlin/dagger/gradle/build/SourceSetConfiguration.kt

Lines changed: 87 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import org.gradle.api.NamedDomainObjectContainer
2020
import org.gradle.api.Project
2121
import org.gradle.api.file.SourceDirectorySet
2222
import org.gradle.api.plugins.JavaPluginExtension
23+
import org.gradle.api.tasks.TaskProvider
2324
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
2425
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
2526
import java.nio.file.Path
@@ -37,34 +38,111 @@ class DaggerSourceSet(
3738
private val kotlinSourceSets: NamedDomainObjectContainer<KotlinSourceSet>,
3839
private val javaSourceSets: NamedDomainObjectContainer<JavaSourceSet>,
3940
) {
41+
private val resourceCopyTask: TaskProvider<ResourceCopyTask> =
42+
project.tasks.register("copyResources", ResourceCopyTask::class.java) {
43+
outputDirectory.set(project.layout.buildDirectory.dir("generated/resources"))
44+
}
45+
46+
init {
47+
listOf(resourceCopyTask.map { it.outputDirectory }).let {
48+
kotlinSourceSets.named("main").configure { resources.setSrcDirs(it) }
49+
javaSourceSets.named("main").configure { resources.setSrcDirs(it) }
50+
}
51+
}
52+
53+
/**
54+
* The main source set whose based path is `<root>/java`
55+
*/
4056
val main: SourceSet = object : SourceSet {
4157
override fun setPackages(packages: List<String>) {
4258
val packagePaths = packages.map { Path(it) }
43-
kotlinSourceSets.getByName("main").kotlin
44-
.includePackages("${project.rootDir}/java", packagePaths)
45-
javaSourceSets.getByName("main").java
46-
.includePackages("${project.rootDir}/java", packagePaths)
59+
kotlinSourceSets.named("main").configure {
60+
kotlin.includePackages("${project.rootDir}/java", packagePaths)
61+
}
62+
javaSourceSets.named("main").configure {
63+
java.includePackages("${project.rootDir}/java", packagePaths)
64+
}
65+
}
66+
67+
override fun setResources(resources: Map<String, String>) {
68+
resourceCopyTask.configure {
69+
val baseDir = project.rootProject.layout.projectDirectory.dir("java")
70+
resources.forEach { (resourceFilePath, jarDirectoryPath) ->
71+
val resource = baseDir.file(resourceFilePath)
72+
resourceSpecs.put(resource.asFile.path, jarDirectoryPath)
73+
inputFiles.add(resource)
74+
}
75+
}
4776
}
4877
}
78+
79+
/**
80+
* The main source set whose based path is `<root>/javatests`
81+
*/
4982
val test: SourceSet = object : SourceSet {
5083
override fun setPackages(packages: List<String>) {
5184
val packagePaths = packages.map { Path(it) }
52-
kotlinSourceSets.getByName("test").kotlin
53-
.includePackages("${project.rootDir}/javatests", packagePaths)
54-
javaSourceSets.getByName("test").java
55-
.includePackages("${project.rootDir}/javatests", packagePaths)
85+
kotlinSourceSets.named("test").configure {
86+
kotlin.includePackages("${project.rootDir}/javatests", packagePaths)
87+
}
88+
javaSourceSets.named("test").configure {
89+
java.includePackages("${project.rootDir}/javatests", packagePaths)
90+
}
91+
}
92+
93+
override fun setResources(resources: Map<String, String>) {
94+
throw UnsupportedOperationException(
95+
"Resources are only configurable for the 'main' source set."
96+
)
5697
}
5798
}
5899

59100
interface SourceSet {
101+
/**
102+
* Sets the list of source packages that are part of the project's source set.
103+
*
104+
* Only sources directly in those packages are included and not in its subpackages.
105+
*
106+
* Example usage:
107+
* ```
108+
* daggerSources {
109+
* main.setPackages(
110+
* listOf(
111+
* "dagger",
112+
* "dagger/assisted",
113+
* "dagger/internal",
114+
* "dagger/multibindings",
115+
* )
116+
* )
117+
* }
118+
* ```
119+
* @see daggerSources
120+
*/
60121
fun setPackages(packages: List<String>)
122+
123+
/**
124+
* Sets the resource file paths and their corresponding artifact location.
125+
*
126+
* Example usage:
127+
* ```
128+
* daggerSources {
129+
* main.setResources(
130+
* mapOf("dagger/r8.pro" to "META-INF/com.android.tools/r8/")
131+
* )
132+
* }
133+
* ```
134+
* @see daggerSources
135+
*/
136+
fun setResources(resources: Map<String, String>)
61137
}
62138
}
63139

64140
/**
65141
* Configure project's source set based on Dagger's project structure.
66142
*
67-
* Specifically it will include sources in the packages specified by [DaggerSourceSet.SourceSet.setPackages].
143+
* Specifically it will include sources in the packages specified by
144+
* [DaggerSourceSet.SourceSet.setPackages] and resources as specified by
145+
* [DaggerSourceSet.SourceSet.setResources].
68146
*/
69147
fun Project.daggerSources(block: DaggerSourceSet.() -> Unit) {
70148
val kotlinExtension = extensions.findByType(KotlinProjectExtension::class.java)

gradle-projects/dagger-runtime/build.gradle.kts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ plugins {
44
alias(libs.plugins.dagger.kotlinJvm)
55
}
66

7-
// TODO(danysantiago): Add proguard files as META-INF resources
87
daggerSources {
98
main.setPackages(
109
listOf(
@@ -14,6 +13,12 @@ daggerSources {
1413
"dagger/multibindings",
1514
)
1615
)
16+
main.setResources(
17+
mapOf(
18+
"dagger/proguard.pro" to "META-INF/com.android.tools/proguard",
19+
"dagger/r8.pro" to "META-INF/com.android.tools/r8"
20+
)
21+
)
1722
test.setPackages(
1823
listOf(
1924
"dagger",

0 commit comments

Comments
 (0)