Skip to content

Commit

Permalink
Store IDE hook state as an input on SpotlessTaskImpl so that we don…
Browse files Browse the repository at this point in the history
…'t violate any configuration cache rules.
  • Loading branch information
nedtwigg committed Oct 24, 2024
1 parent 0f88859 commit ce70ea7
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,34 @@
import java.io.IOException;
import java.nio.file.Files;

import javax.annotation.Nullable;

import org.gradle.api.Project;

import com.diffplug.common.base.Errors;
import com.diffplug.common.io.ByteStreams;
import com.diffplug.spotless.DirtyState;
import com.diffplug.spotless.Formatter;
import com.diffplug.spotless.NoLambda;

class IdeHook {
static class State extends NoLambda.EqualityBasedOnSerialization {
final @Nullable String path;
final boolean useStdIn;
final boolean useStdOut;

State(Project project) {
path = (String) project.findProperty(PROPERTY);
if (path != null) {
useStdIn = project.hasProperty(USE_STD_IN);
useStdOut = project.hasProperty(USE_STD_OUT);
} else {
useStdIn = false;
useStdOut = false;
}
}
}

final static String PROPERTY = "spotlessIdeHook";
final static String USE_STD_IN = "spotlessIdeHookUseStdIn";
final static String USE_STD_OUT = "spotlessIdeHookUseStdOut";
Expand All @@ -33,9 +55,8 @@ private static void dumpIsClean() {
System.err.println("IS CLEAN");
}

static void performHook(SpotlessTaskImpl spotlessTask) {
String path = (String) spotlessTask.getProject().property(PROPERTY);
File file = new File(path);
static void performHook(SpotlessTaskImpl spotlessTask, IdeHook.State state) {
File file = new File(state.path);
if (!file.isAbsolute()) {
System.err.println("Argument passed to " + PROPERTY + " must be an absolute path");
return;
Expand All @@ -50,7 +71,7 @@ static void performHook(SpotlessTaskImpl spotlessTask) {
}
}
byte[] bytes;
if (spotlessTask.getProject().hasProperty(USE_STD_IN)) {
if (state.useStdIn) {
bytes = ByteStreams.toByteArray(System.in);
} else {
bytes = Files.readAllBytes(file.toPath());
Expand All @@ -63,7 +84,7 @@ static void performHook(SpotlessTaskImpl spotlessTask) {
System.err.println("Run 'spotlessDiagnose' for details https://github.com/diffplug/spotless/blob/main/PADDEDCELL.md");
} else {
System.err.println("IS DIRTY");
if (spotlessTask.getProject().hasProperty(USE_STD_OUT)) {
if (state.useStdOut) {
dirty.writeCanonicalTo(System.out);
} else {
dirty.writeCanonicalTo(file);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 DiffPlug
* Copyright 2016-2024 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -48,15 +48,15 @@ public SpotlessExtensionImpl(Project project) {

@Override
protected void createFormatTasks(String name, FormatExtension formatExtension) {
boolean isIdeHook = project.hasProperty(IdeHook.PROPERTY);
IdeHook.State ideHook = new IdeHook.State(project);
TaskContainer tasks = project.getTasks();

// create the SpotlessTask
String taskName = EXTENSION + SpotlessPlugin.capitalize(name);
TaskProvider<SpotlessTaskImpl> spotlessTask = tasks.register(taskName, SpotlessTaskImpl.class, task -> {
task.init(getRegisterDependenciesTask().getTaskService());
task.setGroup(TASK_GROUP);
task.setEnabled(!isIdeHook);
task.getIdeHookState().set(ideHook);
// clean removes the SpotlessCache, so we have to run after clean
task.mustRunAfter(BasePlugin.CLEAN_TASK_NAME);
});
Expand All @@ -75,23 +75,18 @@ protected void createFormatTasks(String name, FormatExtension formatExtension) {
TaskProvider<SpotlessApply> applyTask = tasks.register(taskName + APPLY, SpotlessApply.class, task -> {
task.init(spotlessTask.get());
task.setGroup(TASK_GROUP);
task.setEnabled(!isIdeHook);
task.setEnabled(ideHook.path == null);
task.dependsOn(spotlessTask);
});
rootApplyTask.configure(task -> {
task.dependsOn(applyTask);

if (isIdeHook) {
// the rootApplyTask is no longer just a marker task, now it does a bit of work itself
task.doLast(unused -> IdeHook.performHook(spotlessTask.get()));
}
task.dependsOn(ideHook.path == null ? applyTask : spotlessTask);
});

TaskProvider<SpotlessCheck> checkTask = tasks.register(taskName + CHECK, SpotlessCheck.class, task -> {
SpotlessTaskImpl source = spotlessTask.get();
task.setGroup(TASK_GROUP);
task.init(source);
task.setEnabled(!isIdeHook);
task.setEnabled(ideHook.path == null);
task.dependsOn(source);

// if the user runs both, make sure that apply happens first,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
import org.gradle.api.GradleException;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileSystemOperations;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.CacheableTask;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.TaskAction;
import org.gradle.work.ChangeType;
Expand All @@ -46,6 +48,9 @@

@CacheableTask
public abstract class SpotlessTaskImpl extends SpotlessTask {
@Input
abstract Property<IdeHook.State> getIdeHookState();

@Internal
abstract DirectoryProperty getProjectDir();

Expand All @@ -69,6 +74,12 @@ Provider<SpotlessTaskService> getTaskServiceProvider() {

@TaskAction
public void performAction(InputChanges inputs) throws Exception {
IdeHook.State ideHook = getIdeHookState().getOrNull();
if (ideHook != null && ideHook.path != null) {
IdeHook.performHook(this, ideHook);
return;
}

SpotlessTaskService taskService = getTaskService().get();
taskService.registerSourceAlreadyRan(this);
if (target == null) {
Expand Down

0 comments on commit ce70ea7

Please sign in to comment.