Skip to content

Commit

Permalink
Support running diktat without configuration (saveourtool#1837)
Browse files Browse the repository at this point in the history
- moved all from 'diktat-common' to 'diktat-rules' and `diktat-api`
- support empty configuration in plugins and cli
  • Loading branch information
nulls authored Nov 30, 2023
1 parent 137b4f7 commit abc481e
Show file tree
Hide file tree
Showing 40 changed files with 335 additions and 367 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |-
Expand Down
16 changes: 16 additions & 0 deletions diktat-api/src/main/kotlin/com/saveourtool/diktat/Constants.kt
Original file line number Diff line number Diff line change
@@ -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"
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,22 @@ 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
* @property reporterArgsList list of arguments to create reporters to report result
* @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<Path>,
val baselineFile: Path?,
val reporterArgsList: List<DiktatReporterCreationArguments> = emptyList(),
val loggingListener: DiktatProcessorListener = DiktatProcessorListener.empty,
) {
constructor(
configFile: Path,
sourceRootDir: Path?,
files: Collection<Path>,
baselineFile: Path?,
reporterArgsList: List<DiktatReporterCreationArguments> = emptyList(),
loggingListener: DiktatProcessorListener = DiktatProcessorListener.empty,
) : this(
configFile.inputStream(),
sourceRootDir,
files,
baselineFile,
reporterArgsList,
loggingListener,
)
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,37 @@ data class DiktatRuleConfig(
val configuration: Map<String, String> = emptyMap(),
val ignoreAnnotated: Set<String> = 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<DiktatRuleConfig>.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<DiktatRuleConfig>.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<DiktatRuleConfig>.isAnnotatedWithIgnoredAnnotation(rule: DiktatRuleNameAware, annotations: Set<String>): Boolean =
findByRuleName(rule)
?.ignoreAnnotated
?.map { it.trim() }
?.map { it.trim('"') }
?.intersect(annotations)
?.isNotEmpty()
?: false
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions diktat-cli/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -42,7 +42,7 @@ class DiktatSmokeTest : DiktatSmokeTestBase() {
function = { testFile ->
format(
ruleSetSupplier = {
val diktatRuleConfigReader = DiktatRuleConfigReaderImpl()
val diktatRuleConfigReader = DiktatRuleConfigYamlReader()
val diktatRuleSetFactory = DiktatRuleSetFactoryImpl()
diktatRuleSetFactory(diktatRuleConfigReader(config.inputStream()))
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -77,7 +75,7 @@ abstract class DiktatSmokeTestBase {
*/
@Suppress("UnsafeCallOnNullableType")
private fun prepareOverriddenRulesConfig(rulesToDisable: List<Warnings> = 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 ->
Expand Down
1 change: 0 additions & 1 deletion diktat-common-test/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
19 changes: 0 additions & 19 deletions diktat-common/build.gradle.kts

This file was deleted.

This file was deleted.

Loading

0 comments on commit abc481e

Please sign in to comment.