// Gradle script for generating serialized public app config (from app.config.js/ts or app.json) and bundling it into the APK import org.apache.tools.ant.taskdefs.condition.Os import org.gradle.util.GradleVersion void runBefore(String dependentTaskName, Task task) { Task dependentTask = tasks.findByPath(dependentTaskName); if (dependentTask != null) { dependentTask.dependsOn task } } def expoConstantsDir = ["node", "-e", "console.log(require('path').dirname(require.resolve('expo-constants/package.json')));"].execute(null, projectDir).text.trim() def config = project.hasProperty("react") ? project.react : []; def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"] afterEvaluate { def projectRoot = file("${rootProject.projectDir}") def inputExcludes = ["android/**", "ios/**"] if (!android.hasProperty('libraryVariants')) { // For traditional application level integration, will be no-op to prevent duplicated app.config creation. return; } android.libraryVariants.each { variant -> def targetName = variant.name.capitalize() def targetPath = variant.dirName def assetsDir = file("$buildDir/generated/assets/expo-constants/${targetPath}") def currentBundleTask = tasks.create( name: "create${targetName}ExpoConfig", type: Exec) { description = "expo-constants: Create config for ${targetName}." doFirst { assetsDir.deleteDir() assetsDir.mkdirs() } // Set up inputs and outputs so gradle can cache the result inputs.files fileTree(dir: projectRoot, excludes: inputExcludes) outputs.dir assetsDir // Switch to project root and generate the app config workingDir projectRoot if (Os.isFamily(Os.FAMILY_WINDOWS)) { commandLine("cmd", "/c", *nodeExecutableAndArgs, "$expoConstantsDir/scripts/getAppConfig.js", projectRoot, assetsDir) } else { commandLine(*nodeExecutableAndArgs, "$expoConstantsDir/scripts/getAppConfig.js", projectRoot, assetsDir) } } def currentCopyAppConfigTask = tasks.create( name: "copy${targetName}ExpoConfig", type: Copy) { description = "expo-constants: Copy generated app.config into ${targetName}." from(assetsDir) into("${projectDir}/src/main/assets") include('app.config') dependsOn(currentBundleTask) } def currentCleanupAppConfigTask = tasks.create( name: "cleanup${targetName}ExpoConfig", type: Delete) { description = "expo-constants: Cleanup generated app.config from ${targetName}." delete files("${projectDir}/src/main/assets/app.config") } // In summary, these tasks try to create `src/main/assets/app.config` in building time for gradle to merge the asset. // And cleanup the generated app.config after building time. def packageTask = tasks.findByPath("package${targetName}Assets") packageTask.dependsOn(currentCopyAppConfigTask) currentCleanupAppConfigTask.dependsOn(packageTask) runBefore("process${targetName}JavaRes", currentCleanupAppConfigTask) } }