QD-5056 Add to yaml glob ignore patterns.

GitOrigin-RevId: 3d2a004cecf42235d6e9084b7ed2811db896178e
This commit is contained in:
alexey.afanasiev
2023-01-29 12:26:00 +01:00
committed by intellij-monorepo-bot
parent 99b1e9eb00
commit bab099bc5d
10 changed files with 98 additions and 22 deletions

View File

@@ -9,20 +9,28 @@ import com.intellij.codeInspection.ex.InspectionToolsSupplier
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.io.toCanonicalPath
import com.intellij.openapi.util.io.toNioPath
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.profile.codeInspection.BaseInspectionProfileManager
import com.intellij.profile.codeInspection.InspectionProfileManager
import com.intellij.profile.codeInspection.PROFILE_DIR
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager
import com.intellij.psi.PsiElement
import com.intellij.psi.search.scope.packageSet.AbstractPackageSet
import com.intellij.psi.search.scope.packageSet.NamedScope
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder
import com.intellij.psi.search.scope.packageSet.PackageSetFactory
import org.jdom.Element
import java.io.File
import java.io.Reader
import java.lang.IllegalArgumentException
import java.nio.file.FileSystems
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.exists
import kotlin.io.path.reader
private const val SCOPE_PREFIX = "ijscope:"
class YamlInspectionConfigImpl(override val inspection: String,
override val enabled: Boolean?,
override val severity: String?,
@@ -78,7 +86,7 @@ class YamlInspectionProfileImpl private constructor(override val profileName: St
companion object {
@JvmStatic
fun loadFrom(reader: Reader,
includeReaders: (String) -> Reader,
includeReaders: (Path) -> Reader,
toolsSupplier: InspectionToolsSupplier,
profileManager: BaseInspectionProfileManager
): YamlInspectionProfileImpl {
@@ -87,6 +95,7 @@ class YamlInspectionProfileImpl private constructor(override val profileName: St
val configurations = profile.inspections.map(::createInspectionConfig)
val groupProvider = CompositeGroupProvider()
groupProvider.addProvider(InspectionGroupProvider.createDynamicGroupProvider())
val groups = profile.groups.map { group -> createGroup(groupProvider, group) }
val customGroupProvider = object : InspectionGroupProvider {
val groupMap = groups.associateBy { group -> group.groupId }
@@ -95,7 +104,15 @@ class YamlInspectionProfileImpl private constructor(override val profileName: St
}
}
groupProvider.addProvider(customGroupProvider)
return YamlInspectionProfileImpl(profile.name, toolsSupplier, profileManager, baseProfile, configurations, groups, groupProvider)
return YamlInspectionProfileImpl(
profile.name,
toolsSupplier,
profileManager,
baseProfile,
configurations,
groups,
groupProvider)
}
@JvmStatic
@@ -107,12 +124,14 @@ class YamlInspectionProfileImpl private constructor(override val profileName: St
val configFile = File(filePath).absoluteFile
require(configFile.exists()) { "File does not exist: ${configFile.canonicalPath}" }
val includeProvider: (String) -> Reader = {
val includeProvider: (Path) -> Reader = {
val includePath = configFile.parent.toNioPath().resolve(it)
require(includePath.exists()) { "File does not exist: ${includePath.toCanonicalPath()}" }
includePath.reader()
}
return loadFrom(configFile.reader(), includeProvider, toolsSupplier, profileManager)
}
@@ -164,12 +183,7 @@ class YamlInspectionProfileImpl private constructor(override val profileName: St
configurations.forEach { configuration ->
val tools = findTools(configuration)
val scopes = configuration.ignore.map { pattern ->
if (pattern.startsWith("!")) {
Pair(NamedScope.UnnamedScope(PackageSetFactory.getInstance().compile(pattern.drop(1))), true)
}
else {
Pair(NamedScope.UnnamedScope(PackageSetFactory.getInstance().compile(pattern)), false)
}
createScope(pattern)
}
tools.asSequence().mapNotNull { tool -> effectiveProfile.getToolsOrNull(tool.shortName, null) }.forEach { inspectionTools ->
val enabled = configuration.enabled
@@ -197,6 +211,38 @@ class YamlInspectionProfileImpl private constructor(override val profileName: St
return effectiveProfile
}
private fun createScope(pattern: String): Pair<NamedScope.UnnamedScope, Boolean> {
return if (pattern.startsWith("!")) {
Pair(parsePattern(pattern.drop(1)), true)
}
else {
Pair(parsePattern(pattern), false)
}
}
private fun parsePattern(pattern: String): NamedScope.UnnamedScope {
if (pattern.startsWith(SCOPE_PREFIX)) {
return NamedScope.UnnamedScope(PackageSetFactory.getInstance().compile(pattern.drop(SCOPE_PREFIX.length)))
}
return getGlobScope(pattern)
}
private fun getGlobScope(pattern: String): NamedScope.UnnamedScope {
val matcher = FileSystems.getDefault().getPathMatcher("glob:$pattern")
val packageSet = object : AbstractPackageSet("glob:$pattern") {
override fun contains(file: VirtualFile, project: Project, holder: NamedScopesHolder?): Boolean {
val root = holder?.projectBaseDir ?: return false
val relativePath = VfsUtilCore.getRelativePath(file, root, File.separatorChar) ?: return false
return matcher.matches(Paths.get(relativePath))
}
}
return NamedScope.UnnamedScope(packageSet)
}
private fun findTools(configuration: YamlBaseConfig): List<InspectionToolWrapper<*, *>> {
return when (configuration) {
is YamlGroupConfig -> baseProfile.getInspectionTools(null).filter { findGroup(configuration.group).includesInspection(it) }

View File

@@ -8,6 +8,8 @@ import org.yaml.snakeyaml.introspector.BeanAccess
import org.yaml.snakeyaml.representer.Representer
import java.io.File
import java.io.Reader
import java.nio.file.Path
import java.nio.file.Paths
class YamlInspectionProfileRaw(
val baseProfile: String? = null,
@@ -32,7 +34,7 @@ class YamlInspectionConfigRaw(
)
fun readConfig(reader: Reader, includeReaders: (String) -> Reader): YamlInspectionProfileRaw {
fun readConfig(reader: Reader, includeReaders: (Path) -> Reader): YamlInspectionProfileRaw {
val merged = readRaw(reader, includeReaders)
val representer = Representer()
representer.propertyUtils.isSkipMissingProperties = true
@@ -61,9 +63,12 @@ private fun merge(first: Map<String, *>, second: Map<String, *>): Map<String, *>
}
}
private fun readRaw(reader: Reader, includeReaders: (String) -> Reader): Map<String, *> {
private fun readRaw(reader: Reader, includeReaders: (Path) -> Reader): Map<String, *> {
val yamlReader = Yaml()
val rawConfig: Map<String, *> = yamlReader.load(reader)
val includedConfigs = (rawConfig["include"] as? List<*>)?.filterIsInstance(String::class.java).orEmpty()
return includedConfigs.fold(rawConfig) { accumulator, path -> merge(accumulator, readRaw(includeReaders.invoke(path), includeReaders)) }
val includedConfigs = (rawConfig["include"] as? List<*>)?.filterIsInstance(String::class.java).orEmpty().map { Paths.get(it) }
return includedConfigs.fold(rawConfig) { accumulator, path ->
merge(accumulator, readRaw(includeReaders.invoke(path)) { includeReaders.invoke(path.parent.resolve(it)) })
}
}

View File

@@ -3,8 +3,11 @@ package com.intellij.codeInspection.inspectionProfile
import com.intellij.codeInspection.ex.InspectionProfileImpl
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.util.JDOMUtil
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.testFramework.TestDataPath
import junit.framework.TestCase
@@ -18,6 +21,10 @@ class YamlInspectionProfileTest: LightPlatformTestCase() {
fun testBasic(){ checkEffectiveProfile() }
fun testBasicGlob(){
checkEffectiveProfile()
}
fun testChainedInclude(){ checkEffectiveProfile() }
fun testChainedOverride(){ checkEffectiveProfile() }

View File

@@ -7,5 +7,5 @@ inspections:
enabled: true
severity: ERROR
ignore:
- "!file:*.*"
- "file:*.java"
- "!ijscope:file:*.*"
- "ijscope:file:*.java"

View File

@@ -0,0 +1,11 @@
$schema: https://json.schemastore.org/idea-inspection-profile-1.0.json
name: Custom name
inspections:
- inspection: TodoComment
enabled: true
severity: ERROR
ignore:
- "!**/*.java"
- "path/Some.java"

View File

@@ -0,0 +1,7 @@
<profile version="1.0">
<option name="myName" value="Custom name" />
<inspection_tool class="TodoComment" enabled="true" level="ERROR" enabled_by_default="true">
<scope name="glob:path/Some.java" level="ERROR" enabled="false" />
<scope name="glob:**/*.java" level="ERROR" enabled="true" />
</inspection_tool>
</profile>

View File

@@ -8,5 +8,5 @@ include:
inspections:
- inspection: TodoComment
ignore:
- "file:*.*"
- "!file:Main.*"
- "ijscope:file:*.*"
- "!ijscope:file:Main.*"

View File

@@ -7,4 +7,4 @@ inspections:
- inspection: TodoComment
severity: ERROR
ignore:
- "!file:Main.*"
- "!ijscope:file:Main.*"

View File

@@ -5,4 +5,4 @@ inspections:
severity: INFO
enabled: true
ignore:
- "file:*.java"
- "ijscope:file:*.java"

View File

@@ -26,5 +26,5 @@ inspections:
enabled: true
severity: ERROR
ignore:
- "!file:*.*"
- "file:*.java"
- "!ijscope:file:*.*"
- "ijscope:file:*.java"