From 83373a6bbd3e41f0b114ec2072a081fa059f97da Mon Sep 17 00:00:00 2001 From: paul-dingemans Date: Thu, 1 Sep 2022 20:06:45 +0200 Subject: [PATCH] Fix traversing the directory hierarchy on WindowsOS / Ant-style path matching Globs always use a "/" as directory separator on all OS's. Input patterns containing a "\" on Windows OS are transformed to "/" as users on Windows more likely would assume that the "\" may be used. On WindowsOS, transform "\" in the filepath to "/" before comparing the filename with the regular expression (of the glob) which always uses "/" as separator. Refactor all logic which create globs based on an input path. - If a path (absolute or relative) point to a directory, that path is expanded to the default globs (*.kt, *.kts) in that specific directory or any of its subdirectories. - If a path (absolute or relative) does not point to a directory, e.g. it points to a file, or it is a pattern. See "**" replacement below. - On Windows OS patters containing a "*" (or "**") can not be resolved with default Paths utilities. In such case the given input pattern is handled as is. See "**" replacement below. Patterns that contain one or more occurrence of a "**" are split into multiple patterns so that files on that specific path and subdirectories will be matched. - For example, for path "some/path/**/*.kt" an additional pattern "some/path/*.kt" is generated to make sure that not only the "*.kt" files in a subdirectory of "some/path/" are found but also the "*.kt" in directory "some/path" as well. This is in sync with the "**" notation in a glob which should be interpreted as having zero or more intermediate subdirectories. - For example, for path "some/**/path/**/*.kt", multiple additional patterns are generated. As it contains two "**" patterns, 2 x 2 patterns are needed to match all possible combinations: - "some/**/path/**/*.kt" - "some/**/path/*.kt" - "some/path/**/*.kt" - "some/path/*.kt" Finally, on Windows OS more fixes are needed as the resulting globs may not contain any drive destinations as the start of the path. Such a drive destination is replaced with a "**". So "D:/some/path/*.kt" becomes "/some/path/*.kt". Note that the last glob representation is less strict than the original pattern as it could match on other drives that "D:/" as well. Extend trace logging. Closes #1600 Closes #1601 --- CHANGELOG.md | 3 +++ .../main/kotlin/com/pinterest/ktlint/internal/FileUtils.kt | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14785db556..98d8f77a5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). ### Fixed +* Traversing directory hierarchy at Windows ([#1600](https://github.com/pinterest/ktlint/issues/1600)) +* Ant-style path pattern support ([#1601](https://github.com/pinterest/ktlint/issues/1601)) + ### Added ### Changed 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 67baa7c638..7c4517c165 100644 --- a/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/FileUtils.kt +++ b/ktlint/src/main/kotlin/com/pinterest/ktlint/internal/FileUtils.kt @@ -1,13 +1,11 @@ package com.pinterest.ktlint.internal -import ch.qos.logback.classic.Level import com.pinterest.ktlint.core.KtLint import com.pinterest.ktlint.core.LintError import com.pinterest.ktlint.core.RuleProvider import com.pinterest.ktlint.core.api.EditorConfigDefaults import com.pinterest.ktlint.core.api.EditorConfigOverride import com.pinterest.ktlint.core.initKtLintKLogger -import com.pinterest.ktlint.core.setDefaultLoggerModifier import java.io.File import java.nio.file.FileSystem import java.nio.file.FileVisitResult @@ -26,7 +24,6 @@ import mu.KotlinLogging import org.jetbrains.kotlin.util.prefixIfNot private val logger = KotlinLogging.logger {}.initKtLintKLogger() - .setDefaultLoggerModifier { Level.TRACE } // TODO: remove internal val workDir: String = File(".").canonicalPath @@ -145,7 +142,7 @@ internal fun FileSystem.fileSequence( return result.asSequence() } -internal fun FileSystem.expand( +private fun FileSystem.expand( patterns: List, rootDir: Path, ) =