Skip to content
This repository has been archived by the owner on Feb 11, 2022. It is now read-only.

Commit

Permalink
Merge pull request #134 from novoda/taso/fix-detekt9
Browse files Browse the repository at this point in the history
Detekt RC9 integration
  • Loading branch information
mr-archano committed Oct 6, 2018
2 parents 358e012 + 99fa10f commit 7f558c9
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 13 deletions.
Expand Up @@ -11,7 +11,7 @@ import org.gradle.api.Task
class DetektConfigurator implements Configurator {

private static final String DETEKT_PLUGIN = 'io.gitlab.arturbosch.detekt'
private static final String LAST_COMPATIBLE_DETEKT_VERSION = '1.0.0.RC8'
private static final String LAST_COMPATIBLE_DETEKT_VERSION = '1.0.0.RC9.2'
private static final String DETEKT_NOT_APPLIED = 'The Detekt plugin is configured but not applied. Please apply the plugin in your build script.\nFor more information see https://github.com/arturbosch/detekt.'
private static final String OUTPUT_NOT_DEFINED = 'Output not defined! To analyze the results, `output` needs to be defined in Detekt profile.'
private static final String DETEKT_CONFIGURATION_ERROR = "A problem occurred while configuring Detekt. Please make sure to use a compatible version (All versions up to $LAST_COMPATIBLE_DETEKT_VERSION)"
Expand Down Expand Up @@ -47,22 +47,36 @@ class DetektConfigurator implements Configurator {
def detekt = project.extensions.findByName('detekt')
config.delegate = detekt
config()
configureToolTask(detekt)

def collectViolations = configureToolTask(detekt)
evaluateViolations.dependsOn collectViolations
}
}

private CollectDetektViolationsTask configureToolTask(detekt) {
def detektTask = project.tasks.findByName('detekt')
if (detektTask?.hasProperty('reports')) {
def reports = detektTask.reports
return createCollectViolationsTask(
violations,
detektTask,
reports.xml.destination,
reports.html.destination
)
}

private void configureToolTask(detekt) {
def detektTask = project.tasks['detektCheck']
detektTask.group = 'verification'

// evaluate violations after detekt
// Fallback to old Detekt versions
def output = resolveOutput(detekt)
if (!output) {
throw new IllegalArgumentException(OUTPUT_NOT_DEFINED)
}
def collectViolations = createCollectViolationsTask(violations, project.file(output))
evaluateViolations.dependsOn collectViolations
collectViolations.dependsOn detektTask
def outputFolder = project.file(output)
return createCollectViolationsTask(
violations,
project.tasks['detektCheck'],
new File(outputFolder, 'detekt-checkstyle.xml'),
new File(outputFolder, 'detekt-report.html')
)
}

private static resolveOutput(detekt) {
Expand All @@ -75,11 +89,13 @@ class DetektConfigurator implements Configurator {
}
}

private CollectDetektViolationsTask createCollectViolationsTask(Violations violations, File outputFolder) {
private CollectDetektViolationsTask createCollectViolationsTask(Violations violations, detektTask, File xmlReportFile, File htmlReportFile) {
project.tasks.create('collectDetektViolations', CollectDetektViolationsTask) { task ->
task.xmlReportFile = new File(outputFolder, 'detekt-checkstyle.xml')
task.htmlReportFile = new File(outputFolder, 'detekt-report.html')
task.xmlReportFile = xmlReportFile
task.htmlReportFile = htmlReportFile
task.violations = violations

task.dependsOn(detektTask)
}
}

Expand Down
@@ -0,0 +1,162 @@
package com.novoda.staticanalysis.internal.detekt

import com.novoda.test.Fixtures
import com.novoda.test.TestProject
import com.novoda.test.TestProjectRule
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized

import static com.novoda.test.LogsSubject.assertThat

@RunWith(Parameterized.class)
class DetektNewIntegrationTest {

private static final String DETEKT_NOT_APPLIED = 'The Detekt plugin is configured but not applied. Please apply the plugin in your build script.'

@Parameterized.Parameters(name = "{0} with Detekt: {1}")
static Iterable rules() {
return [
[TestProjectRule.forKotlinProject(), "1.0.0.RC9.2"],
[TestProjectRule.forAndroidKotlinProject(), "1.0.0.RC9.2"],
]*.toArray()
}

@Rule
public final TestProjectRule projectRule
private final String detektVersion

DetektNewIntegrationTest(TestProjectRule projectRule, String detektVersion) {
this.projectRule = projectRule
this.detektVersion = detektVersion
}

@Test
void shouldFailBuildOnConfigurationWhenDetektConfiguredButNotApplied() {
def result = projectRule.newProject()
.withToolsConfig(detektConfiguration(Fixtures.Detekt.SOURCES_WITH_ERRORS, detektVersion))
.buildAndFail('check')

assertThat(result.logs).contains(DETEKT_NOT_APPLIED)
}

@Test
void shouldFailBuildWhenDetektWarningsOverTheThreshold() {
def result = createProjectWithZeroThreshold(Fixtures.Detekt.SOURCES_WITH_WARNINGS)
.buildAndFail('check')

assertThat(result.logs).containsLimitExceeded(0, 1)
assertThat(result.logs).containsDetektViolations(0, 1,
result.buildFileUrl('reports/detekt/detekt.html'))
}

@Test
void shouldFailBuildWhenDetektErrorsOverTheThreshold() {
def result = createProjectWithZeroThreshold(Fixtures.Detekt.SOURCES_WITH_ERRORS)
.buildAndFail('check')

assertThat(result.logs).containsLimitExceeded(1, 0)
assertThat(result.logs).containsDetektViolations(1, 0,
result.buildFileUrl('reports/detekt/detekt.html'))
}

@Test
void shouldNotFailWhenDetektIsNotConfigured() throws Exception {
def result = createProjectWithoutDetekt()
.build('check')

assertThat(result.logs).doesNotContainDetektViolations()
}

@Test
void shouldNotFailWhenWarningsAreWithinThreshold() throws Exception {
def result = createProjectWith(Fixtures.Detekt.SOURCES_WITH_WARNINGS, 1, 0)
.build('check')

assertThat(result.logs).containsDetektViolations(0, 1,
result.buildFileUrl('reports/detekt/detekt.html'))
}

@Test
void shouldNotFailWhenErrorsAreWithinThreshold() throws Exception {
def result = createProjectWith(Fixtures.Detekt.SOURCES_WITH_ERRORS, 0, 1)
.build('check')

assertThat(result.logs).containsDetektViolations(1, 0,
result.buildFileUrl('reports/detekt/detekt.html'))
}

@Test
void shouldNotFailBuildWhenNoDetektWarningsOrErrorsEncounteredAndNoThresholdTrespassed() {
def testProject = projectRule.newProject()
.withPlugin("io.gitlab.arturbosch.detekt", detektVersion)
.withPenalty('''{
maxWarnings = 0
maxErrors = 0
}''')
.withToolsConfig(detektConfigurationWithoutInput(detektVersion))

TestProject.Result result = testProject
.build('check')

assertThat(result.logs).doesNotContainLimitExceeded()
assertThat(result.logs).doesNotContainDetektViolations()
}

private TestProject createProjectWithZeroThreshold(File sources) {
createProjectWith(sources)
}

private TestProject createProjectWith(File sources, int maxWarnings = 0, int maxErrors = 0) {
projectRule.newProject()
.withPlugin("io.gitlab.arturbosch.detekt", detektVersion)
.withSourceSet('main', sources)
.withPenalty("""{
maxWarnings = ${maxWarnings}
maxErrors = ${maxErrors}
}""")
.withToolsConfig(detektConfiguration(sources, detektVersion))
}

private TestProject createProjectWithoutDetekt() {
projectRule.newProject()
.withPlugin("io.gitlab.arturbosch.detekt", detektVersion)
.withSourceSet('main', Fixtures.Detekt.SOURCES_WITH_WARNINGS)
.withPenalty('''{
maxWarnings = 0
maxErrors = 0
}''')
}

private static String detektConfiguration(File input, String detektVersion) {
detektWith(detektVersion, """
config = files('${Fixtures.Detekt.RULES}')
// The input just needs to be configured for the tests.
// Probably detekt doesn't pick up the changed source sets.
// In a example project it was not needed.
input = files("${input}")
""")
}

private static String detektConfigurationWithoutInput(String detektVersion) {
detektWith(detektVersion, """
config = files('${Fixtures.Detekt.RULES}')
""")
}

private static String detektWith(String detektVersion, String configuration) {
"""
detekt {
toolVersion '${detektVersion}'
${configuration.stripIndent()}
reports {
xml.enabled = true
html.enabled = true
}
}
"""
}
}

0 comments on commit 7f558c9

Please sign in to comment.