Combined BuildConfig variables in gradle flavor dimensions
Asked Answered
E

3

8

In my Android application I have two flavor dimensions: "brand" (brand1, brand2) and "environment" (staging, production). I added the "environment" dimension after a while and I had previously defined some BuildConfig variables for the different brands. To be more specific, I defined the BASE_URL like this:

flavorDimensions 'brand'
productFlavors {

    brand1 {
        dimension 'brand'
        ...
        buildConfigField "String", "BASE_URL", "\"http://brand.one.api/\""
        ...
    }

    brand2 {
        dimension 'brand'
        ...
        buildConfigField "String", "BASE_URL", "\"http://brand.two.api/\""
        ...
    }
}

Now, I added the "environment" dimension and what I'd like to set are four different endpoints:

  1. Brand1-staging: "http://brand.one.staging.api/"
  2. Brand1-production: "http://brand.one.production.api/"
  3. Brand2-staging: "http://brand.two.staging.api/"
  4. Brand2-production: "http://brand.two.production.api/"

But I can't figure out how to create a BuildConfig variable for a specific combination of flavor dimensions. Is this even possible with bare gradle?

Thanks

Effector answered 24/10, 2016 at 7:50 Comment(0)
E
2

After some further investigation I found a similar question here.

It seems you need to add a function to iterate build variant names and check if they match some desired name.

My problem was that actually I had 3 dimensions: "brand", "environment" and "api" (15 for production and 21 for debugging with instant run). So the variants name would look like brand1Api15StagingDebug, ..., brand2Api21ProductionRelease, ... etc.

What I needed here was some groovy regex matching combined with the linked question above. Finally the function I made looks like this:

android.applicationVariants.all { variant ->
    if (variant.getName() ==~ /brand1Api[0-9]{2}Staging.*/) {
        variant.buildConfigField "String", "BASE_URL", "\"http://brand.one.staging.api//\""
    } else if(variant.getName() ==~ /brand1Api[0-9]{2}Production.*/){
        variant.buildConfigField "String", "BASE_URL", "\"http://brand.one.production.api/\""
    } else if(variant.getName() ==~ /brand2Api[0-9]{2}Staging.*/) {
        variant.buildConfigField "String", "BASE_URL", "\"http://brand.two.staging.api//\""
    } else if(variant.getName() ==~ /brand2Api[0-9]{2}Production.*/){
        variant.buildConfigField "String", "BASE_URL", "\"http://brand.two.production.api/\""
    } else {
        throw new Exception("Unexpected variant name: " + variant.getName())
    }
}

I added an exception throw at the end of the chain so if anyone changes the variant names to ones unchecked here, the build would fail. This is important to avoid building applications with wrong endpoints.

Works like a charm.

Effector answered 24/10, 2016 at 8:26 Comment(1)
Please, have a look at my solution, I think it takes the best part of your solution and makes it a bit more readable.Dahliadahlstrom
C
2

I did some thing like this , Having combination of flavour and brand together

flavorDimensions "brand", "server"
productFlavors {

    brand1 {
        dimension 'brand'
        ...
        buildConfigField "String", "BASE_URL_STAGING", "\"http://brand.one.staging.api/\""
        buildConfigField "String", "BASE_URL_PRODUCTION", "\"http://brand.one.production.api/\""
        ...
    }

    brand2 {
        dimension 'brand'
        ...
        buildConfigField "String", "BASE_URL_STAGING", "\"http://brand.two.staging.api/\""
        buildConfigField "String", "BASE_URL_PRODUCTION", "\"http://brand.two.production.api/\""
        ...
    }

    staging {
        dimension 'server'
        buildConfigField "String", "BASE_URL", 'BuildConfig.BASE_URL_STAGING'
    }

     production {
       dimension 'server'
       buildConfigField "String", "BASE_URL", 'BuildConfig.BASE_URL_PRODUCTION'

    }


}
Chancellorship answered 7/12, 2022 at 17:30 Comment(0)
D
1

You can define one flavor dimension to have multiple values to choose one specific value later on. First, add those values to flavors:

productFlavors.all {
    ext.myAnalyticsUrl = [dev: null, test: null, production: null]
}

Then define all values for one flavor:

    flavor1 {
            dimension "region"
            myAnalyticsUrl = [
                    dev: *devUrl*,
                    test: *testUrl*,
                    production: *productionUrl*
            ]
    }

    dev {
            dimension "environment"
            ...
    }
    test {
            dimension "environment"
            ...
    }
    production {
            dimension "environment"
            ...
    }

Now outside of android scope:

android.applicationVariants.all { variant ->

    def regionFlavor = variant.productFlavors.find{ flavor -> flavor.getFlavorDimension() == "region" }
    def environmentFlavor = variant.productFlavors.find{ flavor -> flavor.getFlavorDimension() == "environment" }

    def analyticsUrl = regionFlavor.myAnalyticsUrl[environmentFlavor.name]
}

Hope it helps!

Dahliadahlstrom answered 10/4, 2023 at 21:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.