背景
- 查看task依赖难
目的
- 通过Plugin或者自定义Task的方式,快速打印出task的依赖关系
分析
Task生命周期
task conf task配置
gradle.afterProject
project.afterEvaluate
gradle.taskGraph.whenReady
:task名字 (:build)
gradle.taskGraph.beforeTask (一个task调用一次)
task exc task执行
gradle.taskGraph.afterTask (一个task调用一次)
gradle.buildFinished
寻找task依赖入口
通过上面的生命周期分析,我们知道在task exc执行之前,所有的task conf会全部配置完成,自然依赖关系会在task执行之前存在。
我们可以自定义一个task,在task执行时,收集目标task的依赖关系
代码
- 自定义task,(需要使用uploadArchives 导出到本地仓库)
class DependencieModel implements Serializable{
public String task //task
public List<DependencieModel> dependencies //当前task的依赖
}
class DependenciesTask extends DefaultTask {
@Optional
String task //配置时输入的变量
String dir = '/depends'
@TaskAction
void findTaskDependencies() throws Exception {
if (TextUtils.isEmpty(task)) {
println('task is empty') //可以替换为抛出一个异常
return
}
Set<Task> tasks = project.getTasksByName(task, true) //通过taskname获取到task,true参数为包含subProject
if (tasks == null || tasks.size() == 0) {
println('task is not exist')
return
}
String desDir = project.rootProject.buildDir.absolutePath + dir
File dir = new File(desDir)
deleteFile(dir)
if (!dir.exists()) {
dir.mkdir()
}
tasks.forEach(new Consumer<Task>() {
@Override
void accept(Task t) {
DependencieModel dependencieModel = new DependencieModel()
collection(t, dependencieModel)
Gson gson = new Gson()
String json = gson.toJson(dependencieModel)
println(json)
String filePath = desDir + '/' + task + "_" + t.project.name + '.json'
File file = new File(filePath)
if (!file.exists()) {
file.createNewFile()
}
FileOutputStream outputStream
try {
outputStream = new FileOutputStream(file)
outputStream.write(json.bytes) //输出到文件中
outputStream.flush()
} catch (Exception e) {
e.printStackTrace()
} finally {
if (outputStream != null) {
outputStream.close()
}
}
}
})
}
def static deleteFile(File file) { //删除文件
if (!file.exists()) {
return
}
if (file.isDirectory()) {
File[] files = file.listFiles()
for (int i = 0; i < files.length; i++) {
deleteFile(files[i])
}
} else if (file.isFile()) {
file.delete()
}
}
def static collection(Task task, DependencieModel model) { //收集task
if (task == null) {
return
}
model.task = task.name
Set<Task> tasks = task.getTaskDependencies().getDependencies(task)
if (tasks != null && !tasks.isEmpty()) {
model.dependencies = new ArrayList<>()
tasks.forEach(new Consumer<Task>() {
@Override
void accept(Task taskChild) {
DependencieModel modelChild = new DependencieModel()
modelChild.task = taskChild.name
model.dependencies.add(modelChild)
collection(taskChild, modelChild)
}
})
}
}
}
- 执行task
task dpendencieTask(type: com.meituan.hotel.DependenciesTask){
task='build'
}
- 输出json
{
"task": "build",
"dependencies": [
{
"task": "check",
"dependencies": [
{
"task": "test",
"dependencies": [
{
"task": "testClasses",
"dependencies": [
{
"task": "processTestResources"
},
{
"task": "compileTestGroovy",
"dependencies": [
{
"task": "classes",
"dependencies": [
{
"task": "compileJava"
},
{
"task": "processResources"
},
{
"task": "compileGroovy",
"dependencies": [
{
"task": "compileJava"
}
]
}
]
},
{
"task": "compileTestJava",
"dependencies": [
{
"task": "classes",
"dependencies": [
{
"task": "compileJava"
},
{
"task": "processResources"
},
{
"task": "compileGroovy",
"dependencies": [
{
"task": "compileJava"
}
]
}
]
}
]
}
]
},
{
"task": "compileTestJava",
"dependencies": [
{
"task": "classes",
"dependencies": [
{
"task": "compileJava"
},
{
"task": "processResources"
},
{
"task": "compileGroovy",
"dependencies": [
{
"task": "compileJava"
}
]
}
]
}
]
}
]
},
{
"task": "classes",
"dependencies": [
{
"task": "compileJava"
},
{
"task": "processResources"
},
{
"task": "compileGroovy",
"dependencies": [
{
"task": "compileJava"
}
]
}
]
}
]
}
]
},
{
"task": "assemble",
"dependencies": [
{
"task": "jar",
"dependencies": [
{
"task": "classes",
"dependencies": [
{
"task": "compileJava"
},
{
"task": "processResources"
},
{
"task": "compileGroovy",
"dependencies": [
{
"task": "compileJava"
}
]
}
]
}
]
}
]
}
]
}