Skip to content

Commit

Permalink
AucFrame 之解放 Gradle
Browse files Browse the repository at this point in the history
  • Loading branch information
Blankj committed Jul 17, 2019
1 parent 041b4af commit 56babed
Show file tree
Hide file tree
Showing 33 changed files with 638 additions and 90 deletions.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.3.31'
repositories {
Expand Down
11 changes: 8 additions & 3 deletions buildAPP.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ android {

dependencies {
// LeakCanary
debugImplementation Config.depConfig.leakcanary.android
debugImplementation Config.depConfig.leakcanary.support_fragment
releaseImplementation Config.depConfig.leakcanary.android_no_op
debugImplementation Config.depConfig.leakcanary.android.dep
debugImplementation Config.depConfig.leakcanary.support_fragment.dep
releaseImplementation Config.depConfig.leakcanary.android_no_op.dep

// 根据 Config.pkgConfig 来依赖所有 pkg
for (def entrySet : ConfigUtils.getApplyPkgs().entrySet()) {
api entrySet.value.dep
}
}

def getSuffix() {
Expand Down
11 changes: 11 additions & 0 deletions buildLib.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,15 @@ android {
lintOptions {
abortOnError false
}
}

dependencies {
if (project.name == 'pkg') {
// if module's name equals 'pkg', api all of export
for (def entrySet : ConfigUtils.getApplyExports().entrySet()) {
api entrySet.value.dep
}
} else if (project.name == 'export') {
api Config.depConfig.lib.common.dep
}
}
58 changes: 44 additions & 14 deletions buildSrc/src/main/groovy/Config.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,56 @@ class Config {
static support_version = '27.1.1'
static leakcanary_version = '1.6.3'

// appConfig 配置的是可以跑 app 的模块,git 提交务必只包含 launcher
static appConfig = ['launcher']
// pkgConfig 配置的是要依赖的功能包,为空则依赖全部,git 提交务必为空
static pkgConfig = []

static depConfig = [
plugin : [
gradle: "com.android.tools.build:gradle:3.3.0",
kotlin: "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version",
feature : [
launcher: [
app: new DepConfig(":feature:launcher:app")
],

feature0: [
app : new DepConfig(":feature:feature0:app"),
pkg : new DepConfig(true, ":feature:feature0:pkg", "com.blankj:feature-feature0-pkg:1.0", true),
export: new DepConfig(":feature:feature0:export"),
],

feature1: [
app : new DepConfig(":feature:feature1:app"),
pkg : new DepConfig(":feature:feature1:pkg"),
export: new DepConfig(":feature:feature1:export"),
],

// template: [
// app : new DepConfig(":feature:template:app"),
// pkg : new DepConfig(":feature:template:pkg"),
// export: new DepConfig(":feature:template:export"),
// ],
],

lib : [
base : new DepConfig(":lib:base"),
common: new DepConfig(":lib:common"),
],

support : [
appcompat_v7: "com.android.support:appcompat-v7:$support_version",
design : "com.android.support:design:$support_version",
multidex : "com.android.support:multidex:1.0.2",
constraint : "com.android.support.constraint:constraint-layout:1.1.3",
appcompat_v7: new DepConfig("com.android.support:appcompat-v7:$support_version"),
design : new DepConfig("com.android.support:design:$support_version"),
multidex : new DepConfig("com.android.support:multidex:1.0.2"),
constraint : new DepConfig("com.android.support.constraint:constraint-layout:1.1.3"),
],
kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version",
utilcode : "com.blankj:utilcode:1.25.0",
free_proguard: "com.blankj:free-proguard:1.0.1",
swipe_panel : "com.blankj:swipe-panel:1.1",
kotlin : new DepConfig("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"),
utilcode : new DepConfig("com.blankj:utilcode:1.25.0"),
free_proguard: new DepConfig("com.blankj:free-proguard:1.0.1"),
swipe_panel : new DepConfig("com.blankj:swipe-panel:1.1"),

leakcanary : [
android : "com.squareup.leakcanary:leakcanary-android:$leakcanary_version",
android_no_op : "com.squareup.leakcanary:leakcanary-android-no-op:$leakcanary_version",
support_fragment: "com.squareup.leakcanary:leakcanary-support-fragment:$leakcanary_version",
android : new DepConfig("com.squareup.leakcanary:leakcanary-android:$leakcanary_version"),
android_no_op : new DepConfig("com.squareup.leakcanary:leakcanary-android-no-op:$leakcanary_version"),
support_fragment: new DepConfig("com.squareup.leakcanary:leakcanary-support-fragment:$leakcanary_version"),
],
]
}
169 changes: 169 additions & 0 deletions buildSrc/src/main/groovy/ConfigUtils.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import org.gradle.BuildListener
import org.gradle.BuildResult
import org.gradle.api.Project
import org.gradle.api.ProjectEvaluationListener
import org.gradle.api.ProjectState
import org.gradle.api.initialization.Settings
import org.gradle.api.invocation.Gradle

class ConfigUtils {

static getApplyPkgs() {
def applyPkgs = getDepConfigByFilter(new DepConfigFilter() {
@Override
boolean accept(String name, DepConfig config) {
if (!config.isApply) return false
return name.endsWith(".pkg")
}
})
GLog.d("getApplyPkgs = ${GLog.object2String(applyPkgs)}")
return applyPkgs
}

static getApplyExports() {
def applyExports = getDepConfigByFilter(new DepConfigFilter() {
@Override
boolean accept(String name, DepConfig config) {
if (!config.isApply) return false
return name.endsWith(".export")
}
})
GLog.d("getApplyExports = ${GLog.object2String(applyExports)}")
return applyExports
}

static addBuildListener(Gradle g) {
g.addBuildListener(new ConfigBuildListener())
}

private static class ConfigBuildListener implements BuildListener {

@Override
void buildStarted(Gradle gradle) {}

@Override
void settingsEvaluated(Settings settings) {
GLog.d("settingsEvaluated")
includeModule(settings)
}

@Override
void projectsLoaded(Gradle gradle) {
GLog.d("projectsLoaded")
generateDep(gradle)

gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
@Override
void beforeEvaluate(Project project) {
if (project.subprojects.isEmpty()) {// 定位到具体 project
if (project.name == "app") {
GLog.l(project.toString() + " applies buildApp.gradle")
project.apply {
from "${project.rootDir.path}/buildApp.gradle"
}
} else {
GLog.l(project.toString() + " applies buildLib.gradle")
project.apply {
from "${project.rootDir.path}/buildLib.gradle"
}
}
}
}

@Override
void afterEvaluate(Project project, ProjectState projectState) {
}
})
}

@Override
void projectsEvaluated(Gradle gradle) {
GLog.d("projectsEvaluated")
}

@Override
void buildFinished(BuildResult result) {
GLog.d("buildFinished")
}

/**
* 在 settings.gradle 中 根据 appConfig 和 pkgConfig 来 include 本地模块
*/
private static includeModule(Settings settings) {
def config = getDepConfigByFilter(new DepConfigFilter() {
@Override
boolean accept(String name, DepConfig config) {
if (name.endsWith('.app')) {// 如果最终是 app 的话
def appName = name.substring('feature.'.length(), name.length() - 4)// 获取 app 模块的名字
if (!Config.appConfig.contains(appName)) {// 如果 Config.appConfig 中不存在,那就不让它进依赖
config.isApply = false
}
}
if (!Config.pkgConfig.isEmpty()) {// 如果 Config.pkgConfig 不为空,说明是 pkg 调试模式
if (name.endsWith('.pkg')) {// 如果是 pkg 的话
def pkgName = name.substring('feature.'.length(), name.length() - 4)// 获取 pkg 模块的名字
if (!Config.pkgConfig.contains(pkgName)) {// 如果 Config.pkgConfig 中不存在,那就不让它进依赖
config.isApply = false
}
}
}
// 过滤出本地并且 apply 的模块
if (!config.isApply) return false
if (!config.useLocal) return false
if (config.localPath == "") return false
return true
}
}).each { _, cfg ->// 把本地模块 include 进去
settings.include cfg.localPath
}
GLog.l("includeModule = ${GLog.object2String(config)}")
}

/**
* 根据 depConfig 生成 dep
*/
private static generateDep(Gradle gradle) {
def config = getDepConfigByFilter(new DepConfigFilter() {
@Override
boolean accept(String name, DepConfig config) {
if (config.useLocal) {// 如果使用的是本地模块,那么把它转化为 project
config.dep = gradle.rootProject.findProject(config.localPath)
} else {// 如果是远端依赖,那就直接使用远端依赖即可
config.dep = config.remotePath
}
return true
}
})
GLog.l("generateDep = ${GLog.object2String(config)}")
}
}

/**
* 根据过滤器来获取 DepConfig
*/
static Map<String, DepConfig> getDepConfigByFilter(DepConfigFilter filter) {
return _getDepConfigByFilter("", Config.depConfig, filter)
}

private static _getDepConfigByFilter(String namePrefix, Map map, DepConfigFilter filter) {
def depConfigList = [:]// 结果 Map
for (Map.Entry entry : map.entrySet()) {
def (name, value) = [entry.getKey(), entry.getValue()]
if (value instanceof Map) {// 如果值是 Map 类型就加到结果 Map 中
namePrefix += (name + '.')
depConfigList.putAll(_getDepConfigByFilter(namePrefix, value, filter))
namePrefix -= (name + '.')
continue
}
def config = value as DepConfig
if (filter == null || filter.accept(namePrefix + name, config)) {
depConfigList.put(namePrefix + name, config)// 符合过滤条件就加到结果 Map 中
}
}
return depConfigList
}

interface DepConfigFilter {
boolean accept(String name, DepConfig config);
}
}
46 changes: 46 additions & 0 deletions buildSrc/src/main/groovy/DepConfig.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class DepConfig {
boolean useLocal // 是否使用本地的
String localPath // 本地路径
String remotePath// 远程路径
boolean isApply // 是否应用
String path // 最后的路径
def dep // 根据条件生成项目最终的依赖项

DepConfig(String path) {
this(path, true)
}

DepConfig(String path, boolean isApply) {
if (path.startsWith(":")) {
this.useLocal = true
this.localPath = path
this.isApply = isApply
} else {
this.useLocal = false
this.remotePath = path
this.isApply = isApply
}
this.path = path
}

DepConfig(boolean useLocal, String localPath, String remotePath) {
this(useLocal, localPath, remotePath, true)
}

DepConfig(boolean useLocal, String localPath, String remotePath, boolean isApply) {
this.useLocal = useLocal
this.localPath = localPath
this.remotePath = remotePath
this.isApply = isApply
this.path = useLocal ? localPath : remotePath
}

@Override
String toString() {
return "DepConfig { " +
"useLocal = " + useLocal +
(dep == null ? ", path = " + path : (", dep = " + dep)) +
", isApply = " + isApply +
" }"
}
}
Loading

0 comments on commit 56babed

Please sign in to comment.