https://kotlinlang.org logo
Title
p

pablisco

02/13/2020, 12:31 PM
f

Fleshgrinder

02/13/2020, 12:36 PM
If it wouldn't still be stringly typed it would be brilliant (consider it a feature request 😉 ).
Something similar for other dependencies would be nice too.
api("org.openjdk.jmh", "1.23") { api("jmh-core"); api("jmh-generator-annprocess") }
(just using JMH here because I have a build file with it directly in front of me).
p

pablisco

02/13/2020, 12:42 PM
yeah, someone mentioned that, looking into it now 🙂
Aaarg! Can’t share code between settings and modules 😭 And settings.gradle is compiles before buildSrc 🙃
f

Fleshgrinder

02/13/2020, 1:47 PM
The
buildSrc
approach is a well known one but it comes with major drawbacks and makes the overall handling actually more complicated than it has to be.
o

Oleg Yukhnevich

02/13/2020, 1:50 PM
for me,
buildSrc
is really very usable, so I can very easy configure every module similar and configurable So, it's project related I think
f

Fleshgrinder

02/13/2020, 1:57 PM
Drawbacks include: you always need to search for an appropriate name and cross your fingers that it never collides with anything else; backticks won't help because dependencies contain tons of chars that are illegal and if we verbatim repeat the name of the dependency we can anyways directly use a string. Gradle will be slower but much worse IntelliJ will be as it has big troubles with Kotlin Script (this is a general known issue). Versions are hardcoded for dependencies, this might be fine for a simple multi-module library where everything is anyways always the same (although it probably could use capabilities) but is a deal breaker for a monorepo with multiple microservices. I went through many iterations with Gradle and declaring dependencies with small to big teams. I never found the right strategy that is understood by everyone and easy to use.
j

Javier

02/13/2020, 2:01 PM
@Oleg Yukhnevich when you update your gradle to 6.0 your settings.gradle.kts will stop working
p

pablisco

02/13/2020, 2:02 PM
Yeah, I was about to mention that, you’re in for a suprise 😅
o

Oleg Yukhnevich

02/13/2020, 2:03 PM
hm, no, it's gradle 6, and it's work 🙂
we can anyways directly use a string
But, if to think, we don't always now string exactly, rly
IntelliJ will be as it has big troubles with Kotlin Script
with 1.3.70 kotlin and 6.x gradle - it's really now much faster, then before
Versions are hardcoded for dependencies
in my lib versions can be easily overridden, if it needed just take any dependency, and use
.version("1.5.0")
or `.version(project.properties["some_version"])
I never found the right strategy that is understood by everyone and easy to use.
Can you also share you tries and drawbacks of them?
j

Javier

02/13/2020, 2:38 PM
@Oleg Yukhnevich I checked your repo and you are using gradle 5.6.4 in your develop branch https://github.com/whyoleg/kamp/blob/develop/gradle/wrapper/gradle-wrapper.properties
o

Oleg Yukhnevich

02/13/2020, 2:39 PM
I sent second repository, where that
plugin
is used 🙂 here: https://github.com/whyoleg/ktd/blob/clients-rework/gradle/wrapper/gradle-wrapper.properties and it's 6.1
j

Javier

02/13/2020, 2:44 PM
Not the same we are talking about I think. BTW feels free to update this https://github.com/whyoleg/kamp/blob/develop/gradle/wrapper/gradle-wrapper.properties I don't know how settings.gradle.kts can use Plugins.rootModule if when it compiles that object is not ready.
o

Oleg Yukhnevich

02/13/2020, 3:38 PM
Ah, about that Okay, It will not work with gradle 6, I know, I just need to inline classpaths But, it just a
plugin
configuration, and it's gradle version not so needed So, if u look at second repository, which I sent, there this plugin is used as build script classpath dependency in settings.gradle.kts and in buildSrc, and it works really well with gradle 6
p

pablisco

02/13/2020, 7:27 PM
I've got something that works on 6 and actually it's easier to use. I'll try to post it later 😅
f

Fleshgrinder

02/13/2020, 7:42 PM
The first thing we tried was dependency locks, but it was to complicated to update only parts. The Java ecosystem with its wild versioning is unbelievable and the major reason why something like this cannot work. PHP might be shit but their dependency management tool Composer got that right from the start. So does cargo from Rust. The next thing was the typed
buildSrc
approach. At that time many people came to this solution and everyone was posting about it everywhere. The issues mentioned above and the fact that many people were extremely confused by
buildSrc
made it a failure as well. The next thing I did was also in conjunction with
buildSrc
but without types, I kept the strings. I find it hard to explain but can post it later. It's actually pretty neat. What I mostly use today is https://plugins.gradle.org/plugin/nebula.resolution-rules combined with
platform
. Not many things require any versions anymore with this approach beause I'm mostly working with Spring. Of course there are still many projects that have no BOM (😠) but in those cases Nebula RR can mitigate it. It has its limitations too https://github.com/nebula-plugins/gradle-resolution-rules-plugin/issues/97 … so at the end of the day one always ends up with complicated Gradle scripts to get those wild Java dependencies nicely aligned.
o

Oleg Yukhnevich

02/14/2020, 7:19 AM
@pablisco
I'll try to post it later
Will wait to try it 🙂 Any git repo exists to track?
@Fleshgrinder Thx for explanation It's really interesting, how people are fighting with dependencies resolution For me, my approach really work good, but Now, I don't use it in really BIG projects, may be smth will change in future And one more thing, that my plugin is really rescue now for me, because it supports declaring MPP dependencies, which now, for many dependencies is really hard to use When you need to apply it in different sourceSets, with same everything except
common/jvm/js/native
suffix With my approach it one line, which, really, decrease amount of code needed for simple dependency management
f

Fleshgrinder

02/14/2020, 7:25 AM
👍 It's really great if it works for you. I think what we can learn from this thread is that it's really hard to find a common solution that works for everything. This also explains why the Gradle team hasn't found it yet. 😛
o

Oleg Yukhnevich

02/14/2020, 7:26 AM
I think,
Gradle metadata
is the first step, to create such solution, so in future, I believe smth will be
f

Fleshgrinder

02/14/2020, 7:29 AM
I sure hope so! But the various Java projects out there also have to settle on a versioning strategy that works and allows tools to build on top. SemVer is perfect for libraries and its time projects adopt it.
p

pablisco

02/14/2020, 4:02 PM
Ok, here is a first prototype: https://gist.github.com/pablisco/e50c792f1febb77af0fbc2d4f8f2810e It works, but I'm gonna try to make it into a grade plugin so it's reusable. I'll update here when ready. For now if anyone wants to try it on their own projects I'll welcome any feedback. The script generates a graph for the modules into
_modules.kt
inside
buildSrc
. This file is determined by the project's file structure. So it should be less friction when adding or extracting modules.
o

Oleg Yukhnevich

02/14/2020, 5:18 PM
I see, what you do, but, what if I need to ignore module for some time? or on some condition, for CI f.e.?
I do similar here https://github.com/whyoleg/kamp/blob/develop/lib/src/main/kotlin/dev/whyoleg/kamp/project/Module.kt (it also generate file in buildSrc, which can be used for modules dependencies) but with explicit modules: https://github.com/whyoleg/ktd/blob/master/settings.gradle.kts
p

pablisco

02/14/2020, 5:28 PM
I'm planning to add an ignore option once I create is as a plugin 😁
Forgot to mention, this adds type safety as we can use the generated modules like this:
api(local.core)
I'm also considering adding a separate plugin to add groovy support for projects that may have a mix of both languages (with large projects and teams it's not trivial to migrate them all at once)
o

Oleg Yukhnevich

02/14/2020, 6:38 PM
the same here: https://github.com/whyoleg/ktd/blob/clients-rework/ktd-client/build.gradle.kts
metadata {
        dependenciesMain {
            api(ProjectModules.core)
        }
    }
metadata is MPP target from kotlin plugin
ProjectModules
is auto generated file in buildSrc
p

pablisco

02/20/2020, 1:47 AM
Here is my implementation: https://github.com/pablisco/auto-module Let me know what you think.
o

Oleg Yukhnevich

02/20/2020, 6:18 AM
Interesting But what more interesting, is what it generate for one of my projects 🙂 I will try it later today!
👍 1
f

Fleshgrinder

02/20/2020, 7:58 AM
Very nice work, you should propose inclusion in Gradle. 🙂 The root module could also use the name of the root project instead of local, no?
p

pablisco

02/20/2020, 8:41 AM
It can be customised to any name 😁