接上一篇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

privatevoiddoBuildStages(StageupTo){...//Afterthispoint,theGradleLaunchercannotbereusedstage=Stage.Build;//PopulatetaskgraphbuildOperationExecutor.run("Calculatetaskgraph",newRunnable(){@Overridepublicvoidrun(){buildConfigurationActionExecuter.select(gradle);if(gradle.getStartParameter().isConfigureOnDemand()){buildListener.projectsEvaluated(gradle);}}});...}


文件路径:

subprojects\core\src\main\java\org\gradle\execution\DefaultBuildConfigurationActionExecuter.java

publicclassDefaultBuildConfigurationActionExecuterimplementsBuildConfigurationActionExecuter{...publicvoidselect(GradleInternalgradle){List<BuildConfigurationAction>processingBuildActions=CollectionUtils.flattenCollections(BuildConfigurationAction.class,configurationActions,taskSelectors);configure(processingBuildActions,gradle,0);}...privatevoidconfigure(finalList<BuildConfigurationAction>processingConfigurationActions,finalGradleInternalgradle,finalintindex){if(index>=processingConfigurationActions.size()){return;}BuildConfigurationActionaction=processingConfigurationActions.get(index);System.out.println("DefaultBuildConfigurationActionExecuteraction:"+action+"index:"+index);/*processingConfigurationActions.get(index)*/action.configure(newBuildExecutionContext(){publicGradleInternalgetGradle(){returngradle;}publicvoidproceed(){configure(processingConfigurationActions,gradle,index+1);}});}}


这个地方的写法挺奇怪的,它的想法是遍历processingConfigurationActions里面的每个action,然后执行它的configure方法,所以它用了递归。

但是个人觉得直接用循环不是更简单直接吗?


先不去管这些,processingConfigurationActions里面有3个成员,他们继承自同一接口BuildConfigurationAction。

org.gradle.execution.ExcludedTaskFilteringBuildConfigurationAction@3ee68eb2index:0org.gradle.execution.DefaultTasksBuildExecutionAction@49cd08f9index:1org.gradle.execution.TaskNameResolvingBuildConfigurationAction@4eace42bindex:2


他们3个分别处理的事情不一样。

a. ExcludedTaskFilteringBuildConfigurationAction用来处理不执行的task,如果用户有配置的话。

代码如下:

文件路径:

subprojects\core\src\main\java\org\gradle\execution\ExcludedTaskFilteringBuildConfigurationAction.java

/***A{@linkBuildConfigurationAction}whichfiltersexcludedtasks.*/publicclassExcludedTaskFilteringBuildConfigurationActionimplementsBuildConfigurationAction{...publicvoidconfigure(BuildExecutionContextcontext){GradleInternalgradle=context.getGradle();Set<String>excludedTaskNames=gradle.getStartParameter().getExcludedTaskNames();if(!excludedTaskNames.isEmpty()){finalSet<Spec<Task>>filters=newHashSet<Spec<Task>>();for(StringtaskName: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

publicclassDefaultTasksBuildExecutionActionimplementsBuildConfigurationAction{...publicvoidconfigure(BuildExecutionContextcontext){StartParameterstartParameter=context.getGradle().getStartParameter();System.out.println("DefaultTasksBuildExecutionActionconfigure.startParameter:"+startParameter);//判断是否有输入task?for(TaskExecutionRequestrequest:startParameter.getTaskRequests()){if(!request.getArgs().isEmpty()){context.proceed();return;}}//没有输入task,尝试使用默认task和helptask//GatherthedefaulttasksfromthisfirstgroupprojectProjectInternalproject=context.getGradle().getDefaultProject();//sothatwedon'tmissoutdefaulttasksprojectConfigurer.configure(project);List<String>defaultTasks=project.getDefaultTasks();if(defaultTasks.size()==0){defaultTasks=Collections.singletonList(ProjectInternal.HELP_TASK);LOGGER.info("Notasksspecified.Usingdefaulttask{}",GUtil.toString(defaultTasks));System.out.println("Notasksspecified.Usingdefaulttask{}"+"-"+GUtil.toString(defaultTasks));}else{LOGGER.info("Notasksspecified.Usingprojectdefaulttasks{}",GUtil.toString(defaultTasks));System.out.println("Notasksspecified.Usingprojectdefaulttasks{}"+"-"+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{@linkBuildConfigurationAction}whichselectstaskswhichmatchtheprovidednames.Foreachname,selectsalltasksinall*projectswhosenameisthegivenname.*/publicclassTaskNameResolvingBuildConfigurationActionimplementsBuildConfigurationAction{...publicvoidconfigure(BuildExecutionContextcontext){System.out.println("TaskNameResolvingBuildConfigurationActionconfigure1");GradleInternalgradle=context.getGradle();TaskGraphExecuterexecuter=gradle.getTaskGraph();List<TaskExecutionRequest>taskParameters=gradle.getStartParameter().getTaskRequests();for(TaskExecutionRequesttaskParameter:taskParameters){System.out.println("TaskNameResolvingBuildConfigurationActionconfigure2");List<TaskSelector.TaskSelection>taskSelections=commandLineTaskParser.parseTasks(taskParameter);for(TaskSelector.TaskSelectiontaskSelection:taskSelections){LOGGER.info("Selectedprimarytask'{}'fromproject{}",taskSelection.getTaskName(),taskSelection.getProjectPath());System.out.println("Selectedprimarytask'{}'fromproject{}"+taskSelection.getTaskName()+"-"+taskSelection.getProjectPath());executer.addTasks(taskSelection.getTasks());}}context.proceed();}}



二. 通知projectsEvaluated

if(gradle.getStartParameter().isConfigureOnDemand()){buildListener.projectsEvaluated(gradle);}


到此为止,所有的准备工作都已经做好了,接下就要真正的执行这个task了。

配置文件加载

gradle文件加载以及相应的plugin 类加载

要执行的task选择


下一篇帖子讲task的执行。