Skip to content

Commit

Permalink
Initial setup of Gradle as a build system for Dagger
Browse files Browse the repository at this point in the history
At the repository root, the root project 'dagger-parent' configures common build functionality and includes the various projects that will be placed 'gradle-projects', for now only the runtime is configured.

The buildSrc directory is a special Gradle sub-project to share common build logic between sub-projects, it will become more useful in time as the projects gets more complex and shared build logic is needed.

Dependencies and versions are defined in a Version Catalog in gradle/libs.versions.toml, these will eventually need to be validated to be in-sync with Bazel's WORKSPACE.

RELNOTES=N/A
PiperOrigin-RevId: 710702061
  • Loading branch information
danysantiago authored and Dagger Team committed Dec 30, 2024
1 parent 98a0275 commit c43783a
Show file tree
Hide file tree
Showing 14 changed files with 606 additions and 0 deletions.
3 changes: 3 additions & 0 deletions buildSrc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Dagger's Gradle build logic

See https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#sec:build_sources
12 changes: 12 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
plugins {
alias(libs.plugins.kotlinJvm)
}

kotlin {
jvmToolchain(18)
}

dependencies {
implementation(gradleApi())
implementation(libs.kotlin.gradlePlugin)
}
18 changes: 18 additions & 0 deletions buildSrc/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
111 changes: 111 additions & 0 deletions buildSrc/src/main/kotlin/dagger/gradle/build/SourceSetConfiguration.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright (C) 2024 The Dagger Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dagger.gradle.build

import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.plugins.JavaPluginExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import java.nio.file.Path
import kotlin.io.path.Path
import kotlin.io.path.isDirectory

private typealias JavaSourceSet = org.gradle.api.tasks.SourceSet

@DslMarker
annotation class DaggerGradleDsl

@DaggerGradleDsl
class DaggerSourceSet(
private val project: Project,
private val kotlinSourceSets: NamedDomainObjectContainer<KotlinSourceSet>,
private val javaSourceSets: NamedDomainObjectContainer<JavaSourceSet>,
) {
val main: SourceSet = object : SourceSet {
override fun setPackages(packages: List<String>) {
val packagePaths = packages.map { Path(it) }
kotlinSourceSets.getByName("main").kotlin
.includePackages("${project.rootDir}/java", packagePaths)
javaSourceSets.getByName("main").java
.includePackages("${project.rootDir}/java", packagePaths)
}
}
val test: SourceSet = object : SourceSet {
override fun setPackages(packages: List<String>) {
val packagePaths = packages.map { Path(it) }
kotlinSourceSets.getByName("test").kotlin
.includePackages("${project.rootDir}/javatests", packagePaths)
javaSourceSets.getByName("test").java
.includePackages("${project.rootDir}/javatests", packagePaths)
}
}

interface SourceSet {
fun setPackages(packages: List<String>)
}
}

/**
* Configure project's source set based on Dagger's project structure.
*
* Specifically it will include sources in the packages specified by [DaggerSourceSet.SourceSet.setPackages].
*/
fun Project.daggerSources(block: DaggerSourceSet.() -> Unit) {
val kotlinExtension = extensions.findByType(KotlinProjectExtension::class.java)
?: error("The daggerSources() configuration must be applied to a Kotlin (JVM) project.")
val javaExtension = extensions.findByType(JavaPluginExtension::class.java)
?: error("The daggerSources() configuration must be applied to a Kotlin (JVM) project.")
val daggerSources = DaggerSourceSet(this, kotlinExtension.sourceSets, javaExtension.sourceSets)
black.invoke(daggerSources)
}

/**
* Includes sources from the given [packages] into this source set.
*
* Only sources within the package directory are included and not its sub-packages.
*/
private fun SourceDirectorySet.includePackages(
basePath: String,
packages: Iterable<Path>,
) {
val packagesDirectories = packages.flatMap { it.expandParts() }.toSet()
setSrcDirs(listOf(basePath)).include {
val path = Path(it.path)
if (Path(basePath).resolve(path).isDirectory()) {
path in packagesDirectories
} else {
path.parent in packages
}
}
}

/**
* Expands a [Path] to includes it parents.
*
* i.e. for `"foo/bar"` it will expand to `setOf("foo", foo/bar")`
*/
private fun Path.expandParts(): Set<Path> {
return buildSet {
var path: Path? = this@expandParts
while (path != null) {
add(path)
path = path.parent
}
}
}
6 changes: 6 additions & 0 deletions gradle-projects/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### Dagger's Gradle projects directories

Each directory is a Gradle sub-project that maps to an artifact and whose sources are part of the
Bazel project structure. At the root of the repository is the parent project that includes the
ones in these directory.

43 changes: 43 additions & 0 deletions gradle-projects/dagger-runtime/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import dagger.gradle.build.daggerSources

plugins {
id(libs.plugins.kotlinJvm.get().pluginId)
}

// TODO(danysantiago): Add proguard files as META-INF resources
daggerSources {
main.setPackages(
listOf(
"dagger",
"dagger/assisted",
"dagger/internal",
"dagger/multibindings",
)
)
test.setPackages(
listOf(
"dagger",
"dagger/internal",
)
)
}

// TODO(danysantiago): Move configuration to a buildSrc plugin so it is applied to all projects
kotlin {
jvmToolchain(18)
compilerOptions {
languageVersion = KotlinVersion.KOTLIN_1_8
apiVersion = KotlinVersion.KOTLIN_1_8
jvmTarget = JvmTarget.JVM_1_8
}
}

dependencies {
api(libs.javax.inject)
api(libs.jakarta.inject)
api(libs.jspecify)

testImplementation(libs.junit)
testImplementation(libs.truth)
testImplementation(libs.guava.jre)
}
18 changes: 18 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Project-wide Gradle settings.
# IDE (e.g. IntelliJ or Android Studio) users:
# Gradle settings configured through the IDE *will override* any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx4g -Xms4g -Dfile.encoding=UTF-8
kotlin.daemon.jvmargs=-Xmx4g -Xms4g -Dfile.encoding=UTF-8

# Enable caching between builds.
org.gradle.caching=true

# Enable configuration caching between builds.
org.gradle.configuration-cache=true

# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
18 changes: 18 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[versions]
kotlin = "2.0.21"
guava = "33.0.0-jre"
junit = "4.13"
truth = "1.4.0"

[libraries]
kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
jakarta-inject = { module = "jakarta.inject:jakarta.inject-api", version = "2.0.1" }
javax-inject = { module = "javax.inject:javax.inject", version = "1" }
jspecify = { module = "org.jspecify:jspecify", version = "1.0.0" }
guava-jre = { module = "com.google.guava:guava", version.ref = "guava" }
junit = { module = "junit:junit", version.ref = "junit" }
truth = { module = "com.google.truth:truth", version.ref = "truth" }

[plugins]
kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit c43783a

Please sign in to comment.