// generate proguard config for log class LogProguardRuleTask extends DefaultTask { @Input String projectName @Input String[] proguardClassList @Input String currentLogLevel @OutputFile File logProguardFile private ArrayList removeLogLevels private HashMap allowedLogLevels LogProguardRuleTask() { removeLogLevels = new ArrayList<>() allowedLogLevels = [VERBOSE: "v", DEBUG : "d", INFO : "i", WARN : "w", ERROR : "e"] } private void updateProguardFile() { File file = logProguardFile if (file.exists()) { file.delete() } file.createNewFile() file.append("\n" + genProguardRules()) } private String genProguardRules() { def rules = "" for (String logClass : proguardClassList) { def rule = genLogRules(logClass, removeLogLevels) logger.lifecycle(rule) rules += rule } return rules } private String genLogRules(clazz, levels) { def sb = new StringBuilder() sb.append(String.format("-assumenosideeffects class %s{\n", clazz)) for (String level : levels) { sb.append(String.format(" public static *** %s(...);\n", level)) } sb.append("}\n") return sb.toString() } @TaskAction void doTaskAction() { println("proguard.gradle, LogProguardRuleTask, doTaskAction()") logger.debug("proguard.gradle, LogProguardRuleTask, doTaskAction()") if (project.name != projectName) { return } if (!project.hasProperty("LOG_LEVEL")) { return } logger.debug("gradle param log level: ${currentLogLevel}") for (def i = 0; i < allowedLogLevels.size(); i++) { if (allowedLogLevels.keySet()[i] != currentLogLevel.toUpperCase()) { removeLogLevels.add(allowedLogLevels.values()[i]) } else { break } } logger.debug("proguard log level: " + removeLogLevels) updateProguardFile() } } def genLogProguardFileTask = tasks.register("genLogProguardFile", LogProguardRuleTask) { projectName = "app" proguardClassList = ["android.util.Log", "com.adealink.frame.log.Log"] currentLogLevel = System.getenv("LOG_LEVEL") if (currentLogLevel == null || currentLogLevel == "") { currentLogLevel = project.hasProperty("LOG_LEVEL") ? project.property("LOG_LEVEL") : "NONE" } logProguardFile = new File(project.buildFile.getParent() + File.separator + "proguard-log.pro") } // remove low level log before compile, since proguard can't remove the concat log clearly class RemoveConcatLogTask extends DefaultTask { @Input String projectName @Input String[] proguardClassList @Input String currentLogLevel private HashMap allowedLogLevels RemoveConcatLogTask() { allowedLogLevels = [VERBOSE: "v", DEBUG : "d", INFO : "i", WARN : "w", ERROR : "e"] } @TaskAction void doTaskAction() { if (project.name != projectName) { return } def paramLevel = "" for (int i = 0; i < allowedLogLevels.size(); i++) { if (allowedLogLevels.keySet()[i] != currentLogLevel.toUpperCase()) { paramLevel += allowedLogLevels.values()[i] + " " } else { break } } def paramClass = "" for (def logClass : proguardClassList) { paramClass += logClass.split('\\.')[-1] + " " } if (paramClass.length() > 0 && paramLevel.length() > 0) { println("proguard.gradle, RemoveConcatLogTask, doTaskAction, python proguard-log paramClass:" + paramClass + " paramLevel:" + paramLevel) // project.exec { // workingDir "." // commandLine "python3", "proguard-log.py", "-c " + paramClass, "-l " + paramLevel // } } } } def emptyConcatLogStringTask = tasks.register("emptyConcatLogString", RemoveConcatLogTask) { projectName = "app" proguardClassList = ["android.util.Log", "com.adealink.frame.log.Log"] currentLogLevel = System.getenv("LOG_LEVEL") if (currentLogLevel == null || currentLogLevel == "") { currentLogLevel = project.hasProperty("LOG_LEVEL") ? project.property("LOG_LEVEL") : "NONE" } } android.applicationVariants.configureEach { if (it.buildType.name != "debug") { it.preBuildProvider.configure { dependsOn emptyConcatLogStringTask } } } tasks.named("preBuild").configure { dependsOn genLogProguardFileTask }