diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 09cc5ebf06..70f59357d3 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -38,13 +38,13 @@ jobs: use-gradlew: true gradle-build-module: |- :diktat-api - :diktat-common :diktat-common-test :diktat-ktlint-engine :diktat-gradle-plugin :diktat-maven-plugin :diktat-rules :diktat-ruleset + :diktat-runner :diktat-dev-ksp :diktat-cli gradle-build-configuration: |- diff --git a/diktat-api/src/main/kotlin/com/saveourtool/diktat/Constants.kt b/diktat-api/src/main/kotlin/com/saveourtool/diktat/Constants.kt new file mode 100644 index 0000000000..1797632335 --- /dev/null +++ b/diktat-api/src/main/kotlin/com/saveourtool/diktat/Constants.kt @@ -0,0 +1,16 @@ +/** + * This file contains common constants for Diktat + */ + +package com.saveourtool.diktat + +/** + * Common application name, that is used in plugins and can be used to Suppress all diktat inspections on the + * particular code block with @Suppress("diktat") + */ +const val DIKTAT = "diktat" + +/** + * Default file name for config file + */ +const val DIKTAT_ANALYSIS_CONF = "diktat-analysis.yml" diff --git a/diktat-api/src/main/kotlin/com/saveourtool/diktat/DiktatRunnerArguments.kt b/diktat-api/src/main/kotlin/com/saveourtool/diktat/DiktatRunnerArguments.kt index fb8db04854..b63d801202 100644 --- a/diktat-api/src/main/kotlin/com/saveourtool/diktat/DiktatRunnerArguments.kt +++ b/diktat-api/src/main/kotlin/com/saveourtool/diktat/DiktatRunnerArguments.kt @@ -4,12 +4,11 @@ import com.saveourtool.diktat.api.DiktatProcessorListener import com.saveourtool.diktat.api.DiktatReporterCreationArguments import java.io.InputStream import java.nio.file.Path -import kotlin.io.path.inputStream /** * Arguments for [DiktatRunner] * - * @property configInputStream an input stream with config to load Diktat's rules + * @property configInputStream an input stream with config to load Diktat's rules or null to use default configs * @property sourceRootDir a common root dir for all provided [files] * @property files a collection of files which needs to be fixed * @property baselineFile an optional path to file with baseline @@ -17,26 +16,10 @@ import kotlin.io.path.inputStream * @property loggingListener listener to log diktat runner phases, [DiktatProcessorListener.empty] by default */ data class DiktatRunnerArguments( - val configInputStream: InputStream, + val configInputStream: InputStream?, val sourceRootDir: Path?, val files: Collection, val baselineFile: Path?, val reporterArgsList: List = emptyList(), val loggingListener: DiktatProcessorListener = DiktatProcessorListener.empty, -) { - constructor( - configFile: Path, - sourceRootDir: Path?, - files: Collection, - baselineFile: Path?, - reporterArgsList: List = emptyList(), - loggingListener: DiktatProcessorListener = DiktatProcessorListener.empty, - ) : this( - configFile.inputStream(), - sourceRootDir, - files, - baselineFile, - reporterArgsList, - loggingListener, - ) -} +) diff --git a/diktat-api/src/main/kotlin/com/saveourtool/diktat/DiktatRunnerFactory.kt b/diktat-api/src/main/kotlin/com/saveourtool/diktat/DiktatRunnerFactory.kt index 85c917fdf2..41c7b2e77e 100644 --- a/diktat-api/src/main/kotlin/com/saveourtool/diktat/DiktatRunnerFactory.kt +++ b/diktat-api/src/main/kotlin/com/saveourtool/diktat/DiktatRunnerFactory.kt @@ -33,7 +33,7 @@ class DiktatRunnerFactory( * @return an instance of [DiktatRunner] created using [args] */ override fun invoke(args: DiktatRunnerArguments): DiktatRunner { - val diktatRuleConfigs = diktatRuleConfigReader(args.configInputStream) + val diktatRuleConfigs = args.configInputStream?.let { diktatRuleConfigReader(it) }.orEmpty() val diktatRuleSet = diktatRuleSetFactory(diktatRuleConfigs) val processor = diktatProcessorFactory(diktatRuleSet) val (baseline, baselineGenerator) = resolveBaseline(args.baselineFile, args.sourceRootDir) diff --git a/diktat-api/src/main/kotlin/com/saveourtool/diktat/api/DiktatRuleConfig.kt b/diktat-api/src/main/kotlin/com/saveourtool/diktat/api/DiktatRuleConfig.kt index 1de4d90f87..36e3fdd0b1 100644 --- a/diktat-api/src/main/kotlin/com/saveourtool/diktat/api/DiktatRuleConfig.kt +++ b/diktat-api/src/main/kotlin/com/saveourtool/diktat/api/DiktatRuleConfig.kt @@ -17,3 +17,37 @@ data class DiktatRuleConfig( val configuration: Map = emptyMap(), val ignoreAnnotated: Set = emptySet(), ) + +/** + * Finds [DiktatRuleConfig] for particular [DiktatRuleNameAware] object. + * + * @param rule a [DiktatRuleNameAware] which configuration will be returned + * @return [DiktatRuleConfig] for a particular rule if it is found, else null + */ +fun List.findByRuleName(rule: DiktatRuleNameAware): DiktatRuleConfig? = this.find { it.name == rule.ruleName() } + +/** + * checking if in yml config particular rule is enabled or disabled + * (!) the default value is "true" (in case there is no config specified) + * + * @param rule a [DiktatRuleNameAware] which is being checked + * @return true if rule is enabled in configuration, else false + */ +fun List.isRuleEnabled(rule: DiktatRuleNameAware): Boolean { + val ruleMatched = findByRuleName(rule) + return ruleMatched?.enabled ?: true +} + +/** + * @param rule diktat inspection + * @param annotations set of annotations that are annotating a block of code + * @return true if the code block is marked with annotation that is in `ignored list` in the rule + */ +fun List.isAnnotatedWithIgnoredAnnotation(rule: DiktatRuleNameAware, annotations: Set): Boolean = + findByRuleName(rule) + ?.ignoreAnnotated + ?.map { it.trim() } + ?.map { it.trim('"') } + ?.intersect(annotations) + ?.isNotEmpty() + ?: false diff --git a/diktat-api/src/main/kotlin/com/saveourtool/diktat/api/DiktatRuleNameAware.kt b/diktat-api/src/main/kotlin/com/saveourtool/diktat/api/DiktatRuleNameAware.kt new file mode 100644 index 0000000000..550b1cead3 --- /dev/null +++ b/diktat-api/src/main/kotlin/com/saveourtool/diktat/api/DiktatRuleNameAware.kt @@ -0,0 +1,11 @@ +package com.saveourtool.diktat.api + +/** + * This interface represents *name* of individual inspection in rule set. + */ +interface DiktatRuleNameAware { + /** + * @return name of this [DiktatRule] + */ + fun ruleName(): String +} diff --git a/diktat-api/src/main/kotlin/com/saveourtool/diktat/common/config/rules/LegacyAliases.kt b/diktat-api/src/main/kotlin/com/saveourtool/diktat/common/config/rules/LegacyAliases.kt new file mode 100644 index 0000000000..48266ef154 --- /dev/null +++ b/diktat-api/src/main/kotlin/com/saveourtool/diktat/common/config/rules/LegacyAliases.kt @@ -0,0 +1,20 @@ +/** + * Contains typealias for legacy support + */ + +package com.saveourtool.diktat.common.config.rules + +import com.saveourtool.diktat.api.DiktatRuleConfig +import com.saveourtool.diktat.api.DiktatRuleNameAware + +const val DIKTAT_CONF_PROPERTY = "diktat.config.path" + +/** + * this constant will be used everywhere in the code to mark usage of Diktat ruleset + * + * Should be removed from Diktat's code and should be presented only in `diktat-ruleset` + */ +const val DIKTAT_RULE_SET_ID = "diktat-ruleset" + +typealias RulesConfig = DiktatRuleConfig +typealias Rule = DiktatRuleNameAware diff --git a/diktat-cli/build.gradle.kts b/diktat-cli/build.gradle.kts index 090bda126e..82244c7493 100644 --- a/diktat-cli/build.gradle.kts +++ b/diktat-cli/build.gradle.kts @@ -26,6 +26,7 @@ dependencies { testImplementation(projects.diktatKtlintEngine) testImplementation(projects.diktatRules) testImplementation(projects.diktatCommonTest) + testImplementation(libs.kaml) testImplementation(libs.junit.jupiter) testImplementation(libs.junit.platform.suite) testImplementation(libs.assertj.core) diff --git a/diktat-cli/src/main/kotlin/com/saveourtool/diktat/cli/DiktatProperties.kt b/diktat-cli/src/main/kotlin/com/saveourtool/diktat/cli/DiktatProperties.kt index ab6863f333..85a6420c60 100644 --- a/diktat-cli/src/main/kotlin/com/saveourtool/diktat/cli/DiktatProperties.kt +++ b/diktat-cli/src/main/kotlin/com/saveourtool/diktat/cli/DiktatProperties.kt @@ -1,13 +1,13 @@ package com.saveourtool.diktat.cli +import com.saveourtool.diktat.DIKTAT +import com.saveourtool.diktat.DIKTAT_ANALYSIS_CONF import com.saveourtool.diktat.DiktatRunnerArguments import com.saveourtool.diktat.ENGINE_INFO import com.saveourtool.diktat.api.DiktatProcessorListener import com.saveourtool.diktat.api.DiktatReporterCreationArguments import com.saveourtool.diktat.api.DiktatReporterFactory import com.saveourtool.diktat.api.DiktatReporterType -import com.saveourtool.diktat.common.config.rules.DIKTAT -import com.saveourtool.diktat.common.config.rules.DIKTAT_ANALYSIS_CONF import com.saveourtool.diktat.util.isKotlinCodeOrScript import com.saveourtool.diktat.util.tryToPathIfExists import com.saveourtool.diktat.util.walkByGlob @@ -22,6 +22,7 @@ import java.nio.file.Path import java.nio.file.Paths import kotlin.io.path.createDirectories +import kotlin.io.path.exists import kotlin.io.path.inputStream import kotlin.io.path.outputStream import kotlin.system.exitProcess @@ -86,7 +87,7 @@ data class DiktatProperties( sourceRootDir = sourceRootDir, ) return DiktatRunnerArguments( - configInputStream = Paths.get(config).inputStream(), + configInputStream = Paths.get(config).takeIf { it.exists() }?.inputStream(), sourceRootDir = sourceRootDir, files = getFiles(sourceRootDir), baselineFile = null, diff --git a/diktat-cli/src/test/kotlin/com/saveourtool/diktat/smoke/DiktatSmokeTest.kt b/diktat-cli/src/test/kotlin/com/saveourtool/diktat/smoke/DiktatSmokeTest.kt index 12d44a280b..9c2a9f987b 100644 --- a/diktat-cli/src/test/kotlin/com/saveourtool/diktat/smoke/DiktatSmokeTest.kt +++ b/diktat-cli/src/test/kotlin/com/saveourtool/diktat/smoke/DiktatSmokeTest.kt @@ -2,7 +2,7 @@ package com.saveourtool.diktat.smoke import com.saveourtool.diktat.api.DiktatError import com.saveourtool.diktat.ktlint.format -import com.saveourtool.diktat.ruleset.rules.DiktatRuleConfigReaderImpl +import com.saveourtool.diktat.ruleset.config.DiktatRuleConfigYamlReader import com.saveourtool.diktat.ruleset.rules.DiktatRuleSetFactoryImpl import com.saveourtool.diktat.test.framework.processing.TestComparatorUnit import org.junit.jupiter.api.Assertions @@ -42,7 +42,7 @@ class DiktatSmokeTest : DiktatSmokeTestBase() { function = { testFile -> format( ruleSetSupplier = { - val diktatRuleConfigReader = DiktatRuleConfigReaderImpl() + val diktatRuleConfigReader = DiktatRuleConfigYamlReader() val diktatRuleSetFactory = DiktatRuleSetFactoryImpl() diktatRuleSetFactory(diktatRuleConfigReader(config.inputStream())) }, diff --git a/diktat-cli/src/test/kotlin/com/saveourtool/diktat/smoke/DiktatSmokeTestBase.kt b/diktat-cli/src/test/kotlin/com/saveourtool/diktat/smoke/DiktatSmokeTestBase.kt index 99d886181e..420c76b0c6 100644 --- a/diktat-cli/src/test/kotlin/com/saveourtool/diktat/smoke/DiktatSmokeTestBase.kt +++ b/diktat-cli/src/test/kotlin/com/saveourtool/diktat/smoke/DiktatSmokeTestBase.kt @@ -10,13 +10,12 @@ import com.saveourtool.diktat.api.DiktatError import com.saveourtool.diktat.common.config.rules.DIKTAT_COMMON import com.saveourtool.diktat.common.config.rules.DIKTAT_RULE_SET_ID import com.saveourtool.diktat.common.config.rules.RulesConfig -import com.saveourtool.diktat.common.config.rules.RulesConfigReader +import com.saveourtool.diktat.ruleset.config.DiktatRuleConfigYamlReader import com.saveourtool.diktat.ruleset.constants.Warnings import com.saveourtool.diktat.ruleset.constants.Warnings.EMPTY_BLOCK_STRUCTURE_ERROR import com.saveourtool.diktat.ruleset.constants.Warnings.FILE_NAME_MATCH_CLASS import com.saveourtool.diktat.ruleset.constants.Warnings.HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE import com.saveourtool.diktat.ruleset.constants.Warnings.KDOC_NO_EMPTY_TAGS -import com.saveourtool.diktat.ruleset.constants.Warnings.KDOC_WITHOUT_PARAM_TAG import com.saveourtool.diktat.ruleset.constants.Warnings.MISSING_KDOC_CLASS_ELEMENTS import com.saveourtool.diktat.ruleset.constants.Warnings.MISSING_KDOC_ON_FUNCTION import com.saveourtool.diktat.ruleset.constants.Warnings.MISSING_KDOC_TOP_LEVEL @@ -37,7 +36,6 @@ import com.saveourtool.diktat.ruleset.utils.indentation.IndentationConfig.Compan import com.charleskorn.kaml.Yaml import com.charleskorn.kaml.YamlConfiguration import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test @@ -77,7 +75,7 @@ abstract class DiktatSmokeTestBase { */ @Suppress("UnsafeCallOnNullableType") private fun prepareOverriddenRulesConfig(rulesToDisable: List = emptyList(), rulesToOverride: RuleToConfig = emptyMap()): Path { - val rulesConfig = RulesConfigReader().read(Paths.get(DEFAULT_CONFIG_PATH).inputStream())!! + val rulesConfig = DiktatRuleConfigYamlReader().invoke(Paths.get(DEFAULT_CONFIG_PATH).inputStream()) .toMutableList() .also { rulesConfig -> rulesToDisable.forEach { warning -> diff --git a/diktat-common-test/build.gradle.kts b/diktat-common-test/build.gradle.kts index b464999d4c..b172bace05 100644 --- a/diktat-common-test/build.gradle.kts +++ b/diktat-common-test/build.gradle.kts @@ -7,7 +7,6 @@ plugins { project.description = "Diktat common for tests" dependencies { - api(projects.diktatCommon) implementation(libs.kotlin.logging) implementation(libs.junit.jupiter.api) implementation(libs.assertj.core) diff --git a/diktat-common/build.gradle.kts b/diktat-common/build.gradle.kts deleted file mode 100644 index fc1c57c0ed..0000000000 --- a/diktat-common/build.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -@Suppress("DSL_SCOPE_VIOLATION", "RUN_IN_SCRIPT") // https://github.com/gradle/gradle/issues/22797 -plugins { - id("com.saveourtool.diktat.buildutils.kotlin-jvm-configuration") - id("com.saveourtool.diktat.buildutils.code-quality-convention") - id("com.saveourtool.diktat.buildutils.publishing-default-configuration") - alias(libs.plugins.kotlin.plugin.serialization) -} - -dependencies { - implementation(libs.kotlin.stdlib.jdk8) - api(libs.kotlinx.serialization.json) - api(libs.kaml) - implementation(libs.apache.commons.cli) - implementation(libs.kotlin.logging) - implementation(projects.diktatApi) - testImplementation(libs.junit.jupiter) - testImplementation(libs.assertj.core) - testImplementation(libs.slf4j.api) -} diff --git a/diktat-common/src/main/kotlin/com/saveourtool/diktat/common/config/reader/AbstractConfigReader.kt b/diktat-common/src/main/kotlin/com/saveourtool/diktat/common/config/reader/AbstractConfigReader.kt deleted file mode 100644 index 7838f5086f..0000000000 --- a/diktat-common/src/main/kotlin/com/saveourtool/diktat/common/config/reader/AbstractConfigReader.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.saveourtool.diktat.common.config.reader - -import io.github.oshai.kotlinlogging.KotlinLogging -import java.io.IOException -import java.io.InputStream -import kotlin.jvm.Throws - -/** - * This class is used to read input stream in any format that you will specify. - * Usage: - * 1) implement this class with implementing the method: - * a. parse - implement parser for your file format (for example parse it to a proper json) - * 2) Use your new class MyReader().read(someInputStream) - * - * @param T - class name parameter that will be used in calculation of classpath - */ -abstract class AbstractConfigReader { - /** - * @param inputStream - input stream - * @return object of type [T] if resource has been parsed successfully - */ - fun read(inputStream: InputStream): T? = try { - parse(inputStream) - } catch (e: IOException) { - log.error(e) { - "Cannot read config from input stream due to: " - } - null - } - - /** - * you can specify your own parser, in example for parsing stream as a json - * - * @param inputStream a [InputStream] representing loaded content - * @return resource parsed as type [T] - * @throws IOException - */ - @Throws(IOException::class) - protected abstract fun parse(inputStream: InputStream): T - - companion object { - private val log = KotlinLogging.logger {} - } -} diff --git a/diktat-common/src/main/kotlin/com/saveourtool/diktat/common/config/rules/RulesConfigReader.kt b/diktat-common/src/main/kotlin/com/saveourtool/diktat/common/config/rules/RulesConfigReader.kt deleted file mode 100644 index d25f7c240f..0000000000 --- a/diktat-common/src/main/kotlin/com/saveourtool/diktat/common/config/rules/RulesConfigReader.kt +++ /dev/null @@ -1,195 +0,0 @@ -/** - * Classes and extensions needed to read and parse rules configuration file - */ - -package com.saveourtool.diktat.common.config.rules - -import com.saveourtool.diktat.api.DiktatRuleConfig -import com.saveourtool.diktat.common.config.reader.AbstractConfigReader -import com.saveourtool.diktat.common.config.rules.RulesConfigReader.Companion.log - -import com.charleskorn.kaml.Yaml -import com.charleskorn.kaml.YamlConfiguration -import com.charleskorn.kaml.decodeFromStream -import io.github.oshai.kotlinlogging.KLogger -import io.github.oshai.kotlinlogging.KotlinLogging - -import java.io.InputStream -import java.util.Locale -import java.util.concurrent.atomic.AtomicInteger - -/** - * Name of common configuration - */ -const val DIKTAT_COMMON = "DIKTAT_COMMON" - -/** - * Common application name, that is used in plugins and can be used to Suppress all diktat inspections on the - * particular code block with @Suppress("diktat") - */ -const val DIKTAT = "diktat" - -/** - * this constant will be used everywhere in the code to mark usage of Diktat ruleset - */ -const val DIKTAT_RULE_SET_ID = "diktat-ruleset" -const val DIKTAT_ANALYSIS_CONF = "diktat-analysis.yml" -const val DIKTAT_CONF_PROPERTY = "diktat.config.path" - -typealias RulesConfig = DiktatRuleConfig - -/** - * This interface represents individual inspection in rule set. - */ -interface Rule { - /** - * @return name of this [Rule] - */ - fun ruleName(): String -} - -/** - * Configuration that allows customizing additional options of particular rules. - * @property config a map of strings with configuration options for a particular rule - */ -open class RuleConfiguration(protected val config: Map) - -/** - * class returns the list of configurations that we have read from a yml: diktat-analysis.yml - */ -open class RulesConfigReader : AbstractConfigReader>() { - private val yamlSerializer by lazy { Yaml(configuration = YamlConfiguration(strictMode = true)) } - - /** - * Parse resource file into list of [RulesConfig] - * - * @param inputStream a [InputStream] representing loaded rules config file - * @return list of [RulesConfig] - */ - override fun parse(inputStream: InputStream): List = yamlSerializer.decodeFromStream(inputStream) - - companion object { - internal val log: KLogger = KotlinLogging.logger {} - } -} - -/** - * class returns the list of common configurations that we have read from a configuration map - * - * @param configuration map of common configuration - */ -data class CommonConfiguration(private val configuration: Map?) { - /** - * List of directory names which will be used to detect test sources - */ - val testAnchors: List by lazy { - val testDirs = (configuration ?: emptyMap()).getOrDefault("testDirs", "test").split(',').map { it.trim() } - if (testDirs.any { !it.lowercase(Locale.getDefault()).endsWith("test") }) { - log.error { "test directory names should end with `test`" } - } - testDirs - } - - /** - * Start of package name, which shoould be common, e.g. org.example.myproject - */ - val domainName: String? by lazy { - configuration?.get("domainName") - } - - /** - * Get disable chapters from configuration - */ - val disabledChapters: String? by lazy { - configuration?.get("disabledChapters") - } - - /** - * Get version of kotlin from configuration - */ - val kotlinVersion: KotlinVersion by lazy { - configuration?.get("kotlinVersion")?.kotlinVersion() ?: run { - if (visitorCounter.incrementAndGet() == 1) { - log.error { "Kotlin version not specified in the configuration file. Will be using ${KotlinVersion.CURRENT} version" } - } - KotlinVersion.CURRENT - } - } - - /** - * Get source directories from configuration - */ - val srcDirectories: List by lazy { - configuration?.get("srcDirectories")?.split(",")?.map { it.trim() } ?: listOf("main") - } - - companion object { - /** - * Counter that helps not to raise multiple warnings about kotlin version - */ - var visitorCounter = AtomicInteger(0) - } -} - -// ================== utils for List from yml config - -/** - * @return common configuration from list of all rules configuration - */ -fun List.getCommonConfiguration() = CommonConfiguration(getCommonConfig()?.configuration) - -/** - * Get [RulesConfig] for particular [Rule] object. - * - * @param rule a [Rule] which configuration will be returned - * @return [RulesConfig] for a particular rule if it is found, else null - */ -fun List.getRuleConfig(rule: Rule): RulesConfig? = this.find { it.name == rule.ruleName() } - -/** - * checking if in yml config particular rule is enabled or disabled - * (!) the default value is "true" (in case there is no config specified) - * - * @param rule a [Rule] which is being checked - * @return true if rule is enabled in configuration, else false - */ -fun List.isRuleEnabled(rule: Rule): Boolean { - val ruleMatched = getRuleConfig(rule) - return ruleMatched?.enabled ?: true -} - -/** - * @param rule diktat inspection - * @param annotations set of annotations that are annotating a block of code - * @return true if the code block is marked with annotation that is in `ignored list` in the rule - */ -fun List.isAnnotatedWithIgnoredAnnotation(rule: Rule, annotations: Set): Boolean = - getRuleConfig(rule) - ?.ignoreAnnotated - ?.map { it.trim() } - ?.map { it.trim('"') } - ?.intersect(annotations) - ?.isNotEmpty() - ?: false - -/** - * Parse string into KotlinVersion - * - * @return KotlinVersion from configuration - */ -fun String.kotlinVersion(): KotlinVersion { - require(this.contains("^(\\d+\\.)(\\d+)\\.?(\\d+)?$".toRegex())) { - "Kotlin version format is incorrect" - } - val versions = this.split(".").map { it.toInt() } - return if (versions.size == 2) { - KotlinVersion(versions[0], versions[1]) - } else { - KotlinVersion(versions[0], versions[1], versions[2]) - } -} - -/** - * Get [RulesConfig] representing common configuration part that can be used in any rule - */ -private fun List.getCommonConfig() = find { it.name == DIKTAT_COMMON } diff --git a/diktat-common/src/test/resources/log4j2.properties b/diktat-common/src/test/resources/log4j2.properties deleted file mode 100644 index 20bfdb44d6..0000000000 --- a/diktat-common/src/test/resources/log4j2.properties +++ /dev/null @@ -1,8 +0,0 @@ -rootLogger.level = info -rootLogger.appenderRef.stdout.ref = STDOUT - -appender.stdout.type = Console -appender.stdout.name = STDOUT -appender.stdout.target = SYSTEM_OUT -appender.stdout.layout.type = PatternLayout -appender.stdout.layout.pattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss} %m%n \ No newline at end of file diff --git a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/DiktatExtension.kt b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/DiktatExtension.kt index 0828de3819..abdf41f0cb 100644 --- a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/DiktatExtension.kt +++ b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/DiktatExtension.kt @@ -5,6 +5,7 @@ import org.gradle.api.Action import org.gradle.api.model.ObjectFactory import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.Optional import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.util.PatternFilterable @@ -51,11 +52,12 @@ open class DiktatExtension @Inject constructor( /** * Path to diktat yml config file. Can be either absolute or relative to project's root directory. - * Default value: `diktat-analysis.yml` in rootDir. + * Default value: `diktat-analysis.yml` in rootDir if it exists or default (empty) configuration */ @get:InputFile + @get:Optional @get:PathSensitive(PathSensitivity.RELATIVE) - lateinit var diktatConfigFile: File + var diktatConfigFile: File? = null /** * Configure input files for diktat task diff --git a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/tasks/DiktatTaskBase.kt b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/tasks/DiktatTaskBase.kt index a3ed0c197a..f8c45c5865 100644 --- a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/tasks/DiktatTaskBase.kt +++ b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/tasks/DiktatTaskBase.kt @@ -53,6 +53,7 @@ abstract class DiktatTaskBase( /** * Config file */ + @get:Optional @get:InputFile abstract val configFile: RegularFileProperty @@ -132,7 +133,7 @@ abstract class DiktatTaskBase( } } DiktatRunnerArguments( - configInputStream = configFile.get().asFile.inputStream(), + configInputStream = configFile.map { it.asFile.inputStream() }.orNull, sourceRootDir = sourceRootDir, files = actualInputs.files.map { it.toPath() }, baselineFile = baselineFile.map { it.asFile.toPath() }.orNull, @@ -203,7 +204,7 @@ abstract class DiktatTaskBase( */ fun TaskProvider.configure(extension: DiktatExtension) { configure { task -> - task.configFile.set(task.project.file(extension.diktatConfigFile)) + extension.diktatConfigFile?.let { diktatConfigFile -> task.configFile.set(task.project.file(diktatConfigFile)) } extension.baseline?.let { baseline -> task.baselineFile.set(task.project.file(baseline)) } task.ignoreFailures = extension.ignoreFailures task.reporters.all.addAll(extension.reporters.all) diff --git a/diktat-ktlint-engine/build.gradle.kts b/diktat-ktlint-engine/build.gradle.kts index e279357033..54f29b284e 100644 --- a/diktat-ktlint-engine/build.gradle.kts +++ b/diktat-ktlint-engine/build.gradle.kts @@ -10,7 +10,6 @@ project.description = "This module builds diktat-api implementation using ktlint dependencies { api(projects.diktatApi) - implementation(projects.diktatCommon) implementation(libs.ktlint.cli.reporter.core) implementation(libs.ktlint.rule.engine) implementation(libs.ktlint.rule.engine.core) diff --git a/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/DiktatBaseMojo.kt b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/DiktatBaseMojo.kt index ae2cf519d3..38411f0d39 100644 --- a/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/DiktatBaseMojo.kt +++ b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/DiktatBaseMojo.kt @@ -87,8 +87,8 @@ abstract class DiktatBaseMojo : AbstractMojo() { * @throws MojoExecutionException if an exception in __KtLint__ has been thrown */ override fun execute() { - val configFile = resolveConfig() ?: throw MojoExecutionException("Configuration file $diktatConfigFile doesn't exist") - log.info("Running diKTat plugin with configuration file $configFile and inputs $inputs" + + val configFile = resolveConfig() + log.info("Running diKTat plugin with ${configFile?.let { "configuration file $it" } ?: "default configuration" } and inputs $inputs" + if (excludes.isNotEmpty()) " and excluding $excludes" else "" ) @@ -104,7 +104,7 @@ abstract class DiktatBaseMojo : AbstractMojo() { val reporterArgsList = reporters.map { it.toCreationArguments(mavenProject, sourceRootDir) } val args = DiktatRunnerArguments( - configInputStream = configFile.inputStream(), + configInputStream = configFile?.inputStream(), sourceRootDir = sourceRootDir, files = files(), baselineFile = baseline?.toPath(), diff --git a/diktat-rules/build.gradle.kts b/diktat-rules/build.gradle.kts index dccf46a8f4..afcf672aff 100644 --- a/diktat-rules/build.gradle.kts +++ b/diktat-rules/build.gradle.kts @@ -10,10 +10,11 @@ plugins { project.description = "The main diktat ruleset" dependencies { - api(projects.diktatCommon) api(projects.diktatApi) implementation(libs.kotlin.stdlib.jdk8) implementation(libs.kotlin.compiler.embeddable) + // kaml is used to read configs from YAML file + implementation(libs.kaml) // guava is used for string case utils implementation(libs.guava) implementation(libs.kotlin.logging) diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/common/config/rules/LegacyUtils.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/common/config/rules/LegacyUtils.kt new file mode 100644 index 0000000000..93c853096e --- /dev/null +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/common/config/rules/LegacyUtils.kt @@ -0,0 +1,35 @@ +/** + * This file contains aliases to support old names and util methods + */ + +package com.saveourtool.diktat.common.config.rules + +import com.saveourtool.diktat.api.DiktatRuleConfig +import com.saveourtool.diktat.api.DiktatRuleNameAware +import com.saveourtool.diktat.api.findByRuleName + +/** + * Name of common configuration + */ +const val DIKTAT_COMMON = "DIKTAT_COMMON" + +typealias RuleConfiguration = com.saveourtool.diktat.ruleset.config.RuleConfiguration +typealias CommonConfiguration = com.saveourtool.diktat.ruleset.config.CommonConfiguration + +/** + * Get [DiktatRuleConfig] for particular [DiktatRuleNameAware] object. + * + * @param rule a [DiktatRuleNameAware] which configuration will be returned + * @return [DiktatRuleConfig] for a particular rule if it is found, else null + */ +fun List.getRuleConfig(rule: DiktatRuleNameAware): DiktatRuleConfig? = this.findByRuleName(rule) + +/** + * @return common configuration from list of all rules configuration + */ +fun List.getCommonConfiguration(): CommonConfiguration = CommonConfiguration(getCommonConfig()?.configuration) + +/** + * Get [DiktatRuleConfig] representing common configuration part that can be used in any rule + */ +private fun List.getCommonConfig() = find { it.name == DIKTAT_COMMON } diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/AbstractDiktatRuleConfigReader.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/AbstractDiktatRuleConfigReader.kt new file mode 100644 index 0000000000..b439950a36 --- /dev/null +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/AbstractDiktatRuleConfigReader.kt @@ -0,0 +1,56 @@ +package com.saveourtool.diktat.ruleset.config + +import com.saveourtool.diktat.api.DiktatRuleConfig +import com.saveourtool.diktat.api.DiktatRuleConfigReader +import com.saveourtool.diktat.common.config.rules.DIKTAT_COMMON +import com.saveourtool.diktat.ruleset.constants.Warnings +import io.github.oshai.kotlinlogging.KotlinLogging +import org.jetbrains.kotlin.org.jline.utils.Levenshtein +import java.io.IOException +import java.io.InputStream +import kotlin.jvm.Throws + +/** + * This class is used to read input stream in any format that you will specify. + * Usage: + * 1) implement this class with implementing the method: + * a. parse - implement parser for your file format (for example parse it to a proper json) + * 2) Use your new class MyReader().read(someInputStream) + */ +abstract class AbstractDiktatRuleConfigReader : DiktatRuleConfigReader { + /** + * @param inputStream - input stream + * @return list of [DiktatRuleConfig] if resource has been parsed successfully + */ + override fun invoke(inputStream: InputStream): List = + read(inputStream)?.onEach(::validate).orEmpty() + + private fun read(inputStream: InputStream): List? = try { + parse(inputStream) + } catch (e: IOException) { + log.error(e) { + "Cannot read config from input stream due to: " + } + null + } + + /** + * you can specify your own parser, in example for parsing stream as a json + * + * @param inputStream a [InputStream] representing loaded content + * @return resource parsed as list of [DiktatRuleConfig] + * @throws IOException + */ + @Throws(IOException::class) + protected abstract fun parse(inputStream: InputStream): List + + private fun validate(config: DiktatRuleConfig) = + require(config.name == DIKTAT_COMMON || config.name in Warnings.names) { + val closestMatch = Warnings.names.minByOrNull { Levenshtein.distance(it, config.name) } + "Warning name <${config.name}> in configuration file is invalid, did you mean <$closestMatch>?" + } + + companion object { + private val log = KotlinLogging.logger {} + } +} diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/CommonConfiguration.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/CommonConfiguration.kt new file mode 100644 index 0000000000..2ee933d072 --- /dev/null +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/CommonConfiguration.kt @@ -0,0 +1,83 @@ +package com.saveourtool.diktat.ruleset.config + +import io.github.oshai.kotlinlogging.KLogger +import io.github.oshai.kotlinlogging.KotlinLogging +import java.util.Locale +import java.util.concurrent.atomic.AtomicInteger + +/** + * class returns the list of common configurations that we have read from a configuration map + * + * @param configuration map of common configuration + */ +data class CommonConfiguration(private val configuration: Map?) { + /** + * List of directory names which will be used to detect test sources + */ + val testAnchors: List by lazy { + val testDirs = (configuration ?: emptyMap()).getOrDefault("testDirs", "test").split(',').map { it.trim() } + if (testDirs.any { !it.lowercase(Locale.getDefault()).endsWith("test") }) { + log.error { "test directory names should end with `test`" } + } + testDirs + } + + /** + * Start of package name, which shoould be common, e.g. org.example.myproject + */ + val domainName: String? by lazy { + configuration?.get("domainName") + } + + /** + * Get disable chapters from configuration + */ + val disabledChapters: String? by lazy { + configuration?.get("disabledChapters") + } + + /** + * Get version of kotlin from configuration + */ + val kotlinVersion: KotlinVersion by lazy { + configuration?.get("kotlinVersion")?.kotlinVersion() ?: run { + if (visitorCounter.incrementAndGet() == 1) { + log.error { "Kotlin version not specified in the configuration file. Will be using ${KotlinVersion.CURRENT} version" } + } + KotlinVersion.CURRENT + } + } + + /** + * Get source directories from configuration + */ + val srcDirectories: List by lazy { + configuration?.get("srcDirectories")?.split(",")?.map { it.trim() } ?: listOf("main") + } + + companion object { + internal val log: KLogger = KotlinLogging.logger {} + + /** + * Counter that helps not to raise multiple warnings about kotlin version + */ + var visitorCounter = AtomicInteger(0) + } +} + +/** + * Parse string into KotlinVersion + * + * @return KotlinVersion from configuration + */ +internal fun String.kotlinVersion(): KotlinVersion { + require(this.contains("^(\\d+\\.)(\\d+)\\.?(\\d+)?$".toRegex())) { + "Kotlin version format is incorrect" + } + val versions = this.split(".").map { it.toInt() } + return if (versions.size == 2) { + KotlinVersion(versions[0], versions[1]) + } else { + KotlinVersion(versions[0], versions[1], versions[2]) + } +} diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/DiktatRuleConfigYamlReader.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/DiktatRuleConfigYamlReader.kt new file mode 100644 index 0000000000..28a83de11c --- /dev/null +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/DiktatRuleConfigYamlReader.kt @@ -0,0 +1,22 @@ +package com.saveourtool.diktat.ruleset.config + +import com.saveourtool.diktat.common.config.rules.RulesConfig +import com.charleskorn.kaml.Yaml +import com.charleskorn.kaml.YamlConfiguration +import com.charleskorn.kaml.decodeFromStream +import java.io.InputStream + +/** + * class returns the list of configurations that we have read from a yml: diktat-analysis.yml + */ +class DiktatRuleConfigYamlReader : AbstractDiktatRuleConfigReader() { + private val yamlSerializer by lazy { Yaml(configuration = YamlConfiguration(strictMode = true)) } + + /** + * Parse resource file into list of [RulesConfig] + * + * @param inputStream a [InputStream] representing loaded rules config file + * @return list of [RulesConfig] + */ + override fun parse(inputStream: InputStream): List = yamlSerializer.decodeFromStream>(inputStream) +} diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/RuleConfiguration.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/RuleConfiguration.kt new file mode 100644 index 0000000000..7d371eb585 --- /dev/null +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/config/RuleConfiguration.kt @@ -0,0 +1,7 @@ +package com.saveourtool.diktat.ruleset.config + +/** + * Configuration that allows customizing additional options of particular rules. + * @property config a map of strings with configuration options for a particular rule + */ +open class RuleConfiguration(protected val config: Map) diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/constants/Warnings.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/constants/Warnings.kt index 602f861225..4cdc310d55 100644 --- a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/constants/Warnings.kt +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/constants/Warnings.kt @@ -1,9 +1,9 @@ package com.saveourtool.diktat.ruleset.constants import com.saveourtool.diktat.api.DiktatErrorEmitter +import com.saveourtool.diktat.api.isRuleEnabled import com.saveourtool.diktat.common.config.rules.Rule import com.saveourtool.diktat.common.config.rules.RulesConfig -import com.saveourtool.diktat.common.config.rules.isRuleEnabled import com.saveourtool.diktat.ruleset.generation.EnumNames import com.saveourtool.diktat.ruleset.utils.isSuppressed import org.jetbrains.kotlin.com.intellij.lang.ASTNode diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRule.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRule.kt index 8edd933d7c..0f6a4b028c 100644 --- a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRule.kt +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRule.kt @@ -1,14 +1,14 @@ package com.saveourtool.diktat.ruleset.rules import com.saveourtool.diktat.api.DiktatErrorEmitter +import com.saveourtool.diktat.api.DiktatRuleNameAware +import com.saveourtool.diktat.api.isRuleEnabled import com.saveourtool.diktat.common.config.rules.RulesConfig -import com.saveourtool.diktat.common.config.rules.isRuleEnabled import com.saveourtool.diktat.ruleset.utils.getFilePathSafely import io.github.oshai.kotlinlogging.KotlinLogging import org.jetbrains.kotlin.com.intellij.lang.ASTNode -private typealias DiktatConfigRule = com.saveourtool.diktat.common.config.rules.Rule private typealias DiktatRuleApi = com.saveourtool.diktat.api.DiktatRule /** @@ -22,7 +22,7 @@ private typealias DiktatRuleApi = com.saveourtool.diktat.api.DiktatRule abstract class DiktatRule( override val id: String, val configRules: List, - private val inspections: List, + private val inspections: List, ) : DiktatRuleApi { /** * Default value is false diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRuleConfigReaderImpl.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRuleConfigReaderImpl.kt deleted file mode 100644 index fa12a80381..0000000000 --- a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRuleConfigReaderImpl.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.saveourtool.diktat.ruleset.rules - -import com.saveourtool.diktat.api.DiktatRuleConfig -import com.saveourtool.diktat.api.DiktatRuleConfigReader -import com.saveourtool.diktat.common.config.rules.DIKTAT_COMMON -import com.saveourtool.diktat.common.config.rules.RulesConfigReader -import com.saveourtool.diktat.ruleset.constants.Warnings -import org.jetbrains.kotlin.org.jline.utils.Levenshtein -import java.io.InputStream - -/** - * Default implementation for [DiktatRuleConfigReader] - */ -class DiktatRuleConfigReaderImpl : DiktatRuleConfigReader { - private val yamlRuleConfigReader = RulesConfigReader() - - override fun invoke(inputStream: InputStream): List = yamlRuleConfigReader - .read(inputStream) - ?.onEach(::validate) - ?: emptyList() - - private fun validate(config: com.saveourtool.diktat.common.config.rules.RulesConfig) = - require(config.name == DIKTAT_COMMON || config.name in Warnings.names) { - val closestMatch = Warnings.names.minByOrNull { Levenshtein.distance(it, config.name) } - "Warning name <${config.name}> in configuration file is invalid, did you mean <$closestMatch>?" - } -} diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter1/IdentifierNaming.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter1/IdentifierNaming.kt index 24fe0cfcba..08dec56835 100644 --- a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter1/IdentifierNaming.kt +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter1/IdentifierNaming.kt @@ -31,7 +31,6 @@ import org.jetbrains.kotlin.KtNodeTypes.DESTRUCTURING_DECLARATION import org.jetbrains.kotlin.KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY import org.jetbrains.kotlin.KtNodeTypes.FUNCTION_TYPE import org.jetbrains.kotlin.KtNodeTypes.OBJECT_DECLARATION -import org.jetbrains.kotlin.KtNodeTypes.PROPERTY import org.jetbrains.kotlin.KtNodeTypes.REFERENCE_EXPRESSION import org.jetbrains.kotlin.KtNodeTypes.TYPE_PARAMETER import org.jetbrains.kotlin.KtNodeTypes.TYPE_REFERENCE diff --git a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/utils/AstNodeUtils.kt b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/utils/AstNodeUtils.kt index f669e8bcb7..460bc94039 100644 --- a/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/utils/AstNodeUtils.kt +++ b/diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/utils/AstNodeUtils.kt @@ -12,10 +12,10 @@ package com.saveourtool.diktat.ruleset.utils -import com.saveourtool.diktat.common.config.rules.DIKTAT +import com.saveourtool.diktat.DIKTAT +import com.saveourtool.diktat.api.isAnnotatedWithIgnoredAnnotation import com.saveourtool.diktat.common.config.rules.Rule import com.saveourtool.diktat.common.config.rules.RulesConfig -import com.saveourtool.diktat.common.config.rules.isAnnotatedWithIgnoredAnnotation import com.saveourtool.diktat.ruleset.rules.chapter1.PackageNaming import org.jetbrains.kotlin.KtNodeTypes diff --git a/diktat-common/src/test/kotlin/com/saveourtool/diktat/test/ConfigReaderTest.kt b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/config/DiktatRuleConfigYamlReaderTest.kt similarity index 67% rename from diktat-common/src/test/kotlin/com/saveourtool/diktat/test/ConfigReaderTest.kt rename to diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/config/DiktatRuleConfigYamlReaderTest.kt index 1f81e04d44..8f77263c2d 100644 --- a/diktat-common/src/test/kotlin/com/saveourtool/diktat/test/ConfigReaderTest.kt +++ b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/config/DiktatRuleConfigYamlReaderTest.kt @@ -1,20 +1,17 @@ -package com.saveourtool.diktat.test +package com.saveourtool.diktat.ruleset.config import com.saveourtool.diktat.common.config.rules.DIKTAT_COMMON import com.saveourtool.diktat.common.config.rules.RulesConfig -import com.saveourtool.diktat.common.config.rules.RulesConfigReader import com.saveourtool.diktat.common.config.rules.getCommonConfiguration -import com.saveourtool.diktat.common.config.rules.kotlinVersion import org.junit.jupiter.api.Test import java.nio.file.Paths import kotlin.io.path.inputStream -class ConfigReaderTest { +class DiktatRuleConfigYamlReaderTest { @Test fun `testing json reading`() { - val rulesConfigList: List? = RulesConfigReader() - .read(Paths.get("src/test/resources/test-rules-config.yml").inputStream()) - requireNotNull(rulesConfigList) + val rulesConfigList: List = DiktatRuleConfigYamlReader() + .invoke(Paths.get("src/test/resources/test-rules-config.yml").inputStream()) assert(rulesConfigList.any { it.name == "CLASS_NAME_INCORRECT" && it.enabled }) assert(rulesConfigList.find { it.name == "CLASS_NAME_INCORRECT" }?.configuration == emptyMap()) assert(rulesConfigList.find { it.name == "DIKTAT_COMMON" } @@ -23,9 +20,8 @@ class ConfigReaderTest { @Test fun `testing kotlin version`() { - val rulesConfigList: List? = RulesConfigReader() - .read(Paths.get("src/test/resources/test-rules-config.yml").inputStream()) - requireNotNull(rulesConfigList) + val rulesConfigList: List = DiktatRuleConfigYamlReader() + .invoke(Paths.get("src/test/resources/test-rules-config.yml").inputStream()) assert(rulesConfigList.getCommonConfiguration().kotlinVersion == kotlinVersion) assert(rulesConfigList.getCommonConfiguration().testAnchors.contains("androidUnitTest")) assert(rulesConfigList.find { it.name == DIKTAT_COMMON } diff --git a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/smoke/RulesConfigValidationTest.kt b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/smoke/RulesConfigValidationTest.kt index a3c12b2edd..f8e4406763 100644 --- a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/smoke/RulesConfigValidationTest.kt +++ b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/smoke/RulesConfigValidationTest.kt @@ -1,6 +1,6 @@ package com.saveourtool.diktat.ruleset.smoke -import com.saveourtool.diktat.ruleset.rules.DiktatRuleConfigReaderImpl +import com.saveourtool.diktat.ruleset.config.DiktatRuleConfigYamlReader import com.saveourtool.diktat.ruleset.rules.DiktatRuleSetFactoryImpl import com.saveourtool.diktat.test.framework.util.deleteIfExistsSilently @@ -76,6 +76,6 @@ class RulesConfigValidationTest { companion object { private val diktatRuleSetFactory = DiktatRuleSetFactoryImpl() - private val diktatRuleConfigReader = DiktatRuleConfigReaderImpl() + private val diktatRuleConfigReader = DiktatRuleConfigYamlReader() } } diff --git a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/utils/RulesConfigYamlTest.kt b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/utils/RulesConfigYamlTest.kt index 01463d3194..2f6aaf59de 100644 --- a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/utils/RulesConfigYamlTest.kt +++ b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/utils/RulesConfigYamlTest.kt @@ -2,9 +2,9 @@ package com.saveourtool.diktat.ruleset.utils import com.saveourtool.diktat.common.config.rules.DIKTAT_COMMON import com.saveourtool.diktat.common.config.rules.RulesConfig -import com.saveourtool.diktat.common.config.rules.RulesConfigReader +import com.saveourtool.diktat.ruleset.config.kotlinVersion +import com.saveourtool.diktat.ruleset.config.DiktatRuleConfigYamlReader import com.saveourtool.diktat.common.config.rules.getRuleConfig -import com.saveourtool.diktat.common.config.rules.kotlinVersion import com.saveourtool.diktat.ruleset.constants.Warnings import com.charleskorn.kaml.Yaml @@ -114,7 +114,7 @@ class RulesConfigYamlTest { Paths.get(nameConfig).takeIf { it.exists() }?.inputStream() ?: javaClass.classLoader.getResourceAsStream(nameConfig) } - ?.let { RulesConfigReader().read(it) } + ?.let { DiktatRuleConfigYamlReader().invoke(it) } ?: emptyList() private fun readAllRulesFromCode() = diff --git a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/util/DiktatRuleSetFactoryImplTest.kt b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/util/DiktatRuleSetFactoryImplTest.kt index 201e98c8d9..0c179f1b4c 100644 --- a/diktat-rules/src/test/kotlin/com/saveourtool/diktat/util/DiktatRuleSetFactoryImplTest.kt +++ b/diktat-rules/src/test/kotlin/com/saveourtool/diktat/util/DiktatRuleSetFactoryImplTest.kt @@ -6,7 +6,7 @@ package com.saveourtool.diktat.util import com.saveourtool.diktat.api.DiktatRuleSet import com.saveourtool.diktat.common.config.rules.RulesConfig -import com.saveourtool.diktat.common.config.rules.RulesConfigReader +import com.saveourtool.diktat.ruleset.config.DiktatRuleConfigYamlReader import com.saveourtool.diktat.ruleset.rules.DiktatRule import com.saveourtool.diktat.ruleset.rules.DiktatRuleSetFactoryImpl import com.saveourtool.diktat.test.framework.util.filterContentMatches @@ -64,7 +64,7 @@ class DiktatRuleSetFactoryImplTest { rulesConfigList: List?, ): DiktatRuleSet = run { rulesConfigList ?: Companion::class.java.classLoader.getResourceAsStream("diktat-analysis.yml") - ?.let { RulesConfigReader().read(it) } + ?.let { DiktatRuleConfigYamlReader().invoke(it) } .orEmpty() } .let(ruleSupplier) diff --git a/diktat-common/src/test/resources/test-rules-config.yml b/diktat-rules/src/test/resources/test-rules-config.yml similarity index 98% rename from diktat-common/src/test/resources/test-rules-config.yml rename to diktat-rules/src/test/resources/test-rules-config.yml index cca805e923..af96265f7c 100644 --- a/diktat-common/src/test/resources/test-rules-config.yml +++ b/diktat-rules/src/test/resources/test-rules-config.yml @@ -51,8 +51,6 @@ enabled: true - name: MISSING_KDOC_CLASS_ELEMENTS enabled: true -- name: BLANK_LINE_AFTER_KDOC - enabled: true - name: KDOC_WITHOUT_PARAM_TAG enabled: true - name: KDOC_WITHOUT_RETURN_TAG @@ -90,7 +88,7 @@ copyrightText: Copyright (c) This is an example. 2012-2020. All rights reserved. - name: HEADER_NOT_BEFORE_PACKAGE enabled: true -- name: HEADER_CONTAINS_DATE_OR_AUTHOR +- name: KDOC_CONTAINS_DATE_OR_AUTHOR enabled: true - name: FILE_IS_TOO_LONG enabled: true diff --git a/diktat-ruleset/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRuleSetProviderV3Spi.kt b/diktat-ruleset/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRuleSetProviderV3Spi.kt index 06c5ff44eb..7b505b93ad 100644 --- a/diktat-ruleset/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRuleSetProviderV3Spi.kt +++ b/diktat-ruleset/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/DiktatRuleSetProviderV3Spi.kt @@ -1,9 +1,10 @@ package com.saveourtool.diktat.ruleset.rules -import com.saveourtool.diktat.common.config.rules.DIKTAT_ANALYSIS_CONF +import com.saveourtool.diktat.DIKTAT_ANALYSIS_CONF import com.saveourtool.diktat.common.config.rules.DIKTAT_CONF_PROPERTY import com.saveourtool.diktat.common.config.rules.DIKTAT_RULE_SET_ID import com.saveourtool.diktat.ktlint.KtLintRuleWrapper.Companion.toKtLint +import com.saveourtool.diktat.ruleset.config.DiktatRuleConfigYamlReader import com.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3 import com.pinterest.ktlint.logger.api.initKtLintKLogger import com.pinterest.ktlint.rule.engine.core.api.RuleProvider @@ -26,7 +27,7 @@ import java.io.InputStream class DiktatRuleSetProviderV3Spi : RuleSetProviderV3( id = RuleSetId(DIKTAT_RULE_SET_ID), ) { - private val diktatRuleConfigReader = DiktatRuleConfigReaderImpl() + private val diktatRuleConfigReader = DiktatRuleConfigYamlReader() private val diktatRuleSetFactory = DiktatRuleSetFactoryImpl() init { diff --git a/diktat-runner/build.gradle.kts b/diktat-runner/build.gradle.kts index 270233ad43..e16959ab43 100644 --- a/diktat-runner/build.gradle.kts +++ b/diktat-runner/build.gradle.kts @@ -15,7 +15,6 @@ project.description = "This module contains runner for diktat" dependencies { api(projects.diktatApi) - api(projects.diktatCommon) implementation(projects.diktatKtlintEngine) implementation(projects.diktatRules) } diff --git a/diktat-runner/src/main/kotlin/com/saveourtool/diktat/DiktatFactories.kt b/diktat-runner/src/main/kotlin/com/saveourtool/diktat/DiktatFactories.kt index 90bee667f6..370a915528 100644 --- a/diktat-runner/src/main/kotlin/com/saveourtool/diktat/DiktatFactories.kt +++ b/diktat-runner/src/main/kotlin/com/saveourtool/diktat/DiktatFactories.kt @@ -11,7 +11,7 @@ import com.saveourtool.diktat.api.DiktatRuleSetFactory import com.saveourtool.diktat.ktlint.DiktatBaselineFactoryImpl import com.saveourtool.diktat.ktlint.DiktatProcessorFactoryImpl import com.saveourtool.diktat.ktlint.DiktatReporterFactoryImpl -import com.saveourtool.diktat.ruleset.rules.DiktatRuleConfigReaderImpl +import com.saveourtool.diktat.ruleset.config.DiktatRuleConfigYamlReader import com.saveourtool.diktat.ruleset.rules.DiktatRuleSetFactoryImpl import generated.KTLINT_VERSION @@ -23,7 +23,7 @@ const val ENGINE_INFO: String = "Ktlint: $KTLINT_VERSION" /** * @return initialized [DiktatRuleConfigReader] */ -val diktatRuleConfigReader: DiktatRuleConfigReader = DiktatRuleConfigReaderImpl() +val diktatRuleConfigReader: DiktatRuleConfigReader = DiktatRuleConfigYamlReader() /** * @return initialized [DiktatRuleSetFactory] diff --git a/settings.gradle.kts b/settings.gradle.kts index 1c8de8a54d..e19f7f930f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -47,7 +47,6 @@ plugins { includeBuild("gradle/plugins") include("diktat-api") -include("diktat-common") include("diktat-common-test") include("diktat-ktlint-engine") include("diktat-gradle-plugin")