Thursday, May 28, 2009

Random Monotone Hacks

I imagine most people who bother to read this blog know that I am rather fond of Monotone, the distributed version control system (a.k.a. DVCS) that we use to maintain Pidgin's code. One of the most convenient features of monotone is that it's extensible via the Lua scripting language. Over our time using monotone, some of us have come across (or written!) some useful snippets of lua code that can be tossed into ~/.monotone/monotonerc to make things easier on us.

The first such snippet is pretty simple. I have three monotone keys that I use for various purposes. One is for Pidgin development, another is for my work on the Guifications project and the Purple Plugin Pack. The third is for my private projects. Instead of needing to remember to specify which key I want to use in specific circumstances, a small snippet of lua can take care of this for me (of course, anyone wanting to use this will need to edit branch patterns and key names appropriately):

function get_branch_key (branch)
d = { ["im.pidgin"]="rekkanoryo@pidgin.im",
["org.guifications"]="rekkanoryo@guifications.org",
["org.rekkanoryo"]="rekkanoryo@rekkanoryo.org"
}

for k, v in pairs(d) do
if string.find(branch, k) then
return v
end
end
end


Monotone also has the ability to cherry-pick revisions from one branch to transplant into another. (Of course, I recognize that other DVCS tools have this capability too.) To do this, ordinarily we would issue a command like mtn pluck some_revision_id within a working copy of the branch we want to transplant the revision to. In our experience, the default log messages for a pluck leave some to be desired. My fellow developer Sadrul wrote this cool bit to add a pluck-log command to Monotone.

The pluck-log command takes a series of individual revision ID's as arguments. For each revision ID in the list of arguments, the command will execute mtn pluck $REV to grab and apply the changes to the workspace. Additionally, the plucked revision's original changelog entry will be inserted into the changelog for the new commit on the current branch. This is particularly useful if you're creating a new release branch by branching from a previous tag, then grabbing individual revisions from your main development branch. This command became popular among us Pidgin developers while we were preparing the Pidgin 2.5.6 release.

Here's the code:

--[[
Pluck a revision with the log and authors filled in for the next commit log.

@author: Sadrul Habib Chowdhury (updated for mtn 0.43 by John Bailey)
--]]

-- pluck-log command
function pluck_log(...)
local revs = {...}
local result
local topsrcdir
local logfile
local log

-- mtn_automate() returns a pair of a boolean and a string; we don't really
-- care about the boolean here, but we need to do something with it.
result, topsrcdir = mtn_automate("get_workspace_root")
topsrcdir = string.gsub(topsrcdir, "\n", "")
logfile = io.open(topsrcdir .. "/_MTN/log", "r")
log = ""

if logfile then
log = logfile:read("*all")
logfile:close()
end

table.foreach(revs,
function (index, rev)
r, sel = mtn_automate("select", rev)

if r == false then return end

for rev in sel:gmatch("%S+") do
r, certs = mtn_automate("certs", rev)

certs:gsub("%s+key \"(.-)\"\n%s*signature \"(.-)\"\n%s*name \"(.-)\"\n%s*value \"(.-)\"\n%s*trust \"(.-)\"",
function(key, sig, name, value, trust)
if name == "changelog" then
log = log .. "*** Plucked rev " .. rev .. " (" .. key .. "):\n" .. value .. "\n"
end
end
)
execute("mtn", "pluck", "-r", rev)
end
end
)

logfile = io.open(topsrcdir .. "/_MTN/log", "w")
logfile:write(log)
logfile:close()
end

register_command("pluck-log", "REVISION1 [REVISION2 [...]]", "Pluck a revision with a good log",
"This plucks a list of revisions, each individually, and adds the changelog of each revision for the next commit log." ..
"\nEXAMPLE:\tmtn pluck-log h:im.pidgin.pidgin deadbeef\n",
"pluck_log")


The resulting log entry will look something like this:

*** Plucked rev 074c5aedf9bbc512331f0d3130f076190b290676 (rekkanoryo@pidgin.im):
Set the default pager host to scsa.msg.yahoo.com; this seems to be what the
official client uses.


Originally, Sadrul wrote this code for mtn 0.42 and earlier, which did not have the mtn automate get_workspace_root functionality. I updated the code to call mtn_automate("get_workspace_root") instead of finding the workspace's root with successive checks of parent directories. The revision ID printed in the log was also truncated to the first 8 digits. Ordinarily, this is fine; however, it's possible that in the future a new revision will be created that has the same first 8 digits and thus the short ID will be ambiguous. I wanted to avoid this situation, so I removed the truncation. I also rearranged a few things to make it easier for me to read. I also have to credit my fellow Pidgin developer Elliott with figuring out that I needed to kill the trailing newline in the string returned from mtn_automate("get_workspace_root").

Hopefully we're not the only ones who find this stuff useful. As I make frequent use of other useful monotone lua hacks, I'll probably post about them here too.

Sunday, May 24, 2009

Pidgin 2.5.6

Well, as most people have noticed by now, we recently released Pidgin 2.5.6. This release was simply a bug and security fix release. Hopefully it will hold everyone over until we can kick 2.6.0 out the door!

Saturday, May 2, 2009

Linux Journal Readers' Choice Award

Yesterday, Linux Journal issued a press release announcing the winners of its annual Readers' Choice Awards. It's an annual event that attracts a lot of attention in the magazine. In their effors to "take the pulse of the Linux community," they run this poll and announce the winners and grant honorable mentions to "strong contenders" in the pool of runners-up.

This year, it's been announced that Pidgin has won a Readers' Choice award for Favorite Communications Tool, a category that we're no stranger to winning--we won this same category last year as well. The landscape is similar as well. This year, we won with 42% of the votes, beating out honorable mention Skype, which received 18% of the votes. Last year, we also garnered 42% of the votes, with Skype and Kopete earning honorable mentions at 17.8% and 12.8% respectively.

Winning this award for the second year in a row reminds us that our work is quite well appreciated, something that is often easy to forget. It also reminds us that every once in a while we need to stand back and thank everyone involved in making Pidgin such a popular project. In this case, we need to thank the 2,000+ people who voted for Pidgin in these Readers' Choice Awards, as well as all our developers, Crazy Patch Writers, drive-by contributors who spot a simple bug and fix it, and our users. All of these people in our community come together to make Pidgin a success as a project, and while we'd be just as happy to work on Pidgin if we had only a few hundred users, we certainly appreciate all of the contributions to our success. Thanks!