From fed22c5236c91c364f63d250195612fc3655047d Mon Sep 17 00:00:00 2001 From: The Coden <75643469+thecoden@users.noreply.github.com> Date: Wed, 9 Dec 2020 11:59:13 -0800 Subject: [PATCH] Implement PathMatcher instead of Klob for Glob Matching --- build.gradle | 1 - ktlint/build.gradle | 1 - .../pinterest/ktlint/internal/FileUtils.kt | 59 +++++++++++++++---- .../ktlint/internal/FileUtilsTest.kt | 41 +++++++++++++ 4 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 ktlint/src/test/kotlin/com/pinterest/ktlint/internal/FileUtilsTest.kt diff --git a/build.gradle b/build.gradle index e484f970c5..1e8dce5d87 100644 --- a/build.gradle +++ b/build.gradle @@ -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 diff --git a/ktlint/build.gradle b/ktlint/build.gradle index ac82b621d7..5450daf2eb 100644 --- a/ktlint/build.gradle +++ b/ktlint/build.gradle @@ -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 diff --git a/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/FileUtils.kt b/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/FileUtils.kt index 9a0c4571b9..9a2c64ec47 100644 --- a/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/FileUtils.kt +++ b/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/FileUtils.kt @@ -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.fileSequence(): Sequence { - 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() } /** @@ -101,3 +95,44 @@ internal fun formatFile( debug = debug ) ) + + +internal class FileMatcher(val baseDirectory: File, patterns: List) { + + private val patterns = patterns.map { + println("Pattern : ${!it.startsWith("!")} : ${it.removePrefix("!")}") + Triple(!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 + } + } +} diff --git a/ktlint/src/test/kotlin/com/pinterest/ktlint/internal/FileUtilsTest.kt b/ktlint/src/test/kotlin/com/pinterest/ktlint/internal/FileUtilsTest.kt new file mode 100644 index 0000000000..125536ba15 --- /dev/null +++ b/ktlint/src/test/kotlin/com/pinterest/ktlint/internal/FileUtilsTest.kt @@ -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/")) + } + } + +}