Adding ESLint to Firefox

For those unfamiliar, ESLint is an open source linter used to ensure a Javascript codebase applies to certain style guidelines or avoids problematic patterns. It’s a common tool used by open source projects to help improve code quality and save time. Firefox — a popular open source web browser created by the Mozilla foundation— has been making use of it in since 2015, but given the size of the application there are still some sections that need coverage.

A Mozilla employee named Mark Banner has written about this initiative to establish ESLint in the remaining unit tests not yet covered in mozilla-central (a Mercurial repo that contains all code required to build Firefox). Recently I was given the opportunity to help him with these changes and decided to go for it.

Why I wanted to help

Part of the reason was to get more familiar with ESlint, but there were others as well. As I’ve learned more about the history of open source I’ve had a growing interest in contributing to Mozilla as it’s had a profound impact on the movement. What’s more, I’ve used Firefox a lot over the years, and I’ve found it genuinely interesting to learn a bit more about its codebase and how it’s maintained/run.

What you should get out of reading this

If you’ve only ever contributed to open source through Github you’ll find that Mozilla runs Firefox differently from you’re probably used to. I’m hoping this post will help educate others new to the company’s tools about their purpose/history, as well as potentially help if they decided to contribute to Firefox in the future. You’ll find that a lot of comparisons between these tools and Github/git are made, as this comparison often helped me understand the ‘point’ of these tools a bit faster.

Bugzilla

Background

Bugzilla is Mozilla’s primary means of tracking bugs for Firefox. If you read a bit about the application on its about page you’ll find that it was created 10 years before Github started and was one of the first ever products created by Mozilla after it launched in 1998.

Projects that use Github as their primary means of tracking bugs will have the benefit of using a tool that has mass adoption. However, the benefit of Bugzilla seems to be that Mozilla effectively has full control over the tool itself since they own it. From the ground up it has the means to suit the company’s own use cases and needs. A full team employed by the company can be dedicated to maintaining and building their own bug tracking application.

Using it for the first time

This was where my work on this fix began. I needed to choose a particular bug/fix from those listed below:

The list of ESLint-related bugs that were available

I opened mozilla-central locally and took a look at the size of the directories listed in each bug. I decided to take a smaller one as I wanted to have as much time as possible understanding how to properly contribute my fixes and set up Firefox from source.

Claiming a Bug

I expressed interest in the bug through the page dedicated to it. From there I was assigned to it by Mark.

Building Firefox from Source

To work on Firefox’s source code I needed to get a copy of it onto my Windows machine and successfully build it. Following these build instructions I was able to get a working copy without too much hassle.

The only real problem that I ran into at this stage was that my attempt to clone the code failed the first time around. However running hg clone https://hg.mozilla.org/mozilla-central a second time seemed to get it working.

Mercurial

Background

Prior to working on this project I had only known about git and TortoiseSVN version control systems.

Mercurial and git started days apart. In fact they started for largely the same reason; the free version of a version control tool called Bitkeeper was being withdrawn and people were looking for a free alternative.

There are many, many more differences between the two and personally found that this stack overflow post did a very good job of explaining some of them, as did this one. On a personal note, a near immediate advantage I found to using Mercurial — which is a common one that people mention — is that the command line interface made more sense. It felt cleaner and easier to use compared to git.

Tracking my changes with Mercurial

My changes to dom/manifest needed to be in two separate commits. The first was straight-forward; I needed to remove dom/manifest from the .eslintignore file and run ./mach eslint — fix parser to generate automatic changes. Much like git I ran hg add and hg commit -m "Message name" to add any updates to staging and commit them.

The manual changes took more work, but weren’t so bad. Every time I changed a file I’d run ./mach eslint — fix [name-of-directory] to test that my changes fixed existing ESLint errors.

Testing my Changes

Since I was changing a lot of unit tests it was important that I ran them and made sure they were still working. However I had a difficult time determining how to do so. After some searching I found this page, but it still wasn’t very clear to me what I should be doing in this scenario. I basically ended up figuring out that I could test my changes with:

./mach mochitest [path-to-directory]

But even then I later found that:

./mach test [path-to-directory]

Worked as well. My assumption is that the latter is the better command to run since test is a standard command name for running unit tests.

Submitting to Phabricatior

Background

Phabricator is an application created and run by a company called Phacility, a company with an ambitious vision and future for its products. Unlike the tools mentioned previously it had its start more recently in 2007, with the start of it being written by Evan Priestly during a Facebook hackathon. Over time it became the de-facto code review tool for Facebook, then the creator left the company, open sourced the tool and named it Phabricator. If you want to read more about it the original project creator has written post you should read here.

A screenshot of Phabricator. Its UI looks a bit familiar…

Working with Phabricator

To work with Phabriactor I needed to follow this guide and create an account. Then I needed to set up arcanist, a tool that can be used to interact with Phabricator locally on the command line.

Arcanist is the official command line tool built by Phabricator. Without any custom implementation this tool is likely the default used by a lot of companies. However, Mozilla has created a custom wrapper around Arcanist called moz-phab, which is the recommended tool to use over Arcanist for the company.

So when working on Firefox you will track your changes with mercurial, or hg . When submitting your commits for review and interacting with their review tool you’ll want to use moz-phab .

Improper Submission

When I first submitted a review to Phabricator I used Arcanist instead of moz-phab. However this had the effect of combining my commits into a single review, which didn’t suit the reviewing conventions that Mozilla seems to favor. I ended up abandoning this initial differential to make a proper one.

I had a question about my changes but mistakenly put them in the summary of my differential when submitting via Arcanist. So be sure not to do this, just make a new comment through the window at the bottom of the page after submitting.

To make it easier for the reviewer to look over my changes I ended up running moz-phab submit {revision number}the second time around. This automatically separated my commits into separate reviews so I could have them looked at individually.

However, running that moz-phab command had an unintended consequence; it changed my original commit messages for some reason . Having used git exclusively for pushing changes I wasn’t familiar with this sort of behavior and wasn’t sure why it was happening. I ended up fixing my commit messages within Phabricator itself, hoping to make a proper fix with Mercurial nearer the end of my submission.

Final Changes

When I was done fixing the comments received in the Phabricator review, I needed to do two last things:

  1. Fix my commit messages
  2. Rebase my changes

It was at this portion where I ran into my most difficult to handle issue. It wasn’t a particularly complex one but had a higher margin of error than any others I encountered so far.

The Problem

The issue started when I ran hg histedit to change my commit messages. A textfile opened and I changed lines like:

pick {commit number} Bug 447937 — Enable ESLint

to

mess {commit number} Bug 1508991-Enable ESLint

Then saved the file, closed it, and ran hg histedit — continue. After that I ran hg log to see if my changes were applied. I was greeted with the following:

Which basically showed that my latest commits and all my work/changes were no longer being kept track of by Mercurial, or at least not properly.

Whenever I ran a Mercurial command, whether it was log, status, diff…I always got this error:

warning: ignoring unknown working parent e48a8ac1884d!

Which basically stated that my latest — parent — revisions weren’t being recognized.

The Solution

At the time I didn’t have that much experience with Mercurial, so I was nervous to make any new changes that could end up breaking things further. Looking on google and stack overflow gave some simpler/surface level suggestions but none of those seemed to work. I decided to ask for more help from people that were better experienced with this workflow.

After corresponding with Mark it was decided that I should try working off the default branch, then incorporate my code in my latest differential. I ran the below commands:

$ hg checkout default
$ hg pull -u
$ arc patch — nobranch D13208

But after running arc patch — nobranch D13208 I ran into the following error:

There were some changes in .eslintignore that needed to be dealt with properly before my differential’s code could be successfully merged in.

One option for dealing with this might be equivalent to the following:

1. create a new branch from default
2. do a hard reset back to the revision my differential originally worked off of
3. run `arc patch — nobranch D1308` in this new branch
4. rename my commits if I still need to
5. rebase, fix .eslintignore conflicts
6. merge the code into master

Almost There

Even though Mercurial and Git and similar they aren’t identical. For example branching works differently with Mercurial than with git. From Mercurial’s documentation:

Branches occur if lines of development diverge. The term “branch” may thus refer to a “diverged line of development”. For Mercurial, a “line of development” is a linear sequence of consecutive changesets.

Some smaller differences include:

  • For Mercurial the master branch is called default.
  • You switch branches by using hg update [branchname] instead of hg checkout [branchname], like you might expect with git.

I still have this last portion of the contribution to complete. It’s not necessarily difficult, but still a bit time consuming since I need to understand Mercurial better to do it properly. When I have my fixes done I’ll be able to run moz-phab submit, and from there my differential in Phabricator will likely be updated and everything merged into master.

Conclusion

I won’t lie, this contribution proved frustrating near the end. But overall I’m very happy that I decided to take this on, since working with these new tools and learning about their history has made me feel like I participated in open source on a more profound level beyond a simple PR on Github. I’m also psyched that I was able to contribute to Firefox itself, given its presence in the industry and what it stands for.