Skip to content

Commit

Permalink
diktat-analysis.yml can be read from a path, where jar is stored (#588)
Browse files Browse the repository at this point in the history
diktat-analysis.yml can be read from a path, where jar is stored

### What's done:
Previously we were able to read 'diktat-analysis.yml' only from a path where ktlint is executed. Now it will also be read from jar file.
  • Loading branch information
orchestr7 authored Nov 30, 2020
1 parent 9cd02d7 commit 11d2c4c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,47 @@ import java.io.File
* 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"

class DiktatRuleSetProvider(private val diktatConfigFile: String = "diktat-analysis.yml") : RuleSetProvider {
/**
* by the default it is expected to have diktat-analysis.yml configuration in the root folder where 'ktlint' is run
* otherwise it will use default configuration where some rules are disabled
* @param diktatConfigFile - configuration file where all configurations for inspections and rules are stored
*/
class DiktatRuleSetProvider(private var diktatConfigFile: String = DIKTAT_ANALYSIS_CONF) : RuleSetProvider {
@Suppress("LongMethod")
override fun get(): RuleSet {
log.debug("Will run $DIKTAT_RULE_SET_ID with $diktatConfigFile (it can be placed to the run directory or the default file from resources will be used)")
if (!File(diktatConfigFile).exists()) {
log.warn("Configuration file $diktatConfigFile not found in file system, the file included in jar will be used. " +
"Some configuration options will be disabled or substituted with defaults. " +
"Custom configuration file should be placed in diktat working directory if run from CLI " +
"or provided as configuration options in plugins."
)
log.debug("Will run $DIKTAT_RULE_SET_ID with $diktatConfigFile" +
" (it can be placed to the run directory or the default file from resources will be used)")
val diktatExecutionPath = File(diktatConfigFile)
if (!diktatExecutionPath.exists()) {
// for some aggregators of static analyzers we need to provide configuration for cli
// in this case diktat would take the configuration from the direcory where jar file is stored
val ruleSetProviderPath =
DiktatRuleSetProvider::class
.java
.protectionDomain
.codeSource
.location
.toURI()

val configPathWithFileName = File(ruleSetProviderPath).absolutePath

val indexOfName = configPathWithFileName.lastIndexOf(File.separator)
val configPath = if (indexOfName > -1) configPathWithFileName.substring(0, indexOfName) else configPathWithFileName
diktatConfigFile = "$configPath${File.separator}$diktatConfigFile"

if (!File(diktatConfigFile).exists()) {
log.warn("Configuration file not found in directory where diktat is run (${diktatExecutionPath.absolutePath}) " +
"or in the directory where diktat.jar is stored ($diktatConfigFile), " +
"the default file included in jar will be used. " +
"Some configuration options will be disabled or substituted with defaults. " +
"Custom configuration file should be placed in diktat working directory if run from CLI " +
"or provided as configuration options in plugins."
)
}
}

val configRules = RulesConfigReader(javaClass.classLoader)
.readResource(diktatConfigFile)
?.onEach(::validate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl
import org.jetbrains.kotlin.lexer.KtTokens.PACKAGE_KEYWORD
import org.slf4j.LoggerFactory
import java.util.concurrent.atomic.AtomicInteger

/**
* Rule 1.3: package name is in lower case and separated by dots, code developed internally in your company (in example Huawei) should start
Expand All @@ -44,8 +45,9 @@ class PackageNaming(private val configRules: List<RulesConfig>) : Rule("package-

val configuration by configRules.getCommonConfiguration()
domainName = configuration.also {
if (it.isDefault) {
log.error("Not able to find an external configuration for domain name in the common configuration (is it missing in yml config?)")
if (it.isDefault && visitorCounter.incrementAndGet() == 1) {
log.error("Not able to find an external configuration for domain name in the common" +
" configuration (is it missing in yml config?)")
}
}
.domainName
Expand Down Expand Up @@ -227,6 +229,12 @@ class PackageNaming(private val configRules: List<RulesConfig>) : Rule("package-
}

companion object {

/**
* tricky hack (counter) that helps not to raise multiple warnings about the package name if config is missing
*/
var visitorCounter = AtomicInteger(0)

/**
* Symbol that is used to separate parts in package name
*/
Expand Down

0 comments on commit 11d2c4c

Please sign in to comment.