OpenSearch/gradle/missing-javadoc.gradle

243 lines
7.4 KiB
Groovy
Raw Normal View History

Merging javadoc feature branch changes to main (#715) * Adds a gradle plugin to validate missing javadocs Use `./gradlew missingJavadoc` to validate missing javadocs. Currently this task fails because several modules are missing appropriate javadocs. Once added, this should pass. Also, precommit PomValidation check currently fails with missing Javadoc plugin, that needs to be fixed - https://github.com/opensearch-project/OpenSearch/issues/449 Thus keeping this in a separate feature branch. Signed-off-by: Himanshu Setia <setiah@amazon.com> * Fix Javadoc errors in module `client/rest` (#685) * Fix Javadoc errors in client/rest module Signed-off-by: Gregor Zurowski <gregor@zurowski.org> * Add package info file in client/rest module Signed-off-by: Gregor Zurowski <gregor@zurowski.org> * Fix typos Signed-off-by: Gregor Zurowski <gregor@zurowski.org> * Add exception documentation to Javadoc Signed-off-by: Gregor Zurowski <gregor@zurowski.org> * Fixes precommit task configuration failures due to newly added missin… (#707) * Fixes precommit task configuration failures due to newly added missingJavadoc task Signed-off-by: Himanshu Setia <setiah@amazon.com> * Fixes javadoc task errors due to PR#685 Signed-off-by: Himanshu Setia <setiah@amazon.com> * Updated CONTRIBUTING.md for info on javadocs Signed-off-by: Himanshu Setia <setiah@amazon.com> * Correcting licenses and naming Signed-off-by: Himanshu Setia <setiah@amazon.com> * Correcting version info Signed-off-by: Himanshu Setia <setiah@amazon.com> Co-authored-by: Gregor Zurowski <gregor@zurowski.org>
2021-05-18 16:21:41 -04:00
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
import javax.annotation.Nullable
/**
* Checks for missing javadocs.
*/
// Original version of this file is ported from the render-javadoc code in Lucene,
// original code under the Apache Software Foundation under Apache 2.0 license
// See - https://github.com/apache/lucene-solr/tree/master/gradle/documentation/render-javadoc
allprojects {
ext {
scriptResources = { buildscript ->
return file(buildscript.sourceFile.absolutePath.replaceAll('.gradle$', ""))
}
}
}
def resources = scriptResources(buildscript)
allprojects {
plugins.withType(JavaPlugin) {
configurations {
missingdoclet
}
dependencies {
missingdoclet "org.opensearch:missing-doclet"
}
ext {
relativeDocPath = project.path.replaceFirst(/:\w+:/, "").replace(':', '/')
docroot = file("${buildDir}/site")
}
// TODO: Add missingJavadoc checks to precommit plugin
// See https://github.com/opensearch-project/OpenSearch/issues/221
// Currently the missingJavadoc task fails due to missing documentation
// across multiple modules. Once javadocs are added, we can
// add this task to precommit plugin.
tasks.withType(MissingJavadocTask).configureEach {
enabled = true
title = "${project.rootProject.name} ${project.name} API"
// Set up custom doclet.
dependsOn configurations.missingdoclet
docletpath = configurations.missingdoclet
}
tasks.register('missingJavadoc', MissingJavadocTask) {
description "This task validates and generates Javadoc API documentation for the main source code."
group "documentation"
taskResources = resources
dependsOn sourceSets.main.compileClasspath
classpath = sourceSets.main.compileClasspath
srcDirSet = sourceSets.main.java
outputDir = project.javadoc.destinationDir
}
}
}
class MissingJavadocTask extends DefaultTask {
@InputFiles
@SkipWhenEmpty
SourceDirectorySet srcDirSet;
@OutputDirectory
File outputDir
@CompileClasspath
FileCollection classpath
@CompileClasspath
FileCollection docletpath
@Input
String title
@Input
boolean linksource = false
@Input
boolean relativeProjectLinks = false
@Input
String javadocMissingLevel = "parameter"
// anything in these packages is checked with level=method. This allows iteratively fixing one package at a time.
@Input
List<String> javadocMissingMethod = []
// default is not to ignore any elements, should only be used to workaround split packages
@Input
List<String> javadocMissingIgnore = []
@Nullable
@Optional
@Input
def executable
@Input
def taskResources
/** Utility method to recursively collect all tasks with same name like this one that we depend on */
private Set findRenderTasksInDependencies() {
Set found = []
def collectDeps
collectDeps = { task -> task.taskDependencies.getDependencies(task).findAll{ it.name == this.name && it.enabled && !found.contains(it) }.each{
found << it
collectDeps(it)
}}
collectDeps(this)
return found
}
@TaskAction
void render() {
def srcDirs = srcDirSet.srcDirs.findAll { dir -> dir.exists() }
def optionsFile = project.file("${getTemporaryDir()}/javadoc-options.txt")
// create the directory, so relative link calculation knows that it's a directory:
outputDir.mkdirs();
def opts = []
opts << [ '-overview', project.file("${srcDirs[0]}/overview.html") ]
opts << [ '-sourcepath', srcDirs.join(File.pathSeparator) ]
if (project.getGroup().toString().startsWith('org.opensearch')) {
opts << [ '-subpackages', 'org.opensearch']
} else {
opts << [ '-subpackages', project.getGroup().toString()]
}
opts << [ '-d', outputDir ]
opts << '-protected'
opts << [ '-encoding', 'UTF-8' ]
opts << [ '-charset', 'UTF-8' ]
opts << [ '-docencoding', 'UTF-8' ]
opts << '-noindex'
opts << '-author'
opts << '-version'
if (linksource) {
opts << '-linksource'
}
opts << '-use'
opts << [ '-locale', 'en_US' ]
opts << [ '-windowtitle', title ]
opts << [ '-doctitle', title ]
if (!classpath.isEmpty()) {
opts << [ '-classpath', classpath.asPath ]
}
opts << [ '-doclet', "org.opensearch.missingdoclet.MissingDoclet" ]
opts << [ '-docletpath', docletpath.asPath ]
opts << [ '--missing-level', javadocMissingLevel ]
if (javadocMissingIgnore) {
opts << [ '--missing-ignore', String.join(',', javadocMissingIgnore) ]
}
if (javadocMissingMethod) {
opts << [ '--missing-method', String.join(',', javadocMissingMethod) ]
}
opts << [ '-quiet' ]
opts << [ '--release', 11 ]
opts << '-Xdoclint:all,-missing'
// Temporary file that holds all javadoc options for the current task.
optionsFile.withWriter("UTF-8", { writer ->
// escapes an option with single quotes or whitespace to be passed in the options.txt file for
def escapeJavadocOption = { String s -> (s =~ /[ '"]/) ? ("'" + s.replaceAll(/[\\'"]/, /\\$0/) + "'") : s }
opts.each { entry ->
if (entry instanceof List) {
writer.write(entry.collect { escapeJavadocOption(it as String) }.join(" "))
} else {
writer.write(escapeJavadocOption(entry as String))
}
writer.write('\n')
}
})
def javadocCmd = {
if (executable == null) {
JavaInstallationRegistry registry = project.extensions.getByType(JavaInstallationRegistry)
JavaInstallation currentJvm = registry.installationForCurrentVirtualMachine.get()
return currentJvm.jdk.get().javadocExecutable.asFile
} else {
return project.file(executable)
}
}()
def outputFile = project.file("${getTemporaryDir()}/javadoc-output.txt")
def result
outputFile.withOutputStream { output ->
result = project.exec {
executable javadocCmd
// we want to capture both stdout and stderr to the same
// stream but gradle attempts to close these separately
// (it has two independent pumping threads) and it can happen
// that one still tries to write something when the other closed
// the underlying output stream.
def wrapped = new java.io.FilterOutputStream(output) {
public void close() {
// no-op. we close this stream manually.
}
}
standardOutput = wrapped
errorOutput = wrapped
args += [ "@${optionsFile}" ]
// -J flags can't be passed via options file... (an error "javadoc: error - invalid flag: -J-Xmx512m" occurs.)
args += [ "-J-Xmx512m" ]
// force locale to be "en_US" (fix for: https://bugs.openjdk.java.net/browse/JDK-8222793)
args += [ "-J-Duser.language=en", "-J-Duser.country=US" ]
ignoreExitValue true
}
}
if (result.getExitValue() != 0) {
// Pipe the output to console. Intentionally skips any encoding conversion
// and pumps raw bytes.
System.out.write(outputFile.bytes)
def cause
try {
result.rethrowFailure()
} catch (ex) {
cause = ex
}
throw new GradleException("Javadoc generation failed for ${project.path},\n Options file at: ${optionsFile}\n Command output at: ${outputFile}", cause)
}
}
}