Reputation: 1406
I have two product flavors for my app:
productFlavors {
europe {
buildConfigField("Boolean", "BEACON_ENABLED", "false")
}
usa {
buildConfigField("Boolean", "BEACON_ENABLED", "true")
}
}
Now I want to get the current flavor name (which one I selected in Android Studio) inside a task to change the path:
task copyJar(type: Copy) {
from('build/intermediates/bundles/' + FLAVOR_NAME + '/release/')
}
How can I obtain FLAVOR_NAME in Gradle?
Thanks
Upvotes: 86
Views: 89704
Reputation: 1659
Here is the "official" getFlavour() function you may find in react-native-config
package. Probably it's most accurate.
def getCurrentFlavor() {
Gradle gradle = getGradle()
// match optional modules followed by the task
// (?:.*:)* is a non-capturing group to skip any :foo:bar: if they exist
// *[a-z]+([A-Za-z]+) will capture the flavor part of the task name onward (e.g., assembleRelease --> Release)
def pattern = Pattern.compile("(?:.*:)*[a-z]+([A-Z][A-Za-z0-9]+)")
def flavor = ""
gradle.getStartParameter().getTaskNames().any { name ->
Matcher matcher = pattern.matcher(name)
if (matcher.find()) {
flavor = matcher.group(1).toLowerCase()
return true
}
}
return flavor
}
Upvotes: 0
Reputation: 1446
I have developed the following function, returning exactly the current flavor name:
def getCurrentFlavor() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern
if( tskReqStr.contains( "assemble" ) ) // to run ./gradlew assembleRelease to build APK
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
else if( tskReqStr.contains( "bundle" ) ) // to run ./gradlew bundleRelease to build .aab
pattern = Pattern.compile("bundle(\\w+)(Release|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")
Matcher matcher = pattern.matcher( tskReqStr )
if( matcher.find() )
return matcher.group(1).toLowerCase()
else
{
println "NO MATCH FOUND"
return ""
}
}
You need also
import java.util.regex.Matcher
import java.util.regex.Pattern
at the beginning or your script. In Android Studio this works by compiling with "Make Project" or "Debug App" button.
def getCurrentVariant() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern
if (tskReqStr.contains("assemble"))
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")
Matcher matcher = pattern.matcher(tskReqStr)
if (matcher.find()){
return matcher.group(2).toLowerCase()
}else{
println "NO MATCH FOUND"
return ""
}
}
A similar question could be: how to get the applicationId? Also in this case, there is no direct way to get the current flavor applicationId. Then I have developed a gradle function using the above defined getCurrentFlavor function as follows:
def getCurrentApplicationId() {
def currFlavor = getCurrentFlavor()
def outStr = ''
android.productFlavors.all{ flavor ->
if( flavor.name==currFlavor )
outStr=flavor.applicationId
}
return outStr
}
Voilà.
Upvotes: 109
Reputation: 2699
Just add the following in your build.gradle
(app level)
def getCurrentFlavour() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
print(tskReqStr.toString())
Pattern pattern;
if( tskReqStr.contains( "assemble" ))
pattern = Pattern.compile("assemble(\\w+)(Release|Staging|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Staging|Debug)")
Matcher matcher = pattern.matcher( tskReqStr )
if( matcher.find() ) {
def value = matcher.group(1).toLowerCase()
return value
} else {
return "";
}
}
Now Inside android
tag,
android {
// android tag starts
defaultConfig {
- - - - - - - -
- - - - - - - -
}
- - - - - - - -
- - - - - - - -
def flavourName = getCurrentFlavour()
if (flavourName == "Dev") {
println("This is Dev")
} else if (flavourName == "Staging") {
println("This is Staging")
} else if (flavourName == "Production") {
println("This is Production")
} else {
println("NA")
}
// android tag ends
}
Now Sync & Build your project.
Upvotes: 2
Reputation: 2309
A combination of aforementioned snippets was needed for me to get this to work.
My full answer to the original question would look like this:
android {
...
applicationVariants.all { variant ->
task "${variant.getName()}CopyJar"(type: Copy) {
from("build/intermediates/bundles/${variant.getFlavorName()}/release/")
}
}
}
This creates a <variant>CopyJar
task for each variant, which you can then run manually.
Upvotes: 1
Reputation: 7076
How to get the flavor name or build variant from a prebuild
task? This is what solved my issue. I added getCurrentFlavor()
or getCurrentVariant()
(from @Poiana Apuana answer) into my task's dependOn
like so:
task getCurrentFlavor() {
// paste Poiana Apuana's answer
}
// OR
//task getCurrentVariant() {
// // paste Poiana Apuana's answer
//}
task myTask(type: Copy) {
dependsOn getCurrentFlavor
// or dependsOn getCurrentVariant
println "flavor name is $projectName"
...
}
preBuild.dependsOn myTask
Check original problem here.
Upvotes: 0
Reputation: 987
Use:
${variant.baseName}.apk"
This return current flavor name
Full Answer
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.baseName}.apk"
}
}
Upvotes: 4
Reputation: 383
I use this
${variant.getFlavorName()}.apk
to format file name output
Upvotes: 29
Reputation: 3625
I slightly changed Poiana Apuana's answer since my flavor has some capital character.
REASON
gradle.getStartParameter().getTaskRequests().toString()
contains your current flavor name but the first character is capital.
However, usually flavor name starts with lowercase. So I forced to change first character to lowercase.
def getCurrentFlavor() {
Gradle gradle = getGradle()
String taskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern
if (taskReqStr.contains("assemble")) {
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
} else {
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")
}
Matcher matcher = pattern.matcher(taskReqStr)
if (matcher.find()) {
String flavor = matcher.group(1)
// This makes first character to lowercase.
char[] c = flavor.toCharArray()
c[0] = Character.toLowerCase(c[0])
flavor = new String(c)
println "getCurrentFlavor:" + flavor
return flavor
} else {
println "getCurrentFlavor:cannot_find_current_flavor"
return ""
}
}
Upvotes: 6
Reputation: 2903
get SELECTED_BUILD_VARIANT from the .iml file after gradle sync completes You can either load it using an xml parser, or less desireable, but probably faster to implement would be to use a regex to find it.
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="your_build_flavorDebug" />
...
(not tested, something like this:)
/(?=<name="SELECTED_BUILD_VARIANT".*value=")[^"]?/
Upvotes: 4
Reputation: 227
you should use this,${variant.productFlavors[0].name}
,it will get productFlavors both IDE and command line.
Upvotes: 14
Reputation: 127
my solution was in that to parse gradle input parameters.
Gradle gradle = getGradle()
Pattern pattern = Pattern.compile(":assemble(.*?)(Release|Debug)");
Matcher matcher = pattern.matcher(gradle.getStartParameter().getTaskRequests().toString());
println(matcher.group(1))
Upvotes: 6
Reputation: 3150
This is what I used some time ago. I hope it's still working with the latest Gradle plugin. I was basically iterating through all flavours and setting a new output file which looks similar to what you are trying to achieve.
applicationVariants.all { com.android.build.gradle.api.ApplicationVariant variant ->
for (flavor in variant.productFlavors) {
variant.outputs[0].outputFile = file("$project.buildDir/${YourNewPath}/${YourNewApkName}.apk")
}
}
Upvotes: 7