gradle-lint-plugin
gradle-lint-plugin copied to clipboard
Does this work on Android projects?
I created a basic Android project from scratch using Android Studio. I then added compile 'com.google.guava:guava:19.0'
to my dependencies, just to give Gradle Lint a test drive. I then added the unused-dependency
rule and ran ./gradlew lintGradle
, but it reported no violations.
Note that Android projects are multi-module by default, and the artifact produced is an APK file.
@trobalik Did you add the unused-dependency
rule in the root project, or an allprojects block? Rules are configured on a per-project basis, so putting it in allprojects is your best bet.
Here's my root build.gradle file:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'com.netflix.nebula:gradle-lint-plugin:latest.release'
}
}
allprojects {
apply plugin: 'nebula.lint'
gradleLint.rules = ['unused-dependency']//'all-dependency', 'archaic-wrapper', 'duplicate-dependency-class']
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
and my app/build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.gradlelintexample"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.google.guava:guava:19.0'
}
Come find me again if you don't mind! We use ASM to scan class files for type (and therefore dependency) references currently, so we may need an alternate for Android?
I'm sitting behind you right now :) Let's talk after this talk.
Here's a link to a sample project on Github: https://github.com/trobalik/GradleLintAndroidExample
I think it's your use of project.convention.getPlugin(JavaPluginConvention)
. The Android plugin is not based on the Java plugin, so JavaPluginConvention does not get mixed in with Android projects as it does with other JVM projects.
@trobalik Thanks for the tip. Indeed source sets for Android projects are managed with a completely separate model on the android extension class. The particulars of this implementation make it difficult to associate source sets with their class output destination and classpaths, but I think I've achieved a reasonable approximation with 8f3ec5f1ba1b9f0cd087b3845d5f66f2d62880da.
The rule currently tries to move compile 'com.android.support:appcompat-v7:23.4.0'
to the runtime configuration, which doesn't exist in the Android world. What do you think we should do with dependencies like this? Have the rule ignore everything in com.android.support
? Are there any other libraries like this that aren't in that group?
Would you prefer me to comment here, or on the commit? First, thanks for working with me on this.
I see an issue with the hard-coded task names. For example: compileReleaseUnitTestJavaWithJavac
. That works fine for projects that don't make use of the 'product flavor' concept, but for those that do, it just won't work. E.g., in a project I'm currently working on, I have a task that looks like this: compileUsReleaseUnitTestJavaWithJavac
. The 'Us' prefix indicates that this task is for the 'us' flavor of the app.
Our product flavors look like this:
flavorDimensions "region"
productFlavors {
ca {
applicationId "com.example"
dimension "region"
}
us {
applicationId "com.example"
dimension "region"
}
}
(note: 'com.example' is a completely arbitrary applicationId that is separate from the project package. It's what identifies the app on Google Play.)
This is because our app works differently in the US and Canada. The 'dimension' attribute is irrelevant for this particular example, but I'm including this here to have an excuse to mention that Android apps can have multiple flavor dimensions. We might, for example, have 'free' and 'paid' flavors alongside our 'region' flavors.
The following code snippet might be of use. It iterates over each application variant ('variant' is the combination of flavor and build type).
android.applicationVariants.all { variant ->
println variant.name
}
In an app with the two standard build types ('release' and 'debug'), as well as the flavors 'us' and 'ca', this would output:
caDebug
caRelease
usDebug
usRelease
The lower-case first letter is intentional.
I should also note, finally, that 'release' and 'debug' build types are entirely optional -- they're really just suggestions, defined right in the default, wizard-produced build script. Apps may have more or less than those two, and they may be named arbitrarily.
All that said, if you can just get a references to project.android.applicationVariants
and loop through the resulting list, that's probably your best bet.
Excellent explanation @trobalik (and necessary as I was really just guessing)! I'll make that change.
Hey @jkschneider, I know you're busy, but I was just wondering if you've been able to make any progress on this.
Sorry @trobalik, I haven't, but I'm still itching to get it done soon.
I'd love to help more directly, but I need to get more familiar with your codebase. Maybe I should do that....
Hello @trobalik @jkschneider . Is there any good news on this topic:) Thanks.
I would LOVE if this got fixed for Android. I have no news, though.
Any update on this? It still doesn't work for Android...
Any news here?
Seems not work. Check my issue https://github.com/nebula-plugins/gradle-lint-plugin/issues/194
Years old, but take a look at https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin, a plugin I've authored that at least answers the question of "which of my dependencies are unused"? (among many others)
Still finds no violation on 15.x.x and older versions, and on newer 17.x.x version doesn't even compile https://github.com/nebula-plugins/gradle-lint-plugin/issues/342
i think you need to at least state in the documentation that plugin does not support Android projects, so that Android developers don't waste their time
i think you need to at least state in the documentation that plugin does not support Android projects, so that Android developers don't waste their time
THIS. I wasted the entire day trying to get this thing working on my Android project until I found this thread.
@4gus71n PTAL https://github.com/autonomousapps/dependency-analysis-gradle-plugin