-
Notifications
You must be signed in to change notification settings - Fork 625
Add a new plugin for Dackka #4023
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
b2e28cb
Moved the CI repo to artifacts only
daymxn 6c890ab
Added missing suppress
daymxn 488a2ec
Added comment about bug
daymxn 5ded464
Removed loose annotations.
daymxn f3c5449
Fixed CampaignMetadata docs
daymxn 127898f
Fixed DocumentID docs
daymxn 6f7a181
Added additional utility methods
daymxn bc655e6
Add the DackkaPlugin
daymxn 361cb78
Added the NDK back to subprojects.
daymxn 54fc5ab
Fix minor javadoc grammar issue
daymxn f67ea2c
Added TODO to move links to task input
daymxn 525819e
Added the NDK back to subprojects.
daymxn ea45f69
Add link to bug for removing class/index headers
daymxn 7b241a9
Add link to bug for fixing book paths
daymxn b572eec
Add link to bug for fixing hyperlinks
daymxn ed7d2a4
Added link to bug for removing domains in links
daymxn f0bcab5
Remove filter for annotation
daymxn ab82741
Refactor Firesite task to draw from generate task
daymxn 0bcb374
Refactor delete task to draw from generate task
daymxn 817e9be
Refactor task dependency structure
daymxn 53326b2
Refactor copy dackka task to use output dir input
daymxn e021ac7
Fix javadoc todo link
daymxn 65d4fa3
Fix getjars bug link
daymxn c6e43ad
Fix projectSpecificSources bug link
daymxn 706e275
Fix projectSpecificSuppressedFiles bug link
daymxn 6560151
Refactor bootclasspath impl for dackka
daymxn 9306449
Add metadatasources to tests/buildscript
daymxn 505ce09
Fix DocumentID Formatting
daymxn c24efc7
Fix formatting in CampaignMetadata
daymxn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
155 changes: 155 additions & 0 deletions
155
buildSrc/src/main/java/com/google/firebase/gradle/plugins/DackkaGenerationTask.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package com.google.firebase.gradle.plugins | ||
|
||
import java.io.File | ||
import javax.inject.Inject | ||
import org.gradle.api.DefaultTask | ||
import org.gradle.api.provider.ListProperty | ||
import org.gradle.api.provider.Property | ||
import org.gradle.api.provider.SetProperty | ||
import org.gradle.api.tasks.Input | ||
import org.gradle.api.tasks.InputFile | ||
import org.gradle.api.tasks.InputFiles | ||
import org.gradle.api.tasks.OutputDirectory | ||
import org.gradle.api.tasks.TaskAction | ||
import org.gradle.process.ExecOperations | ||
import org.gradle.workers.WorkAction | ||
import org.gradle.workers.WorkParameters | ||
import org.gradle.workers.WorkerExecutor | ||
import org.json.JSONObject | ||
|
||
/** | ||
* Extension class for [GenerateDocumentationTask]. | ||
* | ||
* Provides public configurations for the task. | ||
* | ||
* @property dackkaJarFile a [File] of the Dackka fat jar | ||
* @property dependencies a list of all dependent jars (the classpath) | ||
* @property kotlinSources a list of kotlin source roots | ||
* @property javaSources a list of java source roots | ||
* @property suppressedFiles a list of files to exclude from documentation | ||
* @property outputDirectory where to store the generated files | ||
*/ | ||
abstract class GenerateDocumentationTaskExtension : DefaultTask() { | ||
@get:InputFile | ||
abstract val dackkaJarFile: Property<File> | ||
|
||
@get:Input | ||
abstract val dependencies: ListProperty<File> | ||
|
||
@get:InputFiles | ||
abstract val kotlinSources: ListProperty<File> | ||
|
||
@get:InputFiles | ||
abstract val javaSources: ListProperty<File> | ||
|
||
@get:InputFiles | ||
abstract val suppressedFiles: ListProperty<File> | ||
|
||
@get:OutputDirectory | ||
abstract val outputDirectory: Property<File> | ||
} | ||
|
||
/** | ||
* Task to run Dackka on a project. | ||
* | ||
* Since dackka needs to be run on the command line, we have to organize the arguments for dackka into | ||
* a json file. We then pass that json file to dackka as an argument. | ||
* | ||
* @see GenerateDocumentationTaskExtension | ||
*/ | ||
abstract class GenerateDocumentationTask @Inject constructor( | ||
private val workerExecutor: WorkerExecutor | ||
) : GenerateDocumentationTaskExtension() { | ||
|
||
@TaskAction | ||
fun build() { | ||
val configFile = saveToJsonFile(constructArguments()) | ||
launchDackka(configFile, workerExecutor) | ||
} | ||
|
||
private fun constructArguments(): JSONObject { | ||
// TODO(b/243675474): Move these to a task input for caching purposes | ||
val linksMap = mapOf( | ||
"android" to "https://developer.android.com/reference/kotlin/", | ||
"google" to "https://developer.android.com/reference/", | ||
"firebase" to "https://firebase.google.com/docs/reference/kotlin/", | ||
"coroutines" to "https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/" | ||
) | ||
|
||
val jsonMap = mapOf( | ||
"moduleName" to "", | ||
"outputDir" to outputDirectory.get().path, | ||
"globalLinks" to "", | ||
"sourceSets" to listOf(mutableMapOf( | ||
"sourceSetID" to mapOf( | ||
"scopeId" to "androidx", | ||
"sourceSetName" to "main" | ||
), | ||
"sourceRoots" to kotlinSources.get().map { it.path } + javaSources.get().map { it.path }, | ||
"classpath" to dependencies.get().map { it.path }, | ||
"documentedVisibilities" to listOf("PUBLIC", "PROTECTED"), | ||
"skipEmptyPackages" to "true", | ||
"suppressedFiles" to suppressedFiles.get().map { it.path }, | ||
"externalDocumentationLinks" to linksMap.map { (name, url) -> mapOf( | ||
"url" to url, | ||
"packageListUrl" to "file://${project.rootDir.absolutePath}/kotlindoc/package-lists/$name/package-list" | ||
daymxn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) } | ||
)), | ||
"offlineMode" to "true", | ||
"noJdkLink" to "true" | ||
) | ||
|
||
return JSONObject(jsonMap) | ||
} | ||
|
||
private fun saveToJsonFile(jsonObject: JSONObject): File { | ||
val outputFile = File.createTempFile("dackkaArgs", ".json") | ||
|
||
outputFile.deleteOnExit() | ||
outputFile.writeText(jsonObject.toString(2)) | ||
|
||
return outputFile | ||
} | ||
|
||
private fun launchDackka(argsFile: File, workerExecutor: WorkerExecutor) { | ||
val workQueue = workerExecutor.noIsolation() | ||
|
||
workQueue.submit(DackkaWorkAction::class.java) { | ||
args.set(listOf(argsFile.path, "-loggingLevel", "WARN")) | ||
classpath.set(setOf(dackkaJarFile.get())) | ||
projectName.set(project.name) | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Parameters needs to launch the Dackka fat jar on the command line. | ||
* | ||
* @property args a list of arguments to pass to Dackka- should include the json arguments file | ||
* @property classpath the classpath to use during execution of the jar file | ||
* @property projectName name of the calling project, used for the devsite tenant (output directory) | ||
*/ | ||
interface DackkaParams : WorkParameters { | ||
val args: ListProperty<String> | ||
val classpath: SetProperty<File> | ||
val projectName: Property<String> | ||
} | ||
|
||
/** | ||
* Work action to launch dackka with a [DackkaParams]. | ||
* | ||
* Work actions are organized sections of work, offered by gradle. | ||
*/ | ||
abstract class DackkaWorkAction @Inject constructor( | ||
private val execOperations: ExecOperations | ||
) : WorkAction<DackkaParams> { | ||
override fun execute() { | ||
execOperations.javaexec { | ||
mainClass.set("org.jetbrains.dokka.MainKt") | ||
args = parameters.args.get() | ||
classpath(parameters.classpath.get()) | ||
|
||
environment("DEVSITE_TENANT", "client/${parameters.projectName.get()}") | ||
} | ||
} | ||
} |
174 changes: 174 additions & 0 deletions
174
buildSrc/src/main/java/com/google/firebase/gradle/plugins/DackkaPlugin.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
package com.google.firebase.gradle.plugins | ||
|
||
import com.android.build.api.attributes.BuildTypeAttr | ||
import com.android.build.gradle.LibraryExtension | ||
import java.io.File | ||
import org.gradle.api.Plugin | ||
import org.gradle.api.Project | ||
import org.gradle.api.provider.Provider | ||
import org.gradle.api.tasks.Copy | ||
import org.gradle.api.tasks.Delete | ||
import org.gradle.kotlin.dsl.getByType | ||
import org.gradle.kotlin.dsl.register | ||
|
||
/** | ||
* Facilitates the creation of Firesite compliant reference documentation. | ||
* | ||
* This plugin handles a procedure of processes, all registered under the "kotlindoc" task. | ||
* | ||
* Those tasks are: | ||
* - Collect the arguments needed to run Dackka | ||
* - Run Dackka with [GenerateDocumentationTask] to create the initial reference docs | ||
* - Clean up the output with [FiresiteTransformTask] to fix minor inconsistencies | ||
* - Remove the java references generated from the task (we do not currently support them) | ||
* - Copies the output files to a common directory under the root project's build directory | ||
* | ||
* @see GenerateDocumentationTask | ||
* @see FiresiteTransformTask | ||
* @see JavadocPlugin | ||
*/ | ||
abstract class DackkaPlugin : Plugin<Project> { | ||
override fun apply(project: Project) { | ||
prepareJavadocConfiguration(project) | ||
registerCleanDackkaDocumentation(project) | ||
project.afterEvaluate { | ||
if (shouldWePublish(project)) { | ||
val generateDocumentation = registerGenerateDackkaDocumentationTask(project) | ||
val outputDirectory = generateDocumentation.flatMap { it.outputDirectory } | ||
val firesiteTransform = registerFiresiteTransformTask(project, outputDirectory) | ||
val deleteJavaReferences = registerDeleteDackkaGeneratedJavaReferencesTask(project, outputDirectory) | ||
val copyOutputToCommonDirectory = | ||
registerCopyDackkaOutputToCommonDirectoryTask(project, outputDirectory) | ||
|
||
project.tasks.register("kotlindoc") { | ||
group = "documentation" | ||
dependsOn( | ||
generateDocumentation, | ||
firesiteTransform, | ||
deleteJavaReferences, | ||
copyOutputToCommonDirectory | ||
) | ||
} | ||
} else { | ||
project.tasks.register("kotlindoc") | ||
} | ||
} | ||
} | ||
|
||
private fun shouldWePublish(project: Project) = | ||
project.extensions.getByType<FirebaseLibraryExtension>().publishJavadoc | ||
|
||
private fun prepareJavadocConfiguration(project: Project) { | ||
val javadocConfig = project.javadocConfig | ||
javadocConfig.dependencies += project.dependencies.create("com.google.code.findbugs:jsr305:3.0.2") | ||
javadocConfig.dependencies += project.dependencies.create("com.google.errorprone:error_prone_annotations:2.15.0") | ||
javadocConfig.attributes.attribute( | ||
BuildTypeAttr.ATTRIBUTE, | ||
project.objects.named(BuildTypeAttr::class.java, "release") | ||
) | ||
} | ||
|
||
private fun registerGenerateDackkaDocumentationTask(project: Project) = | ||
project.tasks.register<GenerateDocumentationTask>("generateDackkaDocumentation") { | ||
with(project.extensions.getByType<LibraryExtension>()) { | ||
libraryVariants.all { | ||
if (name == "release") { | ||
mustRunAfter("createFullJarRelease") | ||
dependsOn("createFullJarRelease") | ||
|
||
val classpath = project.provider { | ||
runtimeConfiguration.getJars() + project.javadocConfig.getJars() + bootClasspath | ||
} | ||
|
||
val sourcesForJava = sourceSets.flatMap { | ||
it.javaDirectories.map { it.absoluteFile } + projectSpecificSources(project) | ||
} | ||
|
||
// this will become useful with the agp upgrade, as they're separate in 7.x+ | ||
val sourcesForKotlin = emptyList<File>() | ||
val excludedFiles = emptyList<File>() + projectSpecificSuppressedFiles(project) | ||
|
||
dependencies.set(classpath) | ||
javaSources.set(sourcesForJava) | ||
kotlinSources.set(sourcesForKotlin) | ||
suppressedFiles.set(excludedFiles) | ||
|
||
applyCommonConfigurations() | ||
} | ||
} | ||
} | ||
} | ||
|
||
// TODO(b/243534168): Remove when fixed | ||
private fun projectSpecificSources(project: Project) = | ||
when (project.name) { | ||
"firebase-common" -> { | ||
project.project(":firebase-firestore").files("src/main/java/com/google/firebase").toList() | ||
} | ||
else -> emptyList() | ||
} | ||
|
||
// TODO(b/243534168): Remove when fixed | ||
private fun projectSpecificSuppressedFiles(project: Project): List<File> = | ||
when (project.name) { | ||
"firebase-common" -> { | ||
val firestoreProject = project.project(":firebase-firestore") | ||
firestoreProject.files("src/main/java/com/google/firebase/firestore").toList() | ||
} | ||
"firebase-firestore" -> { | ||
project.files("src/main/java/com/google/firebase/Timestamp.java").toList() | ||
} | ||
else -> emptyList() | ||
} | ||
|
||
private fun GenerateDocumentationTask.applyCommonConfigurations() { | ||
val dackkaFile = project.provider { project.dackkaConfig.singleFile } | ||
val dackkaOutputDirectory = File(project.buildDir, "dackkaDocumentation") | ||
|
||
dackkaJarFile.set(dackkaFile) | ||
outputDirectory.set(dackkaOutputDirectory) | ||
} | ||
|
||
private fun registerFiresiteTransformTask(project: Project, outputDirectory: Provider<File>) = | ||
project.tasks.register<FiresiteTransformTask>("firesiteTransform") { | ||
dackkaFiles.set(outputDirectory) | ||
} | ||
|
||
// If we decide to publish java variants, we'll need to address the generated format as well | ||
private fun registerDeleteDackkaGeneratedJavaReferencesTask(project: Project, outputDirectory: Provider<File>) = | ||
project.tasks.register<Delete>("deleteDackkaGeneratedJavaReferences") { | ||
mustRunAfter("generateDackkaDocumentation") | ||
|
||
val filesWeDoNotNeed = listOf( | ||
"reference/client", | ||
"reference/com" | ||
) | ||
val filesToDelete = outputDirectory.map { dir -> | ||
filesWeDoNotNeed.map { | ||
project.files("${dir.path}/$it") | ||
} | ||
} | ||
|
||
delete(filesToDelete) | ||
} | ||
|
||
private fun registerCopyDackkaOutputToCommonDirectoryTask(project: Project, outputDirectory: Provider<File>) = | ||
project.tasks.register<Copy>("copyDackkaOutputToCommonDirectory") { | ||
mustRunAfter("deleteDackkaGeneratedJavaReferences") | ||
mustRunAfter("firesiteTransform") | ||
|
||
val referenceFolder = outputDirectory.map { project.file("${it.path}/reference") } | ||
val outputFolder = project.file("${project.rootProject.buildDir}/firebase-kotlindoc") | ||
|
||
from(referenceFolder) | ||
destinationDir = outputFolder | ||
} | ||
|
||
// Useful for local testing, but may not be desired for standard use (that's why it's not depended on) | ||
private fun registerCleanDackkaDocumentation(project: Project) = | ||
project.tasks.register<Delete>("cleanDackkaDocumentation") { | ||
group = "cleanup" | ||
|
||
delete("${project.buildDir}/dackkaDocumentation") | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.