Skip to content

Commit

Permalink
Add a task to run forbiddenapis using cli
Browse files Browse the repository at this point in the history
Add a task that offers an equivalent check to the forbidden APIs plugin,
but runs it using the forbiddenAPIs CLI instead.

This isn't wired into precommit first, and doesn't work for projects
that require specific signatures, etc. It's meant to show how this can
be used. The next step is to make a custom task type and configure it
based on the project extension from the pugin and make some minor
adjustments to some build scripts as we can't  bee 100% compatible with
that at least due to how additional signatures are passed.

Notes:
- there's no `--target` for the CLI version so we have to pass in
specific bundled signature names
- the cli task already wires to `runtimeJavaHome`
- no equivalent for `failOnUnsupportedJava = false` but doesn't seem to
be a problem. Tested with Java 8 to 11
- there's no way to pass additional signatures as URL, these will have
to be on the file system, and can't be resources on the cp unless we
rely on how forbiddenapis is implemented and mimic them as boundled
signatures.
- the average of 3 runs is 4% slower using the CLI for :server.
( `./gradlew clean :server:forbiddenApis` vs `./gradlew clean
:server:forbiddenApisCli`)
- up-to-date checks don't work on the cli task yet, that will happen
with the custom task.

See also: elastic#31715
  • Loading branch information
alpar-t committed Jul 16, 2018
1 parent b65c586 commit 02262d5
Showing 1 changed file with 61 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import de.thetaphi.forbiddenapis.gradle.ForbiddenApisPlugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.FileCollection
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.quality.Checkstyle
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.StopExecutionException

/**
* Validation tasks which should be run before committing. These run before tests.
Expand All @@ -40,7 +43,11 @@ class PrecommitTasks {
project.tasks.create('licenseHeaders', LicenseHeadersTask.class),
project.tasks.create('filepermissions', FilePermissionsTask.class),
project.tasks.create('jarHell', JarHellTask.class),
project.tasks.create('thirdPartyAudit', ThirdPartyAuditTask.class)]
project.tasks.create('thirdPartyAudit', ThirdPartyAuditTask.class)
]

// Configure it but don't add it as a dependency yet
configureForbiddenApisCli(project)

// tasks with just tests don't need dependency licenses, so this flag makes adding
// the task optional
Expand Down Expand Up @@ -96,9 +103,62 @@ class PrecommitTasks {
}
Task forbiddenApis = project.tasks.findByName('forbiddenApis')
forbiddenApis.group = "" // clear group, so this does not show up under verification tasks

return forbiddenApis
}

private static Task configureForbiddenApisCli(Project project) {
project.configurations.create("forbiddenApisCliJar")
project.dependencies {
forbiddenApisCliJar 'de.thetaphi:forbiddenapis:2.5'
}
Task forbiddenApisCli = project.tasks.create('forbiddenApisCli')
project.ext.getForbiddenSignaturesFile = { name -> project.getForbiddenSignaturesFile(name) }

project.sourceSets.forEach { sourceSet ->
forbiddenApisCli.dependsOn(
project.tasks.create(sourceSet.getTaskName('forbiddenApisCli', null), JavaExec) {
classpath = project.files(
project.configurations.forbiddenApisCliJar,
sourceSet.compileClasspath,
sourceSet.runtimeClasspath
)
main = 'de.thetaphi.forbiddenapis.cli.CliMain'
executable = "${project.runtimeJavaHome}/bin/java"
[
'jdk-unsafe-1.8', 'jdk-deprecated-1.8', 'jdk-non-portable', 'jdk-system-out'
].forEach { args "-b", it }
[
getForbiddenSignaturesFile(project, 'jdk-signatures'),
getForbiddenSignaturesFile(project, 'es-all-signatures')
].forEach { args "-f", it }
if (sourceSet.name == 'test') {
args "-f", getForbiddenSignaturesFile(project, 'es-test-signatures')
args "-f", getForbiddenSignaturesFile(project, 'http-signatures')
} else {
args "-f", getForbiddenSignaturesFile(project, 'es-server-signatures')
}
args "--suppressannotation", '**.SuppressForbidden'
dependsOn sourceSet.classesTaskName
doFirst {
// Forbidden APIs expects only existing dirs, and requires at least one
FileCollection existingOutputs = sourceSet.output.classesDirs
.filter { it.exists() }
if (existingOutputs.isEmpty()) {
throw new StopExecutionException("${sourceSet.name} has no outputs")
}
existingOutputs.forEach { args "-d", it }
}
}
)
}
return forbiddenApisCli
}

private static File getForbiddenSignaturesFile(project, String name) {
return project.rootProject.file('buildSrc/src/main/resources/forbidden/' + name + '.txt')
}

private static Task configureCheckstyle(Project project) {
// Always copy the checkstyle configuration files to 'buildDir/checkstyle' since the resources could be located in a jar
// file. If the resources are located in a jar, Gradle will fail when it tries to turn the URL into a file
Expand Down

0 comments on commit 02262d5

Please sign in to comment.