I've created a ticket for explicit script dependen...
# scripting
a
I've created a ticket for explicit script dependencies declaration: https://youtrack.jetbrains.com/issue/KT-31021. I do not have a clear idea about such declarations, but I think we really need them, otherwise tooling for script writing seems to be very unstable.
g
I commented your issue about Gradle-related use case
a
Still did not manage to move dev configutation to buildSrc. When two or more plugins are starting to interact, process of finding problems in configuration becomes quite painful. Everything is "red" and you do not know which module causes the problem. I think that the problem lies exactly in what I have written in the issue, namely inability to explicitly define environment for each separate file.
g
But you can define environment for each separate file
a
You mean plugins block? It does not work. I can't understand how those plugins blocks are loaded and where should I declare the version (because I can do it only once). Also, in your example you use a regular function for configuration, but in dev branch I have to use node plugin for js tests and I can't see node plugin form this file without additionally configuring plugins. And I can't use plugins block for regular kt file
g
It does not work
It works, I showed it in my sample
but in dev branch I have to use node plugin for js tests
I will send you sample of this later
a
I tried to reproduce it and got a lot of bizarre errors without any way to understand why I got them.
g
I can’t understand how those plugins blocks are loaded and where should I declare the version
If you use this plugin in buildSrc you should define version in buildSrc/build.gradle dependencies
a
Also, why do you use function for MPP configuration instead of plugin? It should work as well.
g
Yes, it will work, just an example, didn’t refactor it to plugin
Okay
give me 5 min, I have a half-backed config for your dev branch, I will push it
a
It is not urgent.
g
It’s just easier to explain with code
you right, better to use plugin instead of just a function, you have type safe accessors
a
It is just frustrating, I've spent few hours yesterday and today and did not manage it to work.
For now there is only problem with
artifactory
plugin, which is purely dynamic, for some reason
publishBuildInfo
property doesn’t work
a
Thanks I will try to make it work
g
Also I’m not sure what is worked before what is not, because JS test failed, but maybe it because problem after migration
@altavir One more thing
RealLUSolverTest > testInvert
is falling for me, but I don’t think that it’s build config problem
a
I've fixed it quite recently, so, no, it is probably not build.
Seems to be working, but IDEA still does not recognize most of the code in buildSrc
Fixed after build
g
Yeah, tooling is still not so smooth, it should index and apply dependencies, same as for any build.gradle.kts but it’s one more additional level
but it’s tooling problem, not problem of build itself
a
I think in still could be solved by explicit script receivers. This way IDE always now what to expect in the script without full compilation.
g
no, you don’t need full compilation
plugins
block is exactly this explicit script receiver that defines classpath of the script
a
The classpath and script receiver are different things. For gradle we probably need both.
g
okay, what is script receiver than? probably I misunderstood your idea
a
For gradle, in most cases the receiver is a
Project
instance, but in some cases it could be a plugin configuration class like
KotlinMultiplatformExtension
if I am running script inside appropriate block. There could be multiple implicit receivers in one script
g
but how you can define it?
see my new exampl
KotlinMultiplatformExtension
is not required
you just configure what you want in type safe accessor
and apply it to any module where you need it
if I am running script inside appropriate block
Again, if you just need some context, why not just use extension function for this context, why do you want use
include
for this
a
Yes, but you implicitly assume that configuration is run inside appropriate plugin block.
g
What do you mean?
a
Because extension function can't have multiple receivers, but script can.
What will happen when you try to apply mpp configuration in wrong plugin?
g
just use function and pass all required receivers, no need to use any kind
include
as in any other Kotlin code
What will happen when you try to apply mpp configuration in wrong plugin
But this checked on build script compile time, not even on runtime
approach with precompiled plugins apply this plugin explicitly to any module where it applied
approach with function that configures some config even do not require plugin application, because you cannot call it if you don’t have required receiver
a
I just tried to move
apply(plugin = "multiplatform-config")
outside plugin check and got completely uncomprehensible error in kotlin-jvm plugin.
g
Yes, because you applied this plugin to module that another incompatible plugin
I would rewrite it and apply
multiplatform-config
to every module explicitly
to avoid such clunky config
you would get the same error if apply
kotlin("jvm")
and
kotlin("multiplatform")
a
Yes, but if we had optional marking for script receivers, we would have type check for that.
g
I will update sample
what do you mean?
in general you should apply some config in root project only if you sure that this config is fine for all modules, otherwise better to do that explicitly
a
Let us assume that we have script call site (I am talking not only about gradle, but about any other script as well). It has a set of explicit receivers like
[ Project, KotlinMultiplatformExtension]
. Now I want to seamlessly move some logic from this block into external script (not necessary precompiled). All I need is to tell this script which receivers to expect and it could work as if the code was right there in the initial file. Also, when we call the script, we can statically check if declared receivers correspond to actual receivers at call site. The class-path is different problem.
g
It has a set of explicit receivers like
[ Project, KotlinMultiplatformExtension]
Copy code
fun Project.configureMpp(kotlin: KotlinMultiplatformExtension)
a
I am not arguing the point. It is possible to do. We are just not using scripting
implicitReceivers
feature to it maximum power.
g
Why do we need implicit receivers if we have explicit ones?
It doesn’t add any boilerplate and make everything type safe
@altavir I updated branch
build-config-refactoring-dev
with your changes from dev to fix conflicts and some additional changes, such as replacing kotlin(“multiplatform”) with id(“multiplatform-config”), so we don’t need this check in submodules
a
I was talking about explicitly defining them.
g
pushed few more changes
Maybe you could show some example how such receiver declaration would work?
a
The "context" for this feature is discussed at KEEP (https://github.com/Kotlin/KEEP/pull/176). Scripting is just one of possible applications for the concept.
g
Yes, I know this KEEP
I would like to have multiple receivers
But not sure how this related to
<https://youtrack.jetbrains.com/issue/KT-31021>
Yeah it would make this look nicer:
Copy code
fun Project.configureMpp(kotlin: KotlinMultiplatformExtension)
something like that
Copy code
fun (Project, KotlinMultiplatformExtension).configureMpp()
but not really differnt for me
a
It is the same basic idea. The difference is that scripting framework already have facilities for multiple receivers. What we lack is a way to make them explicit.
g
Yeah, now I see how multiple receivers may be used for scripting, but how it can be beneficial for Gradle Kotlin DSL?
a
In current precompiled plugins - not so much, but if we simply want to separate large script into few small ones, it could be quite beneficial.
g
Yes, I agree, this may be interesting use case, as I understand now, there is no way to include or just extract different scripts to own files and than combine them
My original comment in KT-31021 was exactly about this, that it may be beneficial (and as I see it now it’s definitely beneficial) for scripting in general, but Gradle has all the ways to manage it now without additional scripting features and actually doing this in a much more flexible way because provides system of plugins
@altavir I updated branch with type safe accessors for sourceSets, now it actually looks good, thanks to explicit multiplatform-config plugin
a
OK, I've update my own branch, I will try to merge it then.
g
I’m not really test publishing, only to mavenLocal(), also I still not sure about problem with artifactory publishBuildInfo property
I can send PR if you want
a
I need to upload my own changes first
g
sure
a
We probably need those things as a stand-alone plugins because they are used quite broadly. I believe JS testing will be present in the next plugin release, but everything else needs to be kotlinified.
g
yes, I agree, I thought about publish this
but it works only with very opinionated config
if you try to make it flexible and configurable it become much more complicated to write plugin
actually, you can even publish those precompiled plugins, it’s possible even from buildSrc
a
I will probably do so sooner or later, because I have several mpp-multiprojects projects with similar structure.
g
lack of opionated publishing is big pain for Gradle imo
probably one day I will return to my abandoned Gradle plugin, where I worked on publishing simplification for common use cases, now it’s easier to do with some latest changes in Gradle