Contributing to Open Source Projects - atom-scalariform

Posted on December 14, 2016 · 5 min read

So far all my experiences in contributing to open source projects share a common trait among them, other than being really simple and minor improvements: I needed something that wasn't yet supported or implemented in a library I had as a dependency, or in a tool I was using.

For instance, I added support for Slick 3.x to sbt-slick, an Sbt plugin to generate Slick table schemas from the database schema definition in its own DDL, because version 3.x wasn't supported yet.

Likewise, I added support for Scala 2.11 to swagger-async-httpclient, which automates the code generation of a Scala HTTP asynchronous client from a Swagger API definition.

My last contribution was shortly after I began to write this blog, so I thought it was something worth to blog about.

Context

While writing a previous post on this blog I was making some changes to the script I use to generate it. It's written in Scala but it uses Ammonite, which allows to compile and execute Scala code without setting up a whole project nor requiring a build tool.

This means I can't use an IDE to edit it. Although I technically could, it would require to setup a Scala project (including dependency management and such) and that would go against the whole point of using Ammonite.

I use Atom instead but, nevertheless, I didn't want to give up all the features you get for free from an IDE. So I looked for some Atom packages that could help providing, at least, Scala source code highlighting and formatting. I found language-scala for highlighting and atom-scalariform for formatting.

The issue

The highlighting worked as expected but when I tried to format the blog-generator script I got an error saying:

You do not have a valid scala file open!

Well, that was somehow reasonable. Ammonite scripts are not standard; moreover, files have .sc extension instead of .scala.

Research

Out of curiosity I took a look at the atom-scalariform repository to check out the Atom plugin code. I assumed that it would be easy to spot the file extension validation section and it was indeed. The code responsible for the validation was, at that time, the following:

https://gist.github.com/pbassiner/c8afc3af6f591702bf173354fa7859ad#file-atom-scalariform_pre_ammonite_support-js

Then I looked for the Atom plugins local folder (~/.atom/packages/) and saw there was a sub-folder for each Atom plugin I had installed. And within the atom-scalariform folder, the same file structure I just saw in the repository. So I opened the atom-scalariform.js file and added .sc as a valid file extension:

https://gist.github.com/pbassiner/c8afc3af6f591702bf173354fa7859ad#file-atom-scalariform_post_ammonite_support-js

Finally I rebooted Atom and voilà! Formatting the Ammonite script was successful:

Formatted scala file!

Digging deeper

Formatting was working but I wanted to customize it. Since the script deals with HTML entities using scalatags I wanted the code to be formatted accordingly:

https://gist.github.com/pbassiner/c8afc3af6f591702bf173354fa7859ad#file-scalatags_example_html_indentation-scala

Digging into the scalariform documentation I found that it should be supported through the danglingCloseParenthesis property. So following atom-scalariform README I created a scalariform.properties file and set it up as follows:

preserveDanglingCloseParenthesis=true

I formatted the script again and it kept the HTML-like indentation intact, but I wasn't satisfied quite yet.

I had to define the path to my scalariform.properties file in the plugin configuration as an absolute path, which then would be applied to any file.

Even though is common to have a formatting standard per language, I think it's convenient to have a per-project basis configuration so you can make minor adaptations in specific projects.

Improving

I thought that it'd be nice to be able to configure the properties file path to be relative to the current project folder. So again, back to the plugin code, I realized there was no hint of how could I do that and, after googling a bit, I came up with this:

https://gist.github.com/pbassiner/c8afc3af6f591702bf173354fa7859ad#file-atom-scalariform_getprojectpath-js

Then I added a new property relativeToProject to the plugin configuration and used it in the formatting process accordingly. I tested both configurations, relative and absolute, and it worked fine.

Contributing

During the process I was already considering contributing to the project so I jumped back to the plugin repository and reviewed the README file looking for any indications on how to contribute, and I also checked out if there were any tests that I should update or even add some new ones. I found none, so I was practically done.

I forked the repository, made two branches (one for the Ammonite scripts support and another for the properties file path) since these were independent improvements, updated the README file in each of them and created the PRs:

  1. add support for ammonite scripts *.sc
  2. scalariform props file absolute/relative path flag

Follow up

Several days later, the project maintainer Jack Hopner kindly merged the first PR right away and asked for some improvements on the second one. I proposed to simplify the configuration by removing the relativeToProject property and then considering the path to the scalariform.properties file to be an absolute path if it starts with a / or a relative path otherwise.

After applying those changes, the second PR was also merged and both contributions were included in the 1.0.0 release of the Atom plugin, which was published shortly after.

Enjoy

That's it, now I'm running Atom with a plugin that contains some code I wrote myself.


Comments

Would you like to leave a comment? Since this blog is hosted on GitHub Pages there's no straightforward way to do so.

Instead, you can add a comment in this GitHub issue. If you'd like to see it here, refresh this page after posting the comment.