Skip to content

Commit

Permalink
Add severity-specific methods to DSL
Browse files Browse the repository at this point in the history
Also add option(String,boolean) overload, and validate check
names earlier.

Fixes #14
  • Loading branch information
tbroyer committed Apr 14, 2019
1 parent aa3d043 commit d965e05
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 41 deletions.
27 changes: 13 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,13 @@ you can pass those arguments to `options.errorprone.errorproneArgs` instead:

The next (optional) step would be to move to using the DSL:
```diff
+ import net.ltgt.gradle.errorprone.CheckSeverity
+
tasks.withType(JavaCompile).configureEach {
options.compilerArgs << "-Xlint:all" << "-Werror"
- options.errorprone.errorproneArgs << "-XepDisableWarningsInGeneratedCode"
- options.errorprone.errorproneArgs << "-Xep:NullAway:ERROR" << "-XepOpt:NullAway:AnnotatedPackages=com.uber"
+ options.errorprone {
+ disableWarningsInGeneratedCode = true
+ check("NullAway", CheckSeverity.ERROR)
+ error("NullAway")
+ option("NullAway:AnnotatedPackages", "net.ltgt")
+ }
}
Expand Down Expand Up @@ -274,16 +272,14 @@ dependencies {
```
and can then be configured on the tasks; for example:
```gradle
import net.ltgt.gradle.errorprone.CheckSeverity
tasks.withType(JavaCompile).configureEach {
options.errorprone {
option("NullAway:AnnotatedPackages", "net.ltgt")
}
}
tasks.named("compileJava").configure {
// Check defaults to WARNING, bump it up to ERROR for the main sources
options.errorprone.check("NullAway", CheckSeverity.ERROR)
// The check defaults to a warning, bump it up to an error for the main sources
options.errorprone.error("NullAway")
}
```
<details>
Expand All @@ -296,8 +292,8 @@ tasks.withType<JavaCompile>().configureEach {
}
}
tasks.named("compileJava", JavaCompile::class) {
// The check defaults to WARNING, bump it up to ERROR for the main sources
options.errorprone.check("NullAway", CheckSeverity.ERROR)
// The check defaults to a warning, bump it up to an error for the main sources
options.errorprone.error("NullAway")
}
```

Expand Down Expand Up @@ -340,11 +336,14 @@ import net.ltgt.gradle.errorprone.errorprone

| Method | Description
| :----- | :----------
| `check(checkNames...)` | Adds checks with their default severity. Useful in combination with `disableAllChecks` to selectively re-enable checks.
| `check(checkName to severity...)` | (Kotlin DSL only) Adds pairs of check name to severity. Severity can be set to `CheckSeverity.OFF` to disable a check.
| `check(checkName, severity)` | Adds a check with a given severity. Severity can be set to `CheckSeverity.OFF` to disable the check.
| `option(optionName)` | Enables a boolean check option. Equivalent to `option(checkName, "true")`.
| `option(optionName, value)` | Adds a check option with a given value.
| `enable(checkNames...)` | Adds checks with their default severity. Useful in combination with `disableAllChecks` to selectively re-enable checks.
| `disable(checkNames...)` | Disable checks.
| `warn(checkNames...)` | Adds checks with warning severity.
| `error(checkNames...)` | Adds checks with error severity.
| `check(checkName to severity...)` | (Kotlin DSL only) Adds pairs of check name to severity.
| `check(checkName, severity)` | Adds a check with a given severity.
| `option(optionName)` | Enables a boolean check option. Equivalent to `option(checkName, true)`.
| `option(optionName, value)` | Adds a check option with a given value. Value can be a boolean or a string.

A check severity can take values: `DEFAULT`, `OFF`, `WARN`, or `ERROR`.
Note that the `net.ltgt.gradle.errorprone.CheckSeverity` needs to be `import`ed into your build scripts (see examples above).
44 changes: 27 additions & 17 deletions src/main/kotlin/net/ltgt/gradle/errorprone/ErrorProneOptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,25 @@ open class ErrorProneOptions constructor(

companion object {
const val NAME = "errorprone"

private fun validate(arg: String) {
if (arg.contains("""\p{IsWhite_Space}""".toRegex()))
throw InvalidUserDataException("""Error Prone options cannot contain white space: "$arg".""")
}

private fun validateName(arg: Map.Entry<String, Any>) {
if (arg.key.contains(':'))
throw InvalidUserDataException("""Error Prone check name cannot contain a colon (":"): "${arg.key}".""")
}
}

fun check(vararg checkNames: String) = checks.putAll(checkNames.map { it to CheckSeverity.DEFAULT })
fun check(vararg pairs: Pair<String, CheckSeverity>) = checks.putAll(pairs)
@Deprecated("Renamed to enable", replaceWith = ReplaceWith("enable(*checkNames)"), level = DeprecationLevel.ERROR)
fun check(vararg checkNames: String) = enable(*checkNames)
fun check(vararg pairs: Pair<String, CheckSeverity>) = pairs.forEach { (checkName, severity) -> check(checkName, severity) }
fun check(checkName: String, severity: CheckSeverity) {
validateName(checkName)
checks[checkName] = severity
}

fun option(name: String) = option(name, "true")
fun enable(vararg checkNames: String) = set(*checkNames, atSeverity = CheckSeverity.DEFAULT)
fun disable(vararg checkNames: String) = set(*checkNames, atSeverity = CheckSeverity.OFF)
fun warn(vararg checkNames: String) = set(*checkNames, atSeverity = CheckSeverity.WARN)
fun error(vararg checkNames: String) = set(*checkNames, atSeverity = CheckSeverity.ERROR)

private fun set(vararg checkNames: String, atSeverity: CheckSeverity) =
checkNames.forEach { check(it, atSeverity) }

@JvmOverloads fun option(name: String, value: Boolean = true) = option(name, value.toString())
fun option(name: String, value: String) {
checkOptions[name] = value
}
Expand All @@ -66,7 +66,7 @@ open class ErrorProneOptions constructor(
booleanOption("-XepCompilingTestOnlyCode", isCompilingTestOnlyCode),
stringOption("-XepExcludedPaths", excludedPaths)
).filterNotNull() +
checks.asSequence().onEach(::validateName).map { (name, severity) -> "-Xep:$name${severity.asArg}" } +
checks.asSequence().map { (name, severity) -> validateName(name); "-Xep:$name${severity.asArg}" } +
checkOptions.asSequence().map { (name, value) -> "-XepOpt:$name=$value" } +
errorproneArgs.getOrElse(emptyList()) +
errorproneArgumentProviders.asSequence().flatMap { it.asArguments().asSequence() }
Expand All @@ -82,10 +82,20 @@ open class ErrorProneOptions constructor(
}

enum class CheckSeverity {
DEFAULT, OFF, WARN, ERROR;
DEFAULT, OFF, WARN, ERROR
}

private val CheckSeverity.asArg: String
get() = if (this == CheckSeverity.DEFAULT) "" else ":$name"

private fun validate(arg: String) {
if (arg.contains("""\p{IsWhite_Space}""".toRegex()))
throw InvalidUserDataException("""Error Prone options cannot contain white space: "$arg".""")
}

internal val asArg: String
get() = if (this == DEFAULT) "" else ":$name"
private fun validateName(checkName: String) {
if (checkName.contains(':'))
throw InvalidUserDataException("""Error Prone check name cannot contain a colon (":"): "$checkName".""")
}

// Extensions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class AndroidIntegrationTest : AbstractPluginIntegrationTest() {
afterEvaluate {
tasks.withType<JavaCompile>().configureEach {
options.errorprone {
check("ArrayEquals", CheckSeverity.OFF)
disable("ArrayEquals")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class ErrorProneOptionsTest {
doTestOptions { ignoreSuppressionAnnotations.set(true) }
doTestOptions { isCompilingTestOnlyCode.set(true) }
doTestOptions { excludedPaths.set(".*/build/generated/.*") }
doTestOptions { check("ArrayEquals") }
doTestOptions { enable("ArrayEquals") }
doTestOptions { disable("ArrayEquals") }
doTestOptions { warn("ArrayEquals") }
doTestOptions { error("ArrayEquals") }
doTestOptions { check("ArrayEquals" to CheckSeverity.OFF) }
doTestOptions { check("ArrayEquals", CheckSeverity.WARN) }
doTestOptions { checks["ArrayEquals"] = CheckSeverity.ERROR }
Expand All @@ -53,7 +56,7 @@ class ErrorProneOptionsTest {
ignoreSuppressionAnnotations.set(true)
isCompilingTestOnlyCode.set(true)
excludedPaths.set(".*/build/generated/.*")
check("BetaApi")
enable("BetaApi")
check("NullAway", CheckSeverity.ERROR)
option("Foo")
option("NullAway:AnnotatedPackages", "net.ltgt.gradle.errorprone")
Expand All @@ -75,7 +78,7 @@ class ErrorProneOptionsTest {

doTestOptions(
{ errorproneArgs.set(mutableListOf("-XepDisableAllChecks", "-Xep:BetaApi")) },
{ disableAllChecks.set(true); check("BetaApi") })
{ disableAllChecks.set(true); enable("BetaApi") })

doTestOptions({
errorproneArgumentProviders.add(CommandLineArgumentProvider {
Expand All @@ -101,7 +104,7 @@ class ErrorProneOptionsTest {
doTestSpaces("-XepExcludedPaths:") {
excludedPaths.set("/home/user/My Projects/project-name/build/generated sources/.*")
}
doTestSpaces("-Xep:") { check("Foo Bar") }
doTestSpaces("-Xep:") { enable("Foo Bar") }
doTestSpaces("-XepOpt:") { option("Foo Bar") }
doTestSpaces("-XepOpt:") { option("Foo", "Bar Baz") }
doTestSpaces("-Xep:Foo -Xep:Bar") { errorproneArgs.add("-Xep:Foo -Xep:Bar") }
Expand All @@ -122,7 +125,7 @@ class ErrorProneOptionsTest {
@Test
fun `rejects colon in check name`() {
try {
ErrorProneOptions(objects).apply({ check("ArrayEquals:OFF") }).toString()
ErrorProneOptions(objects).apply({ enable("ArrayEquals:OFF") }).toString()
fail("Should have thrown")
} catch (e: InvalidUserDataException) {
assertThat(e).hasMessageThat()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class ErrorPronePluginIntegrationTest : AbstractPluginIntegrationTest() {
tasks.withType<JavaCompile>().configureEach {
options.errorprone {
check("ArrayEquals", CheckSeverity.OFF)
disable("ArrayEquals")
}
}
""".trimIndent())
Expand Down Expand Up @@ -124,7 +124,7 @@ class ErrorPronePluginIntegrationTest : AbstractPluginIntegrationTest() {
errorprone(project(":customCheck"))
}
tasks.withType<JavaCompile>().configureEach {
options.errorprone.check("MyCustomCheck", CheckSeverity.ERROR)
options.errorprone.error("MyCustomCheck")
}
""".trimIndent())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ManualConfigurationIntegrationTest : AbstractPluginIntegrationTest() {
options.errorprone {
isEnabled.set(true)
disableAllChecks.set(true)
check("ArrayEquals", CheckSeverity.ERROR)
error("ArrayEquals")
}
}
""".trimIndent())
Expand Down Expand Up @@ -74,7 +74,7 @@ class ManualConfigurationIntegrationTest : AbstractPluginIntegrationTest() {
options.errorprone {
disableAllChecks.set(true)
check("ArrayEquals", CheckSeverity.ERROR)
error("ArrayEquals")
}
}
""".trimIndent())
Expand Down

0 comments on commit d965e05

Please sign in to comment.