
com.mcxiaoke.packer.ng.ArchiveAllApkTask.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of plugin Show documentation
Show all versions of plugin Show documentation
Next Generation Android Multi Packer Gradle Plugin
package com.mcxiaoke.packer.ng
import com.android.build.gradle.api.BaseVariant
import com.android.builder.model.SigningConfig
import com.mcxiaoke.packer.cli.PackerNgUtils
import groovy.io.FileType
import groovy.text.SimpleTemplateEngine
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.InvalidUserDataException
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import java.text.SimpleDateFormat
/**
* User: mcxiaoke
* Date: 15/11/23
* Time: 14:40
*/
class ArchiveAllApkTask extends DefaultTask {
static final TAG = PackerNgPlugin.TAG
@Input
BaseVariant theVariant
@Input
PackerNgExtension theExtension
@Input
List theMarkets
ArchiveAllApkTask() {
setDescription('modify original apk file and move to release dir')
}
@TaskAction
void showMessage() {
project.logger.info("${name}: ${description}")
}
void checkMarkets() throws GradleException {
if (theMarkets == null || theMarkets.isEmpty()) {
throw new InvalidUserDataException(":${name} " +
"no markets found, please check your market file!")
}
}
SigningConfig getSigningConfig() {
def config1 = theVariant.buildType.signingConfig
def config2 = theVariant.mergedFlavor.signingConfig
return config1 == null ? config2 : config1
}
void checkSigningConfig() throws GradleException {
logger.info(":${name} buildType.signingConfig = " +
"${theVariant.buildType.signingConfig}")
logger.info(":${name} mergedFlavor.signingConfig = " +
"${theVariant.mergedFlavor.signingConfig}")
def signingConfig = getSigningConfig()
if (theExtension.checkSigningConfig && signingConfig == null) {
throw new GradleException(":${project.name}:${name} " +
"signingConfig not found, task aborted, " +
"please check your signingConfig!")
}
}
void checkApkSignature(File file) throws GradleException {
File apkPath = project.rootDir.toPath().relativize(file.toPath()).toFile()
boolean apkVerified = PackerNgUtils.verifyApk(apkPath)
if (!apkVerified) {
throw new GradleException(":${name} " +
"apk ${apkPath} not v2 signed, please check your signingConfig!")
}
}
@TaskAction
void modify() {
logger.info("====================PACKER APK TASK BEGIN====================")
checkMarkets()
checkSigningConfig()
File originalFile = theVariant.outputs[0].outputFile
checkApkSignature(originalFile)
File outputDir = theExtension.archiveOutput
File apkPath = project.rootDir.toPath().relativize(originalFile.toPath()).toFile()
println(":${project.name}:${name} apk: ${apkPath}")
logger.info(":${name} output dir:${outputDir.absolutePath}")
if (!outputDir.exists()) {
outputDir.mkdirs()
} else {
logger.info(":${name} delete old apks in ${outputDir.absolutePath}")
// delete old apks
outputDir.eachFile(FileType.FILES) { file ->
if (file.getName().endsWith(".apk")) {
file.delete()
}
}
}
logger.info(":${project.name}:${name} markets:[${theMarkets.join(', ')}]")
for (String market : theMarkets) {
File tempFile = new File(outputDir, market + ".tmp")
copyTo(originalFile, tempFile)
try {
PackerNgUtils.writeChannel(tempFile, market)
String apkName = buildApkName(theVariant, market, tempFile)
File finalFile = new File(outputDir, apkName)
if (PackerNgUtils.verifyChannel(tempFile, market)) {
println(":${project.name}:${name} Generating apk for ${market}")
tempFile.renameTo(finalFile)
} else {
throw new GradleException(":${name} ${market} apk verify failed.")
}
} catch (IOException ex) {
throw new GradleException(":${name} ${market} apk generate failed.", ex)
} finally {
tempFile.delete()
}
}
println(":${project.name}:${name} all ${theMarkets.size()} apks saved to ${outputDir.path}")
println("\nPackerNg Build Successful!")
logger.info("====================PACKER APK TASK END====================")
}
/**
* build human readable apk name
* @param variant Variant
* @return final apk name
*/
String buildApkName(variant, market, apkFile) {
def buildTime = new SimpleDateFormat('yyyyMMdd-HHmmss').format(new Date())
File file = apkFile
def fileMD5 = HASH.md5(file)
def fileSHA1 = HASH.sha1(file)
def nameMap = [
'appName' : project.name,
'projectName': project.rootProject.name,
'fileMD5' : fileMD5,
'fileSHA1' : fileSHA1,
'flavorName' : market,
'buildType' : variant.buildType.name,
'versionName': variant.versionName,
'versionCode': variant.versionCode,
'appPkg' : variant.applicationId,
'buildTime' : buildTime
]
def defaultTemplate = PackerNgExtension.DEFAULT_NAME_TEMPLATE
def engine = new SimpleTemplateEngine()
def template = theExtension.archiveNameFormat == null ? defaultTemplate : theExtension.archiveNameFormat
def fileName = engine.createTemplate(template).make(nameMap).toString()
return fileName + '.apk'
}
static void copyTo(File src, File dest) {
def input = src.newInputStream()
def output = dest.newOutputStream()
output << input
input.close()
output.close()
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy