iGoDa iGoDa - 2 months ago 8
Android Question

Change dependency through a task in gradle

I've build a lib, that in order to compile the application needs to set the specific flavor and release/debug type.
However I'm trying to do this using a systemProperty when assembling the gradle via command.

To do that I'm doing something like this:

gradlew init assembleRelease -D P="flavor1"


On the build.gradle of the application I created a task to consume this "P" system property like:

task init(type: JavaExec){
systemProperty "Production", System.getProperty("P") //this variable comes from command variable
rootProject.ext.set("Production", systemProperties["Production"]);
}


Despite all this the following code runs always before the init task:

dependencies{
if(rootProject.ext.Production == "flavor1"){
releaseCompile "compile with flavor1"
}else{
releaseCompile "compile with flavor2"
}
}


Is there any way to change dependencies on the task init, in order to create an apk based on flavor set by a system property on a command line?

Note: I have an application, which add a dependency of a lib, which has many flavors, and what I want to change on the fly via the command line is the dependency to add on the application of this lib.

Answer

Well, what you do is just gambling. You do both, the setting of rootProject.ext.Production and the consuming of rootProject.ext.Production in the configuration phase. But I don't think there is some guarantee which is executed first the way you declared it. Besides that, using a JavaExec tasks configuration phase code to set some ext properties on the project is total non-sense anyway.

Instead of

task init(type: JavaExec){
    systemProperty "Production", System.getProperty("P")   //this variable comes from command variable
    rootProject.ext.set("Production", systemProperties["Production"]);
}

dependencies{
   if(rootProject.ext.Production == "flavor1"){
      releaseCompile "compile with flavor1"
   }else{
      releaseCompile "compile with flavor2"
   }
}

simply write

dependencies{
   if(System.properties.P == 'flavor1'){
      releaseCompile 'compile with flavor1'
   }else{
      releaseCompile 'compile with flavor2'
   }
}

or if you need it as variable on the rootProject because of subprojects needing the value in their build file

rootProject.ext.Production = System.properties.P;

dependencies{
   if(rootProject.Production == 'flavor1'){
      releaseCompile 'compile with flavor1'
   }else{
      releaseCompile 'compile with flavor2'
   }
}

If you just need it in the same build file multiple times, a local variable would also do, no need for a project ext-property

def production = System.properties.P;

dependencies{
   if(production == 'flavor1'){
      releaseCompile 'compile with flavor1'
   }else{
      releaseCompile 'compile with flavor2'
   }
}

Besides that, I wouldn't use a system property, but a project property.
Just use

dependencies{
   if(production == 'flavor1'){
      releaseCompile 'compile with flavor1'
   }else{
      releaseCompile 'compile with flavor2'
   }
}

and call it with gradlew assembleRelease -P production=flavor1