Gradle – Build Sass Per ProductFlavor (Multi-Folder)

Introduction

This article explores how to structure and build Sass files for different product flavors in your Android project using Gradle, especially when dealing with multiple folders.

Project Setup

1. Project Structure

Organize your Sass files based on product flavors. Example structure:

src/
├── main/
│   └── assets/
│       └── sass/
│           └── shared/
│               └── styles.scss
├── flavor1/
│   └── assets/
│       └── sass/
│           └── flavor1/
│               └── styles.scss
└── flavor2/
    └── assets/
        └── sass/
            └── flavor2/
                └── styles.scss

2. Gradle Configuration

android {
    ...
    productFlavors {
        flavor1 {
            ...
            sourceSets {
                main.assets.srcDirs += 'src/flavor1/assets'
            }
        }
        flavor2 {
            ...
            sourceSets {
                main.assets.srcDirs += 'src/flavor2/assets'
            }
        }
    }
    ...
}

3. Dependencies

Add the necessary dependencies to your `build.gradle` (Module: app):

dependencies {
    implementation "androidx.core:core-ktx:1.8.0"
    implementation "androidx.appcompat:appcompat:1.5.1"
    implementation "com.google.android.material:material:1.7.0"

    implementation 'com.github.jraska:intellij-gradle-plugin:1.1.0' // Optional: for IDE integration

    implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.7.20'

    // Sass & Libsass
    implementation 'com.github.xamarin:Android.tools.libsass:1.5.1' // For older projects 
    // or
    implementation("io.github.novacrypto:libsass-android:1.2.0") // Newer libsass
}

Building Sass with Gradle

1. Customize Sass Build Task

Create a custom Gradle task to handle Sass compilation. You can use a plugin like `intellij-gradle-plugin` to help manage this.

task buildSass(type: Exec) {
    doFirst {
        // Ensure the output directory exists
        file("build/sass").mkdirs()
    }

    workingDir "build/sass"
    commandLine "sass", "--no-cache", "--output-style", "compressed", "--load-path", "src/main/assets/sass/shared", "--load-path", "src/flavor1/assets/sass/flavor1" // Paths need to be adjusted based on your project
    dependsOn ':app:flavor1DebugAssets' // Or your respective build task
    doLast {
        // If your project uses product flavors, you might need to generate separate CSS files for each flavor
        copy {
            from("build/sass")
            into "build/sass/flavor1/"
        }
    }
}
// Sample output for flavor1 (assuming a styles.scss file)
build/sass/flavor1/
    styles.css

2. Include Build Sass Task

Ensure your `buildSass` task runs as part of the build process.

android {
    ...
    buildTypes {
        debug {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets.main.assets.srcDirs += 'src/main/assets'

    productFlavors {
        flavor1 {
            ...
            sourceSets {
                main.assets.srcDirs += 'src/flavor1/assets'
            }
            applicationId 'com.example.your_app.flavor1'
            resValue "string", "app_name", "Your App - Flavor 1"

            buildConfigField "String", "FLAVOR", "\"Flavor 1\""

            buildConfigField "String", "DEBUG_HOST", "\"https://api.example.com/flavor1\""
            buildConfigField "Boolean", "IS_DEBUG", "true"

        }
        flavor2 {
            ...
            sourceSets {
                main.assets.srcDirs += 'src/flavor2/assets'
            }
            applicationId 'com.example.your_app.flavor2'
            resValue "string", "app_name", "Your App - Flavor 2"

            buildConfigField "String", "FLAVOR", "\"Flavor 2\""

            buildConfigField "String", "DEBUG_HOST", "\"https://api.example.com/flavor2\""
            buildConfigField "Boolean", "IS_DEBUG", "true"
        }
    }

    // Build your Sass
    tasks.register('buildSass') {
        it.dependsOn ':app:assemble' // For example, you can make buildSass run after ':app:assemble'
    }

}

Including CSS in your project

After building your Sass files, you need to include the generated CSS in your Android project.

// In your layout file (example: activity_main.xml)


// In your styles.xml

    

// In your colors.xml

    #3F51B5
    #303F9F
    #FF4081
    #FFFFFF

Comparison Table

Feature Main (Shared) Flavor 1 Flavor 2
Sass Files src/main/assets/sass/shared/styles.scss src/flavor1/assets/sass/flavor1/styles.scss src/flavor2/assets/sass/flavor2/styles.scss
CSS Output (Not applicable) build/sass/flavor1/styles.css build/sass/flavor2/styles.css

Benefits

  • Code Organization: Separate Sass files for each product flavor improve code clarity and maintainability.
  • Customization: Easily apply specific styles based on product flavors, reducing the need for conditional logic in Sass.
  • Improved Build Process: Automates Sass compilation as part of the build process, ensuring CSS files are up-to-date.

Conclusion

By using Gradle tasks and properly structuring your Sass files, you can efficiently build Sass for different product flavors. This approach ensures a clean, customizable, and manageable codebase for your Android projects.


Leave a Reply

Your email address will not be published. Required fields are marked *