ktlint-gradle icon indicating copy to clipboard operation
ktlint-gradle copied to clipboard

Exclude configuration is ignored

Open jivimberg opened this issue 2 years ago • 4 comments

On plugin version 10.2.1 the following configuration is ignored:

ktlint {
    filter {
        exclude("**/generated/**")
    }
}

It works fine on version 10.2.0.

Also tried with

ktlint {
    filter {
        exclude { element -> element.file.path.contains("generated/") }
    }
}

And it yielded the same result.

Might be a regression from #266

jivimberg avatar Apr 22 '22 16:04 jivimberg

Seeing this as well, but on any of the 10.x versions. Luckily in my case what I needed to exclude was an entire sourceset so was able to just disable the task.

dalewking avatar May 02 '22 21:05 dalewking

Same here. For me, it did not work with 10.0.0 - 10.3.0

the workaround was to use:

filter {
  //exclude("**/generated/**")
  exclude { projectDir.toURI().relativize(it.file.toURI()).path.contains("/generated/") }
}

trks1970 avatar Jun 03 '22 16:06 trks1970

I had a similar issue in my project. In my case I was configuring src dirs after project evaluation, so the sources were getting added after the filter was applied. At least that was my hypothesis, I didn't dig into the sources to confirm it. But what helped solving it - is to configure src dirs lazily at config time.

E.g.:

Before the change:

project.afterEvaluate {
    sourceSets.main {
        java {
            srcDirs(tasks.withType<CodegenTask>())
        }
    }
}

After the change:

project.sourceSets.main {
    java {
        srcDirs(tasks.withType<CodegenTask>())
    }
}

monosoul avatar Jun 09 '22 09:06 monosoul

+1'd. Working with a file pattern is not working for me, too. I gave fixing this bug a shot, but working with Gradle's APIs gave me a headache. I think this is the offending line:

https://github.com/JLLeitschuh/ktlint-gradle/blob/1b5b4e7c328e89a8486a0d1776b05d5d943513f8/plugin/src/main/kotlin/org/jlleitschuh/gradle/ktlint/tasks/BaseKtLintCheckTask.kt#L113

Because we cannot pass getAsFileTree() a root directory for the file tree, filtering by relative path, e.g., **/generated/**, does not work. We would need to work out a way to convert the FileCollection into a FileTree with a root, for example the project directory, which will be the base for relative path patterns to match against.

Lastly, we may defend against regression by making the exclusion pattern in KtlintPluginTest#ignoreExcludedSources more complicated, for example as in:

ktlint.filter { exclude("**/src/**/fail-*.kt") }

f4lco avatar Jul 14 '22 14:07 f4lco

It'd be great if we had an official fix.

ktlint {
  filter {
    exclude("**/generated/**")
    exclude { projectDir.toURI().relativize(it.file.toURI()).path.contains("/generated/") }
  }
}

doesn't work for me.

bartekpacia avatar Sep 26 '22 10:09 bartekpacia

you can put logger statements inside of filter, and log it to help. This is working for me, official fix is needed though, at least the docs if nothing more.

ktlint {
  filter {
    exclude { it.file.path.contains("generated") }
  }
}

xenoterracide avatar Oct 13 '22 11:10 xenoterracide

For those still struggling with this issue, here's how you can configure the filter to make it work consistently:

tasks {
    runKtlintCheckOverMainSourceSet {
        setSource(
            project.sourceSets.main.map { sourceSet ->
                sourceSet.allSource.filter { file ->
                    !file.path.contains("/generated-jooq/")
                }
            }
        )
    }
}

where runKtlintCheckOverMainSourceSet - is the task name generated by the plugin for the main source set. If you have multiple source sets where you need to exclude files you'll have to do that explicitly for every source set. Here's another example for test source set:

tasks {
    runKtlintCheckOverTestSourceSet {
        setSource(
            project.sourceSets.test.map { sourceSet ->
                sourceSet.allSource.filter { file ->
                    !file.path.contains("some-path")
                }
            }
        )
    }
}

monosoul avatar Oct 31 '22 17:10 monosoul

I'm still having this issue myself on 11.2.0.

mikeholler avatar Feb 24 '23 17:02 mikeholler

Thanks. I'll look into this

wakingrufus avatar Feb 25 '23 17:02 wakingrufus

There are several issues about filtered file tree on gradle < 7.5 version

  • https://github.com/gradle/gradle/issues/19780
  • https://github.com/gradle/gradle/issues/20391
  • https://github.com/gradle/gradle/issues/20680

Although it is difficult to identify the exact cause of the issue, updating the Gradle version(7.5) will solve the problem.

enif-lee avatar Mar 04 '23 19:03 enif-lee

The most useful thing for us at this point is if someone could contribute a pull request with a failing unit test demonstrating the problem. From there, we can dig into what's going on.

JLLeitschuh avatar Apr 03 '23 21:04 JLLeitschuh

What @monosoul mentions seems to be the case for me as well. We had a plugin modifying srcDirs afterEvaluate and the issue got fixed once we removed it.

alejandrolorefice avatar Apr 18 '23 10:04 alejandrolorefice

Weird behavior: setting the source set manually as in https://github.com/JLLeitschuh/ktlint-gradle/issues/579#issuecomment-1297402108 doesn't work:

tasks {
    runKtlintCheckOverCommonMainSourceSet {
        setSource(
            kotlin.sourceSets.commonMain.map {
                it.kotlin.filter { file ->
                    file.toRelativeString(projectDir) != "src/commonMain/kotlin/Models.kt"
                }
            }
        )
    }
}

What does work is evaluating source in a doFirst block:

tasks {
    runKtlintCheckOverCommonMainSourceSet {
        setSource(
            kotlin.sourceSets.commonMain.map {
                it.kotlin.filter { file ->
                    file.toRelativeString(projectDir) != "src/commonMain/kotlin/Models.kt"
                }
            }
        )

        doFirst {
            source.forEach { println(it) }
        }
    }
}

Eagerly evaluating the argument to setSource, i.e. by calling toList(), doesn't work.

It seems to me that the intermediate source collection should be removed, as the filter should be applied as late as possible and sourceFiles should be evaluated lazily in a task action instead of hoping Gradle does the right thing.

tadfisher avatar May 25 '23 21:05 tadfisher

I've something weird .. doesn't know if it's related (if it's not, I'll open a separate issue)

With these configurations:

ktlint {
    android.set(true)
    enableExperimentalRules.set(true)
    filter {
        exclude { element -> element.file.path.contains("generated/") }
        exclude { element -> element.file.path.contains("build/") }
    }
}

And :

tasks {
    runKtlintCheckOverCommonMainSourceSet {
        doFirst {
            source.forEach { println(it) }
        }
    }
}

The task :common:runKtlintCheckOverCommonMainSourceSet doesn't print my file in the folder /common/build/.../commonMain (and do print when I remove the filter). But, tasks :common:ktlintAndroidMainSourceSetCheck and :common:ktlintIosMainSourceSetCheck failed on a file in /common/build/.../[androidMain | iosMain]! I understand that's normal as the task checkOver is on the CommonMain sourceset. But when I run ktlintCheck, the tasks for android and ios (runKtlintCheckOver[Android | Ios]MainSourceSet) do not run!

I'm on Gradle 8.

Edit: Nevermind, it works now! Don't know if it's related but since this message, I bump my version to 11.5.0 and ktlint to 0.50.0 and remove a workaround for ksp.

guyaumetremblay avatar Jul 11 '23 12:07 guyaumetremblay

Just to clarify with everyone, with this plugin, we don't implement the PatternFilterable that you are calling exclude on. We just support the API and directly pass it to the Gradle sourceFiles here.

We generally try to avoid any additional file reduction, to the best of our ability.

https://github.com/JLLeitschuh/ktlint-gradle/blob/840e72e2526f9061431491a2a553d58b9c0b0060/plugin/src/main/kotlin/org/jlleitschuh/gradle/ktlint/tasks/BaseKtLintCheckTask.kt#L115

JLLeitschuh avatar Jul 12 '23 23:07 JLLeitschuh

If it helps anyone, I found that I had to run the gradle clean task before generating baseline(s) otherwise the exclude didn't eliminate files that I wanted ignored.

zakhenry avatar Aug 30 '23 20:08 zakhenry

i have confirmed that on the latest ktlint-gradle and gradle versions, this is working as intended.

wakingrufus avatar Oct 10 '23 14:10 wakingrufus