Serious question: Is “Directed Acyclical Graph” really an unknown term for people? The author harped on it pretty hard, but what it is…is pretty apparent, no? I mean, I’ve encountered the term often, but I don’t think I had any need to look it up…
I’m a computer engineer with more than a decade of development experience with embedded systems… I use C/C++/python everyday and “Directed Acyclical Graph” is never mentioned by name, no one in my experience says make me a DAG. Hell, I had to look it up when I read your comment and went “oh that’s what those are called”. I use em to show relationships between states or to descide a system that is best diagramed using a DAG. Do I or anyone I’ve talked to in my career call them DAG… lol no.
You also use Git everyday (most likely) and that mentions Directed Acyclic Graph (DAG) all over the place. https://git-scm.com/docs/user-manual#the-object-database
Just like you don’t have to understand what a DAG is to use Git, you don’t need to understand a DAG to use Gradle. The author is blowing smoke about nothing.
I thought this was basic CS 101, part of DSA
Yeah, I’d be pretty wary of a dev who needed clarification on DAGs…
deleted by creator
They probably know what it is, but it’s a bad point if they’re trying to paint DAGs as esoteric CS stuff for the average programmer. I needed to use a topological sort for work coding 2 weeks ago, and any time you’re using a build system, even as simple as Make, you’re using DAGs. Acting like it’s a tough concept makes me wonder why I should accept the rest of the argument.
Can’t say I have a strong feeling about Gradle though 🤷♀️
Agreed. Why would a person need to look it up when the name literally describes it. Directed? Means connections are in a single direction. Acyclic? A-cyclic = non-cyclical, doesn’t have cycles. Graph is… well a graph.
Which part does the author think an average programmer should struggle with?
It’s very well-known and common knowledge. It’s certainly something that I will talk about without feeling the need to define terms or something. I would assume anyone unfamiliar with it either didn’t pay attention in school or never went to school to begin with.
I’m guessing I didn’t know what it is by name because I never went for a compsci degree so you’re probably right
It’s never too late to learn about them. They’re super common in practice so it’s very helpful to know about them. A lot of things are a DAG, like tree data structures and dependency graphs. Having no cycles in a directed graph has a lot of nice properties too, like allowing one to use efficient graph traversal algorithms, topological sorting, or its transitive closure. It’s come up multiple times in my career so it’s definitely worth knowing imo.
Not by name at any rate
Programmer/devops here. Without looking it up, I don’t know what a DAG is. However, I’m guessing if I saw one, I’d recognize it.
…looked it up…
Immediately a dependency chart comes to mind
Gradle is absolute rubbish, definitely the worst experience I’ve had with a build system. But Maven is also rubbish.
IMO a CLI should be the primary way of interacting with the build system (see e.g. Go, Rust, JS with NPM or Yarn, Python with Poetry) and manually editing the build file should be reserved for edge cases and extensions.
As someone who wants to use Kotlin or Scala, is there another way to get around these two? Coming from .NET or NPM I found both of these to be terrible.
The “default” build tool for Scala is sbt.
There is Mill https://github.com/com-lihaoyi/mill
Which offers a nicer experience than the default Scala build tool: https://www.scala-sbt.org/
I personally like sbt a lot, but I’ve been told mill is more approachable.
Please give me a stable (!) interface to write plugins for “extravagant” features. If other devs are building open-source plugins, I am willing to use them instead of writing them independently.
this definitely does not describe maven. Maven’s interface is terrible, can’t accomplish a lot of stuff (due to the fact that it doesn’t use a DAG…), and people don’t write plugins for Maven. For example, nothing like the reckon plugin exists at all for Maven, and writing one would be an absolute nightmare.
After the initial effort to write the build file, I should rarely touch it (unless I am incrementing version numbers).
this either means you built the perfect CI/CD process to start and wasted a lot of time on it, or you never improve your processes at all. I completely disagree with this.
We were momentarily happy not having to write and read (pom.)XML files ever again, and we jumped the boat too early. Our problem was never Maven, but XML…
If that were the case then people would just use Polyglot for Maven and write their build files in Ruby, or Kotlin, or Java, or Yaml, or whatever. But that’s clearly not the problem with Maven.
Quickly, without opening your CS reference book, tell me what’s a Directed Acyclic Graph
if you don’t know what a DAG is then you’re really gonna struggle with understanding the VCS tools you use every single day…
This will happen because you never had the patience (by then!) to read the documentation in its entirety. And bare in mind, Gradle’s documentation is not something you can skim on the weekend or from your mobile phone while sitting on the bus. On the contrary, it’s a “hard” read, full of specific technical jargon you need to familiarize yourself with.
I have definitely never read even a tenth of the gradle docs. Yes, Gradle is hard to understand, but just like you don’t have to understand a DAG to use git you don’t have to understand most of it to use Gradle
Gradle is not the tool you hack your way into by copying paste stuff from StackOverflow. If you haven’t done so already, allocate time to read the documentation.
this is just good advice for all programming (yes, gradle is programming, unlike maven)
This is not the case with gradle. Incrementing to a new major version is always painful (for non-trivial builds):
ok, which is it? Do you want
- Let me list a few dependencies by using a purely descriptive approach;
- Please give me a stable (!) interface to write plugins for “extravagant” features. If other devs are building open-source plugins, I am willing to use them instead of writing them independently.
- After the initial effort to write the build file, I should rarely touch it (unless I am incrementing version numbers).
or do you want to build complex builds very easily and be able to modify them in a non-painful manner later?
You can’t get both.
The maven projects I’ve seen and used hardly ever update the maven version. and when we do, it breaks things terribly, except it’s because maven packages its own Java version that conflicts with your build, so not only does Maven not list it as a breaking change, you only find out after you’ve completed the update and then something in prod is broken… Ask me how I know this.
Please make no mistake; when you choose to use Gradle, you will program your build file, not configure it.
yes… this is why people like gradle more than maven. you actually have control.
The build.gradle is a running program in disguise
… it’s not in disguise… it literally says in the docs and when you are generating a new project, that you are using either Groovy or Kotlin.
Without the ability to properly debug the build process and the non-standard hacks people are willing to put in the build file, things can become less portable and extremely environment-dependent or simply not idempotent
Gradle is both more testable and more debuggable than Maven…
Do you remember when people were creating .sh scripts to build things? There’s a reason we’ve stopped doing so.
yes… because it wasn’t testable… unlike gradle.
Even if it’s easy to do so, the Gradle build shouldn’t replace a proper CI/CD pipeline,
finally, something I agree with. Yes you shouldn’t replace CI/CD with gradle, I don’t know who is doing this though…
It ran tests and integrated directly with Sonarqube, created custom reports based on the static code analysis results, performed infrastructure changes, etc. Why!? Because it was possible.
… wat… gradle shouldn’t run tests? it shouldn’t call sonarqube? how else are you going to run tests or call sonarqube? The only one I agree with here is infrastructure changes, but even then, that’s exactly how CDK works. You call CDK to build and deploy your application. You usually do this through
npx cdk
, but if you wanted to it would massively simplify it to have a single command to handle deploys.The reality, this fragmented the community and brought even more confusion to the uninitiated.
yes! yes it did! The switchover was not smooth. But now, every (or at least all the ones I’ve seen) doc has kotlin examples listed before groovy examples. Most people on the forums and the slack only use kotlin. If you are using Groovy you most likely will struggle much much more than with Kotlin.
Compared to the Groovy DSL, the Kotlin DSL seems to be more strict and more opinionated.
wasn’t the author just saying that you should avoid adding arbitrary logic? Why would being opinionated be a bad thing here?
So if you are a Java developer planning to use Gradle with the Kotlin DSL, you have to be familiar with Groovy (to be able to read the old materials),
umm. no. no you don’t. The docs have had Kotlin for a long long time now.
but you also need to learn enough Kotlin to be able to write your build file.
kotlin is wayyyy easier to learn than groovy.
Why is it necessary to learn a new programming language to master a build tool!?
so is the recommendation that Maven now be written in Java? Or Gradle be written in Java? I don’t get the recommendation here. My team uses Kotlin for everything. We still are mostly using Maven. Using Kotlin everywhere is a huge benefit. We’re trying to switch over to Gradle completely and Gradle having Kotlin as a DSL is fantastic. Needing to deal with XML files sucks, but it’s not nearly as bad as how slow and difficult to configure Maven is. If you’re using Python you need to learn up to 15 different tools and styles in order to correctly build every project out there. Gradle is a multi-language build tool. It’s not just for Java. It can be used for literally any language out there. I’ve seen it used for building C projects even. You could use it to build a monorepo of every language out there. You should be comparing it to Bazel and Buck rather than Maven.
That is not to say that Gradle is the best build system out there. It has a lot of problems with it. It’s definitely not my favorite build system. Bundler, Mix, and Cargo are all much better as a build and dependency management system than Gradle. But Maven is a long, long way down the list.
Maven has a high learning curve, but once learned it is incredibly simple to use.
That high bar is created by the tool configuration. You can change and hack everything, but you have to understand how Maven works to do so. This generally blocks people from doing really stupid things, because you have to learn how maven works to successfully modify it and in doing so you learn why you shouldn’t.
This is the exact weakness of Gradle, the barrier for modification is far lower and the tool is far less rigid. So you get lots of people who are still learning implement all sorts of weird and terrible practice.
The end result is I can usually dust off someone elses old maven project and it will build immediately using “mvn clean install”, about half the gradle projects I have been brought in on won’t without reverse engineering effort because they have things hard coded all over them. A not small percentage are so mangled they can’t be built without the dev who wrote it’s machine.
Also you really shouldn’t be tinkering with your build pipelines that much. Initial constraints determine the initial solution, then periodically you review them to improve. DevSecOps exists to speed development and ease support it isn’t a goal in of itself
Completely agree. I can jump into any maven project and understand it with ease. Gradle on the other hand requires deep understanding of the build file due to all the flexibility that it offers.
I can agree with most of that, but my point wasn’t that you should be “tinkering” with your build file, but that as time goes on and your project grows and your team grows you should be making improvements. No active project sits still, and having a tool like maven that is incredibly rigid and hard to use and modify makes that growth incredibly painful.
For example, you can easily start with gradle with just a few lines. You don’t need to worry about plugins, extra tasks, etc. Then as your project grows you can add in things like mutation testing, integration testing, plugins to share your configuration between all your projects. This growth is incredibly easy with a build tool that uses a DSL rather than one that is purely descriptive.
Yes, it’s massive pain if you pick up someone’s project and they’ve made a mess of things. But if you actually work with competent people this generally isn’t a problem. And it shouldn’t be a problem if you’re using open source projects that have a decent number of users.
Maven has unit and integration test phases and there are a multitude of plugins designed to hook into those phases but there are constraints by design.
Trying to hook everything into the build management system is a source of technical debt, your using a tool for something it wasn’t designed.
I would look at what makes sense within the build management system and what makes sense in a CI pipeline.
CI tools have different DSL and usually provide a means to manage environments. Certain integration and system level tests are best performed there.
For instance I keep system tests as a seperate managed project. The project can be executed from developer machines for local builds but I also create a small build pipeline to build the project, deploy it and run the system tests against it triggered by pull requests.
This is why I say the build management system doesn’t really change, because you should treat everything as descrete standalone components.
The Parent POM gets updates once every six months, the basic build verification CI pipeline only changes to the latest language release, etc…
Projects which try to embed gitflow into a pom or integrate CD into the gradle file are the unbuildable messes I get asked to fix.
Trying to hook everything into the build management system is a source of technical debt, your using a tool for something it wasn’t designed.
I never said to do this…
CI tools have different DSL and usually provide a means to manage environments. Certain integration and system level tests are best performed there.
Hm? no, definitely don’t do this. We’ve literally spent half a decade at my current company trying to get rid of the system that previous devs that thought this was a good idea, and this is exactly what they did. Your integration tests and system level tests should not depend on the environment you run them in. You should be able to execute them from anywhere and have them run the same. Depending on CI to do that for you means that you are tightly tied to not only your CI, but whomever maintains that infrastructure, the resources around that infrastructure, whether those are build machines, secrets, or even the workflows themselves.
For instance I keep system tests as a seperate managed project. The project can be executed from developer machines for local builds but I also create a small build pipeline to build the project, deploy it and run the system tests against it triggered by pull requests.
That… has nothing to do with CI/CD… You’re just not using your build management tool (which is built to execute tests) to execute your tests…
This is why I say the build management system doesn’t really change, because you should treat everything as descrete standalone components.
I do not understand what you’re saying here. You’re going to have to explain more.
The Parent POM gets updates once every six months, the basic build verification CI pipeline only changes to the latest language release, etc…
And is that because you’re not actually updating your dependencies that are in your parent POM? Because we update dependencies multiple times a week. Not really sure where you’re going with this though.
Projects which try to embed gitflow into a pom or integrate CD into the gradle file are the unbuildable messes I get asked to fix.
I don’t think I ever recommended either of those things. For one, gitflow is a terrible workflow, and two, why would you need to integrate CD into the gradle file? Your pipeline calls your gradle tasks to perform the things your build needs. Not making gradle into a CI tool.
Boom roasted
🍿