codepush.gradle 5.36 KB
Newer Older
silver47gin's avatar
silver47gin committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
// Adapted from https://raw.githubusercontent.com/facebook/react-native/d16ff3bd8b92fa84a9007bf5ebedd8153e4c089d/react.gradle

import java.nio.file.Paths;

def config = project.hasProperty("react") ? project.react : [];
def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"

// because elvis operator
def elvisFile(thing) {
    return thing ? file(thing) : null;
}

void runBefore(String dependentTaskName, Task task) {
    Task dependentTask = tasks.findByPath(dependentTaskName);
    if (dependentTask != null) {
        dependentTask.dependsOn task
    }
}

gradle.projectsEvaluated {
    android.buildTypes.each {
        // to prevent incorrect long value restoration from strings.xml we need to wrap it with double quotes
        // https://github.com/microsoft/cordova-plugin-code-push/issues/264
        it.resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())
    }
    
    android.applicationVariants.all { variant ->
        def nodeModulesPath;
        if (config.root) {
            nodeModulesPath = Paths.get(config.root, "/node_modules");
        } else if (project.hasProperty('nodeModulesPath')) {
            nodeModulesPath = project.nodeModulesPath
        } else {
            nodeModulesPath = "../../node_modules";
        }

        def targetName = variant.name.capitalize()
        def targetPath = variant.dirName

        def jsBundleDir;
        def resourcesDir;
        def jsBundleFile;

        // Additional node commandline arguments
        def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
        def extraPackagerArgs = config.extraPackagerArgs ?: []

        // Make this task run right after the bundle task
        def generateBundledResourcesHash;

        if (variant.hasProperty("bundleJsAndAssets")) {
            def reactBundleTask = variant.bundleJsAndAssets
            jsBundleDir = reactBundleTask.generatedAssetsFolders[0].absolutePath
            resourcesDir = reactBundleTask.generatedResFolders[0].absolutePath
            jsBundleFile = file("$jsBundleDir/$bundleAssetName")

            generateBundledResourcesHash = tasks.create(
                    name: "generateBundledResourcesHash${targetName}",
                    type: Exec) {
                commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/react-native-code-push/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir)

                enabled config."bundleIn${targetName}" ||
                config."bundleIn${variant.buildType.name.capitalize()}" ?:
                targetName.toLowerCase().contains("release")
            }   
        } else {
            def jsBundleDirConfigName = "jsBundleDir${targetName}"
            jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?:
                    file("$buildDir/intermediates/assets/${targetPath}")

            def resourcesDirConfigName = "resourcesDir${targetName}"
            resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?:
                    file("$buildDir/intermediates/res/merged/${targetPath}")

            // In case version of 'Android Plugin for Gradle'' is lower than 1.3.0 
            // '$buildDir' has slightly different structure - 'merged' folder
            // does not exists so '${targetPath}' folder contains directly in 'res' folder.
            if (!resourcesDir.exists() && file("$buildDir/intermediates/res/${targetPath}").exists()) {
                resourcesDir = file("$buildDir/intermediates/res/${targetPath}")
            }

            jsBundleFile = file("$jsBundleDir/$bundleAssetName")

            def resourcesMapTempFileName = "CodePushResourcesMap-" + java.util.UUID.randomUUID().toString().substring(0,8) + ".json"

            generateBundledResourcesHash = tasks.create(
                    name: "generateBundledResourcesHash${targetName}",
                    type: Exec) {
                commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/react-native-code-push/scripts/generateBundledResourcesHash.js", resourcesDir, jsBundleFile, jsBundleDir, resourcesMapTempFileName)
            }

            // Make this task run right before the bundle task
            def recordFilesBeforeBundleCommand = tasks.create(
                    name: "recordFilesBeforeBundleCommand${targetName}",
                    type: Exec) {
                commandLine (*nodeExecutableAndArgs, "${nodeModulesPath}/react-native-code-push/scripts/recordFilesBeforeBundleCommand.js", resourcesDir, resourcesMapTempFileName)
            }

            recordFilesBeforeBundleCommand.dependsOn("merge${targetName}Resources")
            recordFilesBeforeBundleCommand.dependsOn("merge${targetName}Assets")
            runBefore("bundle${targetName}JsAndAssets", recordFilesBeforeBundleCommand)

            // We need to generate and record the resources map, but we use it to generate the bundle hash
            generateBundledResourcesHash.dependsOn("recordFilesBeforeBundleCommand${targetName}")
        }

        generateBundledResourcesHash.dependsOn("bundle${targetName}JsAndAssets")
        runBefore("processArmeabi-v7a${targetName}Resources", generateBundledResourcesHash)
        runBefore("processX86${targetName}Resources", generateBundledResourcesHash)
        runBefore("processUniversal${targetName}Resources", generateBundledResourcesHash)
        runBefore("process${targetName}Resources", generateBundledResourcesHash)
    }
}