Extract traversing through directories to the common code

This commit is contained in:
Nikolay Krasko
2020-08-10 14:56:47 +03:00
parent 8db588c7f0
commit bb0ea56d63
@@ -8,8 +8,6 @@ package org.jetbrains.kotlin.code
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.io.systemIndependentPath import com.intellij.openapi.util.io.systemIndependentPath
import junit.framework.TestCase import junit.framework.TestCase
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
import java.io.File import java.io.File
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
@@ -20,7 +18,9 @@ class CodeConformanceTest : TestCase() {
private val JAVA_FILE_PATTERN = Pattern.compile(".+\\.java") private val JAVA_FILE_PATTERN = Pattern.compile(".+\\.java")
private val SOURCES_FILE_PATTERN = Pattern.compile("(.+\\.java|.+\\.kt|.+\\.js)") private val SOURCES_FILE_PATTERN = Pattern.compile("(.+\\.java|.+\\.kt|.+\\.js)")
private const val MAX_STEPS_COUNT = 100 private const val MAX_STEPS_COUNT = 100
private val NON_SOURCE_EXCLUDED_FILES_AND_DIRS = listOf( private val nonSourcesMatcher = FileMatcher(
File("."),
listOf(
".git", ".git",
"build/js", "build/js",
"buildSrc", "buildSrc",
@@ -58,7 +58,8 @@ class CodeConformanceTest : TestCase() {
"libraries/tools/kotlin-test-nodejs-runner/node_modules", "libraries/tools/kotlin-test-nodejs-runner/node_modules",
"libraries/tools/kotlinp/src", "libraries/tools/kotlinp/src",
"out" "out"
).map(::File) )
)
private val COPYRIGHT_EXCLUDED_FILES_AND_DIRS = listOf( private val COPYRIGHT_EXCLUDED_FILES_AND_DIRS = listOf(
"build", "build",
@@ -125,18 +126,10 @@ class CodeConformanceTest : TestCase() {
fun testForgottenBunchDirectivesAndFiles() { fun testForgottenBunchDirectivesAndFiles() {
val sourceBunchFilePattern = Pattern.compile("(.+\\.java|.+\\.kt|.+\\.js)(\\.\\w+)?") val sourceBunchFilePattern = Pattern.compile("(.+\\.java|.+\\.kt|.+\\.js)(\\.\\w+)?")
val root = File(".") val root = nonSourcesMatcher.root
val nonSourceMatcher = FileMatcher(root, NON_SOURCE_EXCLUDED_FILES_AND_DIRS)
val extensions = File(root, ".bunch").readLines().map { it.split("_") }.flatten().toSet() val extensions = File(root, ".bunch").readLines().map { it.split("_") }.flatten().toSet()
val failBuilder = mutableListOf<String>() val failBuilder = mutableListOf<String>()
root.walkTopDown() nonSourcesMatcher.walkTopDown(sourceBunchFilePattern).forEach { sourceFile ->
.onEnter { dir ->
!nonSourceMatcher.matchExact(dir) // Don't enter to ignored dirs
}
.filter { file -> !nonSourceMatcher.matchExact(file) } // filter ignored files
.filter { file -> sourceBunchFilePattern.matcher(file.name).matches() }
.filter { file -> file.isFile }
.forEach { sourceFile ->
val matches = Regex("BUNCH (\\w+)") val matches = Regex("BUNCH (\\w+)")
.findAll(sourceFile.readText()) .findAll(sourceFile.readText())
.map { it.groupValues[1] } .map { it.groupValues[1] }
@@ -208,16 +201,7 @@ class CodeConformanceTest : TestCase() {
} }
) )
val root = File(".") nonSourcesMatcher.walkTopDown(SOURCES_FILE_PATTERN).forEach { sourceFile ->
val nonSourceMatcher = FileMatcher(root, NON_SOURCE_EXCLUDED_FILES_AND_DIRS)
root.walkTopDown()
.onEnter { dir ->
!nonSourceMatcher.matchExact(dir) // Don't enter to ignored dirs
}
.filter { file -> !nonSourceMatcher.matchExact(file) } // filter ignored files
.filter { file -> SOURCES_FILE_PATTERN.matcher(file.name).matches() }
.filter { file -> file.isFile }
.forEach { sourceFile ->
val source = sourceFile.readText() val source = sourceFile.readText()
for (test in tests) { for (test in tests) {
if (test.filter(source)) test.result.add(sourceFile) if (test.filter(source)) test.result.add(sourceFile)
@@ -263,7 +247,8 @@ class CodeConformanceTest : TestCase() {
} }
} }
private class FileMatcher(val root: File, files: Collection<File>) { private class FileMatcher(val root: File, paths: Collection<String>) {
private val files = paths.filter { !it.startsWith("*/") }.map(::File)
private val names = files.mapTo(HashSet()) { it.name } private val names = files.mapTo(HashSet()) { it.name }
private val paths = files.mapTo(HashSet()) { it.systemIndependentPath } private val paths = files.mapTo(HashSet()) { it.systemIndependentPath }
private val relativePaths = files.filter { it.isDirectory }.mapTo(HashSet()) { it.systemIndependentPath + "/" } private val relativePaths = files.filter { it.isDirectory }.mapTo(HashSet()) { it.systemIndependentPath + "/" }
@@ -279,13 +264,22 @@ class CodeConformanceTest : TestCase() {
} }
} }
fun testRepositoriesAbuse() { private fun FileMatcher.walkTopDown(filePattern: Pattern): Sequence<File> {
class RepoAllowList(val repo: String, root: File, allowList: Set<String>) { return root.walkTopDown()
val allowFiles = allowList.map(::File) .onEnter { dir ->
val matcher = FileMatcher(root, allowFiles) !matchExact(dir) // Don't enter to ignored dirs
}
.filter { file -> !matchExact(file) } // filter ignored files
.filter { file -> filePattern.matcher(file.name).matches() }
.filter { file -> file.isFile }
} }
val root = File(".") fun testRepositoriesAbuse() {
class RepoAllowList(val repo: String, root: File, allowList: Set<String>) {
val matcher = FileMatcher(root, allowList)
}
val root = nonSourcesMatcher.root
val repoCheckers = listOf( val repoCheckers = listOf(
RepoAllowList( RepoAllowList(
@@ -307,7 +301,8 @@ class CodeConformanceTest : TestCase() {
"idea/testData/gradle/packagePrefixImport/packagePrefixNonMPP/build.gradle", "idea/testData/gradle/packagePrefixImport/packagePrefixNonMPP/build.gradle",
"idea/testData/gradle/gradleFacetImportTest/jvmImportWithCustomSourceSets_1_1_2/build.gradle", "idea/testData/gradle/gradleFacetImportTest/jvmImportWithCustomSourceSets_1_1_2/build.gradle",
"idea/testData/gradle/gradleFacetImportTest/jvmImport_1_1_2/build.gradle", "idea/testData/gradle/gradleFacetImportTest/jvmImport_1_1_2/build.gradle",
"idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/MultiplePluginVersionGradleImportingTestCase.kt" "idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/MultiplePluginVersionGradleImportingTestCase.kt",
"idea/testData/perfTest/native/_common/build.gradle.kts.header"
) )
), ),
RepoAllowList( RepoAllowList(
@@ -338,7 +333,8 @@ class CodeConformanceTest : TestCase() {
"idea/testData/gradle/configurator/configureJvmEAPWithBuildGradleKts/build.gradle.kts.after", "idea/testData/gradle/configurator/configureJvmEAPWithBuildGradleKts/build.gradle.kts.after",
"idea/testData/perfTest/native/_common/settings.gradle.kts", "idea/testData/perfTest/native/_common/settings.gradle.kts",
"kotlin-ultimate/gradle/cidrPluginTools.gradle.kts", "kotlin-ultimate/gradle/cidrPluginTools.gradle.kts",
"libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/service/KotlinVersionProviderService.kt" "libraries/tools/new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/core/service/KotlinVersionProviderService.kt",
"idea/testData/perfTest/native/_common/build.gradle.kts.header"
) )
) )
) )
@@ -346,20 +342,8 @@ class CodeConformanceTest : TestCase() {
data class RepoOccurance(val repo: String, val file: File) data class RepoOccurance(val repo: String, val file: File)
data class RepoOccurrences(val repo: String, val files: Collection<File>) data class RepoOccurrences(val repo: String, val files: Collection<File>)
val extensions = hashSetOf("java", "kt", "gradle", "kts", "xml", "after") val extensionsPattern = Pattern.compile(".+\\.(java|kt|gradle|kts|xml)(\\.\\w+)?")
val nonSourceMatcher = FileMatcher(root, NON_SOURCE_EXCLUDED_FILES_AND_DIRS) val repoOccurrences: List<RepoOccurrences> = nonSourcesMatcher.walkTopDown(extensionsPattern)
val traceStack = mutableListOf<Long>()
val repoOccurrences: List<RepoOccurrences> = root.walkTopDown()
.onEnter { dir ->
traceStack.push(System.nanoTime())
!nonSourceMatcher.matchExact(dir)
} // don't visit dirs
.onLeave { dir ->
val start = traceStack.pop()
println("${dir.path} - ${(System.nanoTime() - start) / 1000}")
}
.filter { file -> file.extension in extensions && file.isFile }
.filter { file -> !nonSourceMatcher.matchExact(file) } // filter ignored files
.flatMap { file -> .flatMap { file ->
val checkers = repoCheckers.filter { checker -> val checkers = repoCheckers.filter { checker ->
!checker.matcher.matchWithContains(file) !checker.matcher.matchWithContains(file)