spotless icon indicating copy to clipboard operation
spotless copied to clipboard

Avoid check of the ratchetFrom branch when Spotless not invoked

Open helloncode opened this issue 2 years ago • 2 comments

Currently, Spotless (Gradle Plugin) performs a check for the presence of the ratchetFrom branch on every command execution. This includes instances where Spotless-specific commands aren't called, which can lead to unnecessary checks, and adds the workaround (e.g. git fetch depth:0) for all cases.

Could we refine the ratchetFrom functionality so that it checks for branch presence only when a Spotless command is actually invoked?

I believe this adjustment could be beneficial for users who integrate Spotless into their development workflows, ensuring that the tool remains as efficient and unobtrusive as possible.

helloncode avatar Nov 23 '23 10:11 helloncode

It would also be nice if the ratchetFrom would accept a lazy string as a () -> String, Supplier<String>, or similar and not get the value of the lazy string until running a Spotless task.

In one of my build scripts, I've written some logic that shells out to git to find the name of the remote for the source repository. If the rachetFrom branch name was lazily evaluated only when a Spotless task is actually running, then I could perform the lookup as a Gradle task and cache the result as a task output.

popematt avatar Apr 12 '24 23:04 popematt

I managed to come up with a workaround using a Git tag.

Using the Kotlin Gradle DSL, and assuming there is a runCommand() extension function that does exactly what its name implies...

val SPOTLESS_TAG = "spotless-rachet-from-this-commit"
val rachetFromCommitIsh by lazy { TODO("Your logic here") } 

spotless {
    "git tag -f $SPOTLESS_TAG".runCommand()
    rachetFrom(SPOTLESS_TAG)
    // If we delete it now, it's too soon, but we can delete it once the task graph is complete 
    // so that it's cleaned up if no `spotless` tasks are going to be run.
    gradle.taskGraph.addTaskExecutionGraphListener { 
        "git tag -d $SPOTLESS_CHECKPOINT_TAG".runCommand()
    }
}

tasks.withType<SpotlessTask> {
    doFirst { "git tag -f $SPOTLESS_TAG $rachetFromCommitIsh".runCommand() }
    doLast { "git tag -d $SPOTLESS_TAG".runCommand() }
}

The downside is that this creates a new tag in (the local copy of) your Git repository. I can definitely live with that in a CI's local copy of the repo, and I think I can live with that on my local copy too.

popematt avatar May 10 '24 23:05 popematt