Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternate sourceSets are not detected #153

Closed
rubengees opened this issue Oct 23, 2018 · 25 comments
Closed

Alternate sourceSets are not detected #153

rubengees opened this issue Oct 23, 2018 · 25 comments
Assignees
Labels

Comments

@rubengees
Copy link

Plugin version: 6.2.0
Ktlint version: Bundled
Project type: Android
Android Gradle plugin version: 3.4.0-alpha01 (happened in earlier 3.3.x ones too)

Config:

apply plugin: "org.jlleitschuh.gradle.ktlint"

ktlint {
    android = true
}

I have configured an alternative sourceSet for my kotlin sources:

sourceSets {
    main {
        java.srcDirs += "src/main/kotlin"
    }
}

Once I do this, the plugin does not seem to be able to detect kotlin files in that directory. Kotlin files in src/main/java are detected.

Is this some misconfiguration on my end? I can create and share a sample project if needed.
Thanks for looking into this!

@Tapchicoma Tapchicoma added the bug label Oct 23, 2018
@Tapchicoma
Copy link
Collaborator

Interesting, I suppose you've applied kotlin-android plugin?

@rubengees
Copy link
Author

Sure, my sample project and also the real project in which I first found this work properly apart from this and the plugin also worked before the Android Gradle Plugin had this change with the lazy configuration (e.g. plugin versions < 6 work).

@Tapchicoma
Copy link
Collaborator

Indeed, I was able to reproduce on android sample project. Will try to fix it.

@Tapchicoma
Copy link
Collaborator

Tapchicoma commented Oct 23, 2018

Also I will assume that plugin version 5.1.0 should work in this case.

@Tapchicoma Tapchicoma self-assigned this Oct 23, 2018
@Tapchicoma
Copy link
Collaborator

The problem here that user defined source sets are only available in afterEvaluate {} block. Usages of this has been removed in #122 (6.x.x versions). So it will be not easy to fix.

Will try to figure out how Gradle Java plugin approaches this issue.

@Tapchicoma
Copy link
Collaborator

@rubengees fix will be available in 6.2.1 version.

@rubengees
Copy link
Author

Cool, thanks!

@tasomaniac
Copy link
Contributor

I'm still having this problem in my integration tests. Not really in a real project. ktlintDebugCheck task gives me NO-SOURCE

Generated project is something like below. Notice that I don't really have anything inside main folder. Instead, I'm adding a srcDir manually where I have the sample files with errors.


buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.4'
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.20'
    }
}
plugins {
    id 'org.jlleitschuh.gradle.ktlint' version '6.1.0'   
    id 'com.novoda.static-analysis'
}
repositories {
    google()
    jcenter()
}
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
    compileSdkVersion 27

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName '1.0'
    }
    lintOptions {
        disable 'OldTargetApi'
    }
    sourceSets {
        main {
            manifest.srcFile '/Users/sdane/dev/taso/gradle-static-analysis-plugin/plugin/src/test/fixtures/AndroidManifest.xml'
            java {
                srcDirs += '/Users/sdane/dev/taso/gradle-static-analysis-plugin/plugin/src/test/fixtures/sources/ktlint/with-error'
            }
        }
    }
    
}

staticAnalysis {
    penalty {
        maxWarnings = 0
        maxErrors = 0
    }
    
            ktlint {
            reporters = [
                org.jlleitschuh.gradle.ktlint.reporter.ReporterType.PLAIN, 
                org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE
            ]
            
            includeVariants { it.name == "debug" }
            }
            
}

@tasomaniac
Copy link
Contributor

As far as I see in the line from referenced PR https://github.com/JLLeitschuh/ktlint-gradle/pull/154/files#diff-513ff7df76b3a229c796d8d72281e589R123

You use ext.sourceSets {, what about using ext.sourceSets.all { instead.

@JLLeitschuh
Copy link
Owner

@tasomaniac Those two suggestions are, functionally, equivalent.

@tasomaniac
Copy link
Contributor

sourceSets function with an Action argument says configure in the docs. So it is used to configure sourceSets. Not sure if it returns a live collection.

all returns a live collection where you will also get future instances in the collection.

@tasomaniac
Copy link
Contributor

Anyways, it seems like not only the additional source sets but the default ones are also ignored when it is used with Novoda plugin. I will investigate this.

novoda/gradle-static-analysis-plugin#146

@JLLeitschuh
Copy link
Owner

@tasomaniac This is the code as it exists in the current release:

target.extensions.configure(BaseExtension::class.java) { ext ->
ext.sourceSets { sourceSet ->
sourceSet.all { androidSourceSet ->
// Passing Callable, so returned FileCollection, will lazy evaluate it
// only when task will need it.
// Solves the problem of having additional source dirs in
// current AndroidSourceSet, that are not available on eager
// evaluation.
createTasks(
androidSourceSet.name,
target.files(Callable { androidSourceSet.java.srcDirs })
)
}
}
}

Is this issue not fixed for you? Do you need it re-opened?

@tasomaniac
Copy link
Contributor

It works if I configure it directly in my build.gradle file. It does not if I let Novoda static analysis plugin to configure KtLint.

That's why I think it is ok to keep this issue closed. I will do some debugging and will get back to you on this.

@tasomaniac
Copy link
Contributor

After long debug session, I finally found the problem. 🎉

It is not just about Novoda plugin, so you can actually re-open this one.

It is a common practice to create tasks for each variant in Android. If you have flavor1Debug and flavor2Debug they would share the debug source set for example. I assumed that ktlint would configure the tasks also based on the Android variant. And you would have main always added as a source set.

The above link you posted created the task by only looking at the sourceSet kinds on the extension, rather than build variants. That is why ktlintDebugCheck only checks for debug folder and skips the main folder. And this was my problem.

Long story short, running ktlintDebugCheck does not include the main sourceSet.

@tasomaniac
Copy link
Contributor

tasomaniac commented Nov 8, 2018

Here, as far as I see, you were using Android variants already. This is the last working version for me.

https://github.com/JLLeitschuh/ktlint-gradle/blob/v5.1.0/plugin/src/main/kotlin/org/jlleitschuh/gradle/ktlint/KtlintPlugin.kt#L101

@JLLeitschuh JLLeitschuh reopened this Nov 8, 2018
@JLLeitschuh
Copy link
Owner

@tasomaniac Can you provide a sample script that demonstrates your problem using the latest version of ktlint-gradle?
Ideally something minimal that doesn't involve the novoda plugin.

@tasomaniac
Copy link
Contributor

Working on fix now. PR is coming soon.

Here how I reproduce it

  • create a new Android project
  • have some kotlin file with errors
  • run ktlintDebugCheck task

@tasomaniac
Copy link
Contributor

One way to reproduce inside the repo:

  • Make an error in the file AlternativeSample.kt inside samples/android-app
  • Run ktlintKellerbierDebugCheck

@Tapchicoma
Copy link
Collaborator

Hmm, I intentionally removed usages of Android variant manager:

  • it is not available for instant app plugin (extension has package-private visibility)
  • To have same approach with plain kotlin projects: check all SourceSet that kotlin plugin has.

Usually user doesn't need to call specific task, but rather call ktlintCheck(or ktlintFormat) task, as it will check only updated sources and use for non-changed sources "UP-TO-DATE" or "FROM CACHE" approaches.

It is a common practice to create tasks for each variant in Android. If you have flavor1Debug and flavor2Debug they would share the debug source set for example. I assumed that ktlint would configure the tasks also based on the Android variant. And you would have main always added as a source set.

Possible solution from ktlint-gradle plugin side is to create special meta tasks for android variants (excluding instant app plugin) that will trigger variant source sets tasks.

@tasomaniac
Copy link
Contributor

This is a huge behavior change though :( I would suggest to put it into changelog.

Usually user doesn't need to call specific task

I don't think it is safe/good to assume this ☝️. On Android people usually call the check tasks only for a certain variant to speed up things. It is really a common practice. Some projects have many flavors.

The big difference between plain Kotlin projects vs Android is that Kotlin only has main as a sourceSet by default whereas Android has many combination of sourceSets and most of them are empty. Meta task idea is good but then naming would be hard, wouldn't it?

As an example: flavor1Debug already has ktlintFlavor1DebugCheck task which does not check the sourceSets for flavor1Debug but checks the flavor1Debug which is usually empty in most projects.

@Tapchicoma
Copy link
Collaborator

Possible way:

  • add Sources to names of current tasks, so it will become ktlintFlavor1DebugSourcesCheck
  • use ktlintFlavor1DebugCheck as variant meta task name

Or:

  • use Variant for this meta tasks name, so they will be something like ktlintFlavor1DebugVariantCheck

@tasomaniac
Copy link
Contributor

Both sounds good to me. 👍

@Tapchicoma
Copy link
Collaborator

Opened new issue #170, as this particular problem doesn't related to original bug problem.

@tasomaniac
Copy link
Contributor

Make sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants