移除 cli

This commit is contained in:
v7lin
2022-11-11 11:55:57 +08:00
parent 9e22127727
commit 83a59ecbb6
6 changed files with 266 additions and 31 deletions

View File

@ -44,9 +44,11 @@ zipalign -p -f -v 4 input.apk output.apk
```groovy
// android/app/build.gradle
apply from: "${project(":walle_kit").projectDir}/walle_kit_v2.gradle" // 推荐非cli方式不支持360加固
apply from: "${project(":walle_kit").projectDir}/walle_kit_v3.gradle" // 推荐非cli方式不支持360加固、不支持腾讯乐固
// 或
apply from: "${project(":walle_kit").projectDir}/walle_kit.gradle" // 推荐cli方式支持360加固
apply from: "${project(":walle_kit").projectDir}/walle_kit_v2.gradle" // 推荐(cli方式支持360加固、支持腾讯乐固
// 或
apply from: "${project(":walle_kit").projectDir}/walle_kit.gradle" // 不推荐cli方式支持360加固、支持腾讯乐固
```
* fileNameFormat
@ -66,6 +68,11 @@ apply from: "${project(":walle_kit").projectDir}/walle_kit.gradle" // 不推荐
* [ - channel](example/android/app/channel)
* [ - channel.json](example/android/app/channel.json)
### walle_kit_v3.gradle
>
> walle_kit_v2.gradle
### walle_kit_v2.gradle
* without flavors

237
android/walle_kit_v3.gradle Normal file
View File

@ -0,0 +1,237 @@
//
//使用方法
//
//apply from: 'walle.gradle'
//
//android {
// productFlavors {
// prod {...}
// }
//
// walleConfigs {
// prod {
// enabled = true
//
// outputDir = file("${project.buildDir}/outputs/apk/${flavorName}/${buildType}/walle") // 默认file("${project.buildDir}/outputs/apk/${flavorName}/${buildType}/walle")
// fileNameFormat = '${appName}-${buildType}-${channelId}.apk' // 默认:'${appName}-${buildType}-${channelId}.apk'
//// channelType = 0 // 0默认1json
// channelFile = file('channel')
// }
// }
//}
//
//walle {
// enabled = false
//}
//
buildscript {
repositories {
google()
mavenCentral()
// 阿里云jcenter镜像
maven { url 'https://maven.aliyun.com/repository/jcenter' }
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.meituan.android.walle:payload_writer:1.1.7'
}
}
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
class Walle {
final String name
Boolean enabled
File outputDir
String fileNameFormat
Integer channelType
File channelFile
Walle(String name = 'default') {
this.name = name
}
// ---
void validate() {
if (enabled == null || !enabled.booleanValue()) {
return
}
if (channelType != null && channelType != 0 && channelType != 1) {
throw new RuntimeException("walle channel type is unsupported for variant '$name'")
}
if (channelFile == null) {
throw new RuntimeException("walle channel file is null for variant '$name'")
}
}
Walle mergeWith(Walle other) {
if (other == null) {
return this
}
def mergeWalle = new Walle(name == 'default' ? other.name : (other.name == 'default' ? name : "$name${other.name.capitalize()}"))
mergeWalle.enabled = other.enabled != null ? other.enabled : enabled
mergeWalle.outputDir = other.outputDir ?: outputDir
mergeWalle.fileNameFormat = other.fileNameFormat ?: fileNameFormat
mergeWalle.channelType = other.channelType ?: channelType
mergeWalle.channelFile = other.channelFile ?: channelFile
return mergeWalle
}
}
apply plugin: WallePlugin
class WallePlugin implements Plugin<Project> {
@Override
void apply(Project target) {
target.extensions.create('walle', Walle.class)
target.plugins.withId('com.android.application') {
def baseWalle = target.walle
def walleConfigs = target.container(Walle.class)
target.android.extensions.walleConfigs = walleConfigs
target.android.applicationVariants.whenObjectAdded { variant ->
def mergeWalle = null
List<Walle> flavorWalles = variant.productFlavors?.stream()?.map{flavor -> walleConfigs.findByName(flavor.name)}?.collect()?.toList() ?: Collections.emptyList()
def buildTypeWalle = walleConfigs.findByName(variant.buildType.name)
if (buildTypeWalle == null && (variant.buildType.name == 'debug' || variant.buildType.name == 'profile')) {
buildTypeWalle = new Walle(variant.buildType.name)
buildTypeWalle.enabled = false
}
// buildType > flavor > base
List<Walle> walles = []
walles.add(baseWalle)
walles.addAll(flavorWalles)
walles.add(buildTypeWalle)
for (def walle in walles) {
if (mergeWalle == null) {
mergeWalle = walle
} else {
mergeWalle = mergeWalle.mergeWith(walle)
}
}
mergeWalle?.validate()
variant.assemble.doLast {
walleWork(target, variant, mergeWalle)
}
}
}
target.afterEvaluate {
if (!target.plugins.hasPlugin('com.android.application')) {
target.logger.warn("The Android Gradle Plugin was not applied. Gradle Walle will not be configured.")
}
}
}
void walleWork(Project target, def variant, Walle walle) {
if (walle == null || walle.enabled == null || !walle.enabled.booleanValue()) {
target.logger.info("Gradle Walle is disabled for variant '${variant.name}'.")
return
}
if (!variant.signingReady && !variant.outputsAreSigned) {
target.logger.error("Signing not ready for Gradle Walle. Be sure to specify a signingConfig for variant '${variant.name}'.")
return
}
println '--- walle ---'
def apkFile = variant.outputs.first().outputFile as File
println "apk file: ${apkFile.path}"
def v2SigningEnabled = v2SigningEnabled(variant)
println "v2SigningEnabled: ${v2SigningEnabled}"
if (!v2SigningEnabled) {
throw new RuntimeException("${apkFile.path} has no v2 signature in Apk Signing Block!")
}
// 预备输出目录
def outputDir = walle.outputDir
if (outputDir == null) {
outputDir = new File(apkFile.parentFile, 'walle')
}
def channelsDir = new File(outputDir, 'channels')
if (!channelsDir.exists()) {
channelsDir.mkdirs()
}
def nameVariantMap = [
'appName' : target.name,
'projectName': target.rootProject.name,
'buildType' : variant.buildType.name,
'versionName': variant.versionName,
'versionCode': variant.versionCode,
'packageName': variant.applicationId,
'flavorName' : variant.flavorName,
'channelId': 'channel'
]
def fileNameFormat = walle.fileNameFormat ?: '${appName}-${buildType}-${channelId}.apk'
def targetApkFile = new File(outputDir, new groovy.text.SimpleTemplateEngine().createTemplate(fileNameFormat).make(nameVariantMap).toString())// new File(outputDir, apkFile.name)
// 复制
java.nio.file.Files.copy(apkFile.toPath(), targetApkFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING)
println "target apk file: ${targetApkFile.path}"
// 读取渠道信息
def channels = []
if (walle.channelType == 1) {
def slurper = new groovy.json.JsonSlurper()
channels = slurper.parse(walle.channelFile)
} else {
walle.channelFile.eachLine { line ->
def lineTrim = line.trim()
if (lineTrim.length() != 0 && !lineTrim.startsWith("#")) {
def channelId = line.split("#").first().trim()
if (channelId.length() != 0) {
channels.add(['alias': channelId, 'channelId': channelId])
}
}
}
}
channels.each { channel ->
nameVariantMap['channelId'] = channel.channelId
def storeDir = channelsDir
if (channel.storeDir != null) {
storeDir = new File(storeDir, channel.storeDir)
if (!storeDir.exists()) {
storeDir.mkdirs()
}
}
def channelApkFile = new File(storeDir, new groovy.text.SimpleTemplateEngine().createTemplate(fileNameFormat).make(nameVariantMap).toString())
def originalApkFile = targetApkFile
if (originalApkFile != targetApkFile) {
println "${channel.alias ?: channel.channelId} original apk file: ${originalApkFile.path}"
}
println "${channel.alias ?: channel.channelId} channel apk file: ${channelApkFile.path}"
writePayload(target, channel, originalApkFile, channelApkFile)
}
println '--- walle ---'
}
boolean v2SigningEnabled(variant) {
def signingConfig = variant.signingConfig
return signingConfig.v2SigningEnabled
}
void writePayload(Project target, def channel, File apkFile, File channelApkFile) {
java.nio.file.Files.copy(apkFile.toPath(), channelApkFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING)
com.meituan.android.walle.ChannelWriter.put(channelApkFile, channel.channelId, channel.extraInfo)
}
}

View File

@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
// walle
apply from: "${project(":walle_kit").projectDir}/walle_kit_v2.gradle"
apply from: "${project(":walle_kit").projectDir}/walle_kit_v3.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
@ -59,15 +59,6 @@ android {
release {
enabled = true
// // [访问管理](https://console.cloud.tencent.com/cam/capi)
// // [移动应用安全](https://console.cloud.tencent.com/ms/reinforce/list)
// tencent {
// secretId = 'xxx'
// secretKey = 'xxx'
//// region = 'ap-guangzhou' // 可选:'ap-guangzhou'、'ap-shanghai',默认:'ap-guangzhou'
// channels = ['tencent', 'tencent-alias']
// }
outputDir = file("${project.buildDir}/outputs/apk/walle") // 默认file("${project.buildDir}/outputs/apk/${flavorName}/${buildType}/walle")
fileNameFormat = '${appName}-${buildType}-${channelId}.apk' // 默认:'${appName}-${buildType}-${channelId}.apk'
// channelType = 0 // 0默认1json

View File

@ -13,6 +13,8 @@ tencent
aliyun
#
huawei
# 耀
honor
# Oppo
oppo
# Vivo

View File

@ -36,6 +36,11 @@
"channelId": "huawei",
"storeDir": "market"
},
{
"alias": "荣耀",
"channelId": "honor",
"storeDir": "market"
},
{
"alias": "Oppo",
"channelId": "oppo",

View File

@ -7,7 +7,7 @@ packages:
name: async
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.8.2"
version: "2.9.0"
boolean_selector:
dependency: transitive
description:
@ -21,21 +21,14 @@ packages:
name: characters
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.1"
version: "1.2.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
version: "1.1.1"
collection:
dependency: transitive
description:
@ -56,7 +49,7 @@ packages:
name: fake_async
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
version: "1.3.1"
flutter:
dependency: "direct main"
description: flutter
@ -94,28 +87,28 @@ packages:
name: matcher
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.11"
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.1.4"
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.7.0"
version: "1.8.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.1"
version: "1.8.2"
plugin_platform_interface:
dependency: transitive
description:
@ -134,7 +127,7 @@ packages:
name: source_span
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.2"
version: "1.9.0"
stack_trace:
dependency: transitive
description:
@ -155,21 +148,21 @@ packages:
name: string_scanner
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
version: "1.1.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.9"
version: "0.4.12"
vector_math:
dependency: transitive
description: