handstandsam
01/31/2024, 5:50 PM.gradle
, .kts
, .toml
. Amper is solving real problems, but do we need another format? Why can't this be a subset of Kotlin or a DSL so we can leverage all existing tooling? The Kotlin PSI tooling can parse this amper.kts
file that only allows a specific DSL. This would also allow us to leverage existing tooling, etc.
There is a lot of advanced usage and custom convention plugins that won't be able to be described in this format. I'm not suggesting that amper.kts
would do this either, but could at least use Kotlin syntax to avoid another language needed to be learned.David Herman
01/31/2024, 5:51 PMmbonnin
01/31/2024, 5:52 PM.kd
: https://kotlinlang.slack.com/archives/C062WG3A7T8/p1699895404568699?thread_ts=1699885069.375749&cid=C062WG3A7T8
I'd love to see something like this happening.
Not only does this mean I can reuse my "how to write litterals" knowledge but also could leverage the API lifecyle annotations like @OptIn
and @Deprecated
that I haven't seen in any other data languageDavid Herman
01/31/2024, 5:53 PMhandstandsam
01/31/2024, 5:54 PMDavid Herman
01/31/2024, 5:55 PMhandstandsam
01/31/2024, 5:56 PMtoml
but I was basically forced to. I wouldn't have chosen that, but I'm sure there are many reasons.David Herman
01/31/2024, 5:57 PMDavid Herman
01/31/2024, 5:58 PMamakeev
02/01/2024, 10:07 AMhandstandsam
02/01/2024, 3:29 PMbuild.gradle.kts
you can have some beautiful DSLs to orchestrate many plugins behind the scenes. One open source plugin is the https://slackhq.github.io/slack-gradle-plugin/ that allows you to do that kind of stuff. Square and Dropbox both have somewhat similar convention plugins.
You could have a really nice block under the kotlin {}
extension (even though it wouldn't be in the kotlin
plugin itself, that could allow you do configure all these things.
Your editor could have special logic for this part of the file to do additional validations, etc, but make this configuration as simple as possible.handstandsam
02/01/2024, 3:30 PMhandstandsam
02/01/2024, 3:32 PMkotlin {}
block, but you already own it, and they are extensible "gradle extensions" and just a DSL definition (meaning they can be used by any plugin)handstandsam
02/01/2024, 3:33 PMlibs toml
or somewhere elseamakeev
02/02/2024, 1:15 PMhandstandsam
02/02/2024, 2:02 PMamakeev
02/02/2024, 2:10 PMDavid Herman
02/02/2024, 4:15 PMmbonnin
02/02/2024, 4:29 PMmbonnin
02/02/2024, 4:31 PMmbonnin
02/02/2024, 4:33 PMamakeev
02/02/2024, 4:53 PMJavier
02/02/2024, 7:31 PMif else
and, overall, deferring everything to Gradle to not throw me through the window.
I have tons of repositories, and each repository has its main branch protected with specific jobs, as I use a Matrix to build the projects with the three OS, those jobs are called: build / macos-latest
, build / ubuntu-latest
, and build / windows-latest
.
What is happening now? I just want to change from macos-latest
to macos-14
to use the new M1 runner, and as I am using reusable workflows, I can edit only a single Yaml, and all repositories will start to use it... but now the job name is no longer called macos-latest
. I need to go to dozens of repositories to change manually the job that protects the branch, if not, I cannot merge any pull request.
So I was thinking of a way to avoid this in the future, and that's it, instead of using a matrix with the exact names (suffix -latest
or -14
) I can go with the OS name and, with "a simple condition", add the suffix, -latest
if it is not macos
, -14
for macos
. If I want to test a specific version in the future, I would not need to change the jobs used to protect the branch in all repositories. As this condition is only appearing in the reusable workflow, it is a one-time change.
But here is when it appears again, my old friend Yaml, losing my time in a solution that would take only 1 second with any real language, even the most garbage language that is not a "configuration language". It can be transformed into hours or end up delegating to Gradle tasks.
Well, it should be a simple if else
... Well, Yaml is here, and yes, I have had to duplicate multiple jobs in the past with if: condition
and another after it with if: !condition
, but at least I get something working... right? I cannot do that here!
I cannot do a simple if else
in the runs-on
, as the language does not allow that, and GitHub Actions authors didn't provide any workaround inside the ${{ }}
template. The fact that you need to write conditions and expressions inside ${{ }}
is already a signal that choosing Yaml was not a very good idea, as you were already patching the limitations of this language. GitHub Actions expressions are pretty well documented, this documentation could be totally dropped with a real language.
I haven't fixed it yet, but, a missing if else
expression is going to provoke I need to add a previous job or whatever to build the job name somehow as I cannot delegate fixing, once again, limitations of Yaml with Gradle. Other solutions? Going to all repositories to change the name and praise I do not have to change it again. Or reading the GitHub API to do it with requests... A lot of things, but none is 1 second solution.
None is as simple as an if else
.
I have spent/wasted thousands of hours in tooling, not only with Gradle, building tooling libraries, and plugins. In open source, and internally. I would not spend any second of my life building any tooling/wrapper library to fix the limitations of a Yaml build tool knowing beforehand it is a problem: https://github.com/typesafegithub/github-workflows-kt
Doing tooling is probably being masochistic, to be honest. But Yaml... Oh my, I'm not that masochistic. Yaml would win me, easily, something Gradle could not do after thousands of hours.
This is ragging a lot, I know. But not directly proportional to the frustrating time I have lost over the years due to the limitations of Yaml. Every second lost with Yaml remembers me to Interstellar planet.
Each tool has its utilities, I understand that... I can use a lot of different tools to move from A to B, depending on the distance it can be debatable if it is better a bicycle, a scooter, a car, or even walking... But sorry, Yaml is a stationary bicycle, there is no debate for me, I cannot move from A to B with it, and I will not build wheels for it. They already exist... Hi Kotlin!
Sorry for the long message and have a good weekend!David Herman
02/03/2024, 6:47 AMJavier
02/03/2024, 8:44 AMif else
with a dependency, o modify any part of it based on some condition, you can.
For example, I build compiler plugins and I am replacing the Kotlin version from the version catalog in Kotlin. So I can test dev versions from the bootstrap repository.
if (kotlinVersion != null) {
version("kotlin") {
strictly(kotlinVersion)
}
}
The above solution could be a real nightmare with a CI and a build tool belonging the Yaml world.
Amper will end up in another layer which will only have sense in very, very, simple projects due Yaml. In the rest of projects you will have a mix of Amper and Gradle files (even the image of Amper in the blog post shows a Gradle file because it cannot apply plugins).
Clean architecture layering vibes.