Skip to content

Commit

Permalink
Implement PathMatcher instead of Klob for Glob Matching
Browse files Browse the repository at this point in the history
  • Loading branch information
thecoden committed Dec 9, 2020
1 parent 1bd287f commit fed22c5
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 14 deletions.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ ext.deps = [
'stdlib' : "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin}",
'compiler': "org.jetbrains.kotlin:kotlin-compiler-embeddable:${versions.kotlin}"
],
'klob' : 'io.codetactics.klob:klob:0.2.1',
ec4j : 'org.ec4j.core:ec4j-core:0.2.2',
'picocli' : 'info.picocli:picocli:3.9.6',
// Testing libraries
Expand Down
1 change: 0 additions & 1 deletion ktlint/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ dependencies {
implementation project(':ktlint-ruleset-test')
implementation deps.kotlin.stdlib
implementation deps.kotlin.compiler
implementation deps.klob
implementation deps.picocli

testImplementation deps.junit
Expand Down
59 changes: 47 additions & 12 deletions ktlint/src/main/kotlin/com/pinterest/ktlint/internal/FileUtils.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,24 @@
package com.pinterest.ktlint.internal

import com.github.shyiko.klob.Glob
import com.pinterest.ktlint.core.KtLint
import com.pinterest.ktlint.core.LintError
import com.pinterest.ktlint.core.RuleSet
import java.io.File
import java.nio.file.FileSystems
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.PathMatcher
import kotlin.system.exitProcess

internal val workDir: String = File(".").canonicalPath

internal fun List<String>.fileSequence(): Sequence<File> {
val glob = if (isEmpty()) {
Glob.from("**/*.kt", "**/*.kts")
val patterns = if (isEmpty()) {
listOf("**/*.kt", "**/*.kts")
} else {
Glob.from(*map(::expandTilde).toTypedArray())
map(::expandTilde).toList()
}

return glob
.iterate(
Paths.get(workDir),
Glob.IterationOption.SKIP_HIDDEN
)
.asSequence()
.map(Path::toFile)
return FileMatcher(File(workDir), patterns).getFiles()
}

/**
Expand Down Expand Up @@ -101,3 +95,44 @@ internal fun formatFile(
debug = debug
)
)


internal class FileMatcher(val baseDirectory: File, patterns: List<String>) {

private val patterns = patterns.map {
println("Pattern : ${!it.startsWith("!")} : ${it.removePrefix("!")}")
Triple<Boolean, PathMatcher, String>(!it.startsWith("!"), FileSystems.getDefault().getPathMatcher("glob:${it.removePrefix("!")}"), it)
}

fun matches(path: Path): Boolean {
var isIncluded = false

for (pattern in patterns) {
if (isIncluded) {
if (!pattern.first) {
isIncluded = !pattern.second.matches(path).also {
println("$path : ${pattern.third} ${if (it) "excludes this file" else ""}")
}
}
} else {
if (pattern.first) {
isIncluded = pattern.second.matches(path).also {
println("$path : ${pattern.third} ${if (it) "includes this file" else ""}")
}
}
}
}

println("Checking : $isIncluded : $path")

return isIncluded
}

fun getFiles() = baseDirectory.walkTopDown().filter { file ->
if (file.isFile) {
matches(baseDirectory.toPath().relativize(file.toPath()))
} else {
false
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.pinterest.ktlint.internal

import java.io.File
import java.nio.file.Paths
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class FileUtilsTest {

@Test
fun negation() {
val filter = FileMatcher(File("/tmp"), listOf(
"**.kt",
"!**/*test*/**.kt",
"!**/prefix*/**.kt",
"!**/*suffix/**.kt"
))

assertTrue(filter.matches(Paths.get("a.kt")))
assertFalse(filter.matches(Paths.get("a/test_/a.kt")))
assertFalse(filter.matches(Paths.get("a/_test_/a.kt")))
assertFalse(filter.matches(Paths.get("a/_test/a.kt")))
assertFalse(filter.matches(Paths.get("a/prefix_/a.kt")))
assertFalse(filter.matches(Paths.get("a/prefix/a.kt")))
assertTrue(filter.matches(Paths.get("a/_prefix/a.kt")))
assertFalse(filter.matches(Paths.get("a/_suffix/a.kt")))
assertFalse(filter.matches(Paths.get("a/suffix/a.kt")))
assertTrue(filter.matches(Paths.get("a/suffix_/a.kt")))
}

@Test
fun overlappingFilePatternTest() {
val result = listOf("src/test/**/*.kt", "!src/test/resources/**").fileSequence()

result.forEach {
assertTrue("File should have been excluded : ${it.path}", !it.path.contains("/resources/"))
}
}

}

0 comments on commit fed22c5

Please sign in to comment.