The power of frustration
TL;DR: I gave a small contribution to Gradle. It was a wonderful experience working with a such large open-source project that is used for way more people than i can think about.
Let me start this blog post by showing what this was all about:
See the ‘Unresolved dependency’ message? That what this is all about. Before the work that I did, that message didn’t appear for Gradle projects. And after wasting some time on an off day because of a typo, I was really frustrated that VSCode didn’t help me not lose this time. In retrospect, i don’t know why this made me so frustrated. Maybe the frustration was piling up for a long time or maybe I wasn’t in a good day, probably never know.
After some time i understood why this never has bugged me as much before: the message appears nicely when working with Maven projects, which is the majority of my daily working projects.
I’ve always been a fan of Gradle: love the syntax (not a fan of XML’s) and it’s something I’m comfortable with. However, as you can see, tooling support isn’t as mature as Maven.
It’s not a secret that open-source software took over the world. Nowadays, it’s almost impossible to find a single piece of complex software that does not use an open-source library. Google has some really good thoughts about why should corporations embrace open-source development, which seems like a trend nowadays.
I’ve been wanting to contribute with open-source for a while, but it’s the kind of stuff that isn’t straightforward. “Where should I start?”, “Will my code be good enough?”, “What should I do first?” were typical questions that i asked myself.
After some time, I found out that finding a problem to solve is actually really hard. There’s a lot of factors to consider: language affinity, project affinity, required knowledge, documentation and the list goes on.
I felt really overwhelmed by all of those questions and requirements. But i found strength and motivation on my earlier described frustration and told myself: I’m fixing this.
While i didn’t really think about it at the time, but that problem did checked out some boxes for me: i had the motivation to do it, Java is a language that I’m comfortable with, and VSCode and Gradle are both amazing piece of software that i would love to contribute to.
First things first, i needed to find if this was a new bug or just something no one (besides me, i guess) cared about enough to fix. I went to VSCode-Java gitter and asked about it, and a maintainer told me that VSCode-Java uses Eclipse internally and that was an Eclipse problem. What VSCode-Java uses is Eclipse Buildship, a collection of Eclipse plugins that provides Gradle support for Eclipse and VSCode-Java.
So I went to the related issue and then contacted a maintainer. The one i reached to was Donát Csikós. He’s the maintainer of Buildship git project, and works on Gradle (the company). Really nice guy, answered me faster than i expected and had all the patience in the world point me out in the right direction to start trying to work on it. I explained what i wanted to do, the issue that i wanted to fix and my motivation for doing so. Buildship has a nice development setup that helps configure all the eclipse stuff.
It’s always worth to check the Wiki page for some ‘How to Contribute’ directions.
Working with a strange codebase can be quite a challenge. Buildship has a lot of java modules, and is fairly complex. I have about 12 years of Java experience and actually had some experience with Eclipse codebase and Eclipse Plugins before and still was overwhelmed about working on it. Thankfully it wasn’t really that hard to pinpoint what Buildship wasn’t doing.
Unfortunately, the core of the problem was the way that Gradle reported unresolved dependencies: there was no API from Gradle that Buildship could use to identify and mark the dependencies on the build.gradle file.
Gradle is a way bigger project than Buildship, and i wasn’t ready to try to work on it… yet. So, after thinking a lot about how to fix it, I’ve reached Donát to talk about my solution. It wasn’t the best solution, and, to be honest, I was kind of afraid to discuss with Donát about it.
This is another overwhelming thing about contributing to open-source: am i good enough to do it?
Gradle added a certain pattern in the dependency name when the dependency couldn't be solved, and my proposal was to verify for this pattern to identify the unresolved dependencies. Matching strings is a error-prone way to do it, but it was all i could do. After reaching an agreement about it, I’ve worked on it and sent the project a pull request.
I had no expectations for my code pass the review flawlessly and it really didn’t. Like i said before, isn’t easy to work on a strange codebase, and not only i had to change some stuff but Donát changed some himself, to make code cleaner and to make it adhere better to the project coding guidelines.
This experience is probably the biggest direct benefit of trying to contribute to an open-source project: learning. Having contact with a well-designed code and work on it probably the best way to learn good coding patterns. Working with different people, who have different opinions about coding is also a great way to learn different thinking patterns.
After submitting the change to the Buildship project I was ready to tackle the main problem: Gradle. To be completely honest, I was confident after working with Buildship, but my confidence got shattered as soon as I downloaded Gradle’s source code: it is huge. Not only the source code is huge, but highly modularized using Java 9 modules (which I’m not really that familiar with), uses three languages (Groovy, Kotlin, and Java).
What I wanted to do was to create a reliable way to inform the Buildship API about unresolved dependencies instead of relying on the name of the dependency. After some time working again with Donát, I did it! I’m not going to enter details here, but it was released on Gradle 6.7 as an incubating feature (a way to mark newer features that can be removed later). I was an AMAZING feeling seeing my name on the release notes.
The next step is to use the feature I implemented in the resolution of unresolved dependencies in Buildship, instead of the hacky stuff that i did. I did not have the time to do it yet, but will surely do shortly soon.