Why is my Gradle plugin causing `Circular dependen...
# community-support
s
Why is my Gradle plugin causing
Circular dependency between the following tasks:
work action Dependencies for XXXXXX
? Looks like the transform action depends on each other? The image is the cycle shows in debugger. Looks like the states of different transform is looping. How can I avoid that? https://github.com/SettingDust/cloche/blob/feature/extract-includes/src/main/kotlin/earth/terrarium/cloche/target/TargetCompilation.kt#L122-L148
Circular dependency between the following tasks:
work action Dependencies for dev.su5ed.sinytra.fabric-api:fabric-api-deprecated:0.92.2+1.11.11+1.20.1 {earth.terrarium.cloche.modState=none}
The Gradle always prefer the shortest path to pick the variant. I can't make the
None
compatible with
Handled
and make the remap action depends on the includes actions. The X problem here is how can I make the remap action prefer
Extracted
than
None
but also accept None at the same time?
v
I guess you need to register the remap action twice, once for transforming "extracted and initial" to "extracted and remapped" and once for transforming "none and initial" to "none and remapped" and then have a disambiguation rule that tells to use "extracted" if both are available or something like that.
👀 1
s
thanks a lot. I'll test
👌 1
Why is it failing with
There was a failure while populating the build operation queue: Value for parameters of RemapAction has not been calculated yet.
I don't know how could I debug https://scans.gradle.com/s/dm2pajihvprjm
Copy code
val remapActionSpec = Action<TransformSpec<RemapAction.Parameters>> {
            it.from.attribute(
                ModTransformationStateAttribute.ATTRIBUTE,
                ModTransformationStateAttribute.INITIAL,
            )

            it.to.attribute(
                ModTransformationStateAttribute.ATTRIBUTE,
                ModTransformationStateAttribute.of(target, compilation, States.REMAPPED),
            )

            it.parameters {
                it.mappings.set(target.loadMappingsTask.flatMap(LoadMappings::output))

                it.sourceNamespace.set(target.modRemapNamespace.get())

                it.extraClasspath.from(compilation.intermediaryMinecraftClasspath)

                it.cacheDirectory.set(getGlobalCacheDirectory(project))

                val modCompileClasspath = project.getModFiles(compilation.sourceSet.compileClasspathConfigurationName) {
                    it.attributes {
                        it.attribute(
                            ModTransformationStateAttribute.ATTRIBUTE,
                            ModTransformationStateAttribute.INITIAL,
                        )
                    }
                }

                val modRuntimeClasspath = project.getModFiles(compilation.sourceSet.runtimeClasspathConfigurationName) {
                    it.attributes {
                        it.attribute(
                            ModTransformationStateAttribute.ATTRIBUTE,
                            ModTransformationStateAttribute.INITIAL,
                        )
                    }
                }

                it.modFiles.from(modCompileClasspath)
                it.modFiles.from(modRuntimeClasspath)
            }
        }

        project.dependencies.registerTransform(RemapAction::class.java) {
            it.from.attribute(IncludeTransformationState.ATTRIBUTE, IncludeTransformationState.Handled)
            remapActionSpec.execute(it)
        }

        project.dependencies.registerTransform(RemapAction::class.java) {
            it.from.attribute(IncludeTransformationState.ATTRIBUTE, IncludeTransformationState.None)
            remapActionSpec.execute(it)
        }
v
Probably because your try to use task outputs as transformation parameter. Just a wild guess though. But almost any need to use
afterEvaluate
is a strong sign that you do something bad. :-)
s
hmmm. It's fine when there is only one remap action. For
afterEvaluate
. There is some user defined lazy configurable. The design here is problematic ya.
v
For such things I found the best solution usually to not have some
Property
that the user configures, but to have a function in the extension that the user can call with the value as argument and then do the necessary configuration in the function body, eventually preventing multiple calls to the function if the first call effect could not be "undone" in the second call.
s
It's a bit complex. Some configuration will be created after user configuring. Which the action needing. Need a refactor anyway.
If I comment out the two include states actions. The remap will work hm
v
Some configuration will be created after user configuring
That's why I said, in a function the user calls. 🙂
👀 1
The moment the user calls the function, you should be able to do the configuration
s
How can I use fallback config if no one called? A
configured
var and execute the configure if it's false when after evaluate?
oh wait. I should make all of them be providers I think
The config should be used and locked after provided
v
Fallback is not really possible nicely. As whenever you check whether to apply the fallback, the user could do the configuration still after that. If you for example do it in
afterEvaluate
(like now), then still the user could do the configuration himself within
afterEvaluate
(which can happen for various reasons) and as he registered his
afterEvaluate
after yours, yours run first. That's why the main earning of using
afterEvaluate
is to introduce timing problems, ordering problems, and race conditions.
If the configuration is something that can be "changed" according to needs, then just do the default right away and change it in the function body. If it can only be done once and not adapted, just require that the user does the function call.
s
How can I know what's the parameter can't be calculated?
v
By debugging I guess
s
I don't know how could I debug the parameters :((
v
Set a breakpoint where the exception happens?
s
find out :DDD. The parameter have cycle. Another problem appears. Only the
None
include state remap action being used. The
Handled
one is ignored. The
DisambiguationRule
haven't invoked at all
图片.png
v
Probably because you didn't what I suggest?
I said
once for transforming "extracted and initial" to "extracted and remapped" and once for transforming "none and initial" to "none and remapped"
what you did is
once for transforming "extracted and initial" to "remapped" and once for transforming "none and initial" to "remapped"
Besides, where comes Handled into play anyway, you did not have anything that transforms to Handled, did you?