Skip to content

Commit 3bf2c19

Browse files
authored
Specify unique ref tags in Dackka output (#4149)
* Add util methods for gradle projects * Disable Javadoc generation on empty projects * Fix ref path generation in Dackka output * Add documentation for util methods * Update the DackkaPlugin docs * Reduced path to relative from tenant * Reduced ref head path even more * Fixed ref tag path to working solution * Disabled publishJavadoc by default for tests It should be enabled explicitly when being tested anyhow, and causes issues otherwise. Instead of disabling it for the tests that don't need it- this is much quicker and easier to manager.
1 parent 6300987 commit 3bf2c19

File tree

8 files changed

+140
-31
lines changed

8 files changed

+140
-31
lines changed

buildSrc/src/main/java/com/google/firebase/gradle/plugins/DackkaPlugin.kt

Lines changed: 94 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import com.android.build.gradle.LibraryExtension
55
import java.io.File
66
import org.gradle.api.Plugin
77
import org.gradle.api.Project
8+
import org.gradle.api.Task
89
import org.gradle.api.provider.Provider
910
import org.gradle.api.tasks.Copy
1011
import org.gradle.api.tasks.Delete
12+
import org.gradle.api.tasks.TaskProvider
1113
import org.gradle.kotlin.dsl.getByType
1214
import org.gradle.kotlin.dsl.register
1315

@@ -90,8 +92,9 @@ tasks above). While we do not currently offer any configuration for the Dackka
9092
plugin, this could change in the future as needed. Currently, the DackkaPlugin
9193
provides sensible defaults to output directories, package lists, and so forth.
9294
93-
The DackkaPlugin also provides three extra tasks:
95+
The DackkaPlugin also provides four extra tasks:
9496
[cleanDackkaDocumentation][registerCleanDackkaDocumentation],
97+
[separateJavadocAndKotlinDoc][registerSeparateJavadocAndKotlinDoc]
9598
[copyJavaDocToCommonDirectory][registerCopyJavaDocToCommonDirectoryTask] and
9699
[copyKotlinDocToCommonDirectory][registerCopyKotlinDocToCommonDirectoryTask].
97100
@@ -100,6 +103,9 @@ the output of Dackka. This is useful when testing Dackka outputs itself- and
100103
shouldn't be apart of the normal flow. The reasoning is that it would otherwise
101104
invalidate the gradle cache.
102105
106+
_separateJavadocAndKotlinDoc_ copies the Javadoc and Kotlindoc directories from Dackka into
107+
their own subdirectories- for easy and consistent differentiation.
108+
103109
_copyJavaDocToCommonDirectory_ copies the JavaDoc variant of the Dackka output for each sdk,
104110
and pastes it in a common directory under the root project's build directory. This makes it easier
105111
to zip the doc files for staging.
@@ -119,24 +125,30 @@ abstract class DackkaPlugin : Plugin<Project> {
119125
registerCleanDackkaDocumentation(project)
120126
project.afterEvaluate {
121127
if (shouldWePublish(project)) {
122-
val generateDocumentation = registerGenerateDackkaDocumentationTask(project)
123-
val dackkaFilesDirectory = generateDocumentation.flatMap { it.outputDirectory }
124-
val firesiteTransform = registerFiresiteTransformTask(project, dackkaFilesDirectory)
125-
val transformedFilesDirectory = firesiteTransform.flatMap { it.outputDirectory }
126-
val copyJavaDocToCommonDirectory = registerCopyJavaDocToCommonDirectoryTask(project, transformedFilesDirectory)
127-
val copyKotlinDocToCommonDirectory = registerCopyKotlinDocToCommonDirectoryTask(project, transformedFilesDirectory)
128+
val dackkaOutputDirectory = project.provider { fileFromBuildDir("dackkaRawOutput") }
129+
val separatedFilesDirectory = project.provider { fileFromBuildDir("dackkaSeparatedFiles") }
130+
val transformedDackkaFilesDirectory = project.provider { fileFromBuildDir("dackkaTransformedFiles") }
131+
132+
val generateDocumentation = registerGenerateDackkaDocumentationTask(project, dackkaOutputDirectory)
133+
val separateJavadocAndKotlinDoc = registerSeparateJavadocAndKotlinDoc(project, dackkaOutputDirectory, separatedFilesDirectory)
134+
val firesiteTransform = registerFiresiteTransformTask(project, separatedFilesDirectory, transformedDackkaFilesDirectory)
135+
val copyJavaDocToCommonDirectory = registerCopyJavaDocToCommonDirectoryTask(project, transformedDackkaFilesDirectory)
136+
val copyKotlinDocToCommonDirectory = registerCopyKotlinDocToCommonDirectoryTask(project, transformedDackkaFilesDirectory)
128137

129138
project.tasks.register("kotlindoc") {
130139
group = "documentation"
131140
dependsOn(
132141
generateDocumentation,
142+
separateJavadocAndKotlinDoc,
133143
firesiteTransform,
134144
copyJavaDocToCommonDirectory,
135145
copyKotlinDocToCommonDirectory
136146
)
137147
}
138148
} else {
139-
project.tasks.register("kotlindoc")
149+
project.tasks.register("kotlindoc") {
150+
group = "documentation"
151+
}
140152
}
141153
}
142154
}
@@ -158,7 +170,10 @@ abstract class DackkaPlugin : Plugin<Project> {
158170
}
159171

160172
// TODO(b/243324828): Refactor when fixed, so we no longer need stubs
161-
private fun registerGenerateDackkaDocumentationTask(project: Project): Provider<GenerateDocumentationTask> {
173+
private fun registerGenerateDackkaDocumentationTask(
174+
project: Project,
175+
targetDirectory: Provider<File>
176+
): Provider<GenerateDocumentationTask> {
162177
val docStubs = project.tasks.register<GenerateStubsTask>("docStubsForDackkaInput")
163178
val docsTask = project.tasks.register<GenerateDocumentationTask>("generateDackkaDocumentation")
164179
with(project.extensions.getByType<LibraryExtension>()) {
@@ -194,6 +209,8 @@ abstract class DackkaPlugin : Plugin<Project> {
194209
kotlinSources.set(sourcesForKotlin)
195210
dependencies.set(classpath)
196211

212+
outputDirectory.set(targetDirectory)
213+
197214
applyCommonConfigurations()
198215
}
199216
}
@@ -232,20 +249,72 @@ abstract class DackkaPlugin : Plugin<Project> {
232249
dependsOnAndMustRunAfter("createFullJarRelease")
233250

234251
val dackkaFile = project.provider { project.dackkaConfig.singleFile }
235-
val dackkaOutputDirectory = File(project.buildDir, "dackkaDocumentation")
236252

237253
dackkaJarFile.set(dackkaFile)
238-
outputDirectory.set(dackkaOutputDirectory)
239254
clientName.set(project.firebaseConfigValue { artifactId })
240255
}
241256

242-
private fun registerFiresiteTransformTask(project: Project, dackkaFilesDirectory: Provider<File>) =
243-
project.tasks.register<FiresiteTransformTask>("firesiteTransform") {
244-
mustRunAfter("generateDackkaDocumentation")
257+
// TODO(b/248302613): Remove when dackka exposes configuration for this
258+
private fun registerSeparateJavadocAndKotlinDoc(
259+
project: Project,
260+
dackkaOutputDirectory: Provider<File>,
261+
outputDirectory: Provider<File>
262+
): TaskProvider<Task> {
263+
val outputJavadocFolder = project.childFile(outputDirectory, "android")
264+
val outputKotlindocFolder = project.childFile(outputDirectory, "kotlin")
265+
266+
val separateJavadoc = project.tasks.register<Copy>("separateJavadoc") {
267+
dependsOn("generateDackkaDocumentation")
268+
269+
val javadocClientFolder = project.childFile(dackkaOutputDirectory, "reference/client")
270+
val javadocComFolder = project.childFile(dackkaOutputDirectory, "reference/com")
271+
272+
fromDirectory(javadocClientFolder)
273+
fromDirectory(javadocComFolder)
274+
275+
into(outputJavadocFolder)
276+
}
277+
278+
val separateKotlindoc = project.tasks.register<Copy>("separateKotlindoc") {
279+
dependsOn("generateDackkaDocumentation")
280+
281+
val kotlindocFolder = project.childFile(dackkaOutputDirectory, "reference/kotlin")
282+
283+
from(kotlindocFolder)
284+
285+
into(outputKotlindocFolder)
286+
}
287+
288+
return project.tasks.register("separateJavadocAndKotlinDoc") {
289+
dependsOn(separateJavadoc, separateKotlindoc)
290+
}
291+
}
292+
293+
private fun registerFiresiteTransformTask(
294+
project: Project,
295+
separatedFilesDirectory: Provider<File>,
296+
targetDirectory: Provider<File>
297+
): TaskProvider<Task> {
298+
val transformJavadoc = project.tasks.register<FiresiteTransformTask>("firesiteTransformJavadoc") {
299+
dependsOnAndMustRunAfter("separateJavadoc")
300+
301+
referenceHeadTagsPath.set("docs/reference/android")
302+
dackkaFiles.set(project.childFile(separatedFilesDirectory, "android"))
303+
outputDirectory.set(project.childFile(targetDirectory, "android"))
304+
}
305+
306+
val transformKotlindoc = project.tasks.register<FiresiteTransformTask>("firesiteTransformKotlindoc") {
307+
dependsOnAndMustRunAfter("separateKotlindoc")
308+
309+
referenceHeadTagsPath.set("docs/reference/kotlin")
310+
dackkaFiles.set(project.childFile(separatedFilesDirectory, "kotlin"))
311+
outputDirectory.set(project.childFile(targetDirectory, "kotlin"))
312+
}
245313

246-
dackkaFiles.set(dackkaFilesDirectory)
247-
outputDirectory.set(project.file("${project.buildDir}/dackkaTransformedFiles"))
314+
return project.tasks.register("firesiteTransform") {
315+
dependsOn(transformJavadoc, transformKotlindoc)
248316
}
317+
}
249318

250319
// TODO(b/246593212): Migrate doc files to single directory
251320
private fun registerCopyJavaDocToCommonDirectoryTask(project: Project, outputDirectory: Provider<File>) =
@@ -258,12 +327,10 @@ abstract class DackkaPlugin : Plugin<Project> {
258327
if (project.rootProject.findProperty("dackkaJavadoc") == "true") {
259328
mustRunAfter("firesiteTransform")
260329

261-
val outputFolder = project.file("${project.rootProject.buildDir}/firebase-kotlindoc/android")
262-
val clientFolder = outputDirectory.map { project.file("${it.path}/reference/client") }
263-
val comFolder = outputDirectory.map { project.file("${it.path}/reference/com") }
330+
val outputFolder = project.rootProject.fileFromBuildDir("firebase-kotlindoc/android")
331+
val javaFolder = project.childFile(outputDirectory, "android")
264332

265-
fromDirectory(clientFolder)
266-
fromDirectory(comFolder)
333+
fromDirectory(javaFolder)
267334

268335
into(outputFolder)
269336
}
@@ -274,8 +341,8 @@ abstract class DackkaPlugin : Plugin<Project> {
274341
project.tasks.register<Copy>("copyKotlinDocToCommonDirectory") {
275342
mustRunAfter("firesiteTransform")
276343

277-
val outputFolder = project.file("${project.rootProject.buildDir}/firebase-kotlindoc")
278-
val kotlinFolder = outputDirectory.map { project.file("${it.path}/reference/kotlin") }
344+
val outputFolder = project.rootProject.fileFromBuildDir("firebase-kotlindoc")
345+
val kotlinFolder = project.childFile(outputDirectory, "kotlin")
279346

280347
fromDirectory(kotlinFolder)
281348

@@ -287,8 +354,9 @@ abstract class DackkaPlugin : Plugin<Project> {
287354
project.tasks.register<Delete>("cleanDackkaDocumentation") {
288355
group = "cleanup"
289356

290-
delete("${project.buildDir}/dackkaDocumentation")
291-
delete("${project.buildDir}/dackkaTransformedFiles")
292-
delete("${project.rootProject.buildDir}/firebase-kotlindoc")
357+
val outputDirs = listOf("dackkaRawOutput", "dackkaSeparatedFiles", "dackkaTransformedFiles")
358+
359+
delete(outputDirs.map { project.fileFromBuildDir(it) })
360+
delete(project.rootProject.fileFromBuildDir("firebase-kotlindoc"))
293361
}
294362
}

buildSrc/src/main/java/com/google/firebase/gradle/plugins/FiresiteTransformTask.kt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import java.io.File
44
import org.gradle.api.DefaultTask
55
import org.gradle.api.provider.Property
66
import org.gradle.api.tasks.CacheableTask
7+
import org.gradle.api.tasks.Input
78
import org.gradle.api.tasks.InputDirectory
89
import org.gradle.api.tasks.OutputDirectory
910
import org.gradle.api.tasks.PathSensitive
@@ -21,6 +22,7 @@ import org.gradle.api.tasks.TaskAction
2122
* - Appends /docs/ to hyperlinks in html files
2223
* - Removes the prefix path from book_path
2324
* - Removes the firebase prefix from all links
25+
* - Changes the path for _reference-head-tags at the top of html files
2426
*
2527
* **Please note:**
2628
* This task is idempotent- meaning it can safely be ran multiple times on the same set of files.
@@ -31,6 +33,9 @@ abstract class FiresiteTransformTask : DefaultTask() {
3133
@get:PathSensitive(PathSensitivity.RELATIVE)
3234
abstract val dackkaFiles: Property<File>
3335

36+
@get:Input
37+
abstract val referenceHeadTagsPath: Property<String>
38+
3439
@get:OutputDirectory
3540
abstract val outputDirectory: Property<File>
3641

@@ -60,7 +65,7 @@ abstract class FiresiteTransformTask : DefaultTask() {
6065
}
6166

6267
private fun File.fixHTMLFile() {
63-
val fixedContent = readText().fixBookPath().fixHyperlinks().removeLeadingFirebaseDomainInLinks()
68+
val fixedContent = readText().fixBookPath().fixHyperlinks().removeLeadingFirebaseDomainInLinks().fixReferenceHeadTagsPath()
6469
writeText(fixedContent)
6570
}
6671

@@ -69,28 +74,33 @@ abstract class FiresiteTransformTask : DefaultTask() {
6974
writeText(fixedContent)
7075
}
7176

77+
// We utilize difference reference head tags between Kotlin and Java docs
78+
// TODO(b/248316730): Remove when dackka exposes configuration for this
79+
private fun String.fixReferenceHeadTagsPath() =
80+
replace(Regex("(?<=include \").*(?=/_reference-head-tags.html\" %})"), referenceHeadTagsPath.get())
81+
7282
// We don't actually upload class or index files,
7383
// so these headers will throw not found errors if not removed.
74-
// TODO(b/243674302): Remove when dackka supports this behavior
84+
// TODO(b/243674302): Remove when dackka exposes configuration for this
7585
private fun String.removeClassHeader() =
7686
remove(Regex("- title: \"Class Index\"\n {2}path: \".+\"\n\n"))
7787
private fun String.removeIndexHeader() =
7888
remove(Regex("- title: \"Package Index\"\n {2}path: \".+\"\n\n"))
7989

8090
// We use a common book for all sdks, wheres dackka expects each sdk to have its own book.
81-
// TODO(b/243674303): Remove when dackka supports this behavior
91+
// TODO(b/243674303): Remove when dackka exposes configuration for this
8292
private fun String.fixBookPath() =
8393
remove(Regex("(?<=setvar book_path ?%})(.+)(?=/_book.yaml\\{% ?endsetvar)"))
8494

8595
// Our documentation lives under /docs/reference/ versus the expected /reference/
86-
// TODO(b/243674305): Remove when dackka supports this behavior
96+
// TODO(b/243674305): Remove when dackka exposes configuration for this
8797
private fun String.fixHyperlinks() =
8898
replace(Regex("(?<=href=\")(/)(?=reference/.*\\.html)"), "/docs/")
8999

90100
// The documentation will work fine without this. This is primarily to make sure that links
91101
// resolve to their local counter part. Meaning when the docs are staged, they will resolve to
92102
// staged docs instead of prod docs- and vise versa.
93-
// TODO(b/243673063): Remove when dackka supports this behavior
103+
// TODO(b/243673063): Remove when dackka exposes configuration for this
94104
private fun String.removeLeadingFirebaseDomainInLinks() =
95105
remove(Regex("(?<=\")(https://firebase\\.google\\.com)(?=/docs/reference)"))
96106
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,35 @@
11
package com.google.firebase.gradle.plugins
22

33
import java.io.File
4+
import org.gradle.api.Project
45
import org.gradle.api.provider.Provider
56
import org.gradle.api.tasks.Copy
67

78
fun Copy.fromDirectory(directory: Provider<File>) =
89
from(directory) {
910
into(directory.map { it.name })
1011
}
12+
13+
/**
14+
* Creates a file at the buildDir for the given [Project].
15+
*
16+
* Syntax sugar for:
17+
*
18+
* ```
19+
* project.file("${project.buildDir}/$path)
20+
* ```
21+
*/
22+
fun Project.fileFromBuildDir(path: String) = file("$buildDir/$path")
23+
24+
/**
25+
* Maps a file provider to another file provider as a sub directory.
26+
*
27+
* Syntax sugar for:
28+
*
29+
* ```
30+
* fileProvider.map { project.file("${it.path}/$path") }
31+
* ```
32+
*/
33+
fun Project.childFile(provider: Provider<File>, childPath: String) = provider.map {
34+
file("${it.path}/$childPath")
35+
}

buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/publishing.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ data class Project(
2929
val externalDependencies: Set<Artifact> = setOf(),
3030
val releaseWith: Project? = null,
3131
val customizePom: String? = null,
32+
val publishJavadoc: Boolean = false,
3233
val libraryType: LibraryType = LibraryType.ANDROID
3334
) {
3435
fun generateBuildFile(): String {
@@ -42,6 +43,7 @@ data class Project(
4243
firebaseLibrary {
4344
${if (releaseWith != null) "releaseWith project(':${releaseWith.name}')" else ""}
4445
${if (customizePom != null) "customizePom {$customizePom}" else ""}
46+
${"publishJavadoc = $publishJavadoc"}
4547
}
4648
${if (libraryType == LibraryType.ANDROID) "android.compileSdkVersion = 26" else ""}
4749

firebase-abt/firebase-abt.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ plugins {
1919
firebaseLibrary {
2020
testLab.enabled = false
2121
publishSources = true
22+
publishJavadoc = false
2223
}
2324

2425
android {

firebase-components/firebase-components.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ plugins {
1818

1919
firebaseLibrary {
2020
publishSources = true
21+
publishJavadoc = false
2122
}
2223

2324
android {

firebase-components/firebase-dynamic-module-support/firebase-dynamic-module-support.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ group = 'com.google.firebase'
2121
firebaseLibrary {
2222
testLab.enabled = false
2323
publishSources = true
24+
publishJavadoc = false
2425
}
2526

2627
android {

firebase-database-collection/firebase-database-collection.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ plugins {
1818

1919
firebaseLibrary {
2020
publishSources = true
21+
publishJavadoc = false
2122
}
2223

2324
android {

0 commit comments

Comments
 (0)