Promise<Result> (@NotNull Project project, @NotNull ProjectTaskContext context, ProjectTask @NotNull ... tasks) { AsyncPromise<Result> resultPromise = new AsyncPromise<>(); TasksExecutionSettingsBuilder executionSettingsBuilder = new TasksExecutionSettingsBuilder(project, tasks); Set<String> rootPaths = executionSettingsBuilder.getRootPaths(); if (rootPaths.isEmpty()) { LOG.warn("Nothing will be run for: " + Arrays.toString(tasks)); resultPromise.setResult(TaskRunnerResults.SUCCESS); return resultPromise; } AtomicInteger successCounter = new AtomicInteger(); AtomicInteger errorCounter = new AtomicInteger(); File outputPathsFile = createTempOutputPathsFileIfNeeded(context); TaskCallback taskCallback = new TaskCallback() { @Override public void onSuccess() { handle(true); } @Override public void onFailure() { handle(false); } private void handle(boolean success) { int successes = success ? successCounter.incrementAndGet() : successCounter.get(); int errors = success ? errorCounter.get() : errorCounter.incrementAndGet(); if (successes + errors == rootPaths.size()) { if (!project.isDisposed()) { try { if (GradleImprovedHotswapDetection.isEnabled()) { GradleImprovedHotswapDetection.processInitScriptOutput(context, outputPathsFile); } else { Set<String> affectedRoots = getAffectedOutputRoots(outputPathsFile, context, executionSettingsBuilder); if (!affectedRoots.isEmpty()) { if (context.isCollectionOfGeneratedFilesEnabled()) { context.addDirtyOutputPathsProvider(() -> affectedRoots); } // refresh on output roots is required in order for the order enumerator to see all roots via VFS // have to refresh in case of errors too, because run configuration may be set to ignore errors CompilerUtil.refreshOutputRoots(affectedRoots); } } } finally { if (outputPathsFile != null) { FileUtil.delete(outputPathsFile); } } } resultPromise.setResult(errors > 0 ? TaskRunnerResults.FAILURE : TaskRunnerResults.SUCCESS); } else { if (successes + errors > rootPaths.size()) { LOG.error("Unexpected callback!"); } } } }; for (String rootProjectPath : rootPaths) { if (!executionSettingsBuilder.containsTasksToExecuteFor(rootProjectPath)) { taskCallback.onSuccess(); LOG.warn("Nothing will be run for: " + Arrays.toString(tasks) + " at '" + rootProjectPath + "'"); continue; } if (outputPathsFile != null && context.isCollectionOfGeneratedFilesEnabled()) { String outputFilePath = FileUtil.toCanonicalPath(outputPathsFile.getAbsolutePath()); GradleVersion v68 = GradleVersion.version("6.8"); Supplier<String> initScriptSupplier; Supplier<String> initScriptUsingServiceSupplier; if (GradleImprovedHotswapDetection.isEnabled()) { initScriptSupplier = () -> GradleImprovedHotswapDetection.getInitScript(outputPathsFile); initScriptUsingServiceSupplier = () -> GradleImprovedHotswapDetection.getInitScriptUsingService(outputPathsFile); } else { initScriptSupplier = () -> String.format(COLLECT_OUTPUT_PATHS_INIT_SCRIPT_TEMPLATE, outputFilePath); initScriptUsingServiceSupplier = () -> String.format(COLLECT_OUTPUT_PATHS_USING_SERVICES_INIT_SCRIPT_TEMPLATE, outputFilePath); } var simple = new LazyVersionSpecificInitScript(initScriptSupplier, "ijpathcollect", v -> v.compareTo(v68) < 0); var services = new LazyVersionSpecificInitScript(initScriptUsingServiceSupplier, "ijpathcollect", v -> v.compareTo(v68) >= 0); executionSettingsBuilder.addInitScripts(rootProjectPath, simple, services); } ExternalSystemTaskExecutionSettings settings = executionSettingsBuilder.build(rootProjectPath); UserDataHolderBase userData = new UserDataHolderBase(); userData.putUserData(PROGRESS_LISTENER_KEY, BuildViewManager.class); userData.putUserData(GradleTaskManager.VERSION_SPECIFIC_SCRIPTS_KEY, executionSettingsBuilder.getVersionedInitScripts(rootProjectPath)); userData.putUserData(GradleTaskManager.INIT_SCRIPT_KEY, join(executionSettingsBuilder.getInitScripts(rootProjectPath), System.lineSeparator())); userData.putUserData(GradleTaskManager.INIT_SCRIPT_PREFIX_KEY, settings.getExecutionName()); ExternalSystemUtil.runTask(settings, DefaultRunExecutor.EXECUTOR_ID, project, GradleConstants.SYSTEM_ID, taskCallback, ProgressExecutionMode.NO_PROGRESS_ASYNC, false, userData); } return resultPromise; }