您好,登錄后才能下訂單哦!
接上一篇 15. Gradle編譯其他應(yīng)用代碼流程(四) - Configure過程 繼續(xù)分析
一. task選擇
到了這個(gè)階段,gradle開始計(jì)算task入口是哪個(gè)? 選擇的邏輯是這樣:
如果用戶收入了task,比如這樣的指令'gradle pmd',那么就執(zhí)行pmd這個(gè)task
如果用戶沒有輸入task,比如直接輸入'gradle',那么看有沒有默認(rèn)的task
如果沒有默認(rèn)的task,那就執(zhí)行help這個(gè)task。大家可以試下直接輸入gradle,看看輸出什么內(nèi)容。
接下來看源代碼。
文件路徑: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); } }); } }
這個(gè)地方的寫法挺奇怪的,它的想法是遍歷processingConfigurationActions里面的每個(gè)action,然后執(zhí)行它的configure方法,所以它用了遞歸。
但是個(gè)人覺得直接用循環(huán)不是更簡(jiǎn)單直接嗎?
先不去管這些,processingConfigurationActions里面有3個(gè)成員,他們繼承自同一接口BuildConfigurationAction。
org.gradle.execution.ExcludedTaskFilteringBuildConfigurationAction@3ee68eb2 index: 0 org.gradle.execution.DefaultTasksBuildExecutionAction@49cd08f9 index: 1 org.gradle.execution.TaskNameResolvingBuildConfigurationAction@4eace42b index: 2
他們3個(gè)分別處理的事情不一樣。
a. ExcludedTaskFilteringBuildConfigurationAction用來處理不執(zhí)行的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用來處理默認(rèn)的task,如果用戶有輸入task,那么就使用用戶輸入的。比如用戶輸入'gradle pmd',那么使用的task就是pmd
如果用戶沒有輸入task,那么就使用默認(rèn)的task
如果默認(rèn)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,嘗試使用默認(rèn)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(如果沒有輸入,則使用默認(rèn)task或者 help)添加到executer里面,為真正執(zhí)行做準(zhǔn)備。
代碼路徑:
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); }
到此為止,所有的準(zhǔn)備工作都已經(jīng)做好了,接下就要真正的執(zhí)行這個(gè)task了。
配置文件加載
gradle文件加載以及相應(yīng)的plugin 類加載
要執(zhí)行的task選擇
下一篇帖子講task的執(zhí)行。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。