50

I would like to be able to run the lint task when I'm building projects with the android studio to ensure the lint rules are being followed.

I have tried using task dependencies but with no luck. My TeamCity build server uses the build task which runs the lint task so that works great. However, the android studio appears to use generateDebugSources and compileDebugJava tasks interchangeably when I have selected the debug build variant.

Here is what I have tried in my build.gradle:

assemble.dependsOn lint
Praful Bhatnagar
  • 7,425
  • 2
  • 36
  • 44
Robert
  • 6,086
  • 19
  • 59
  • 84

8 Answers8

44

If you just want to configure your Android Studio project to run the lint check before the default run configuration without affecting how your gradle tasks are configured, you can follow these steps.

  1. Open the run configurations drop down and choose edit

enter image description here

  1. Select your app run configuration

enter image description here

  1. Press the '+' to add a new step

enter image description here

  1. Choose "Gradle-aware Make"

enter image description here

  1. Type 'check' and choose the option with your app module name and check. (Mine is :app:check)

enter image description here

  1. Press the up arrow to move the new check step before the existing Gradle-aware make step

enter image description here

Now, Android Studio will run the lint check and fail the build if any lint errors occur.

Ross Hambrick
  • 5,880
  • 2
  • 43
  • 34
  • 5
    This works but ideally I wouldn't want everyone in the project to have to setup their environment this way. Is there a way to do this with gradle? – Robert Dec 05 '14 at 21:41
  • Since this is closest to what I actually want I'm marking this as the correct answer for now. – Robert Jan 27 '15 at 23:35
  • 2
    can we setup this in gradle build somehow..? – Ewoks Sep 24 '15 at 13:48
  • You can setup this on gradle, kind of a hack but works. The idea is to make assemble tasks depend on lint tasks so that on every run you will also run lint. I wrote the code in an answer bellow. – Yoel Gluschnaider Jan 15 '16 at 15:16
39

To runt lint and analyze your project, simply select Analyze > Inspect Code.

You should get a nice window with all issues.

enter image description here

Also check Run lint in Android Studio for more information.


I did a little more research, try adding this to your build.gradle.

lintOptions {
      abortOnError true
  } 

There are many options that you can apply to the build.gradle

Andrew Gable
  • 2,692
  • 2
  • 24
  • 36
  • 5
    I want to prevent compilation of the project on any lint error to ensure the lint rules are being followed. Running a code inspection could simply be ignored and not guarantee the lint rules are being followed at compile time. – Robert Apr 04 '14 at 15:47
  • 1
    How do I append a lint call in my build.gradle? – Robert Apr 04 '14 at 17:00
  • 3
    I'm already using the abortOnError which is why the build breaks on my build server. Android studio does not run the lint task when building a project. How do I run the lint task when building a project? – Robert Apr 04 '14 at 17:12
  • Can you call you just call build server? See http://stackoverflow.com/questions/19529559/launch-custom-gradle-android-build-in-android-studio – Andrew Gable Apr 04 '14 at 17:22
  • It's not clear how building different variants solves my issue. – Robert Dec 05 '14 at 21:45
  • 3
    I don't want to run the lint task manually, I want it to be run when making the project. – Robert Dec 08 '14 at 18:53
28

To do this in build.gradle, add the following lines to your build.gradle:

android {
  applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def lintTask = tasks["lint${variant.name.capitalize()}"]
        output.assemble.dependsOn lintTask
    }
  }
  ...
}

This makes all of your assemble tasks depend on the lint task effectively running them before every assemble call that is executed by Android Studio.

Edit

With Android Gradle Plugin 3.3 and Gradle 5.x this is a revised version using Kotlin script:

applicationVariants.all {
  val lintTask = tasks["lint${name.capitalize()}"]
  assembleProvider.get().dependsOn.add(lintTask)
}
Yoel Gluschnaider
  • 1,785
  • 1
  • 16
  • 20
12

just run the "check" task

./gradlew clean check assembleRelease
Praful Bhatnagar
  • 7,425
  • 2
  • 36
  • 44
stephane k.
  • 1,668
  • 20
  • 21
6

here is my solution which also works when you click Build - Make Project in Android Studio:

android {
..
    afterEvaluate {
        applicationVariants.all {
            variant ->
                // variantName: e.g. Debug, Release
                def variantName = variant.name.capitalize()
                // now we tell gradle to always start lint after compile
                // e.g. start lintDebug after compileDebugSources
                project.tasks["compile${variantName}Sources"].doLast {
                    project.tasks["lint${variantName}"].execute()
                }
        }
    }
}
TmTron
  • 17,012
  • 10
  • 94
  • 142
  • Great answer!! Something that I'm looking for. However, it gives me the below error `Could not find method execute() for arguments [] on task ':app:lintDebug' of type com.android.build.gradle.tasks.LintPerVariantTask.` – Saran Sankaran Nov 29 '19 at 05:41
  • Thanks! You save my life! – Alberto Aug 14 '20 at 14:20
  • The execute method was removed on the recent version of Gradle, here is the alternative which work for me : `project.tasks["compile${variantName}Sources"].dependsOn("lint${variantName}")` – Sofien Rahmouni Dec 21 '22 at 15:47
5

If you want to force Android Studio project to run the lint check before the default run configuration without affecting how your gradle tasks are configured, AND you want to do this in the gradle build system, then you can add the following block outside of the android block in the app module's build.gradle as follows:

android {
....
    lintOptions {
        abortOnError true
    }
}

tasks.whenTaskAdded { task ->
    if (task.name == 'compileDevDebugSources') {
        task.dependsOn lint
        task.mustRunAfter lint
    }
}

Replace compileDevDebugSources with the desired build variant that you have already defined, eg. compileReleaseSources, compileDebugSources, compileStagingDebugSources, etc.

This was tested working on Android Studio 3.0

Phileo99
  • 5,581
  • 2
  • 46
  • 54
4

Just modifying answer of @Yoel Gluschnaider

For me if I use Val it shows error like this : Could not set unknown property 'lintTask' for object of type com.android.build.gradle.internal.api.ApplicationVariantImpl.

So I replace it

applicationVariants.all {
    def lintTask = tasks["lint${name.capitalize()}"]
    assembleProvider.get().dependsOn.add(lintTask)
}

and it work fine!!

Praful Bhatnagar
  • 7,425
  • 2
  • 36
  • 44
Rushabh Shah
  • 680
  • 4
  • 22
0

More performant answers follow Gradle task configuration avoidance is as below

Gradle kts version

android {
    applicationVariants.configureEach {
        val variantName =
            name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ENGLISH) else it.toString() }
        val lintTaskName = "lint$variantName"
        val lintTask = tasks.named("lint$variantName")
        assembleProvider.dependsOn(lintTask, tasks.named("detekt$variantName"))
    }
}

Groovy version

android {
    applicationVariants.configureEach {
        def variantName = name.capitalize()
        def lintTaskName = "lint$variantName"
        def lintTask = tasks.named("lint$variantName")
        assembleProvider.configure {
            dependsOn lintTask
        }
    }
}

Pros:

  1. Didn't call assembleProvider.get() which defeats the purpose of configuration avoidance
  2. Lint task is accessed using a named function which lazily accesses the task when it is required(mentioned at Gradle migration guide)
  3. Uses configureEach which configure each task when required rather than eagarly
AndroidEngineX
  • 975
  • 1
  • 9
  • 22