Running Multiple Reformat Gradle Tasks Gives Error


I have a plugin where we are trying to change it to run its reformat action on save on multiple files at once. 


We do this now by looping through all open files being saved, e.g. 

for (Document document : documents) {
var file = PsiDocumentManager.getInstance(project).getPsiFile(document);

if (file == null) {

new ReformatCodeProcessor(file).run();

The actual gradle task execution is as follows:

// Constructs execution settings, setting the gradle task and its options
ExternalSystemTaskExecutionSettings settings = constructTaskExecutionSettings(fileToProcess);

// Execute gradle task
ExternalSystemUtil.runTask(settings, DefaultRunExecutor.EXECUTOR_ID, myProject, GradleConstants.SYSTEM_ID, null,
ProgressExecutionMode.IN_BACKGROUND_ASYNC, false);

However when testing this, we get the error:

Cannot use connection to Gradle distribution xxxx as it has been stopped.

See a reproduction of the issue here

Any idea how to fix this?

评论操作 固定链接

How is the reformatting related to executing a Gradle task? When and where is that Gradle task triggered from?

评论操作 固定链接

Hi Yahn, sorry it wasn't more clear. The 'reformatting' is done through a spotless gradle task. 

So the flow is the user kicks off an Action:

ReformatCodeAction extends AnAction

which then calls a processor:

public class ReformatCodeProcessor extends AbstractLayoutCodeProcessor

This then calls the actual gradle task as shown above. Does that help clear things up?

评论操作 固定链接

There's dedicated hook to invoke external formatter, did you consider it? Not sure why you want to call it via Gradle.

评论操作 固定链接

Yann, I think it's because a lot of people already use Spotless Gradle , which includes features listed in that README such as:

Spotless supports all of Gradle's built-in performance features (incremental build, remote and local buildcache, lazy configuration, etc), and also automatically fixes idempotence issues, infers line-endings from git, is cautious about misconfigured encoding bugs, and can use git to ratchet formatting without "format-everything" commits.

It also allows for a lot of settings as shown here

Even if this isn't necessarily the correct way to do it, using the external code formatter sounds like a new project outside the scope of spotless-intellij-gradle since we would have to implement these steps and the result would be more of a `spotless-intellij` project than a `spotless-intellij-gradle` project.

Could you help with how to fix this current problem of not being able to run multiple gradle tasks at once to unblock this format on save feature for this specific plugin which uses Spotless Gradle for the formatting? Or is that not possible?

评论操作 固定链接

Ryan Gurney what is the reason to call the formatter on per-file basis? Is not one invocation enough?
From what I see in the docs, the Gradle-Spotless plugin does not have file specific tasks, it always works per-project.
Also, Gradle does not officially support running multiple builds of same project in parallel.

As Yann Cebron already mentioned, the External Code Formatter API is a great place to call external tool to format the code. You can use same API   ExternalSystemUtil.runTask   there to invoke spotlessApply task

评论操作 固定链接

Nikita Skvortsov that's a very good point, and thanks for the response! Spotless actually does have file-specific functionality in the Gradle plugin using the ide hook, however right now it only supports one file. There is a request for that to change but I doubt it will be done in the near future. Running the gradle command without that flag would result in ALL files in the project being processed by the plugin, which would take a very long time and isn't really in the spirit of "format on save". 

Perhaps all I can do right now is wait for the ide hook to support multiple files. 


re: External Code Formatter -- what benefits does that give for running the gradle task as opposed to my current implementation running the task via an Action? 

评论操作 固定链接

External Code Formatter benefits are not about running the gradle task (this code will stay the same), but about integrating into IDEA's ecosystem. Your formatter will be properly called on "Reformat Code..." action in IDEA, will respect Actions on Save configuration, will be able to get text ranges to format etc.