From 1c3e62bebbfdbd495e081607a8885462d2eb0a0d Mon Sep 17 00:00:00 2001 From: "Vitaly V. Pinchuk" Date: Tue, 13 Sep 2022 00:37:32 +0300 Subject: [PATCH] Add config generator for custom rules (#5080) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [WIP] Add config generator for custom rules * [WIP] Add config generator for custom rules * [WIP] Add config generator for custom rules * Fix tests for Windows * WIP * Fix handling filenames Co-authored-by: Brais Gabín * Update tests Co-authored-by: Brais Gabín --- .../detekt/generator/DetektPrinter.kt | 6 ++ .../arturbosch/detekt/generator/Generator.kt | 20 +++++++ .../detekt/generator/GeneratorArgs.kt | 14 ++++- .../arturbosch/detekt/generator/Main.kt | 5 ++ .../printer/defaultconfig/ConfigPrinter.kt | 7 +++ .../detekt/generator/printer/GeneratorSpec.kt | 59 +++++++++++++++++++ 6 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/GeneratorSpec.kt diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektPrinter.kt index 0df824a317c..7fd4075a4af 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektPrinter.kt @@ -43,6 +43,12 @@ class DetektPrinter(private val arguments: GeneratorArgs) { } } + fun printCustomRuleConfig(pages: List, folder: String) { + yamlWriter.write(Paths.get(folder), "config") { + ConfigPrinter.printCustomRuleConfig(pages) + } + } + private fun markdownHeader(ruleSet: String): String { check(ruleSet.length > 1) { "Rule set name must be not empty or less than two symbols." } return """ diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Generator.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Generator.kt index af96985c763..23745b99eb2 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Generator.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Generator.kt @@ -39,4 +39,24 @@ class Generator( outPrinter.println("\nGenerated all detekt documentation in $time ms.") } + + fun executeCustomRuleConfig() { + val parser = KtCompiler() + val time = measureTimeMillis { + arguments.inputPath + .map { parseAll(parser, it.resolve("src/main/kotlin/")) to it } + .forEach { (list: Collection, folder: Path) -> + val collector = DetektCollector() + list.forEach { file -> + collector.visit(file) + } + printer.printCustomRuleConfig( + collector.items, + folder.resolve("src/main/resources/config/").toString() + ) + } + } + + outPrinter.println("\nGenerated custom rules config in $time ms.") + } } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/GeneratorArgs.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/GeneratorArgs.kt index 6a6b4fa6f0f..d1e34e9d569 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/GeneratorArgs.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/GeneratorArgs.kt @@ -16,21 +16,21 @@ class GeneratorArgs { @Parameter( names = ["--documentation", "-d"], - required = true, + required = false, description = "Output path for generated documentation." ) private var documentation: String? = null @Parameter( names = ["--config", "-c"], - required = true, + required = false, description = "Output path for generated detekt config." ) private var config: String? = null @Parameter( names = ["--cli-options"], - required = true, + required = false, description = "Output path for generated cli options page." ) private var cliOptions: String? = null @@ -42,6 +42,14 @@ class GeneratorArgs { ) var help: Boolean = false + @Parameter( + names = ["--generate-custom-rule-config", "-gcrc"], + required = false, + description = "Generate config for user-defined rules. " + + "Path to user rules can be specified with --input option" + ) + var generateCustomRuleConfig: Boolean = false + val inputPath: List by lazy { checkNotNull(input) { "Input parameter was not initialized by jcommander!" } .splitToSequence(",", ";") diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Main.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Main.kt index d4b72ee1189..b5b2aa21c7d 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Main.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/Main.kt @@ -17,6 +17,11 @@ fun main(args: Array) { exitProcess(0) } + if (options.generateCustomRuleConfig) { + Generator(options).executeCustomRuleConfig() + return + } + require(Files.isDirectory(options.documentationPath)) { "Documentation path must be a directory." } require(Files.isDirectory(options.configPath)) { "Config path must be a directory." } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/ConfigPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/ConfigPrinter.kt index 10bf2f683ac..401b1da79e9 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/ConfigPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/ConfigPrinter.kt @@ -24,6 +24,13 @@ object ConfigPrinter : DocumentationPrinter> { } } + fun printCustomRuleConfig(item: List): String { + return yaml { + item.sortedBy { it.ruleSet.name } + .forEach { printRuleSetPage(it) } + } + } + private fun defaultBuildConfiguration(): String = """ build: maxIssues: 0 diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/GeneratorSpec.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/GeneratorSpec.kt new file mode 100644 index 00000000000..0aa8c0d4e01 --- /dev/null +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/GeneratorSpec.kt @@ -0,0 +1,59 @@ +package io.gitlab.arturbosch.detekt.generator.printer + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.AfterAll +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test +import java.io.File +import java.nio.file.Files +import java.nio.file.Paths +import kotlin.io.path.readText + +class GeneratorSpec { + @Test + fun `config files generated successfully`() { + assertThat(Paths.get(tempDir1.toString(), configPath)).exists() + assertThat(Paths.get(tempDir2.toString(), configPath)).exists() + } + + @Test + fun `config files have their own content`() { + assertThat(Paths.get(tempDir1.toString(), configPath).readText()) + .contains("complexity:") + .doesNotContain("coroutines:") + + assertThat(Paths.get(tempDir2.toString(), configPath).readText()) + .contains("coroutines:") + .doesNotContain("complexity:") + } + + companion object { + private const val sourceDir1 = "../detekt-rules-complexity" + private const val sourceDir2 = "../detekt-rules-coroutines" + private const val configPath = "/src/main/resources/config/config.yml" + + private val tempDir1: File = Files.createTempDirectory(null).toFile() + private val tempDir2: File = Files.createTempDirectory(null).toFile() + + @JvmStatic + @BeforeAll + fun init() { + File(Paths.get(sourceDir1).toString()).copyRecursively(tempDir1) + File(Paths.get(sourceDir2).toString()).copyRecursively(tempDir2) + + val args = arrayOf( + "--generate-custom-rule-config", + "--input", + "$tempDir1, $tempDir2", + ) + io.gitlab.arturbosch.detekt.generator.main(args) + } + + @JvmStatic + @AfterAll + fun tearDown() { + tempDir1.deleteRecursively() + tempDir2.deleteRecursively() + } + } +}