Rotem
Rotem

Reputation: 2356

How to use gradle and proguard printmapping to create out.map file with version code

I'm using this file to build the release.apk file.

android {
   compileSdkVersion 21
   buildToolsVersion '20.0.0'
   signingConfigs {
      ...
   }
   buildTypes {
    debug {
        debuggable true
        jniDebugBuild true
    }
    release {
        runProguard true
        proguardFile('proguard-project.txt')
        debuggable false
        signingConfig signingConfigs.release
       }
   }
   defaultConfig {
       minSdkVersion 14
       targetSdkVersion 21
   }
   productFlavors {
   }
   lintOptions {
    disable 'ValidFragment'
   }

}

in the proguard-project.txt I have this:

-printmapping build\outputs\apk\out.map

everything is working great, all I want to do it that the out.map file name will contain the version code, for example out.29.map where 29 is the version code.

Thanks

Upvotes: 1

Views: 2229

Answers (2)

Ryhan
Ryhan

Reputation: 1885

Here's a lightweight plugin that checks the default directory of where the mapping file should be and appends the version, versionCode and timestamp to the file. If you've explicitly gave proguard another path inside of proguard configuration with -printmapping there's a way to specify that path to the plug-in in your build.gradle:

apply plugin: 'com.android.application'
apply plugin: ProguardMapFileVersioning

proguardmapfileversioning.proguardPath = "app\\mapping.txt"

Plugin source code:

class ProguardMapFileVersioning implements Plugin<Object> {
    @Override
    public void apply(Object object) {
        try {
            Project project = null
            if (object != null)
                project = (Project) object

            if (project != null) {
                project.extensions.create("proguardmapfileversioning", ProguardMapFileVersioningExtension)
                project.task('ProguardMapFileVersioning') {
                    project.gradle.taskGraph.afterTask { Task task, TaskState taskState ->

                        AppExtension android = (AppExtension) project.extensions.findByName("android")
                        String versionName = android.defaultConfig.versionName
                        String versionCode = android.defaultConfig.versionCode

                        String taskName = 'assembleRelease'
                        if (task.name.startsWith('assemble') &&
                                task.name.endsWith('Release')) {
                            try {
                                String _default = "app\\build\\outputs\\apk\\mapping.txt"
                                String proguardPath = project.proguardmapfileversioning.proguardPath
                                if (proguardPath == null || proguardPath.isEmpty()) {
                                    proguardPath = _default
                                    println("Proguard mapping file path not specified, default to " + _default)
                                }
                                println("Proguard path: " + proguardPath)
                                File f = new File(proguardPath)
                                if (!f.exists()) {
                                    println("Mapping file: " + f.getAbsolutePath() + " does not exist, exiting..")
                                    return
                                } else {
                                    println("Found mapping file, continuing..")
                                }
                                String oldName = f.getName()

                                int index = oldName.lastIndexOf(".")
                                String nameWithoutExt
                                String ext
                                if (index > 0) {
                                    ext = oldName.substring(index)

                                    if (!ext == '.txt' && !ext == '.map') {
                                        println("Please provide a supported mapping file extension (.txt or .map) ... exiting.")
                                        return
                                    }

                                    nameWithoutExt = oldName.substring(0, index)
                                } else {
                                    println("Please provide mapping file extension.. exiting.")
                                    return
                                }
                                println("Extension type: " + ext)

                                String newName = nameWithoutExt + versionName +
                                        "(" + versionCode + ")" + "_" + getDate() + ext
                                f.renameTo(newName)

                                println("SUCCESS! Proguard mapping file has been renamed from " + oldName + " to " + newName)

                                if (proguardPath == _default)
                                    println("The new mapping file may have also been moved to inside the app/ directory")

                            } catch (ClassCastException e) {
                                e.printStackTrace()
                            }
                        }
                    }
                }
            } else {
                println("Object is null.")
            }
        } catch (ClassCastException e) {
            e.printStackTrace()
            println("Object != Project")
        }
    }

    def static getDate() {
        def d = new Date()
        def f = d.format('yyyy-MM-dd\'T\'HHmmss')
        return f
    }
}

class ProguardMapFileVersioningExtension {
    def String proguardPath = "app\\build\\outputs\\apk\\mapping.txt"
}

Upvotes: 0

Rotem
Rotem

Reputation: 2356

So, this is how it done

first define a function to get the version name

def getVersionName() {
    File stringsXmlFile = new File("src\\main\\res\\values\\strings.xml")
    String contents = stringsXmlFile.getText()
    String version = contents.find("<string name=\"version\">[^<]*</string>");
    version = version.replace("<string name=\"version\">", "").replace("string>", "")
    version = version.replace("<", "")
    version = version.substring(0, version.length() - 1)

    return version
}

second, define after task function

gradle.taskGraph.afterTask { Task task, TaskState state ->
    if (task.name.equals("assembleRelease")) {

        File proguard = new File("build\\outputs\\apk\\out.map")
        proguard.renameTo("build\\outputs\\apk\\out-" + getVersionName() + ".map")

    }
}

that's it.

Upvotes: 1

Related Questions