How to apply plugin to only one flavor in gradle?

AndroidAndroid StudioGradleNewrelicAndroid Productflavors

Android Problem Overview


I have a multi-flavored, multi-build-typed android project and I want to integrate the NewRelic plugin. But I have to apply it only for one of the customers, thus only for one product flavor.
NewRelic uses instrumentation and the plugin would generate code in other flavors if I applied the plugin there, and that is not permitted for us.

So my question is: How can I use the apply plugin: something command in the gradle file to be applied to only one of my flavors?

Android Solutions


Solution 1 - Android

Use this code:

if (!getGradle().getStartParameter().getTaskRequests()
        .toString().contains("Develop")){
    apply plugin: 'com.google.gms.google-services'
}

getGradle().getStartParameter().getTaskRequests().toString() returns something like [DefaultTaskExecutionRequest{args=[:app:generateDevelopDebugSources],projectPath='null'}] so as stated in the comments Develop must start with an uppercase.

Solution 2 - Android

Tried different solutions, but none of them worked for me. This is what I came up with and seems to work as far as I tested:

build.gradle

productFlavors {
    someFlavorWithGoogleGcm {
        dimension "type"
        applicationId "com.example.withGcm"
        ext.useGoogleGcm = true
    }
    someFlavorWithoutGoogleGcm {
        dimension "type"
        applicationId "com.example.withoutGcm"
    }
}

And outside the configuration, inside the build.gradle file:

android.productFlavors.each { flavor ->
    if (getGradle().getStartParameter().getTaskRequests().toString().toLowerCase().contains(flavor.name) && flavor.ext.useGoogleGcm) {
        println("Building flavor with Google GCM [${flavor.name}] - applying plugin")
        apply plugin: 'com.google.gms.google-services'
    }
}

Solution 3 - Android

I simply used apply plugin: 'com.google.gms.google-services' inside the flavor in app level build.gradle and it works just fine.

productFlavors {
    ..... your other flavors ....
    yourFlv {
        ....
        ....
        apply plugin: 'com.google.gms.google-services'
    }
}

No extra step needed.

Solution 4 - Android

  1. Define variable - def fl

  2. Initialize variable in you Flavours (and/or builds)

         productFlavors {
         
                 freeFlavour {
                     (...)
                     fl = "free"
                 }
         
                 paidFlavour {
                     (...)
                     fl = "paid"
                 }
             }
    
  3. Use if statement -

    if (fl == "free") { apply plugin: something }

Solution 5 - Android

I found a solution, but it is not the best so far. So I'm not sure anymore, that what I wanted to do initially is possible. The gradle file evaluation and the choosing of the right flavor and build type is in different phases of the gradle build, so what I've done is:

I use a build parameter from the command line. When that paramerer is true, I apply the plugin, when it is not even there, I also apply it (for IDE build). I use Jenkins, so I could write that parameter in the build job.

build.gradle file:

// First we have to attach a task to the project, which will be running first
gradle.projectsEvaluated {
    preBuild.dependsOn(applyNewRelicByProperty)
}

// Then check on the parameter, which comes from the command line
task applyNewRelicByProperty {
    if(!project.hasProperty('compileNewRelic')) {
        // NewRelic on: 'compileNewRelic' property not set, so running from IDE.
        apply plugin: 'newrelic'
    } else if(project.hasProperty('compileNewRelic') && project.getProperties().get('compileNewRelic').equals('true')) {
        // NewRelic on: 'compileNewRelic' property is set and it is 'true'.
        apply plugin: 'newrelic'
    } else {
        // NewRelic off
        println("No NewRelic")
    }
}

And you have to run the gradle build by this:

assembleYourApp -PcompileNewRelic=true

Solution 6 - Android

After upgrading to Gradle 4.2, the approach by Tarps stopped working, so I ended up combining it with Erik's answer.

Set ext.useGoogleGcm for each flavour in your build.gradle:

productFlavors {
    a {
        ...
        ext.useGoogleGcm = true
    }
    b {
        ...
        ext.useGoogleGcm = false
    }
}

Then at the bottom of the file:

apply plugin: 'com.google.gms.google-services'

afterEvaluate {
    android.productFlavors.each { flavor ->
        tasks.matching {
            it.name.contains('GoogleServices') && it.name.contains(flavor.name.capitalize())
        }*.enabled = flavor.ext.useGoogleGcm
    }
}

In the output for your assembleRelease task, you should see tasks with "GoogleServices" in the name have run for those that are true and skipped for those that are false. If your build complains about toCapitalize, you could use toLowerCase on both it.name and flavor.name.

Solution 7 - Android

In the case of the Google Services Gradle plugin, the following works.

apply plugin: 'com.google.gms.google-services'

afterEvaluate {
    tasks.matching { it.name.contains("GoogleServices") && !it.name.contains(yourFlavorName) }*.enabled = false
}

where yourFlavorName is a capitalised string containing the name of your flavor that must apply the plugin; all other flavors don't use the plugin.

Note that the plugin is still applied to other flavors; this solution just disables the *GoogleServices* task(s) for them. That assumes that the Google Services Gradle plugin only applies changes by adding a task containing substring "GoogleServices", which might not work in the future.

To check that this works, you can check the dependencies, e.g. like so:

./gradlew app:dependencyInsight --configuration yourFlavorNameDebugCompileClasspath --dependency google | grep -i services

That should show some dependencies for yourFlavorName but not for other flavor names:

./gradlew app:dependencyInsight --configuration otherFlavorNameDebugCompileClasspath --dependency google | grep -i services

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionszidijaniView Question on Stackoverflow
Solution 1 - AndroidPavel SantaevView Answer on Stackoverflow
Solution 2 - AndroidTarpsView Answer on Stackoverflow
Solution 3 - Androidmayank1513View Answer on Stackoverflow
Solution 4 - AndroidSergey BondarenkoView Answer on Stackoverflow
Solution 5 - AndroidszidijaniView Answer on Stackoverflow
Solution 6 - AndroidStormFooView Answer on Stackoverflow
Solution 7 - AndroidErikView Answer on Stackoverflow