Support using projects as step dependency (ktlint rule sets only at this time)#2999
Open
bric3 wants to merge 6 commits into
Open
Support using projects as step dependency (ktlint rule sets only at this time)#2999bric3 wants to merge 6 commits into
bric3 wants to merge 6 commits into
Conversation
Use named project configurations so existing configurations.all rules can continue substituting a Maven rule set with a local project. Keep root buildscript resolution detached for Gradle 9 compatibility. This is a transitional compatibility fix. A follow-up adds an explicit project dependency API because named configurations are not suitable for every resolution scope.
Ktlint custom rule sets could previously rely on dependency substitution to replace a module with a local project. Detached configurations introduced for Gradle 9 buildscript predeclaration do not inherit those container-wide rules. Accept project dependencies directly and register their resolved JARs as Spotless task inputs. Gradle can infer producer tasks while preserving incremental and configuration-cache behavior, including transitive and predeclared project rules.
Resolve ktlint, Maven rule sets, and local project rule sets through one detached configuration. Gradle can mediate shared transitives and infer producer tasks. Keep the ktlint version selected by the DSL strict. Model generated project JARs as additional `@Classpath` inputs and defer their signatures until execution. This preserves configuration-cache reuse and predeclare semantics while rejecting projects that request another version of the selected ktlint module.
Change and reload a real local rule provider after restoring the predeclared classpath from configuration cache. This proves Gradle rebuilds the producer JAR and reruns Spotless with the new implementation.
Contributor
Author
|
cc @ntkoopman |
Member
|
Wow! This was very kind of you @bric3, a lot of complexity for an unusual case. This LGTM although we need to fix the windows test failures somehow. |
Oracle explicitly documents that open URLClassLoader JARs cannot be replaced on Windows until the loader is closed. Technotes on URLClassLoader : > The application can then replace the JAR file, and create a new > URLClassLoader instance to load from the same location, but this time > using the new implementation of the classes/resources. However, since > it can't be predicted exactly when finalization and garbage collection > will occur, problems are caused for applications which need to be able > to do this in a predictable and timely fashion. > It is a problem on Windows, because open files cannot be deleted or > replaced. https://docs.oracle.com/javase/8/docs/technotes/guides/net/ClassLoader.html
Contributor
Author
Yes, I started minimalist, then other things to consider started to fall apart when tested 😢 |
Contributor
Author
|
oh no my attempted fix didn't work 😢 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ktlint custom rule sets can now be supplied as local Gradle projects:
spotless { kotlin { ktlint("1.0.1").customRuleSets( "com.example:published-rules:1.2", project(":ktlint-rules"), ) } }This removes the need to rely on configuration-wide dependency substitution when using an unpublished rule set from the same Gradle build. Seen in #1901 (comment)
Motivation
The detached configurations introduced in #2929 are necessary for Gradle 9 buildscript predeclaration. However, detached configurations are not part of the project's configuration container, so rules registered through
configurations.configureEach, including dependency substitution, do not apply to them.Comments in #1901 suggests some builds relied on that undocumented behavior to substitute a published ktlint rule-set coordinate with a local project, as discussed in #1901. Indeed the DSL already supported the idea with an API that allowed to pass maven coordinates. Having the DSL to support local projects seems legitimate.
Implementation
This was trickier than anticipated. As multiple aspects surface in when properly requesting a project.
Here's what changed:
Projectinstances alongside maven coordinates incustomRuleSets.dependsOn.spotlessPredeclarebehavior.Please DO NOT FORCE PUSH. Don't worry about messy history, it's easier to do code review if we can tell what happened after the review, and force pushing breaks that.
Please make sure that your PR allows edits from maintainers. Sometimes it's faster for us to just fix something than it is to describe how to fix it.
After creating the PR, please add a commit that adds a bullet-point under the
[Unreleased]section of CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md which includes:If your change only affects a build plugin, and not the lib, then you only need to update the
plugin-foo/CHANGES.mdfor that plugin.If your change affects lib in an end-user-visible way (fixing a bug, updating a version) then you need to update
CHANGES.mdfor both the lib and all build plugins. Users of a build plugin shouldn't have to refer to lib to see changes that affect them.This makes it easier for the maintainers to quickly release your changes :)