Hi guys, how to mark a closure or lambda as `@Inpu...
# community-support
z
Hi guys, how to mark a closure or lambda as
@Input
, I tried something like:
Copy code
kt
  @get:Optional
  @get:Input
  public open val keyTransformer: Property<KeyTransformer> = objectFactory.property()

  public fun interface KeyTransformer : Serializable {
    public fun transform(key: String): String
  }
but it fails for:
Copy code
java.lang.NoClassDefFoundError: com/github/jengelman/gradle/plugins/shadow/transformers/KeyTransformer
  at org.gradle.internal.cc.impl.serialize.ClassLoadingKt.classForName(ClassLoading.kt:27)
  at org.gradle.internal.cc.impl.serialize.DefaultClassDecoder.decodeClass(DefaultClassDecoder.kt:50)
  at org.gradle.internal.serialize.graph.DefaultReadContext.readClass(Contexts.kt:288)
  at org.gradle.internal.serialize.graph.codecs.BeanCodec.decode(BeanCodec.kt:41)
  at org.gradle.internal.serialize.graph.CombinatorsKt$reentrant$1$decodeLoop$1.invokeSuspend(Combinators.kt:122)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
  at kotlin.coroutines.ContinuationKt.startCoroutine(Continuation.kt:115)
or
Copy code
> Cannot fingerprint input property 'transformers.PropertiesFileTransformer_Decorated$0.keyTransformer': value 'build_6c52heuashhvkr1mlhojx3t85$1@30280cc3' cannot be serialized.
b
You can‘t really capture a function as input. Inputs should be data, such as scalar values or files. What’s the bigger picture here? Do you want to let users specify the behavior of the task?
z
I wan't to make ShadowJar task re-executed after keyTransformer changed, keyTransformer is configurable, but seems no way to do so. https://github.com/GradleUp/shadow/blob/main/src/main/kotlin/com/github/jengelman/[…]gradle/plugins/shadow/transformers/PropertiesFileTransformer.kt
a
I think you'd have to create another
@Input
property and expose the dynamic value as a ValueSource
z
That sounds like a good idea!
But we still need
(String) -> String
invocations in execution time,
ValueSource
seems is not suitable for this case...
b
You could look into Gradle‘s code how Copy tracks the closures passed to from and into. But I don‘t think it does it correctly. I think if you have an up to date Copy and you change the closure it‘s still up to date 🤷‍♂️
l
@get:Nested val keyTransformer: Property<(String) -> String>
might work
j
I think this is in fact an open issue in the Copy tasks: https://github.com/gradle/gradle/issues/861 (known issue for 8 years 🙈 ) Generally, I think there it is solved by all closures/lambdas/actions filling a CopySpec, which is then serializable. But having that ability to define a
(String)->String
transformer as input would be interesting for a couple of use cases. I had a similar request for a plugin recently... Please share if you discover a working solution.
z
Thanks for your sharing.