Gradle編譯時所有Task信息打印

Gradle工程編譯的過程,就是執行目標task的過程,如果task存在依賴,則先執行依賴task,如此反覆,直到觸達無依賴的task

就這樣,從無依賴task -> 目標task的執行鏈即建立,接着依次執行task即可,每個task之間數據傳輸,主要是通過task inputs和outputs描述文件來完成的

所以,gradle編譯所有task信息的打印,應該包含

  1. 按task執行順序打印task name
  2. 可以打印task的inputs和outputs數據
  3. 將輸出json信息保存到本地文件

我寫了一個gradle腳本來完成上述信息輸出:

import groovy.json.JsonOutput

//輸出數據結構
class TaskItem{
    String aname
    List<String> inputs = new ArrayList<>()
    List<String> outputs = new ArrayList<>()
}

class Dumper{
    //正則表達式,用於過濾要dump inputs和outputs的task
    //這裏配置名稱包含Jni的task,大家可以根據需要自行配置
    String taskInOutDirDumpFilter = "^.*Jni.*"
    String type
    File logOutDir
    List<TaskItem> taskList = new ArrayList<>()
    File logfile
    boolean isAvaliable = false

    Dumper(String type, File dir){
        this.type = type
        this.logOutDir = dir
    }

    def makeLogFile(){
        logfile = new File(logOutDir, "taskdump-${type}.json")
        if (logfile.exists()) {
            logfile.delete()
        }

        logfile.createNewFile()
    }

    def collectData(Task t){
        t.doFirst {
            if (name == "pre${type}Build" && !isAvaliable){
                isAvaliable = true
                makeLogFile()
            }

            if (!isAvaliable){
                return
            }

            TaskItem item = taskList.find {
                it.aname == path
            }

            if (item != null){
                return
            }

            item = new TaskItem()
            item.aname = path

            taskList.add(item)

            def matcher = name =~ taskInOutDirDumpFilter
            if (matcher.size() > 0){
                println "-------match task path = ${path}"

                t.inputs.each {
                    it.files.each {
                        item.inputs.add(it.absolutePath)
                    }
                }

                t.outputs.each {
                    it.files.each {
                        item.outputs.add(it.absolutePath)
                    }
                }
            }
        }
    }

    def dumpData2File(){
//        println " ------- dumpData2File " + logfile.getPath()
        def s = JsonOutput.toJson(taskList)

        logfile.write(s)
    }
}

Map<String, Dumper> dumperMap = new HashMap<>()
//數據dump目錄
def dumpDir = new File(buildDir, "taskdump")
if (!dumpDir.exists()){
    dumpDir.mkdirs()
}

rootProject.childProjects.each {
        it.value.afterEvaluate {Project pp ->
        def isAndroidLibrary = pp.plugins.hasPlugin("com.android.library")
        def variants = isAndroidLibrary ? pp.android.libraryVariants : pp.android.applicationVariants

        variants.all { def variant ->
            // Create variant and target names
            def targetName = variant.name.capitalize()
            def dumper = dumperMap.get(targetName)

            if (dumper == null){
                dumper = new Dumper(targetName, dumpDir)
                dumperMap.put(targetName, dumper)
            }

            pp.tasks.each {
                dumper.collectData(it)
            }
        }
    }
}

gradle.buildFinished {
    dumperMap.each {
        if (it.value.isAvaliable){
            it.value.dumpData2File()
        }
    }
}

將腳本命名並保存到工程目錄下,比如dumptask.gradle,並保存道app module的根目錄,接着再app module的build.gradle引入

apply from: "dumptask.gradle"

接着執行

./gradlew assembleDebug

執行結束後, dump信息保存到如下文件

app/build/taskdump/taskdump-Debug.json
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章