Skip to content

Commit 56babed

Browse files
committed
AucFrame 之解放 Gradle
1 parent 041b4af commit 56babed

33 files changed

+638
-90
lines changed

build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
2-
32
buildscript {
43
ext.kotlin_version = '1.3.31'
54
repositories {

buildAPP.gradle

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,14 @@ android {
4141

4242
dependencies {
4343
// LeakCanary
44-
debugImplementation Config.depConfig.leakcanary.android
45-
debugImplementation Config.depConfig.leakcanary.support_fragment
46-
releaseImplementation Config.depConfig.leakcanary.android_no_op
44+
debugImplementation Config.depConfig.leakcanary.android.dep
45+
debugImplementation Config.depConfig.leakcanary.support_fragment.dep
46+
releaseImplementation Config.depConfig.leakcanary.android_no_op.dep
47+
48+
// 根据 Config.pkgConfig 来依赖所有 pkg
49+
for (def entrySet : ConfigUtils.getApplyPkgs().entrySet()) {
50+
api entrySet.value.dep
51+
}
4752
}
4853

4954
def getSuffix() {

buildLib.gradle

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,15 @@ android {
2525
lintOptions {
2626
abortOnError false
2727
}
28+
}
29+
30+
dependencies {
31+
if (project.name == 'pkg') {
32+
// if module's name equals 'pkg', api all of export
33+
for (def entrySet : ConfigUtils.getApplyExports().entrySet()) {
34+
api entrySet.value.dep
35+
}
36+
} else if (project.name == 'export') {
37+
api Config.depConfig.lib.common.dep
38+
}
2839
}

buildSrc/src/main/groovy/Config.groovy

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,56 @@ class Config {
1313
static support_version = '27.1.1'
1414
static leakcanary_version = '1.6.3'
1515

16+
// appConfig 配置的是可以跑 app 的模块,git 提交务必只包含 launcher
17+
static appConfig = ['launcher']
18+
// pkgConfig 配置的是要依赖的功能包,为空则依赖全部,git 提交务必为空
19+
static pkgConfig = []
20+
1621
static depConfig = [
17-
plugin : [
18-
gradle: "com.android.tools.build:gradle:3.3.0",
19-
kotlin: "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version",
22+
feature : [
23+
launcher: [
24+
app: new DepConfig(":feature:launcher:app")
25+
],
26+
27+
feature0: [
28+
app : new DepConfig(":feature:feature0:app"),
29+
pkg : new DepConfig(true, ":feature:feature0:pkg", "com.blankj:feature-feature0-pkg:1.0", true),
30+
export: new DepConfig(":feature:feature0:export"),
31+
],
32+
33+
feature1: [
34+
app : new DepConfig(":feature:feature1:app"),
35+
pkg : new DepConfig(":feature:feature1:pkg"),
36+
export: new DepConfig(":feature:feature1:export"),
37+
],
38+
39+
// template: [
40+
// app : new DepConfig(":feature:template:app"),
41+
// pkg : new DepConfig(":feature:template:pkg"),
42+
// export: new DepConfig(":feature:template:export"),
43+
// ],
2044
],
45+
46+
lib : [
47+
base : new DepConfig(":lib:base"),
48+
common: new DepConfig(":lib:common"),
49+
],
50+
2151
support : [
22-
appcompat_v7: "com.android.support:appcompat-v7:$support_version",
23-
design : "com.android.support:design:$support_version",
24-
multidex : "com.android.support:multidex:1.0.2",
25-
constraint : "com.android.support.constraint:constraint-layout:1.1.3",
52+
appcompat_v7: new DepConfig("com.android.support:appcompat-v7:$support_version"),
53+
design : new DepConfig("com.android.support:design:$support_version"),
54+
multidex : new DepConfig("com.android.support:multidex:1.0.2"),
55+
constraint : new DepConfig("com.android.support.constraint:constraint-layout:1.1.3"),
2656
],
27-
kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version",
28-
utilcode : "com.blankj:utilcode:1.25.0",
29-
free_proguard: "com.blankj:free-proguard:1.0.1",
30-
swipe_panel : "com.blankj:swipe-panel:1.1",
57+
kotlin : new DepConfig("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"),
58+
utilcode : new DepConfig("com.blankj:utilcode:1.25.0"),
59+
free_proguard: new DepConfig("com.blankj:free-proguard:1.0.1"),
60+
swipe_panel : new DepConfig("com.blankj:swipe-panel:1.1"),
3161

3262
leakcanary : [
33-
android : "com.squareup.leakcanary:leakcanary-android:$leakcanary_version",
34-
android_no_op : "com.squareup.leakcanary:leakcanary-android-no-op:$leakcanary_version",
35-
support_fragment: "com.squareup.leakcanary:leakcanary-support-fragment:$leakcanary_version",
63+
android : new DepConfig("com.squareup.leakcanary:leakcanary-android:$leakcanary_version"),
64+
android_no_op : new DepConfig("com.squareup.leakcanary:leakcanary-android-no-op:$leakcanary_version"),
65+
support_fragment: new DepConfig("com.squareup.leakcanary:leakcanary-support-fragment:$leakcanary_version"),
3666
],
3767
]
3868
}
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import org.gradle.BuildListener
2+
import org.gradle.BuildResult
3+
import org.gradle.api.Project
4+
import org.gradle.api.ProjectEvaluationListener
5+
import org.gradle.api.ProjectState
6+
import org.gradle.api.initialization.Settings
7+
import org.gradle.api.invocation.Gradle
8+
9+
class ConfigUtils {
10+
11+
static getApplyPkgs() {
12+
def applyPkgs = getDepConfigByFilter(new DepConfigFilter() {
13+
@Override
14+
boolean accept(String name, DepConfig config) {
15+
if (!config.isApply) return false
16+
return name.endsWith(".pkg")
17+
}
18+
})
19+
GLog.d("getApplyPkgs = ${GLog.object2String(applyPkgs)}")
20+
return applyPkgs
21+
}
22+
23+
static getApplyExports() {
24+
def applyExports = getDepConfigByFilter(new DepConfigFilter() {
25+
@Override
26+
boolean accept(String name, DepConfig config) {
27+
if (!config.isApply) return false
28+
return name.endsWith(".export")
29+
}
30+
})
31+
GLog.d("getApplyExports = ${GLog.object2String(applyExports)}")
32+
return applyExports
33+
}
34+
35+
static addBuildListener(Gradle g) {
36+
g.addBuildListener(new ConfigBuildListener())
37+
}
38+
39+
private static class ConfigBuildListener implements BuildListener {
40+
41+
@Override
42+
void buildStarted(Gradle gradle) {}
43+
44+
@Override
45+
void settingsEvaluated(Settings settings) {
46+
GLog.d("settingsEvaluated")
47+
includeModule(settings)
48+
}
49+
50+
@Override
51+
void projectsLoaded(Gradle gradle) {
52+
GLog.d("projectsLoaded")
53+
generateDep(gradle)
54+
55+
gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
56+
@Override
57+
void beforeEvaluate(Project project) {
58+
if (project.subprojects.isEmpty()) {// 定位到具体 project
59+
if (project.name == "app") {
60+
GLog.l(project.toString() + " applies buildApp.gradle")
61+
project.apply {
62+
from "${project.rootDir.path}/buildApp.gradle"
63+
}
64+
} else {
65+
GLog.l(project.toString() + " applies buildLib.gradle")
66+
project.apply {
67+
from "${project.rootDir.path}/buildLib.gradle"
68+
}
69+
}
70+
}
71+
}
72+
73+
@Override
74+
void afterEvaluate(Project project, ProjectState projectState) {
75+
}
76+
})
77+
}
78+
79+
@Override
80+
void projectsEvaluated(Gradle gradle) {
81+
GLog.d("projectsEvaluated")
82+
}
83+
84+
@Override
85+
void buildFinished(BuildResult result) {
86+
GLog.d("buildFinished")
87+
}
88+
89+
/**
90+
* 在 settings.gradle 中 根据 appConfig 和 pkgConfig 来 include 本地模块
91+
*/
92+
private static includeModule(Settings settings) {
93+
def config = getDepConfigByFilter(new DepConfigFilter() {
94+
@Override
95+
boolean accept(String name, DepConfig config) {
96+
if (name.endsWith('.app')) {// 如果最终是 app 的话
97+
def appName = name.substring('feature.'.length(), name.length() - 4)// 获取 app 模块的名字
98+
if (!Config.appConfig.contains(appName)) {// 如果 Config.appConfig 中不存在,那就不让它进依赖
99+
config.isApply = false
100+
}
101+
}
102+
if (!Config.pkgConfig.isEmpty()) {// 如果 Config.pkgConfig 不为空,说明是 pkg 调试模式
103+
if (name.endsWith('.pkg')) {// 如果是 pkg 的话
104+
def pkgName = name.substring('feature.'.length(), name.length() - 4)// 获取 pkg 模块的名字
105+
if (!Config.pkgConfig.contains(pkgName)) {// 如果 Config.pkgConfig 中不存在,那就不让它进依赖
106+
config.isApply = false
107+
}
108+
}
109+
}
110+
// 过滤出本地并且 apply 的模块
111+
if (!config.isApply) return false
112+
if (!config.useLocal) return false
113+
if (config.localPath == "") return false
114+
return true
115+
}
116+
}).each { _, cfg ->// 把本地模块 include 进去
117+
settings.include cfg.localPath
118+
}
119+
GLog.l("includeModule = ${GLog.object2String(config)}")
120+
}
121+
122+
/**
123+
* 根据 depConfig 生成 dep
124+
*/
125+
private static generateDep(Gradle gradle) {
126+
def config = getDepConfigByFilter(new DepConfigFilter() {
127+
@Override
128+
boolean accept(String name, DepConfig config) {
129+
if (config.useLocal) {// 如果使用的是本地模块,那么把它转化为 project
130+
config.dep = gradle.rootProject.findProject(config.localPath)
131+
} else {// 如果是远端依赖,那就直接使用远端依赖即可
132+
config.dep = config.remotePath
133+
}
134+
return true
135+
}
136+
})
137+
GLog.l("generateDep = ${GLog.object2String(config)}")
138+
}
139+
}
140+
141+
/**
142+
* 根据过滤器来获取 DepConfig
143+
*/
144+
static Map<String, DepConfig> getDepConfigByFilter(DepConfigFilter filter) {
145+
return _getDepConfigByFilter("", Config.depConfig, filter)
146+
}
147+
148+
private static _getDepConfigByFilter(String namePrefix, Map map, DepConfigFilter filter) {
149+
def depConfigList = [:]// 结果 Map
150+
for (Map.Entry entry : map.entrySet()) {
151+
def (name, value) = [entry.getKey(), entry.getValue()]
152+
if (value instanceof Map) {// 如果值是 Map 类型就加到结果 Map 中
153+
namePrefix += (name + '.')
154+
depConfigList.putAll(_getDepConfigByFilter(namePrefix, value, filter))
155+
namePrefix -= (name + '.')
156+
continue
157+
}
158+
def config = value as DepConfig
159+
if (filter == null || filter.accept(namePrefix + name, config)) {
160+
depConfigList.put(namePrefix + name, config)// 符合过滤条件就加到结果 Map 中
161+
}
162+
}
163+
return depConfigList
164+
}
165+
166+
interface DepConfigFilter {
167+
boolean accept(String name, DepConfig config);
168+
}
169+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
class DepConfig {
2+
boolean useLocal // 是否使用本地的
3+
String localPath // 本地路径
4+
String remotePath// 远程路径
5+
boolean isApply // 是否应用
6+
String path // 最后的路径
7+
def dep // 根据条件生成项目最终的依赖项
8+
9+
DepConfig(String path) {
10+
this(path, true)
11+
}
12+
13+
DepConfig(String path, boolean isApply) {
14+
if (path.startsWith(":")) {
15+
this.useLocal = true
16+
this.localPath = path
17+
this.isApply = isApply
18+
} else {
19+
this.useLocal = false
20+
this.remotePath = path
21+
this.isApply = isApply
22+
}
23+
this.path = path
24+
}
25+
26+
DepConfig(boolean useLocal, String localPath, String remotePath) {
27+
this(useLocal, localPath, remotePath, true)
28+
}
29+
30+
DepConfig(boolean useLocal, String localPath, String remotePath, boolean isApply) {
31+
this.useLocal = useLocal
32+
this.localPath = localPath
33+
this.remotePath = remotePath
34+
this.isApply = isApply
35+
this.path = useLocal ? localPath : remotePath
36+
}
37+
38+
@Override
39+
String toString() {
40+
return "DepConfig { " +
41+
"useLocal = " + useLocal +
42+
(dep == null ? ", path = " + path : (", dep = " + dep)) +
43+
", isApply = " + isApply +
44+
" }"
45+
}
46+
}

0 commit comments

Comments
 (0)