Things I want someone to create for me, volume 1

A mechanism that automatically expands all collapsed merges in a pushlog view. I don’t care if it’s a Firefox extension or modification to the pushloghtml source that adds an expand=1 parameter to the query string; I am tired of manually expanding each one.

Sometimes I do other things than write code

I don’t always write code, but when I do… no wait, that’s not right. Here’s what I’ve been up to in the past week:

I sing in the an all-male university a capella group called The Water Boys. Our end of term concert is happening on Sunday, and the overall club EOT concert just occurred last weekend:

I also sing in a barbershop quartet called the Bearded Baritones, which doesn’t allow me to hide in the background nearly as much as the 17 person group does (third from right, if curious):

Having just attended my last class of my university career (assuming exams go well), I have to say that this is one aspect of the past five years that I will miss dearly when I move to Toronto this summer.

smartmake redux: harder, better, faster, stronger

Do you get frustrated about how long it takes to build Firefox after you’ve only made a small change to a single file? Have you heard the words “incremental build”, or tried to only build one or two directories but can’t figure out why your changes aren’t showing up?

You are not alone.

I released my smartmake tool last year to allow people to specify then directories they’ve changed, and in return the tool would perform a correct incremental build. No hassle, no sweat. The name was deceptive; it was a pretty dumb tool, but it got the job done with a little help from the user. However, there is a rule that any build system tool eventually reimplements the functionality of make, and so I am proud to release smartmake v2, which requires less work than ever before to produce correct incremental builds.

Thanks to the hard work of the illustrious Till Schneidereit (till on IRC), smartmake now finds every source file modified since the last time you performed an incremental build, and performs a (mostly) minimal rebuild. It will also complain if it comes across any modified files for which it doesn’t have any dependency information, and suggest you perform a full build instead.

Go ahead, give it a shot! Tell me (or Till) what goes wrong so that we can fix it. I recommend doing a full build, then making a small change and running smartmake.py '5 minutes ago' to kick it off and get the timestamp caching happening.

Answering questions by looking at code

A contributor recently asked a question in #introduction that I couldn’t answer immediately, but I suspected that I could find the answer without too much work. I also decided to write down the steps I took and the reasons I took them, with the intent of creating a worked example of finding answers in the Firefox code.

The question: how do I determine if a given URI pointing to an RSS feed is subscribed as a live bookmark?

My first instinct when looking for code I have never touched before is to start with the visible strings in the Firefox interface. In this case, I went to slashdot.org and clicked on the RSS feed button to take me to the RSS feed viewer. Under the options for possible subscriptions, there is the “Live Bookmarks” choice. I’m going to find the code that handles subscribing a live bookmark, which should lead me to the way to find out if a feed is currently subscribed.

So, off to MXR: http://mxr.mozilla.org/mozilla-central/search?string=Live+Bookmarks&find=&findi=&filter=^[^\0]*%24&hitlimit=&tree=mozilla-central

Strings are usually stored in special localized files, where the actual string is referred to by a unique name. In this case, we’re looking at subscribe.properties, which shows us that some code should be using the name liveBookmarks to show the localized string in the feed viewer window.

Let’s look that up: http://mxr.mozilla.org/mozilla-central/search?string=livebookmarks&find=&findi=&filter=^[^\0]*%24&hitlimit=&tree=mozilla-central

Out of the results, subscribe.xml sounds like something I want to read: http://mxr.mozilla.org/mozilla-central/source/browser/components/feeds/content/subscribe.xml#53

Unfortunately, that line turns out to be not very interesting. However, let’s see what we can find for liveBookmarksMenuItem, which sounds like it might be the item for the live bookmarks option in the dropdown: http://mxr.mozilla.org/mozilla-central/ident?i=liveBookmarksMenuItem

Let’s look at FeedWriter.js from the results: http://mxr.mozilla.org/mozilla-central/source/browser/components/feeds/src/FeedWriter.js

Woah, that’s a lot of code! Let’s take a step back – we care about the subscribing action right now. Going back to subscribe.xml (http://mxr.mozilla.org/mozilla-central/source/browser/components/feeds/content/subscribe.xml), notice that the button is called subscribeButton. That sounds really useful! Let’s look in feedwriter.js again for that (just a regular ctr+f operation): http://mxr.mozilla.org/mozilla-central/source/browser/components/feeds/src/FeedWriter.js#859

Now, let’s find the function subscribe (ctr+f for subscribe:, as that’s commonly how member functions are defined in the Firefox source): http://mxr.mozilla.org/mozilla-central/source/browser/components/feeds/src/FeedWriter.js#1241

Reading the source of subscribe(), we come to
http://mxr.mozilla.org/mozilla-central/ident?i=addToClientReader

We can see the definition of addToClientReader at http://mxr.mozilla.org/mozilla-central/source/browser/components/feeds/src/FeedConverter.js#390. Let’s look at what else is defined here – this seems to be implementing the nsIFeedResultService interface, so we can look up the nsIFeedResultService.idl file in MXR: http://mxr.mozilla.org/mozilla-central/source/browser/components/feeds/public/nsIFeedResultService.idl.

Unfortunately, the service seems to be dealing with actual feed contents, and it doesn’t look like there’s a direct function to help us – let’s step back and see how addToClientReader is implemented.

http://mxr.mozilla.org/mozilla-central/source/browser/components/feeds/src/FeedConverter.js#448 is an important line – let’s look at addLiveBookmark (I just clicked the name again): http://mxr.mozilla.org/mozilla-central/ident?i=addLiveBookmark

Take a look at http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser-places.js#457. This shows us how a bookmark dialog is created, but not the actual subscription process. However, the important part is line 471, which shows us the type "livemark". Let’s search for that string and see what other code uses it: http://mxr.mozilla.org/mozilla-central/search?string=livemark

Woah! There are a lot of results! Since I’m not certain what I’m looking for at this point, I find the best thing to do here is to scan all the results quickly, looking for interesting snippets or filenames before opening any particular file. Partway down, there’s a file called test_bug636917_isLivemark.js (http://mxr.mozilla.org/mozilla-central/source/toolkit/components/places/PlacesUtils.jsm

Searching for livemarks in this file, we find line 2234 which defines the livemarks object as the nsILivemarkService service. Let’s look that up!

First the idl definition, to see if this service will be useful: http://mxr.mozilla.org/mozilla-central/source/toolkit/components/places/nsILivemarkService.idl. There’s a method called getLivemarkIdForFeedURI (http://mxr.mozilla.org/mozilla-central/source/toolkit/components/places/nsILivemarkService.idl#107), which looks to be exactly what we want – it gives us a -1 result for a non-registered feed and another number for a registered one.

So, to sum up – we have found a service that will take a URI and return a value that can be used to determine whether a given feed is a subscribed livemark, and we have learned that livemarks are the internal name for Live Bookmarks. The only bit remaining now is to get access to this service, but we can either use PlacesUtils.livemarks for that (if we import PlacesUtils.jsm), or just use a normal getService call. These are just details; the hard part of answering the original question is complete!

A Firefox regression hunter VM!

I am happy to announce the first public unveiling of my Fox in a Box project. The enthusiasm for my idea of putting together a dev VM was loud and clear in my last post, mainly from testers who expressed interest in hunting regressions at a more granular level. The README in the first link hopefully contains enough details for anybody to get themselves set up with a minimal Ubuntu 11.04 VM with a preset clone of mozilla-central ready to build. I experienced clobber build times of 30-45 minutes in my tests; your mileage may vary. So please, run $ git clone git://github.com/jdm/foxinabox.git, follow the README and let me know how it goes for you!

A Firefox dev VM?

I’ve been toying with the idea of creating a virtual machine that’s ready to build mozilla-central out of the box. The original idea I had was that it would be really easy to get new contributors started, and it would allow us to set up finicky things like the hgrc correctly. However, it was pointed out to me that build times in VMs are pretty terrible, which does make it less attractive. However however, I have seen comments from technical people in bugs that they would like to help find regression ranges smaller than 24 hours, but they lack the time to figure out how to set up a build. Is it worth creating a VM for finding regression ranges? I can imagine it being really pleasant to start a VM, run a script, and check back in every 30 minutes to see if the next build is ready for testing. Alternatively, implementing Kyle Huey’s proposed solution would also be a pretty big step to easing those pains.

A spoonful of sugar helps the .mozconfig go down

In my work with new Mozilla contributors, I’ve seen a number of people get hung up on the whole .mozconfig voodoo madness. Yes, we made it possible to download the source and build it without having to even think about creating one, but as soon as you want to use a debug build, or build Fennec, the dream is over. Therefore, I’ve put together mozconfig.py which is designed to walk users through the process of creating a working .mozconfig file tailored to their needs.

The best way to use it at present is as follows:

$ ./mozconfig.py 2>~/mozilla-central/.mozconfig

This will send the generated file contents directly into the relevant .mozconfig, so all that’s left is running make. I’d love to be able to programmatically determine whether the program is actually invoked this way, so it could give helpful instructions otherwise. However, I’m open for ways in which to improve it (keep in mind the target audience of “people who need to work on common tasks that require changing .mozconfig options”), and I’m really keen on ideas of how best to market this (wiki pages, etc.) so that it reaches the widest possible audience.

Making bugs more attractive for other people to fix

There are two takeaway points that I would like to state up front:

  1. when you find a bug that’s well-scoped and you have a fairly clear idea of how to fix it, add [mentor=yournickname] to the whiteboard.
  2. when stating that a bug is good for someone else to work on, please please add a comment with relevant MXR links and information on how to fix it.

I’m absolutely thrilled to see people marking bugs as being good for other people to fix. That’s what the “good first bug” and “mentor=” annotations are all about. It’s a message from someone who understands the issue, and it indicates that the bug is fixable with a reasonable amount of effort on the part of someone who is not a core contributor.

I’m going to go out on a limb and say that using [good first bug] is no longer desirable. The list of bugs with this annotation has grown beyond a manageable size (not in a good way), and it can appear like an impenetrable barrier for someone who shows up with the idea that they “want to work on Firefox.” Now, I subscribe to the RSS feed of this list, so I see every new addition and will likely to ping the culprit on IRC and ask whether the bug in question would make a better mentored bug. What is a mentored bug, you might ask? Segue!

Mentored bugs are the new hotness. A mentored bug is one in which someone with knowledge of the code in question has added the [mentor=name] annotation to the bug’s whiteboard, and represents a contract that:

  • the issue is fixable
  • a fix is desired
  • there exists a plan for how to proceed with fixing it
  • the specified mentor understands the problem and proposed solution

These are the absolute basics. Without these guarantees, a bug should not be assigned a mentor, and certainly shouldn’t be proposed to a contributor looking for work.

Furthermore, I propose that bug mentorship be a social contract as well. When I was a volunteer contributor with a non-Mozilla day job, I found it difficult to get on IRC during work hours, so I wasn’t able to have real-time conversations with my mentor. Moreover, the work I was doing was understood by very few people, so the folks on IRC in the evenings couldn’t really help me either. Therefore, I recommend that bug mentors make the commitment to respond to emails from contributors regarding the bug in question, because that can significantly ease the burden for eager volunteers in situations like my own. I have carried on several long email conversations with people working on my mentored bugs, consisting of advice, links to documentation, and technical support, and they have resulted in patches for those bugs every single time.

So, should you become a bug mentor? Absolutely! How can you decide whether a given bug is a good candidate for mentorship? Here’s a helpful checklist that I go through when considering that question:

  • Does it fulfill the basic requirements above?
  • Am I willing/able to answer questions about the proposed solution, or do I know who to point a contributor towards if I don’t have the answers?

That’s it! Bug mentorship is easiest when you have a complete understanding of a problem, but all that is truly necessary is enough knowledge to act as a willing guide for someone who knows less than you.

The final point that I want to emphasize – when you’re marking a bug as being good for another person to work on, please take a few moments to dump your investigative work in the bug. Function names, MXR links, steps to reproduce, explanations of the problem and how it can be solved: these are the stepping stones that allow a contributor to start looking into how to solve the problem without waiting to get in contact with you. The less latency involved, the better. Remember, these bugs are often being approached by people with very little experience in the code in question – spell out the assumptions you make, and you’ll make someone else’s job easier.

Appendix A – Types of bugs that are good candidates for mentoring:

  • Reliable edge-case crashes – easily reproducible, typically not in the critical path, great visibility (contributor can demonstrate behaviour change to third party)
  • Bugs containing simple (or at least explicitly spelled-out), verified testcases – easily reproducible, good visibility
  • Well-scoped tasks (ie. change all uses of X to Y, remove Z) – easily explained

Two years he walks the earth

Two years ago today I sent an email to Benjamin Smedberg saying that I wanted to help out with Electrolysis. I regret nothing except how quickly the intervening time has passed. Bring on two more years!

The Fast and the Furious: bzexport

If you’re a bzexport user, you’ll want to pull the latest revision. It’s recently been getting slower due to the number of http requests that need to be made (the tradeoff here is that it’s also been getting more correct), but I’ve pushed three patches that have reversed that downward slide into the molasses. By sending more data than is strictly necessary, caching information such as user name to email translations, and avoiding fetching data that rarely changes, I’ve noticeably improved the running time of bzexport on my machine. Give it a shot!

If you’re not a bzexport user, and you write patches that are submitted to bugzilla, you’re missing out. Bzexport simplifies that process of getting a patch out of your local machine and into the hands of your reviewer, making you a happier and more productive person.