Posts tagged “programming”.

The Holy Grail of Kickass API Documentation

Disclaimer: this is a bunch of vaporware.

Read/Write Asymmetry

It’s been a while since people solved the problem of making API documentation easily readable, while keeping it closely tied to the code: keep it in comments in the source code and export it to HTML.

One problem that still remains is that developers suck at writing documentation. They have no need for it (it’s just a waste of time: they already know how that stuff works), and they often don’t use the API they develop themselves, or at least not in all possible use cases, so they end up not knowing very well which information is most valuable to the users.

Users, on the other hand, know it all too well. They know a hack around that quirky behavior; they inadvertently found that undocumented feature (or was it a bug?); they have collectively field-tested it in a hundred times as many use cases as the author had originally foreseen; and they know what needs to be known.

They write about it too! You can see countless blog posts, forum answers, even comments appended to the documentation itself taking up where it left off. It just happens that this stuff never makes its way back into the official docs because it’s too much of a hassle!

If you’re just a user of some library, you usually have it installed in some far-away system directory, outside of source control, and read-only. Making a change to the documentation means finding where the repository is hosted, checking it out locally, finding where in the code that bloody method is implemented, making a change and sending a patch (where to, again?). That’s not your job right?

So why don’t we just make it all a wiki huh? Easy as pie. No funky markup in comment blocks, no generation step, it’s all HTML. You’re reading it, you spot something wrong or incomplete, edit it right there and you’re back to reading before you can say “back to reading.” And where is the code now? Well, somewhere completely dissociated from the documentation. You’re not even sure which version you’re reading about.

So what we really want is API documentation that:

  • comes directly from the source code;
  • is easily editable as a wiki;
  • and goes back to the source code.

There and Back Again

Rdoc.info takes any arbitrary repository and generates API documentation for you. So far it only works for Ruby repositories on Github, but it’s the only one I know so it’s the one I’ll talk about. The idea is applicable to anything that does the same type of auto-generation though.

That’s really cool then! Our first requirement is covered.

The second requirement is making a wiki, so I think we can borrow from about five million solutions.

Now HOW?! How do you turn that stuff back into source code again?!

chmod +w RDoc

Documentation on rdoc.info is generated per repository, per user, so you can decide, for each repository, if its documentation should be wiki-editable or not (if you made it this far I assume you really want it really bad). In that case, all you have to do is create a public branch called “docs”, and rdoc.info starts tracking that instead of the master branch, generating a wiki from it. Now you just tell everyone to come and edit!

Gathering edits

Rdoc.info forks your repository and commits every wiki edit to that fork. It’s quite simple: it just replaces the comment block next to a method/class/whatever with the edited version. On every commit, you receive a pull request.

Displaying

On the website, rdoc.info shows the latest wiki-edited docs by default, with a read-only “canonical” tab showing the last official version that was pushed before the recent edits.

Merging back

When you receive the pull request from rdoc.info, you merge rdoc.info’s branch back into yours, resolving possible conflicts and integrating the changes.

Edit History

What if you push to your “docs” branch when there are wiki commits that you haven’t integrated? Rdocs.info can’t try a normal merge, as there might be conflicts, and the whole thing has to be automatic. If it just does a “reset hard”, it’ll lose previous edits. So it does a merge, but with a no-hostages approach: automatically resolve every conflict by choosing your changes. It will count as a normal edit in the wiki, with the previous version still in the history.

Reverting to a particular version from the wiki interface is the same thing: the contents (only the doc comments, not the code) of the chosen version are commited on top of the current commit, and can be diffed with it.

Attribution, Statistics, Reputation

If the user making the edit is logged in, the commit can have her as the author, and statistics can be kept on who helped out the most and that kind of stuff. Methods with the least content can be marked as “stubs”, and editing those can be worth more points.

More into metadata territory, the developer could also possibly benefit from indirect usage statistics (through clicks and searches), and people up/downvoting individual methods, maybe even commenting on their design (whether they should be split in two; if the parameters or return values make sense, etc.).

You want it too?

From the few services I know which host API docs, I think the most likely to implement something like this are either rdoc.info or ApiDock. So write them and ask for it! (hey, I told you it was vaporware.)

Update: Apparently, something like this has been tried already by DocBox as a Google Summer of Code project. The code on Github is from last year and the website pointed at by RubyFlow seems to be down. Anyone with more info on this?

  • Share/Bookmark

Code Review + Google Wave = Code Wave !

Doing some exploratory thinking about the possibilities opened by Google Wave, I came up with this very early idea of something that could turn out to be pretty interesting. In explaining it, I’ll assume you’ve watched that huge 1h20min video they have about it (it’s worth every minute, but there’s an abridged — 10min — version).

Motivation

People have been doing code review through email for ages. It’s the easiest, dead-simple way of doing it. Just add a post-receive-hook to your repository and make it email a diff of every new commit to a mailing list. People answer to that email, inlining comments where needed. Great, you say. But… It’s not 2.0. Bummer.

You know what is 2.0? Review Board. Very pretty web interface, AJAX, all that goodness (seriously, it’s awesome, I’m even working on it myself). But… It’s not Email.

You know what is Email and 2.0? You’re absolutely right! Google Wave*! :)

So how do we tie it to the code?

Code Wave

The idea so far includes developing four separate pieces of software — one wave robot, two gadgets and one stand-alone web application which will use the embed API — , but the basic idea is to map every commit and every file to its own wave. Think of it as a code browser on steroids.

The Robot

The robot handles creating, linking and updating the repository content, access control and custom markup.

It creates one “absolute” wave for each version of each file and directory, plus one “relative” (HEAD) wave for each, which gets updated with every new commit. This way, one can look at a particular version of a file using the absolute wave, but also use the Playback functionality on the relative wave to watch it evolve as new changes are committed. Since waves can be linked to one another, besides being able to make directory listings, we can also have a header on each wave, linking to the usual previous/next/head commits. This is the “code browser” part.

When new commits arrive, they each also get their own wave, with the commit message, diff content and a link to each file changed. As with any wave, people can comment inline on any part they want, even chat about it, effectively doing (possibly live!) code review. The conversation history will be kept (and “playbackable”) in the wave, and people who are participants will be notified of the changes and can also come and chip in.

The robot also handles access control. Apparently waves, at least so far, don’t allow one to say “nobody can edit the content, only add comments.” If I’m right about that, the robot will need to watch and overwrite any changes to the content itself (the content must always reflect the repository), leaving only comments. On the web interface (which we’ll talk about in a sec), people can decide to “watch” certain (or all) files or directories, being notified about changes in them (much like in Review Board). The robot accomplishes this by adding these people to the commit waves where these files/directories are changed, so the wave pops up in their inboxes. The original committer always gets added, so she gets notified about any comments on her changes.

Another cool thing to have is special markup, so the robot watches for stuff like revision numbers/sha1s and turns them into links to the appropriate wave. It can also be configured through the web interface to turn ticket numbers and the like into links.

The Web Interface

It serves two main purposes: store settings and provide a way to browse the repository and comments.

Settings to be stored are repository path, privacy levels, groups of users, change watchers, robot behavior, etc.

Since waves can be embedded into normal web pages, this is also a nice way to make all that content (files, diffs and reviews) available online without needing a wave client. We could even think about indexing everything and making it searchable.

Gadget Number One

Syntax highlighting, plain and simple. Highlight code, skip (wave) comments, allow raw copying, etc. Could also be used to fold and unfold comment threads, so you could have a look at the diffs without the cruft. Maybe we could borrow some things from Bespin?

Gadget Number Two

Link helper. Like the Google button, that lets you search for something and drag results into the wave, this helper would allow you to refer to other files in the repository, searching them by name/path and dragging them in. Not sure how useful this really is, just thought it was a nifty idea.

The Future

Emacs Client

Imagine this: you’re there, nurturing your code on emacs (you are using emacs right?), and you spot something funky. It shouldn’t be there, or there’s a better way to do it, or you have a question about it. You put your cursor over the funky line, hit Control+Meta+Shift+whatever and what happens? Your trusty emacs takes the “git blame” for that line (or the equivalent in your SCM of choice), asks the web app for the wave URL associated with the commit sha1, splits your window in half and shows you said wave (do you have any doubt there will be an emacs wave client?) with the cursor right on the corresponding line in the diff, ready for you to hit M-x add-wave-reply and send your comments the committer’s way. It also might just be that someone already had the same issue, and you’ll see a threaded conversation there with the answer.

Editing

Right now we’ve only mentioned writing on commit waves (code review), but file waves were read-only. I haven’t thought out the details for this yet, but maybe there can be something like embedding Bespin on Google Wave, or the other way around, so that people can do real-time collaborative code editing (while also chatting through inline comments) and then mutually decide to commit. The file wave could wrap the file’s content in a header with a commit command.

The Present

So, how far are we into this project? Well, nowhere, really. It’s just a recent idea I had, and I don’t even have a Google Wave Sandbox account yet (hint, hint if you’re a googler). So if you liked it, feel free to go ahead and implement it. Many of the parts I described can be done independently (like the emacs wave client), so you don’t have to take on everything at once. And if you ever get around to building this (under a free license, of course) and making tons of money, please send me a couple beers :)

Also, this is a very rough draft, so suggestions or any kind of feedback is appreciated.

* For a non-ludicrous version of this comparison, take a look at: http://smartbear.com/white-paper.php?content=docs/articles%2FFour-Kinds-Of-Review.html

  • Share/Bookmark