接上一篇 15. Gradle编译其他应用代码流程(四) - Configure过程 继续分析
一. task选择
到了这个阶段,gradle开始计算task入口是哪个? 选择的逻辑是这样:
如果用户收入了task,比如这样的指令'gradle pmd',那么就执行pmd这个task
如果用户没有输入task,比如直接输入'gradle',那么看有没有默认的task
如果没有默认的task,那就执行help这个task。大家可以试下直接输入gradle,看看输出什么内容。
接下来看源代码。
文件路径:subprojects\core\src\main\java\org\gradle\initialization\DefaultGradleLauncher.java
private void doBuildStages(Stage upTo) {
...
// After this point, the GradleLauncher cannot be reused
stage = Stage.Build;
// Populate task graph
buildOperationExecutor.run("Calculate task graph", new Runnable() {
@Override
public void run() {
buildConfigurationActionExecuter.select(gradle);
if (gradle.getStartParameter().isConfigureOnDemand()) {
buildListener.projectsEvaluated(gradle);
}
}
});
...
}
文件路径:
subprojects\core\src\main\java\org\gradle\execution\DefaultBuildConfigurationActionExecuter.java
public class DefaultBuildConfigurationActionExecuter implements BuildConfigurationActionExecuter {
...
public void select(GradleInternal gradle) {
List<BuildConfigurationAction> processingBuildActions = CollectionUtils.flattenCollections(BuildConfigurationAction.class, configurationActions, taskSelectors);
configure(processingBuildActions, gradle, 0);
}
...
private void configure(final List<BuildConfigurationAction> processingConfigurationActions, final GradleInternal gradle, final int index) {
if (index >= processingConfigurationActions.size()) {
return;
}
BuildConfigurationAction action = processingConfigurationActions.get(index);
System.out.println("DefaultBuildConfigurationActionExecuter action: " + action + " index: " + index);
/*processingConfigurationActions.get(index)*/action.configure(new BuildExecutionContext() {
public GradleInternal getGradle() {
return gradle;
}
public void proceed() {
configure(processingConfigurationActions, gradle, index + 1);
}
});
}
}
这个地方的写法挺奇怪的,它的想法是遍历processingConfigurationActions里面的每个action,然后执行它的configure方法,所以它用了递归。
但是个人觉得直接用循环不是更简单直接吗?
先不去管这些,processingConfigurationActions里面有3个成员,他们继承自同一接口BuildConfigurationAction。
org.gradle.execution.ExcludedTaskFilteringBuildConfigurationAction@3ee68eb2 index: 0
org.gradle.execution.DefaultTasksBuildExecutionAction@49cd08f9 index: 1
org.gradle.execution.TaskNameResolvingBuildConfigurationAction@4eace42b index: 2
他们3个分别处理的事情不一样。
a. ExcludedTaskFilteringBuildConfigurationAction用来处理不执行的task,如果用户有配置的话。
代码如下:
文件路径:
subprojects\core\src\main\java\org\gradle\execution\ExcludedTaskFilteringBuildConfigurationAction.java
/**
* A {@link BuildConfigurationAction} which filters excluded tasks.
*/
public class ExcludedTaskFilteringBuildConfigurationAction implements BuildConfigurationAction {
...
public void configure(BuildExecutionContext context) {
GradleInternal gradle = context.getGradle();
Set<String> excludedTaskNames = gradle.getStartParameter().getExcludedTaskNames();
if (!excludedTaskNames.isEmpty()) {
final Set<Spec<Task>> filters = new HashSet<Spec<Task>>();
for (String taskName : excludedTaskNames) {
filters.add(taskSelector.getFilter(taskName));
}
gradle.getTaskGraph().useFilter(Specs.intersect(filters));
}
context.proceed();
}
}
b. DefaultTasksBuildExecutionAction用来处理默认的task,如果用户有输入task,那么就使用用户输入的。比如用户输入'gradle pmd',那么使用的task就是pmd
如果用户没有输入task,那么就使用默认的task
如果默认task也没有,则使用help task,比如用户直接输入'gradle'
文件路径:
subprojects\core\src\main\java\org\gradle\execution\DefaultTasksBuildExecutionAction.java
public class DefaultTasksBuildExecutionAction implements BuildConfigurationAction {
...
public void configure(BuildExecutionContext context) {
StartParameter startParameter = context.getGradle().getStartParameter();
System.out.println("DefaultTasksBuildExecutionAction configure. startParameter: " + startParameter);
//判断是否有输入task?
for (TaskExecutionRequest request : startParameter.getTaskRequests()) {
if (!request.getArgs().isEmpty()) {
context.proceed();
return;
}
}
//没有输入task,尝试使用默认task和help task
// Gather the default tasks from this first group project
ProjectInternal project = context.getGradle().getDefaultProject();
//so that we don't miss out default tasks
projectConfigurer.configure(project);
List<String> defaultTasks = project.getDefaultTasks();
if (defaultTasks.size() == 0) {
defaultTasks = Collections.singletonList(ProjectInternal.HELP_TASK);
LOGGER.info("No tasks specified. Using default task {}", GUtil.toString(defaultTasks));
System.out.println("No tasks specified. Using default task {}" + "-" + GUtil.toString(defaultTasks));
} else {
LOGGER.info("No tasks specified. Using project default tasks {}", GUtil.toString(defaultTasks));
System.out.println("No tasks specified. Using project default tasks {}" + " - " + GUtil.toString(defaultTasks));
}
startParameter.setTaskNames(defaultTasks);
context.proceed();
}
}
c. TaskNameResolvingBuildConfigurationAction
把输入的task(如果没有输入,则使用默认task或者 help)添加到executer里面,为真正执行做准备。
代码路径:
subprojects\core\src\main\java\org\gradle\execution\TaskNameResolvingBuildConfigurationAction.java
/**
* A {@link BuildConfigurationAction} which selects tasks which match the provided names. For each name, selects all tasks in all
* projects whose name is the given name.
*/
public class TaskNameResolvingBuildConfigurationAction implements BuildConfigurationAction {
...
public void configure(BuildExecutionContext context) {
System.out.println("TaskNameResolvingBuildConfigurationAction configure 1");
GradleInternal gradle = context.getGradle();
TaskGraphExecuter executer = gradle.getTaskGraph();
List<TaskExecutionRequest> taskParameters = gradle.getStartParameter().getTaskRequests();
for (TaskExecutionRequest taskParameter : taskParameters) {
System.out.println("TaskNameResolvingBuildConfigurationAction configure 2");
List<TaskSelector.TaskSelection> taskSelections = commandLineTaskParser.parseTasks(taskParameter);
for (TaskSelector.TaskSelection taskSelection : taskSelections) {
LOGGER.info("Selected primary task '{}' from project {}", taskSelection.getTaskName(), taskSelection.getProjectPath());
System.out.println("Selected primary task '{}' from project {}" + taskSelection.getTaskName() + "-"+ taskSelection.getProjectPath());
executer.addTasks(taskSelection.getTasks());
}
}
context.proceed();
}
}
二. 通知projectsEvaluated
if (gradle.getStartParameter().isConfigureOnDemand()) {
buildListener.projectsEvaluated(gradle);
}
到此为止,所有的准备工作都已经做好了,接下就要真正的执行这个task了。
配置文件加载
gradle文件加载以及相应的plugin 类加载
要执行的task选择
下一篇帖子讲task的执行。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。