<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-18929277</id><updated>2016-02-18T09:07:17.583-08:00</updated><category term="jetpack"/><title type='text'>mykzilla</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default?start-index=26&amp;max-results=25'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>114</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-18929277.post-3538029308224239292</id><published>2016-01-11T08:57:00.001-08:00</published><updated>2016-01-11T08:57:31.366-08:00</updated><title type='text'>URL Has Been Changed</title><content type='html'>&lt;dl&gt;&lt;dd&gt;The URL you have reached, &lt;a href=&quot;http://mykzilla.blogspot.com/&quot;&gt;http://mykzilla.blogspot.com/&lt;/a&gt;, has been changed.  The new URL is &lt;a href=&quot;https://mykzilla.org/&quot;&gt;https://mykzilla.org/&lt;/a&gt;. Please make a note of it.&lt;/dd&gt;&lt;/dl&gt;</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/3538029308224239292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=3538029308224239292' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/3538029308224239292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/3538029308224239292'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2016/01/url-has-been-changed.html' title='URL Has Been Changed'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/08518329693863067865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-7658939959003799797</id><published>2015-06-23T16:05:00.000-07:00</published><updated>2015-06-23T16:07:06.667-07:00</updated><title type='text'>Introducing PluotSorbet</title><content type='html'>&lt;a href=&quot;https://github.com/mozilla/pluotsorbet&quot;&gt;PluotSorbet&lt;/a&gt; is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Java_Platform,_Micro_Edition&quot;&gt;J2ME&lt;/a&gt;-compatible virtual machine written in JavaScript. Its goal is to enable users you run J2ME apps (i.e. &lt;a href=&quot;https://en.wikipedia.org/wiki/MIDlet&quot;&gt;MIDlets&lt;/a&gt;) in web apps without a native plugin. It does this by interpreting Java bytecode and compiling it to JavaScript code. It also provides a virtual filesystem (via &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API&quot;&gt;IndexedDB&lt;/a&gt;), network sockets (through the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/TCPSocket&quot;&gt;TCPSocket API&lt;/a&gt;), and other common J2ME APIs, like &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Contacts_API&quot;&gt;Contacts&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The project reuses as much existing code as possible, to minimize its surface area and maximize its compatibility with other J2ME implementations. It incorporates the &lt;a href=&quot;https://java.net/projects/phoneme&quot;&gt;PhoneME&lt;/a&gt; reference implementation, numerous tests from &lt;a href=&quot;https://www.sourceware.org/mauve/&quot;&gt;Mauve&lt;/a&gt;, and a variety of JavaScript libraries (including &lt;a href=&quot;http://www-cs-students.stanford.edu/%7Etjw/jsbn/&quot;&gt;jsbn&lt;/a&gt;, &lt;a href=&quot;https://github.com/digitalbazaar/forge&quot;&gt;Forge&lt;/a&gt;, and &lt;a href=&quot;https://github.com/eligrey/FileSaver.js&quot;&gt;FileSaver.js&lt;/a&gt;). The virtual machine is originally based on &lt;a href=&quot;https://github.com/YaroslavGaponov/node-jvm&quot;&gt;node-jvm&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;PluotSorbet  makes it possible to bring J2ME apps to Firefox OS. J2ME may be a moribund platform, but it still has &lt;a href=&quot;http://netmarketshare.com/operating-system-market-share.aspx?qprid=9&amp;amp;qpcustom=Java+ME&amp;amp;qpcustomb=1&quot;&gt;non-negligible market share&lt;/a&gt;,  not to mention a number of useful apps. So it retains residual  value, which PluotSorbet can extend to Firefox OS devices.&lt;br /&gt;&lt;br /&gt;PluotSorbet is also still under development, with a variety of issues to address. To learn more about PluotSorbet, check out its &lt;a href=&quot;https://github.com/mozilla/pluotsorbet/blob/master/README.md&quot;&gt;README&lt;/a&gt;, clone its &lt;a href=&quot;https://github.com/mozilla/pluotsorbet&quot;&gt;Git repository&lt;/a&gt;, peruse its &lt;a href=&quot;https://github.com/mozilla/pluotsorbet/issues&quot;&gt;issue tracker&lt;/a&gt;, and say hello to its developers in &lt;a href=&quot;irc://irc.mozilla.org/pluotsorbet&quot;&gt;irc.mozilla.org#pluotsorbet&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/7658939959003799797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=7658939959003799797' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7658939959003799797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7658939959003799797'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2015/06/introducing-pluotsorbet.html' title='Introducing PluotSorbet'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/08518329693863067865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-2146007198307190404</id><published>2014-03-28T16:58:00.002-07:00</published><updated>2014-03-28T16:58:42.947-07:00</updated><title type='text'>simplify asynchronous method declarations with Task.async()</title><content type='html'>In Mozilla code, &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;Task.spawn()&lt;/span&gt; is becoming a common way to implement asynchronous operations, especially methods like the &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;greet&lt;/span&gt; method in this &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;greeter&lt;/span&gt; object:&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;background: #202020; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;greeter&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: #d0d0d0;&quot;&gt;message:&lt;/span&gt; &lt;span style=&quot;color: #ed9d13;&quot;&gt;&quot;Hello, NAME!&quot;&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: #d0d0d0;&quot;&gt;greet:&lt;/span&gt; &lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;(name)&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;Task.spawn((&lt;/span&gt;&lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;*()&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;sendGreeting(&lt;/span&gt;&lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;.message.replace(&lt;/span&gt;&lt;span style=&quot;color: #ed9d13;&quot;&gt;/NAME/&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;name));&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color: #d0d0d0;&quot;&gt;}).bind(&lt;/span&gt;&lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;);&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: #d0d0d0;&quot;&gt;})&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;Task.spawn()&lt;/span&gt; makes the operation logic simple, but the wrapper function and &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;bind()&lt;/span&gt; call required to start the task on method invocation and bind its &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;this&lt;/span&gt; reference make the overall implementation complex.&lt;br /&gt;&lt;br /&gt;Enter &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;Task.async()&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Like &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;Task.spawn()&lt;/span&gt;, it creates a task, but it doesn&#39;t immediately start it. Instead, it returns an &quot;async function&quot; whose invocation starts the task, and the async function binds the task to its own &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;this&lt;/span&gt; reference at invocation time. That makes it simpler to declare the method:&lt;br /&gt;&lt;br /&gt;&lt;!-- HTML generated using hilite.me --&gt; &lt;div style=&quot;background: #202020; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;greeter&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: #d0d0d0;&quot;&gt;message:&lt;/span&gt; &lt;span style=&quot;color: #ed9d13;&quot;&gt;&quot;Hello, NAME!&quot;&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: #d0d0d0;&quot;&gt;greet:&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;Task.async(&lt;/span&gt;&lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;*(name)&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;sendGreeting(&lt;/span&gt;&lt;span style=&quot;color: #6ab825; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;.message.replace(&lt;/span&gt;&lt;span style=&quot;color: #ed9d13;&quot;&gt;/NAME/&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;name));&lt;/span&gt;&lt;br /&gt;  &lt;span style=&quot;color: #d0d0d0;&quot;&gt;})&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;With identical semantics:&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;background: #202020; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;greeter.greet(&lt;/span&gt;&lt;span style=&quot;color: #ed9d13;&quot;&gt;&quot;Mitchell&quot;&lt;/span&gt;&lt;span style=&quot;color: #d0d0d0;&quot;&gt;).then((reply)&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;...&lt;/span&gt; &lt;span style=&quot;color: #d0d0d0;&quot;&gt;});&lt;/span&gt; &lt;span style=&quot;color: #999999; font-style: italic;&quot;&gt;// behaves the same&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;(And it avoids a couple anti-patterns in the process.)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;Task.async()&lt;/span&gt; is inspired by ECMAScript&#39;s &lt;a href=&quot;http://wiki.ecmascript.org/doku.php?id=strawman:async_functions&quot;&gt;Async Functions strawman proposal&lt;/a&gt; and &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/hh191443.aspx&quot;&gt;C#&#39;s Async modifier&lt;/a&gt; and was implemented in &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=966182&quot;&gt;bug 966182&lt;/a&gt;. It isn&#39;t limited to use in method declarations, although it&#39;s particularly helpful for them.&lt;br /&gt;&lt;br /&gt;Use it to implement your next asynchronous operation!&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/2146007198307190404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=2146007198307190404' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/2146007198307190404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/2146007198307190404'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2014/03/simplify-asynchronous-method.html' title='simplify asynchronous method declarations with Task.async()'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/08518329693863067865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-7603765594353319606</id><published>2014-03-27T13:14:00.000-07:00</published><updated>2014-03-27T13:14:20.326-07:00</updated><title type='text'>qualifications for leadership</title><content type='html'>I&#39;ve been surprised by the negative reaction to Brendan&#39;s promotion by  some of my fellow supporters of marriage equality. Perhaps I take it too  much for granted that Mozillians recognize the diversity of their community in every possible  respect, including politically and religiously, and that the &lt;span style=&quot;font-style: italic;&quot;&gt;only&lt;/span&gt; thing we share in common is our  commitment to Mozilla&#39;s mission and the principles for participation.&lt;br /&gt;&lt;br /&gt;Those principles are reflected in our &lt;a href=&quot;http://www.mozilla.org/en-US/about/governance/policies/participation/&quot;&gt;Community  Participation Agreement&lt;/a&gt;, to which Brendan has always shown fealty  (since long before it was formalized, in my 15-year experience with  him), and which could not possibly be clearer about the welcoming nature  of Mozilla to all constructive contributors.&lt;br /&gt;  &lt;br /&gt;I know that marriage equality has been a long, difficult, and painful  battle, the kind that rubs nerves raw and makes it challenging to show  any charity to its opponents. But they aren&#39;t all bigots, and I take Brendan at his &lt;a href=&quot;https://brendaneich.com/2014/03/inclusiveness-at-mozilla/&quot;&gt;word and deed&lt;/a&gt; that he&#39;s as committed as I am to the community&#39;s inclusive ideals (and the organization&#39;s employment policies).&lt;br /&gt;  &lt;br /&gt;As Andrew Sullivan eloquently states in his recent blog post on &lt;a href=&quot;http://dish.andrewsullivan.com/2014/03/24/religious-belief-and-bigotry/&quot;&gt;Religious  Belief and Bigotry&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;margin-left: 40px;&quot;&gt;&quot;Twenty years ago, I was confidently  told by my leftist gay friends that Americans were all anti-gay bigots  and would never, ever back marriage rights so I should stop trying to  reason them out of their opposition. My friends were wrong. Americans  are not all bigots. Not even close. They can be persuaded rather than  attacked. And if we behave magnanimously and give maximal space for  those who sincerely oppose us, then eventual persuasion will be more  likely. And our victory more moral and more enduring.&quot;   &lt;/div&gt;&lt;br /&gt;I&#39;m chastened to admit that I substantially shared his friends&#39; opinion  twenty years ago. But I&#39;m happy to realize I was wrong. And perhaps Brendan will one day do the same. Either way, he  qualifies to be a leader at any level in the Mozilla community (and organization), as do the many other Mozilla  leaders whose beliefs undoubtedly differ sharply from my own.&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/7603765594353319606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=7603765594353319606' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7603765594353319606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7603765594353319606'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2014/03/qualifications-for-leadership.html' title='qualifications for leadership'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/08518329693863067865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-4907835732389141704</id><published>2013-10-15T17:05:00.003-07:00</published><updated>2013-10-15T17:05:53.226-07:00</updated><title type='text'>from Webapp SDK to r2d2b2g, Firefox OS Simulator, and the App Manager</title><content type='html'>A little over a year ago, on August 31, 2012, I brainstormed the outline of a &quot;Webapp SDK&quot;:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-qFEN48-NFBI/Ul2-QToFUkI/AAAAAAAAAEY/Pah7FtanWfo/s1600/2012-08-31+10.57.00.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;300&quot; src=&quot;http://2.bp.blogspot.com/-qFEN48-NFBI/Ul2-QToFUkI/AAAAAAAAAEY/Pah7FtanWfo/s400/2012-08-31+10.57.00.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;That outline was the genesis for the &lt;a href=&quot;https://hacks.mozilla.org/2012/10/r2d2b2g-an-experimental-prototype-firefox-os-test-environment/&quot;&gt;r2d2b2g experiment&lt;/a&gt;, which built the &lt;a href=&quot;http://www.blueskyonmars.com/2012/11/08/r2d2b2g-is-becoming-the-firefox-os-simulator/&quot;&gt;Firefox OS Simulator&lt;/a&gt;, whose initial version hit the web on September 14, 2012 and which has gone through numerous iterations since then as we evaluated various features to enhance app development.&lt;br /&gt;&lt;br /&gt;And that experiment spurred Mozilla&#39;s &lt;a href=&quot;https://wiki.mozilla.org/DevTools&quot;&gt;Developer Tools group&lt;/a&gt;, particularly its nascent &lt;a href=&quot;https://wiki.mozilla.org/DevTools/AppTools&quot;&gt;App Tools team&lt;/a&gt;, to build Firefox&#39;s new App Manager, which landed last month and was &lt;a href=&quot;https://hacks.mozilla.org/2013/10/introducing-the-firefox-os-app-manager/&quot;&gt;introduced today on Hacks&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Despite the twisty passage from experiment to product, that initial outline bears a surprising resemblance to the App Manager feature set. The Manager checks off three of the four features on the outline&#39;s primary list—&quot;start Gaia in B2G,&quot; &quot;package app,&quot; and &quot;test app in Gaia/B2G&quot;—plus a few on its secondary list, like &quot;debug from Firefox&quot; and &quot;test on mobile device,&quot; with &quot;edit manifest in GUI&quot; well underway over in &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=912912&quot;&gt;bug 912912&lt;/a&gt;. And the Simulator continues to provide B2G/Gaia via an easy-to-install addon that integrates with the Manager.&lt;br /&gt;&lt;br /&gt;Like any good product of a successful experiment, however, the Manager&#39;s reach has exceeded its progenitor&#39;s grasp! So it also gives you access to pre-installed apps, lets you take screenshots of device/Simulator screens, and will doubtless continue to sprout handy features to make app development great.&lt;br /&gt;&lt;br /&gt;So kudos to the folks who built it, and long live the App Manager!&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/4907835732389141704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=4907835732389141704' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/4907835732389141704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/4907835732389141704'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2013/10/from-webapp-sdk-to-r2d2b2g-firefox-os.html' title='from Webapp SDK to r2d2b2g, Firefox OS Simulator, and the App Manager'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-qFEN48-NFBI/Ul2-QToFUkI/AAAAAAAAAEY/Pah7FtanWfo/s72-c/2012-08-31+10.57.00.jpg" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-4775473125409851813</id><published>2013-08-23T10:55:00.001-07:00</published><updated>2013-08-23T10:55:06.641-07:00</updated><title type='text'>fixing this morning&#39;s mach OS X psutil bustage</title><content type='html'>If mach is broken in your mozilla-central clone on Mac OS X this      morning:&lt;br&gt;      &lt;blockquote&gt;&lt;tt&gt;08-23 10:20 &amp;gt; ./mach build&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;Error running mach:&lt;/tt&gt;&lt;br&gt;        &lt;br&gt;        &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&#39;build&#39;]&lt;/tt&gt;&lt;br&gt;        &lt;br&gt;        &lt;tt&gt;The error occurred in code that was called by the mach          command. This is either&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;a bug in the called code itself or in the way that mach is          calling it.&lt;/tt&gt;&lt;br&gt;        &lt;br&gt;        &lt;tt&gt;You should consider filing a bug for this issue.&lt;/tt&gt;&lt;br&gt;        &lt;br&gt;        &lt;tt&gt;If filing a bug, please include the full output of mach,          including this error&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;message.&lt;/tt&gt;&lt;br&gt;        &lt;br&gt;        &lt;tt&gt;The details of the failure are as follows:&lt;/tt&gt;&lt;br&gt;        &lt;br&gt;        &lt;tt&gt;AttributeError: &#39;module&#39; object has no attribute          &#39;TCPS_ESTABLISHED&#39;&lt;/tt&gt;&lt;br&gt;        &lt;br&gt;        &lt;tt&gt;&amp;nbsp; File          &quot;/Users/myk/Mozilla/central/python/mozbuild/mozbuild/mach_commands.py&quot;,          line 293, in build&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from mozbuild.controller.building import BuildMonitor&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;&amp;nbsp; File          &quot;/Users/myk/Mozilla/central/python/mozbuild/mozbuild/controller/building.py&quot;,          line 22, in &amp;lt;module&amp;gt;&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; import psutil&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;&amp;nbsp; File          &quot;/Users/myk/Mozilla/central/python/psutil/psutil/__init__.py&quot;,          line 95, in &amp;lt;module&amp;gt;&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; import psutil._psosx as _psplatform&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;&amp;nbsp; File          &quot;/Users/myk/Mozilla/central/python/psutil/psutil/_psosx.py&quot;,          line 48, in &amp;lt;module&amp;gt;&lt;/tt&gt;&lt;br&gt;        &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _TCP_STATES_TABLE = {_psutil_osx.TCPS_ESTABLISHED :          CONN_ESTABLISHED,&lt;/tt&gt;&lt;br&gt;      &lt;/blockquote&gt;      &lt;br&gt;      Then you&#39;ve been bit by the fix for &lt;a        href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=908296&quot;&gt;bug        908296&lt;/a&gt;. To resolve the bustage, run this command in your Hg      clone:&lt;br&gt;      &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html;        charset=ISO-8859-1&quot;&gt;      &lt;blockquote&gt;hg status -in python/psutil | xargs rm&lt;br&gt;      &lt;/blockquote&gt;      &lt;br&gt;      Or, if you&#39;ve cloned the &lt;a        href=&quot;https://github.com/mozilla/mozilla-central&quot;&gt;Git mirror&lt;/a&gt;,      run this instead:&lt;br&gt;      &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html;        charset=ISO-8859-1&quot;&gt;      &lt;blockquote&gt;git clean -xf python/psutil&lt;br&gt;      &lt;/blockquote&gt;      &lt;br&gt;    </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/4775473125409851813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=4775473125409851813' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/4775473125409851813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/4775473125409851813'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2013/08/fixing-this-mornings-mach-os-x-psutil.html' title='fixing this morning&#39;s mach OS X psutil bustage'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-7658176042227879683</id><published>2013-06-07T16:04:00.000-07:00</published><updated>2013-06-07T16:04:04.952-07:00</updated><title type='text'>64-bit Linux ADB for Simulator</title><content type='html'>Thanks to the efforts of new Mozilla intern &lt;a href=&quot;https://github.com/bkase&quot;&gt;Brandon Kase&lt;/a&gt;, the &lt;a href=&quot;https://ftp.mozilla.org/pub/mozilla.org/labs/r2d2b2g/r2d2b2g-linux.xpi&quot;&gt;latest        preview build of Firefox OS Simulator for Linux&lt;/a&gt; includes a     64-bit version of ADB, so you can push an app to an FxOS device from     64-bit Linux installations without any extra packages!&lt;br /&gt;     &lt;br /&gt;     Building it was tricky, because the Android SDK build scripts don&#39;t     support that target. Brandon first tried simply specifying the     target, which worked on an older version of ADB (1.0.24). But it     failed on the latest version (1.0.31), which links with a bundled     copy of libcrypto that includes 32-bit assembly.&lt;br /&gt;     &lt;br /&gt;     Ubuntu 13.04 (Raring) ships a 64-bit &lt;a href=&quot;http://packages.ubuntu.com/raring/android-tools-adb&quot;&gt;android-tools-adb       package&lt;/a&gt;, though, so we knew it could be done. And its &lt;a href=&quot;http://packages.ubuntu.com/source/raring/android-tools&quot;&gt;source       package&lt;/a&gt;&#39;s build system is much simpler than the SDK&#39;s. We just     needed a binary that works on distributions with older versions of     glibc than Raring&#39;s 2.17. And one that doesn&#39;t depend on a specific     version of libcrypto, which varies around the Linux world; whereas     Raring&#39;s ADB executable appears to need the specific version that     comes with that distribution.&lt;br /&gt;     &lt;br /&gt;     So Brandon modified the source package&#39;s Makefile to link libcrypto     statically (note the absolute path to libcrypto.a, which may vary):&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;     &lt;tt&gt;--- debian/makefiles/adb.mk&amp;nbsp;&amp;nbsp;&amp;nbsp; 2013-03-26 14:15:41.000000000       -0700&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;+++ adb-static-crypto.mk&amp;nbsp;&amp;nbsp;&amp;nbsp; 2013-06-06 16:51:52.794521267       -0700&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;@@ -40,15 +40,16 @@&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;CPPFLAGS+= -I.&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;CPPFLAGS+= -I../include&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;CPPFLAGS+= -I../../../external/zlib&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;+CPPFLAGS+= -I/usr/include/openssl&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;-LIBS+= -lc -lpthread -lz -lcrypto&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;+LIBS+= -lc -lpthread -lz -ldl&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;OBJS= $(SRCS:.c=.o)&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;all: adb&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;adb: $(OBJS)&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp; $(CC) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;+&amp;nbsp;&amp;nbsp;&amp;nbsp; $(CC) -o $@ $(LDFLAGS) $(OBJS)       /usr/lib/x86_64-linux-gnu/libcrypto.a $(LIBS)&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;clean:&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;    &lt;/tt&gt;&lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rm -rf $(OBJS) adb&lt;/tt&gt;&lt;/blockquote&gt;&lt;br /&gt;     Then I copied the source package to my CentOS 16 build machine     (which has glibc 2.12) and built it there. After which the resultant     executable worked on all the distributions we tested: Ubuntu 13.04,     Ubuntu 10.04, CentOS 16, and Arch Linux (kernel 3.9.3-1-ARCH).&lt;br /&gt;     &lt;br /&gt;     Presumably it will work on others too. But if it still doesn&#39;t work     for you, &lt;a href=&quot;https://github.com/mozilla/r2d2b2g/issues&quot;&gt;let us       know&lt;/a&gt;!&lt;br /&gt;     &lt;br /&gt;     And if you just want the ADB executable, sans Simulator, &lt;a href=&quot;https://ftp.mozilla.org/pub/mozilla.org/labs/r2d2b2g/adb-1.0.31-linux64.zip&quot;&gt;here        it is&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/7658176042227879683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=7658176042227879683' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7658176042227879683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7658176042227879683'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2013/06/64-bit-linux-adb-for-simulator.html' title='64-bit Linux ADB for Simulator'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-2950140535922521480</id><published>2012-10-02T12:08:00.001-07:00</published><updated>2012-10-02T12:13:24.657-07:00</updated><title type='text'>r2d2b2g implementation details</title><content type='html'>Over at Mozilla Hacks, I just &lt;a href=&quot;https://hacks.mozilla.org/2012/10/r2d2b2g-an-experimental-prototype-firefox-os-test-environment/&quot;&gt;blogged            about r2d2b2g&lt;/a&gt; (ratta-datta-batta-ga), an experimental      prototype test environment for Firefox OS that makes it drop-dead      simple to test your app in &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Boot_to_Gecko/Using_the_B2G_desktop_client&quot;&gt;B2G            Desktop&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;r2d2b2g is an addon, but it bundles &lt;a href=&quot;https://ftp.mozilla.org/pub/mozilla.org/b2g/nightly/latest-mozilla-central/&quot;&gt;B2G            Desktop nightly builds&lt;/a&gt;, which are native executables, and thus      the addon is platform-specific, with packages available for &lt;a href=&quot;https://ftp.mozilla.org/pub/mozilla.org/labs/r2d2b2g/r2d2b2g-mac.xpi&quot;&gt;Mac&lt;/a&gt;,      &lt;a href=&quot;https://ftp.mozilla.org/pub/mozilla.org/labs/r2d2b2g/r2d2b2g-linux.xpi&quot;&gt;Linux            32-bit&lt;/a&gt;, and &lt;a href=&quot;https://ftp.mozilla.org/pub/mozilla.org/labs/r2d2b2g/r2d2b2g-windows.xpi&quot;&gt;Windows&lt;/a&gt;      (caveat: B2G Desktop for Windows currently crashes on startup due to      bug            &lt;strike&gt;&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=794662&quot;&gt;794662&lt;/a&gt;&lt;/strike&gt;      &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=795484&quot;&gt;795484&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;The packages are large, 50-60MB each, partly because of the      executables, but mostly because they also bundle &lt;a href=&quot;https://wiki.mozilla.org/Gaia&quot;&gt;Gaia&lt;/a&gt; profiles, including      all default apps. (It&#39;s probably worth bundling a few of these, for      demonstration purposes, but we could make the packages much smaller      by removing the rest.)&lt;br /&gt;&lt;br /&gt;r2d2b2g uses the &lt;a href=&quot;https://addons.mozilla.org/en-US/developers/builder&quot;&gt;Add-on        SDK&lt;/a&gt; as its addon framework and relies on several third-party      addon modules (&lt;a href=&quot;https://github.com/ochameau/jetpack-subprocess&quot;&gt;subprocess&lt;/a&gt;,      &lt;a href=&quot;https://github.com/voldsoftware/menuitems-jplib&quot;&gt;menuitems&lt;/a&gt;)      along with some Python utilities (&lt;a href=&quot;https://github.com/mozilla/mozdownload&quot;&gt;mozdownload&lt;/a&gt;, &lt;a href=&quot;https://github.com/mozilla/mozbase&quot;&gt;mozbase&lt;/a&gt;) to download      and unpack B2G Desktop builds. Plus Gaia, although recent work to      bundle Gaia profiles with B2G Desktop builds may break that      dependency.&lt;br /&gt;&lt;br /&gt;I&#39;ve demoed the project to a variety of folks over the last couple      weeks, and I&#39;ve received a bunch of positive feedback about it. B2G      Desktop combines approachability with phoneliness and is the best      existing test environment for Firefox OS. But its configuration is a      challenge, and it provides no obvious affordances for installing and      testing your own app. r2d2b2g shows that these problems are      tractable (even if it doesn&#39;t yet solve them all) and demonstrates a      promising product path.&lt;br /&gt;&lt;br /&gt;After seeing r2d2b2g, Kevin Dangoor drafted a &lt;a href=&quot;https://docs.google.com/document/d/1OptOCWO4b_b1aa4Gtwr82_q-mW5ybteoWNpPAJUIFNk/edit&quot;&gt;PRD            for a Firefox OS Simulator&lt;/a&gt; that I&#39;ll use to guide further      development. Interested in participating? Clone the code from its &lt;a href=&quot;https://github.com/mozilla/r2d2b2g&quot;&gt;GitHub repository&lt;/a&gt;      and contribute your improvements!&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/2950140535922521480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=2950140535922521480' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/2950140535922521480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/2950140535922521480'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2012/10/r2d2b2g-implementation-details.html' title='r2d2b2g implementation details'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-704490864096897779</id><published>2012-03-07T18:04:00.001-08:00</published><updated>2012-03-07T18:04:16.546-08:00</updated><title type='text'>Next/Previous Tab on Mac Consistent At Last</title><content type='html'>After blogging about the &lt;a href=&quot;http://mykzilla.blogspot.com/2011/09/nextprevious-tab-keyboard-shortcuts-on.html&quot;&gt;inconsistency       of keyboard shortcuts for Next/Previous Tab on Mac&lt;/a&gt; last year,     I found out that Firefox, Thunderbird, and Komodo also support     Command + Option + LeftArrow|RightArrow, and Adium has a General     &amp;gt; &quot;Switch tabs with&quot; pref that I can set to the same chord.&lt;br&gt;     &lt;br&gt;     (Later, I switched IM clients from Adium to InstantBird, which also     supports that combination.)&lt;br&gt;     &lt;br&gt;     That left Terminal, which I couldn&#39;t figure out how to configure to     support the same shortcut. Until now.&lt;br&gt;     &lt;br&gt;     I&#39;m not sure if it&#39;s because I have since upgraded to Mac OS X 10.7     (Lion). I could&#39;ve sworn I tried something like this back when I     wrote that previous blog post, and it didn&#39;t work.&lt;br&gt;     &lt;ol&gt;       &lt;li&gt;Go to System Preferences &amp;gt; Keyboard &amp;gt; Keyboard Shortcuts         &amp;gt; Application Shortcuts.&lt;/li&gt;       &lt;li&gt;Press the + (plus) button.&lt;/li&gt;       &lt;li&gt;Select &quot;Other...&quot; from the Application menu and select         Utilities &amp;gt; Terminal from the file picker dialog.&lt;/li&gt;       &lt;li&gt;Enter &quot;Select Next Tab&quot; (without the quotes) into the Menu         Title field.&lt;/li&gt;       &lt;li&gt;Focus the Keyboard Shortcut field and press Command + Option +         RightArrow to set the keyboard shortcut, which will appear as         &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html;           charset=ISO-8859-1&quot;&gt;         &amp;#8997;&amp;#8984;&amp;#8594;.&lt;/li&gt;       &lt;li&gt;Press the Add button.&lt;/li&gt;     &lt;/ol&gt;     &lt;p&gt;Repeat steps 4-6 with &quot;Select Previous Tab&quot; and Command + Option       + LeftArrow, which will appear as       &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html;         charset=ISO-8859-1&quot;&gt;       &amp;#8997;&amp;#8984;&amp;#8592;.&lt;br&gt;     &lt;/p&gt;     &lt;p&gt;Those shortcuts should now work in Terminal.&lt;br&gt;     &lt;/p&gt;     &lt;p&gt;With this change, all five of my current primary productivity       applications on Mac (Firefox, Thunderbird, Instantbird, Komodo,       and Terminal) support a consistent pair of keyboard shortcuts for       Next/Previous Tab, which are two of the most common commands I       issue in all of those apps.&lt;br&gt;     &lt;/p&gt;     &lt;p&gt;Woot!&lt;br&gt;       &lt;br&gt;     &lt;/p&gt;   </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/704490864096897779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=704490864096897779' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/704490864096897779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/704490864096897779'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2012/03/nextprevious-tab-on-mac-consistent-at.html' title='Next/Previous Tab on Mac Consistent At Last'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-4717272844287397408</id><published>2012-03-07T13:46:00.001-08:00</published><updated>2012-03-07T13:46:45.454-08:00</updated><title type='text'>generating a fingerprint for an SSH key</title><content type='html'>After recently &lt;a href=&quot;https://github.com/blog/1068-public-key-security-vulnerability-and-mitigation&quot;&gt;discovering       a security vulnerability&lt;/a&gt; that allows an attacker to add an SSH     key to a GitHub user account, GitHub is requiring all users to audit     their SSH keys. Its &lt;a href=&quot;https://github.com/settings/ssh/audit&quot;&gt;audit       page&lt;/a&gt; lists one&#39;s keys by type and fingerprint, but it doesn&#39;t     say how it generated the fingerprint or how to generate one for your     local copy of a key to compare it with. Nor does it let you see the     whole key.&lt;br&gt;     &lt;br&gt;     And since I don&#39;t generate such fingerprints very often, I didn&#39;t     know how to do it. So I tried &lt;tt&gt;cksum&lt;/tt&gt;, &lt;tt&gt;md5&lt;/tt&gt;, and &lt;tt&gt;shasum&lt;/tt&gt;     on my Mac, but none of their checksums matched. Turns out the tool     to use is &lt;tt&gt;ssh-keygen&lt;/tt&gt;:&lt;br&gt;     &lt;br&gt;     &lt;tt&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp; ssh-keygen -l -f path/to/keyfile&lt;/tt&gt;&lt;br&gt;     &lt;br&gt;   </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/4717272844287397408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=4717272844287397408' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/4717272844287397408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/4717272844287397408'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2012/03/generating-fingerprint-for-ssh-key.html' title='generating a fingerprint for an SSH key'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-3538011216013400890</id><published>2011-10-17T10:38:00.001-07:00</published><updated>2011-10-17T10:38:52.345-07:00</updated><title type='text'>Mozilla Status Board Text is Markdown</title><content type='html'>It isn&#39;t documented anywhere that I can find, but Benjamin     Smedberg&#39;s handy &lt;a       href=&quot;http://benjamin.smedbergs.us/weekly-updates.fcgi/&quot;&gt;Mozilla       Status Board&lt;/a&gt; tool parses status text as &lt;a       href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt;,     which is how I added a &lt;b&gt;Didn&#39;t&lt;/b&gt; header to the &lt;b&gt;Done&lt;/b&gt;     section of my &lt;a       href=&quot;http://benjamin.smedbergs.us/weekly-updates.fcgi/user/mykmelez&quot;&gt;status       update&lt;/a&gt; with all the things I planned to do last week but     didn&#39;t make happen. (The &lt;b&gt;Done&lt;/b&gt;, &lt;b&gt;Next&lt;/b&gt;, and &lt;b&gt;Coordination&lt;/b&gt;     headers are all &lt;b&gt;H4&lt;/b&gt;s, so I prepended four hash marks to &lt;tt&gt;####       &lt;b&gt;Didn&#39;t&lt;/b&gt;&lt;/tt&gt; to make it the same size).&lt;br&gt;     &lt;br&gt;     (Note that &lt;tt&gt;[&lt;a         href=&quot;http://daringfireball.net/projects/markdown/basics&quot;&gt;Markdown-style         links&lt;/a&gt;](&lt;a class=&quot;moz-txt-link-freetext&quot; href=&quot;http://daringfireball.net/projects/markdown/basics&quot;&gt;http://daringfireball.net/projects/markdown/basics&lt;/a&gt;)&lt;/tt&gt;     don&#39;t work and cause the entire section in which they appear to     remain unparsed. However angle-bracketed URLs, as recommended by &lt;tt&gt;&lt;a href=&quot;http://labs.apache.org/webarch/uri/rfc/rfc3986.html#delimiting&quot;&gt;RFC         3986&lt;/a&gt;       &lt;a class=&quot;moz-txt-link-rfc2396E&quot; href=&quot;http://labs.apache.org/webarch/uri/rfc/rfc3986.html#delimiting&quot;&gt;&amp;lt;http://labs.apache.org/webarch/uri/rfc/rfc3986.html#delimiting&amp;gt;&lt;/a&gt;&lt;/tt&gt;,     work when added to the ends of lines. And &quot;&lt;tt&gt;bug ###&lt;/tt&gt;&quot;     references are auto-linkified.)&lt;br&gt;     &lt;br&gt;   </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/3538011216013400890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=3538011216013400890' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/3538011216013400890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/3538011216013400890'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2011/10/mozilla-status-board-text-is-markdown.html' title='Mozilla Status Board Text is Markdown'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-3002229182794927051</id><published>2011-09-16T08:32:00.001-07:00</published><updated>2011-09-16T08:32:13.528-07:00</updated><title type='text'>to all the bugs I&#39;ve filed before</title><content type='html'>The &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=20142&quot;&gt;first       bug I filed&lt;/a&gt; was marked as &lt;i&gt;duplicate&lt;/i&gt;; the &lt;a       href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=20187&quot;&gt;second&lt;/a&gt;     was &lt;i&gt;worksforme&lt;/i&gt; (although Chris Petersen could reproduce it     before he couldn&#39;t anymore); and the &lt;a       href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=24840&quot;&gt;third&lt;/a&gt;     was &lt;i&gt;invalid&lt;/i&gt; (it was the spec, not the code, that was     errant). The &lt;a       href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=25082&quot;&gt;fourth&lt;/a&gt;     is the first that was &lt;i&gt;fixed&lt;/i&gt;.&lt;br&gt;     &lt;br&gt;   </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/3002229182794927051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=3002229182794927051' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/3002229182794927051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/3002229182794927051'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2011/09/to-all-bugs-ive-filed-before.html' title='to all the bugs I&#39;ve filed before'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-2481752447493541518</id><published>2011-09-09T17:01:00.000-07:00</published><updated>2011-09-09T17:00:36.580-07:00</updated><title type='text'>&quot;Next/Previous Tab&quot; Keyboard Shortcuts on Windows</title><content type='html'>On my Windows laptop, I use the following four programs with tabbed     interfaces on a regular basis:&lt;br&gt;     &lt;ul&gt;       &lt;li&gt;Firefox&lt;/li&gt;       &lt;li&gt;Thunderbird&lt;/li&gt;       &lt;li&gt;Instantbird&lt;/li&gt;       &lt;li&gt;Komodo IDE&lt;/li&gt;     &lt;/ul&gt;     (I&#39;d love to have tabs in my Windows terminal app of choice, &lt;a       href=&quot;http://code.google.com/p/mintty/&quot;&gt;Mintty&lt;/a&gt;, but its     developer &lt;a       href=&quot;http://code.google.com/p/mintty/issues/detail?id=8&quot;&gt;thinks       tabs should be implemented at the window manager level&lt;/a&gt;.)&lt;br&gt;     &lt;br&gt;     Unlike &lt;a href=&quot;http://mykzilla.blogspot.com/2011/09/nextprevious-tab-keyboard-shortcuts-on.html&quot;&gt;on       my Mac&lt;/a&gt;, all those programs implement the same keyboard     shortcut for switching to the previous/next tab, and it&#39;s a simple     one with just a two-key chord: Control + PageUp / PageDown.&lt;br&gt;     &lt;br&gt;     Ha!&lt;br&gt;     &lt;br&gt;   </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/2481752447493541518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=2481752447493541518' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/2481752447493541518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/2481752447493541518'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2011/09/nextprevious-tab-keyboard-shortcuts-on_09.html' title='&quot;Next/Previous Tab&quot; Keyboard Shortcuts on Windows'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-1639696569383368856</id><published>2011-09-08T17:03:00.001-07:00</published><updated>2011-09-08T17:03:31.723-07:00</updated><title type='text'>&quot;Next/Previous Tab&quot; Keyboard Shortcuts on Mac</title><content type='html'>On my Mac, I use the following five programs with tabbed interfaces     on a regular basis:&lt;br&gt;     &lt;ul&gt;       &lt;li&gt;Firefox&lt;/li&gt;       &lt;li&gt;Thunderbird&lt;/li&gt;       &lt;li&gt;Adium&lt;/li&gt;       &lt;li&gt;Terminal&lt;/li&gt;       &lt;li&gt;Komodo IDE&lt;/li&gt;     &lt;/ul&gt;     &lt;br&gt;     And those programs implement the following five different keyboard     shortcuts for switching to the previous/next tab:&lt;br&gt;     &lt;ul&gt;       &lt;li&gt;Control + PageUp / PageDown (Firefox, Thunderbird)&lt;br&gt;       &lt;/li&gt;       &lt;li&gt;Command + LeftArrow / RightArrow (Adium)&lt;/li&gt;       &lt;li&gt;Command + PageUp / PageDown (Komodo IDE)&lt;/li&gt;       &lt;li&gt;Command + Shift + [ / ] (Terminal)&lt;/li&gt;       &lt;li&gt;Command + Shift + LeftArrow / RightArrow (Terminal)&lt;/li&gt;     &lt;/ul&gt;     Hrm.&lt;br&gt;     &lt;br&gt;   </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/1639696569383368856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=1639696569383368856' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/1639696569383368856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/1639696569383368856'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2011/09/nextprevious-tab-keyboard-shortcuts-on.html' title='&quot;Next/Previous Tab&quot; Keyboard Shortcuts on Mac'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-4435398397928021957</id><published>2011-09-07T14:25:00.000-07:00</published><updated>2011-09-20T11:37:47.397-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jetpack"/><title type='text'>gitflow vs. the SDK</title><content type='html'>&lt;a href=&quot;http://nvie.com/posts/a-successful-git-branching-model/&quot;&gt;gitflow&lt;/a&gt; is a model for developing and shipping software using &lt;a href=&quot;http://git-scm.com/&quot;&gt;Git&lt;/a&gt;. &lt;a href=&quot;https://addons.mozilla.org/en-US/developers/builder&quot;&gt;Add-on SDK&lt;/a&gt; uses Git, and &lt;a href=&quot;https://wiki.mozilla.org/Jetpack/Development_Process&quot;&gt;it too has a model&lt;/a&gt;, which is similar to gitflow in some ways and different in others. Here&#39;s a comparison of the two and some thoughts on why they vary.&lt;br /&gt;&lt;br /&gt;First, some similarities: both models use multiple branches, including an ongoing branch for general development and another ongoing branch that is always ready for release (their names vary, but that&#39;s a trivial difference). Both also permit development on temporary feature (topic) branches and utilize a branch for stabilization of the codebase leading up to a release. And both accommodate the occasional hotfix release in similar ways.&lt;br /&gt;&lt;br /&gt;(Aside: gitflow appears to encourage feature branches, but I tend to agree with &lt;a href=&quot;http://martinfowler.com/bliki/FeatureBranch.html&quot;&gt;Martin Fowler&lt;/a&gt; through &lt;a href=&quot;http://pauljulius.com/blog/2009/09/03/feature-branches-are-poor-mans-modular-architecture/&quot;&gt;Paul Julius&lt;/a&gt; that continuously integrating with a central development branch is preferable.)&lt;br /&gt;&lt;br /&gt;Second, some differences: the SDK uses a single ongoing stabilization branch, while gitflow uses multiple short-lived stabilization branches, one per release. And in the SDK, stabilization fixes land on the development branch and then get cherry-picked to the stabilization branch; whereas in gitflow, stabilization fixes land on the stabilization branch and then get merged to the development branch.&lt;br /&gt;&lt;br /&gt;(Also, the SDK releases on a regular time/quality-driven &quot;train&quot; schedule similar to &lt;a href=&quot;http://mozilla.github.com/process-releases/draft/development_overview/&quot;&gt;Firefox&#39;s&lt;/a&gt;, while  gitflow may anticipate an irregular feature/quality-driven release schedule, although it can be  applied to projects with train schedules, like &lt;a href=&quot;http://lloyd.io/applying-gitflow&quot;&gt;BrowserID&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;A benefit of gitflow&#39;s approach to stabilization is that its change graph includes only distinct changes, whereas cherry-picking adds duplicate, semi-associated changes to the SDK&#39;s graph. However, a downside of gitflow&#39;s approach is that developers must attend to where they land changes, whereas SDK developers always land changes on its development branch, and its release manager takes on the chore of getting those changes onto the stabilization branch.&lt;br /&gt;&lt;br /&gt;(It isn&#39;t clear what happens in gitflow if a change lands on the development branch while a release is being stabilized and afterward is identified as being wanted for the release. Perhaps it gets cherry-picked?)&lt;br /&gt;&lt;br /&gt;Overall, these models seem fairly similar, and it wouldn&#39;t be too hard to make the SDK&#39;s be essentially gitflow. We would just need to stipulate that developers land stabilization fixes on the stabilization branch, and the release manager&#39;s job would then be to merge that branch back to the development branch periodically instead of cherry-picking in the other direction.&lt;br /&gt;&lt;br /&gt;However, it isn&#39;t clear to me that such a change would be preferable. What do you think?</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/4435398397928021957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=4435398397928021957' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/4435398397928021957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/4435398397928021957'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2011/09/gitflow-vs-sdk.html' title='gitflow vs. the SDK'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-8020854027593557159</id><published>2011-08-21T22:51:00.000-07:00</published><updated>2011-09-20T11:38:43.594-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jetpack"/><title type='text'>Administer Git? Get a job!</title><content type='html'>As I &lt;a href=&quot;http://mykzilla.blogspot.com/2011/08/why-add-on-sdk-doesnt-land-in-mozilla.html&quot;&gt;mentioned       recently&lt;/a&gt;, &lt;a href=&quot;http://git-scm.com/&quot;&gt;Git&lt;/a&gt; (on &lt;a       href=&quot;https://github.com/&quot;&gt;GitHub&lt;/a&gt;) has become a popular VCS     for Mozilla-related projects.&lt;br&gt;     &lt;br&gt;     GitHub is a fantastic tool for collaboration, and the site does a     great job running a Git server, but given the importance of the VCS,     and because Mozilla&#39;s automated test machines don&#39;t have access to     servers outside the Mozilla firewall, Mozilla should &lt;a       href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=528360&quot;&gt;run its       own Git server&lt;/a&gt; (that syncs with GitHub, so developers can     continue to use that site for collaboration).&lt;br&gt;     &lt;br&gt;     Unfortunately, the organization doesn&#39;t have a great deal of     in-house Git server administration experience, but we&#39;re &lt;a href=&quot;http://hire.jobvite.com/CompanyJobs/Careers.aspx?c=qpX9Vfwa&amp;amp;cs=9Kt9Vfw1&amp;amp;page=Job%20Description&amp;amp;j=oIfPVfwr&quot;&gt;hiring       systems administrators&lt;/a&gt;, so if you grok Git hosting and meet     the other requirements, &lt;a href=&quot;http://hire.jobvite.com/CompanyJobs/Careers.aspx?c=qpX9Vfwa&amp;amp;page=Apply&amp;amp;j=oIfPVfwr&quot;&gt;send       in your resume&lt;/a&gt;!&lt;br&gt;     &lt;br&gt;   </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/8020854027593557159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=8020854027593557159' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/8020854027593557159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/8020854027593557159'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2011/08/administer-git-get-job.html' title='Administer Git? Get a job!'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-1307851753993957811</id><published>2011-08-11T13:33:00.000-07:00</published><updated>2011-09-20T11:38:43.545-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jetpack"/><title type='text'>Why the Add-on SDK Doesn&#39;t &quot;Land in mozilla-central&quot;</title><content type='html'>Various Mozillians sometimes suggest that the Add-on SDK should &quot;land  in mozilla-central&quot; and wonder why it doesn&#39;t. Here&#39;s  why.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Add-on SDK depends on features of Firefox (and Gecko), and the SDK&#39;s development process synchronizes its release schedule with Firefox&#39;s. Nevertheless, the SDK  isn&#39;t a component of Firefox, it&#39;s a distinct product with its own  codebase, development process, and release schedule.&lt;br /&gt;&lt;br /&gt;Mozilla makes multiple products that interact with Firefox  (addons.mozilla.org, a.k.a. AMO, is another), and distinct product development  efforts should generally utilize separate code repositories, to avoid  contention between the projects regarding tree management, the stages of  the software development lifecycle (i.e. when which branch is in alpha,  beta, etc.), and the schedules for merging between branches.&lt;br /&gt;&lt;br /&gt;There can be exceptions to that principle, for products that share a  bunch of code, use the same development process, and have the same  release schedule (cf. the Firefoxes for desktop and mobile). But the  SDK is not one of those exceptions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It shares no code with Firefox. Its process utilizes one fewer branch  and six fewer weeks of development than the Firefox development process,  to minimize the burden of branch management and stabilization build  testing on its much smaller development team and testing community. And  it merges its branches and ships its releases two weeks before Firefox, to give AMO and addon developers time to update addons for each new version of the browser.&lt;br /&gt;&lt;br /&gt;Living in its own repository makes it possible for the SDK to have these differences in its process, and it also makes it possible for us to change the  process in the future, for example to move up the branch/release dates  one week, if we discover that AMO and addon developers would benefit from three  weeks of lead time; or to ship twice as frequently, if we determine  that doing so would get APIs for new Firefox features into  developers&#39; hands faster.&lt;br /&gt;&lt;br /&gt;Finally, the Jetpack project has a vibrant community of contributors  (including both organization staff and volunteers) who strongly prefer  contributing via Git and &lt;a href=&quot;https://github.com/&quot;&gt;GitHub&lt;/a&gt;, because they find it easier, more efficient, and more  enjoyable, and for whom working in mozilla-central would mean taking too  great a hit on their productivity, passion, and participation.&lt;br /&gt;&lt;br /&gt;Mozilla Labs innovates not only on features and  user experience but also on development process and tools, and while Jetpack didn&#39;t lead the way to GitHub, we were a fast follower once  early experiments validated its benefits. And our experience since then has only confirmed our decision, as GitHub has proven to be a fantastic tool for branch management, code review/integration, and other software development tasks.&lt;br /&gt;&lt;br /&gt;Other Mozillians agree: there are now almost two hundred members and  over one hundred repositories (not counting forks) in the Mozilla organization on GitHub, with major initiatives like &lt;a href=&quot;https://github.com/mozilla/openwebapps&quot;&gt;Open Web Apps&lt;/a&gt; and &lt;a href=&quot;https://github.com/mozilla/browserid&quot;&gt;BrowserID&lt;/a&gt; being hosted there, not to mention all the  Mozilla projects in user repositories, including &lt;a href=&quot;https://github.com/graydon/rust&quot;&gt;Rust&lt;/a&gt; and &lt;a href=&quot;https://github.com/jbalogh/zamboni&quot;&gt;Zamboni&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Even if we don&#39;t make mozilla-central the canonical repository for SDK  development, however, we could still periodically drop a copy of the SDK  source against which Firefox changes should be tested into  mozilla-central. And doing so would theoretically make it easier for Firefox  developers to run SDK tests when they discover that a Firefox change  breaks the SDK, because they wouldn&#39;t have to get the SDK first.&lt;br /&gt;&lt;br /&gt;But the benefit to Firefox developers is minimal. Currently, we  periodically drop a reference to the SDK revision against which Firefox  changes should be tested, and developers have to do the following to  initiate testing:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;nbsp; wget -i testing/jetpack/jetpack-location.txt -O addon-sdk.tar.bz2
    &lt;br /&gt;&amp;nbsp; tar xjf addon-sdk.tar.bz2
    &lt;br /&gt;&amp;nbsp; cd addon-sdk-[revision]
    &lt;br /&gt;&amp;nbsp; source bin/activate
    &lt;br /&gt;&amp;nbsp; cfx testall --binary path/to/Firefox/build
    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We can simplify this to:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;nbsp; testing/jetpack/clone
    &lt;br /&gt;&amp;nbsp; cd addon-sdk
    &lt;br /&gt;&amp;nbsp; source bin/activate
    &lt;br /&gt;&amp;nbsp; cfx testall --binary path/to/Firefox/build
    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Whereas if we dropped the source instead of just a reference to it, it would instead be the only slightly simpler:  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;nbsp; cd testing/jetpack/addon-sdk
    &lt;br /&gt;&amp;nbsp; source bin/activate
    &lt;br /&gt;&amp;nbsp; cfx testall --binary path/to/Firefox/build
    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Either of which can be abstracted to a single make target.&lt;br /&gt;&lt;br /&gt;But if we were to drop source instead of a reference thereto, the drops  would be larger and riskier changes. And test automation would  still need to be updated to support Git (or at least continue to use  brittle Git -&amp;gt; Mercurial mirroring), in order to run tests on SDK  changes, which periodic source drops do not address.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, this doesn&#39;t mean that no SDK code will ever land in mozilla-central.&lt;br /&gt;&lt;br /&gt;Various folks have discussed integrating parts of the SDK into core  Firefox&lt;span class=&quot;st&quot;&gt;—&lt;/span&gt;including stable API implementations, the module loader, and  possibly the bootstrapper&lt;span class=&quot;st&quot;&gt;—&lt;/span&gt;to reduce the size of addon packages, improve  addon startup times, and decrease addon memory consumption. I have  written a very preliminary draft of a &lt;a href=&quot;https://wiki.mozilla.org/Features/Jetpack/Land_Parts_of_Add-on_SDK_In_Core&quot;&gt;feature page describing this work&lt;/a&gt;,  although I do not think it is a high priority at the moment, relative to the other priorities identified in the &lt;a href=&quot;https://wiki.mozilla.org/Jetpack/Roadmap&quot;&gt;Jetpack roadmap&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And Dietrich Ayala recently suggested &lt;a href=&quot;http://groups.google.com/group/mozilla.dev.planning/browse_frm/thread/2b57ebe15aad4130&quot;&gt;integrating the SDK into core  Firefox for use by core features&lt;/a&gt;,  by which he presumably also means the API implementations/module  loader/bootstrapper rather than the command-line tool for testing and  packaging addons.&lt;br /&gt;&lt;br /&gt;Nevertheless, I am (and, I suspect, the whole Jetpack team is) even open  to discussing integration of the command-line tool (or its replacement  by a graphical equivalent), merging together the two products, and  erasing the distinction between them, just as Firefox ships with core  features for web development.&amp;nbsp; We&#39;ve even drafted a &lt;a href=&quot;https://wiki.mozilla.org/Features/Jetpack/Add-on_SDK_as_an_Addon&quot;&gt;feature page for  converting the SDK into an addon&lt;/a&gt;,  which is a big step in that direction.&lt;br /&gt;&lt;br /&gt;But until that happens, farther on up the road, the SDK is its own  product that we develop with its own process and ship on its own schedule. And it has good reason to live in its own repository, and a Git one at that, as do the many (and growing number of) other Mozilla projects using similar processes and tools, which our community-wide development, collaboration, and testing infrastructure must evolve to accommodate.</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/1307851753993957811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=1307851753993957811' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/1307851753993957811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/1307851753993957811'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2011/08/why-add-on-sdk-doesnt-land-in-mozilla.html' title='Why the Add-on SDK Doesn&#39;t &quot;Land in mozilla-central&quot;'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-6715608859512848344</id><published>2010-12-02T11:07:00.001-08:00</published><updated>2011-09-20T11:38:43.568-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jetpack"/><title type='text'>SDK Training and More at Add-on-Con</title><content type='html'>&lt;div class=&quot;moz-text-html&quot; lang=&quot;x-western&quot;&gt;Next Wednesday, December       8, I&#39;ll be at &lt;a href=&quot;http://addoncon.com/&quot;&gt;Add-on-Con&lt;/a&gt;.&lt;br&gt;       &lt;br&gt;       In the morning, I&#39;ll conduct a training session introducing       Mozilla&#39;s new Add-on SDK, which makes it faster and easier to       build Firefox add-ons. Afterwards, I&#39;ll be around and about to       discuss add-ons and answer questions about the SDK and add-on       development generally.&lt;br&gt;       &lt;br&gt;       Lots of other Mozilla folks will also be on hand over the course       of the two-day conference, including &lt;a         href=&quot;http://www.oxymoronical.com/&quot;&gt;Dave Townsend&lt;/a&gt;, Jorge       Villalobos, &lt;a href=&quot;http://jboriss.wordpress.com/&quot;&gt;Jeniffer         Boriss&lt;/a&gt;, &lt;a href=&quot;http://starkravingfinkle.org/blog/&quot;&gt;Mark         Finkle&lt;/a&gt;, and &lt;a href=&quot;http://blog.fligtar.com/&quot;&gt;Justin Scott&lt;/a&gt;.       A rockin&#39; time should be had by all. Join us!&lt;br&gt;       &lt;br&gt;     &lt;/div&gt;   </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/6715608859512848344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=6715608859512848344' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/6715608859512848344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/6715608859512848344'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2010/12/sdk-training-and-more-at-add-on-con.html' title='SDK Training and More at Add-on-Con'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-1323551422046235302</id><published>2010-11-27T20:47:00.001-08:00</published><updated>2011-09-20T11:38:43.550-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jetpack"/><title type='text'>Further Adventures In Git(/Hub)ery</title><content type='html'>&lt;div class=&quot;moz-text-html&quot; lang=&quot;x-western&quot;&gt; This evening I decided       to check if there were any outstanding pull requests for the SDK       repository (to which I haven&#39;t been paying attention).&lt;br&gt;       &lt;br&gt;       There were! The oldest was &lt;a         href=&quot;https://github.com/mozilla/addon-sdk/pull/29&quot;&gt;pull request         29&lt;/a&gt; from Thomas Bassetto, which contains two small fixes (&lt;a href=&quot;https://github.com/tbassetto/addon-sdk/commit/8268334070d03a896d5c006d1b4db94d4cb44b17&quot;&gt;first&lt;/a&gt;,       &lt;a href=&quot;https://github.com/tbassetto/addon-sdk/commit/666ad7a99e05e338348dfc579d5b1f75e8d3bb1b&quot;&gt;second&lt;/a&gt;)       to the docs.&lt;br&gt;       &lt;br&gt;       So I fetched the branch of his fork in which the changes reside:&lt;br&gt;       &lt;br&gt;       &lt;blockquote&gt;&lt;tt&gt;$ git fetch &lt;a class=&quot;moz-txt-link-freetext&quot;             href=&quot;https://github.com/tbassetto/addon-sdk.git&quot;&gt;https://github.com/tbassetto/addon-sdk.git&lt;/a&gt;           master&lt;/tt&gt;&lt;br&gt;       &lt;/blockquote&gt;       &lt;br&gt;       But that branch (and the fork in general) is a few weeks       out-of-date, so &quot;&lt;tt&gt;git diff HEAD FETCH_HEAD&lt;/tt&gt;&quot; showed a bunch       of changes, and it was unclear how painful the merge would be.&lt;br&gt;       &lt;br&gt;       Thus I decided to try cherry-picking the changes, my first time       using &quot;&lt;tt&gt;git cherry-pick&lt;/tt&gt;&quot;.&lt;br&gt;       &lt;br&gt;       The first one went great:&lt;br&gt;       &lt;br&gt;       &lt;blockquote&gt;&lt;tt&gt;$ git cherry-pick           8268334070d03a896d5c006d1b4db94d4cb44b17&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;Finished one cherry-pick.&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;[master ceadb1f] Fixed an internal link in the widget doc&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;&amp;nbsp;1 files changed, 1 insertions(+), 1 deletions(-)&lt;/tt&gt;&lt;br&gt;       &lt;/blockquote&gt;       &lt;br&gt;       Except that I realized afterward I hadn&#39;t added &quot;r,a=myk&quot; to the       commit message. So I tried &quot;&lt;tt&gt;git commit --amend&lt;/tt&gt;&quot; for the       first time, which worked just fine:&lt;br&gt;       &lt;br&gt;       &lt;blockquote&gt;&lt;tt&gt;$ git commit --amend&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;[master 2d674a6] Fixed an internal link in the widget doc;           r,a=myk&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;&amp;nbsp;1 files changed, 1 insertions(+), 1 deletions(-)&lt;/tt&gt;&lt;br&gt;       &lt;/blockquote&gt;       &lt;br&gt;       Next time I&#39;ll remember to use the &quot;&lt;tt&gt;--edit&lt;/tt&gt;&quot; flag to &quot;&lt;tt&gt;git          cherry-pick&lt;/tt&gt;&quot;, which lets one &quot;edit the commit message prior       to committing.&quot;&lt;br&gt;       &lt;br&gt;       The second cherry-pick was more complicated, because I only wanted       one of the two changes in the commit (in &lt;a href=&quot;https://github.com/tbassetto/addon-sdk/commit/666ad7a99e05e338348dfc579d5b1f75e8d3bb1b#commitcomment-204023&quot;&gt;my          review&lt;/a&gt;, I had identified the second change as unnecessary);       and, as it turned out, also because there was a merge conflict       with other commits.&lt;br&gt;       &lt;br&gt;       I started by cherry-picking the commit with the &quot;&lt;tt&gt;--no-commit&lt;/tt&gt;&quot;       option (so I could remove the second change):&lt;br&gt;       &lt;br&gt;       &lt;blockquote&gt;&lt;tt&gt;$ git cherry-pick --no-commit           666ad7a99e05e338348dfc579d5b1f75e8d3bb1b&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;Automatic cherry-pick failed.&amp;nbsp; After resolving the           conflicts,&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;mark the corrected paths with &#39;git add &amp;lt;paths&amp;gt;&#39; or           &#39;git rm &amp;lt;paths&amp;gt;&#39; and commit the result.&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;When commiting, use the option &#39;-c 666ad7a&#39; to retain           authorship and message.&lt;/tt&gt;&lt;br&gt;       &lt;/blockquote&gt;       &lt;br&gt;       The conflict was trivial, and I knew where it was, so I resolved       it manually (instead of trying &quot;&lt;tt&gt;git mergetool&lt;/tt&gt;&quot; for the       first time), removed the second change, added the merged file, and       committed the result, using the &quot;&lt;tt&gt;-c&lt;/tt&gt;&quot; option to preserve       the original author and commit message while allowing me to edit       the message to add &quot;r,a=myk&quot;:&lt;br&gt;       &lt;br&gt;       &lt;blockquote&gt;&lt;tt&gt;$ git add packages/addon-kit/docs/request.md&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;$ git commit -c 666ad7a&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;[master 774d1cb] Completed the example in the Request module           documentation; r,a=myk&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;&amp;nbsp;1 files changed, 1 insertions(+), 0 deletions(-)&lt;/tt&gt;&lt;br&gt;       &lt;/blockquote&gt;       &lt;br&gt;       Then I used &quot;&lt;tt&gt;gitg&lt;/tt&gt;&quot; and &quot;&lt;tt&gt;git log master         ^upstream/master&lt;/tt&gt;&quot; to verify that the commits looked good to       go, after which I pushed them:&lt;br&gt;       &lt;br&gt;       &lt;blockquote&gt;&lt;tt&gt;$ git push upstream master&lt;/tt&gt;&lt;br&gt;         &lt;tt&gt;[git&#39;s standard obscure and disconcerting gobbledygook]&lt;/tt&gt;&lt;br&gt;       &lt;/blockquote&gt;       &lt;br&gt;       Finally, I closed the pull request with &lt;a         href=&quot;https://github.com/mozilla/addon-sdk/pull/29#issuecomment-570630&quot;&gt;this          comment&lt;/a&gt; that summarized what I did and provided links to the       cherry-picked commits.&lt;br&gt;       &lt;br&gt;       It would have been nice if the cherry-picked commit that didn&#39;t       have merge conflicts (and which I didn&#39;t change in the process of       merging) had kept its original commit ID, but I sense that that is       somehow a fundamental violation of the model.&lt;br&gt;       &lt;br&gt;       It would also have been nice if the cherry-picked commit messages       had been automatically annotated with references to the original       commits.&lt;br&gt;       &lt;br&gt;       But overall the process seemed pretty reasonable, it was fairly       easy to do what I wanted and recover from mistakes, and the       author, committer, reviewer, and approver are clearly indicated in       the cherry-picked commits (&lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/2d674a6ea84d3be88b5365b2d24b994297a60d7a&quot;&gt;first&lt;/a&gt;,       &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/774d1cbf49e152a030a0bf6cbde7b4139c8c3f49&quot;&gt;second&lt;/a&gt;).&lt;br&gt;       &lt;br&gt;       [Also &lt;a href=&quot;http://groups.google.com/group/mozilla-labs-jetpack/browse_thread/thread/430750c65fe80231&quot;&gt;posted         to the discussion group&lt;/a&gt;.]&lt;br&gt;       &lt;br&gt;     &lt;/div&gt;   </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/1323551422046235302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=1323551422046235302' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/1323551422046235302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/1323551422046235302'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2010/11/further-adventures-in-githubery.html' title='Further Adventures In Git(/Hub)ery'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-7960433840999647174</id><published>2010-11-27T20:39:00.001-08:00</published><updated>2011-09-20T11:38:43.583-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jetpack"/><title type='text'>More Git/Hub Workflow Experiences</title><content type='html'>After posting about my &lt;a href=&quot;http://mykzilla.blogspot.com/2010/11/github-workflow-experiences.html&quot;&gt;first       Git/Hub workflow experiences&lt;/a&gt;, I got lots of helpful input from     various folks, particularly Erik Vold, Irakli Gozalishvili, and     Brian Warner, which led me to refine my process for handling pull     requests:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;From the &quot;how to merge this pull request&quot; section of the pull         request page (f.e. &lt;a href=&quot;https://github.com/mozilla/addon-sdk/pull/43&quot;&gt;pull           request 34&lt;/a&gt;), copy the command from step two, but change         the word &quot;pull&quot; to &quot;fetch&quot; to fetch the remote branch containing         the changes without also merging it:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;git fetch &lt;a class=&quot;moz-txt-link-freetext&quot; href=&quot;https://github.com/toolness/jetpack-sdk.git&quot;&gt;https://github.com/toolness/jetpack-sdk.git&lt;/a&gt;           bug-610507&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Use the magic FETCH_HEAD reference to the last fetched branch         to verify that the set of changes is what you expect:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;git diff &lt;/tt&gt;&lt;tt&gt;HEAD &lt;/tt&gt;&lt;tt&gt;FETCH_HEAD&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;(The exact syntax here may need some work; HEAD..FETCH_HEAD?         three dots?)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Merge the remote branch into your local branch with a custom         commit message:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;git merge FETCH_HEAD --no-ff -m&quot;bug 610507: get rid of the           nsjetpack package; r=myk&quot;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Push the changes upstream:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;git push upstream master&lt;/tt&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I like this set of commands because it doesn&#39;t require me to add a     remote, I can copy/paste the fetch command from GitHub (being     careful not to issue the pull before I change it to a fetch), and I     always type the same FETCH_HEAD reference to the remote branch in     step three.&lt;br /&gt;&lt;br /&gt;However, I wish the &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/0e23d1c1555d5de228ed7ad62c8715e2775d2390&quot;&gt;merge        commit page&lt;/a&gt; explicitly referenced the &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/68b6e306dfeccef103b071e0812dc3a375830ac0&quot;&gt;specific&lt;/a&gt;     &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/715cb47c720bcdd11846cae6c6cab325bb1a982b&quot;&gt;commits&lt;/a&gt;     that were merged. It does mention that it&#39;s a branch merge, it isn&#39;t     obvious how to get from that page to the pages for the commits I     merged from the branch.&lt;br /&gt;&lt;br /&gt;&quot;&lt;tt&gt;git log --oneline --graph&lt;/tt&gt;&quot;, &lt;tt&gt;gitg&lt;/tt&gt;, and &lt;tt&gt;gitk&lt;/tt&gt;     do give me that information, though, so I&#39;m ok on the command line,     anyway.&lt;br /&gt;&lt;br /&gt;[More discussion can be found in the &lt;a href=&quot;http://groups.google.com/group/mozilla-labs-jetpack/browse_thread/thread/2c6cb3e7f3bec468&quot;&gt;discussion       group thread&lt;/a&gt;.]</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/7960433840999647174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=7960433840999647174' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7960433840999647174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7960433840999647174'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2010/11/more-github-workflow-experiences.html' title='More Git/Hub Workflow Experiences'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-7037189428773681360</id><published>2010-11-12T18:55:00.000-08:00</published><updated>2011-09-20T11:38:43.577-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jetpack"/><title type='text'>Git/Hub Workflow Experiences</title><content type='html'>&lt;div class=&quot;moz-text-html&quot; lang=&quot;x-western&quot;&gt;The Jetpack project recently migrated its SDK repository to Git (hosted on GitHub), and we&#39;ve been working out changes to the bug/review/commit workflow that GitHub&#39;s tools enable (specifically, pull requests).&lt;/div&gt;&lt;div class=&quot;moz-text-html&quot; lang=&quot;x-western&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;moz-text-html&quot; lang=&quot;x-western&quot;&gt;Here are some of my initial experiences and my thoughts on them (which I&#39;ve also &lt;a href=&quot;http://groups.google.com/group/mozilla-labs-jetpack/browse_thread/thread/2c6cb3e7f3bec468&quot;&gt;posted to the Jetpack discussion group&lt;/a&gt;).&lt;/div&gt;&lt;div class=&quot;moz-text-html&quot; lang=&quot;x-western&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;moz-text-html&quot; lang=&quot;x-western&quot;&gt; &lt;/div&gt;&lt;div class=&quot;moz-text-html&quot; lang=&quot;x-western&quot;&gt;     Warning: Git wonkery ahead, with excruciating details. I would not     want to read this post. I recommend you skip it. ;-)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;     Part 1: Wherein I Handle My First Pull Request&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To fix some test failures, Atul submitted &lt;a href=&quot;https://github.com/mozilla/addon-sdk/pull/33&quot;&gt;GitHub pull       request 33&lt;/a&gt;, I reviewed the changes (comprising &lt;a href=&quot;https://github.com/toolness/jetpack-sdk/commit/97619b0b25554712756827de883883c9b810319d&quot;&gt;two&lt;/a&gt;     &lt;a href=&quot;https://github.com/toolness/jetpack-sdk/commit/405390a586f6c09bad2b26183fe2925d09bcd52b&quot;&gt;commits&lt;/a&gt;)     on GitHub, and then I pushed them to the canonical repository via     the following set of commands:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;git checkout -b toolness-&lt;span class=&quot;commit-ref from&quot;&gt;4.0b7-bustage-fixes&lt;/span&gt;         master&lt;/li&gt;&lt;li&gt;git pull &lt;a class=&quot;moz-txt-link-freetext&quot; href=&quot;https://github.com/toolness/jetpack-sdk.git&quot;&gt;https://github.com/toolness/jetpack-sdk.git&lt;/a&gt; &lt;span class=&quot;commit-ref from&quot;&gt;4.0b7-bustage-fixes&lt;/span&gt;&lt;/li&gt;&lt;li&gt;git checkout master&lt;/li&gt;&lt;li&gt;git merge toolness-&lt;span class=&quot;commit-ref from&quot;&gt;4.0b7-bustage-fixes&lt;/span&gt;&lt;/li&gt;&lt;li&gt;git push upstream master&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;That landed the &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/97619b0b25554712756827de883883c9b810319d&quot;&gt;two&lt;/a&gt;     &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/405390a586f6c09bad2b26183fe2925d09bcd52b&quot;&gt;commits&lt;/a&gt;     in the canonical repository, but it isn&#39;t obvious that they were     related (i.e. part of the same pull request), that I was the one who     reviewed them, or that I was the one who pushed them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Part 2: Wherein I Handle My Second Pull Request&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Thus, for the fix for &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=611042&quot;&gt;bug       611042&lt;/a&gt;, for which Atul submitted &lt;a href=&quot;https://github.com/mozilla/addon-sdk/pull/34&quot;&gt;GitHub pull       request 34&lt;/a&gt;, I again reviewed the changes (also comprising &lt;a href=&quot;https://github.com/toolness/jetpack-sdk/commit/5e6ca0e1834e65623f6ac87d3828965da420847c&quot;&gt;two&lt;/a&gt;     &lt;a href=&quot;https://github.com/toolness/jetpack-sdk/commit/1ab9c78c94fb08610460ad19fd763a7402fc233c&quot;&gt;commits&lt;/a&gt;)     on GitHub, but then I pushed them to the &lt;a href=&quot;https://github.com/mozilla/addon-sdk&quot;&gt;canonical repository&lt;/a&gt;     via this different set of commands (after discussion with Atul and     Patrick Walton of the Rust team):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;git checkout -b toolness-bug-611042 master&lt;/li&gt;&lt;li&gt;git pull &lt;a class=&quot;moz-txt-link-freetext&quot; href=&quot;https://github.com/toolness/jetpack-sdk.git&quot;&gt;https://github.com/toolness/jetpack-sdk.git&lt;/a&gt;         bug-611042&lt;/li&gt;&lt;li&gt;(There might have been something else here, since the pull         request resulted in a merge; I don&#39;t quite remember.)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;git checkout master&lt;/li&gt;&lt;li&gt;git merge --no-ff --no-commit toolness-bug-611042&lt;/li&gt;&lt;li&gt;git commit --signoff -m &quot;bug 611042: remove         request.response.xml for e10s compatibility; r=myk&quot; --author         &quot;atul&quot;&lt;/li&gt;&lt;li&gt;git push upstream master&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Because Atul&#39;s pull request was no longer against the tip (since I     had just merged those previous changes), when I pulled the remote     bug-611042 branch into my local toolness-bug-611042 branch (step 2),     I had to merge his changes, which resulted in a &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/6a3c9e2a614f29b61e580a7a7619f91dd1306eea&quot;&gt;merge       commit&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Merging the changes to my local master with &quot;--no-ff&quot; and     &quot;--no-commit&quot; (step 5) then allowed me to commit the merge to my     master branch manually (step 6), resulting in another &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/9f202a3003cddace040bc695ab7137d4a31051ec&quot;&gt;merge       commit&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For the second merge commit, I specified &quot;--signoff&quot;, which added     &quot;Signed-off-by: Myk Melez &lt;a class=&quot;moz-txt-link-rfc2396E&quot; href=&quot;mailto:myk@mozilla.org&quot;&gt;&lt;myk@mozilla.org&gt;&lt;/myk@mozilla.org&gt;&lt;/a&gt;&quot; to the commit     message; crafted a custom commit message that included &quot;r=myk&quot;; and     specified &#39;--author &quot;atul&quot;&#39;, which made Atul the author of the     merge.&lt;br /&gt;&lt;br /&gt;I dislike having the former merge commit in history, since it&#39;s     extraneous, unuseful details about how I did the merging locally     before I pushed to the canonical repository. I&#39;m not sure how to     avoid it, though.&lt;br /&gt;&lt;br /&gt;On the other hand, I like having the latter merge commit in history,     since it provides context for Atul&#39;s &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/5e6ca0e1834e65623f6ac87d3828965da420847c&quot;&gt;two&lt;/a&gt;     &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/1ab9c78c94fb08610460ad19fd763a7402fc233c&quot;&gt;commits&lt;/a&gt;:     the bug number, the fact that the changes were reviewed, and a     commit message that describes the changes as a whole.&lt;br /&gt;&lt;br /&gt;I&#39;m ambivalent about --signoff vs. adding &quot;r=myk&quot; to the commit     message, as they seem equivalentish, with --signoff being more     explicit (so in theory it might form part of an enlightened workflow     in the future), while &quot;r=myk&quot; is simpler.&lt;br /&gt;&lt;br /&gt;And I dislike having made Atul the author of the merge, since it&#39;s     incorrect: he wasn&#39;t the author of the merge, he was only the author     of the changes (for which he is correctly credited). And if the     merge itself caused problems (f.e. I accidentally backed out other     recent changes in the process), I would be the one responsible for     fixing those problems, not Atul.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Part 3: Pushing Patches&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In addition to pull requests, one can also contribute via patches.     I&#39;ve pushed a few of these via something like the following set of     commands:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;git apply patch.diff&lt;/li&gt;&lt;li&gt;git commit -a -m &quot;bug &lt;number&gt;: &lt;description changes=&quot;&quot; of=&quot;&quot;&gt;; r=myk&quot; --author &quot;&lt;author name=&quot;&quot;&gt;&quot;&lt;br /&gt;&lt;/author&gt;&lt;/description&gt;&lt;/number&gt;&lt;/li&gt;&lt;li&gt;git push upstream master&lt;/li&gt;&lt;/ol&gt;That results in a commit like &lt;a href=&quot;https://github.com/mozilla/addon-sdk/commit/026b4e8e78336c2dbbf30edb14e5db78ca4afb21&quot;&gt;this       one&lt;/a&gt;, which shows me as the committer and the patch author as     the author. And that seems like a fine record of what happened.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Part 4: To Bug or Not To Bug?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One of the questions GitHub raises is whether or not every change     deserves a bug report. And if not, how do we differentiate those     that do from the rest?&lt;br /&gt;&lt;br /&gt;I don&#39;t have the definitive answers to these questions, but my     sense, from my experience so far, is that we shouldn&#39;t require all     changes to be accompanied by bug reports, but larger, riskier,     time-consuming, and/or controversial changes should have reports to     capture history, provide a forum for discussion, and permit project     planning; while bug reports should be optional for smaller, safer,     quickly-resolved, and/or non-controversial changes.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/7037189428773681360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=7037189428773681360' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7037189428773681360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7037189428773681360'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2010/11/github-workflow-experiences.html' title='Git/Hub Workflow Experiences'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-236254320002589931</id><published>2010-07-15T14:22:00.000-07:00</published><updated>2011-09-20T11:38:43.557-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jetpack"/><title type='text'>My Recent Jetpack Presentations</title><content type='html'>The last few weeks have been presentation-heavy.&lt;br /&gt;&lt;br /&gt;First, I gave a presentation about the Jetpack project (past accomplishments, present status, future plans) at the &lt;a href=&quot;https://wiki.mozilla.org/MAOW:2010:London&quot;&gt;2010 London Mozilla Add-ons Workshop&lt;/a&gt; (MAOW), including a demo of using &lt;a href=&quot;https://builder.mozillalabs.com/&quot;&gt;Add-on Builder&lt;/a&gt; to build an add-on in five minutes.&lt;br /&gt;&lt;br /&gt;Then I reprised the Add-on Builder demo as part of the opening day keynote at the &lt;a href=&quot;https://wiki.mozilla.org/Summit2010&quot;&gt;Mozilla Summit&lt;/a&gt;, where it got a great reception. You can watch it in &lt;a href=&quot;http://www.youtube.com/watch?v=lKN4_fOKEWQ&quot;&gt;this Youtube video&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Finally, I gave an updated version of the MAOW presentation on the third day of the summit. The slides are available in &lt;a href=&quot;https://people.mozilla.com/%7Emyk/presentations/Prepare%20for%20Liftoff%20-%20Summit%202010.odp&quot;&gt;OpenDocument&lt;/a&gt; and &lt;a href=&quot;https://people.mozilla.com/%7Emyk/presentations/Prepare%20for%20Liftoff%20-%20Summit%202010.pdf&quot;&gt;PDF&lt;/a&gt; formats, and Jetpack presentation materials generally are all available from the &lt;a href=&quot;https://wiki.mozilla.org/Labs/Jetpack/Presentations&quot;&gt;Jetpack Presentations wiki page&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/236254320002589931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=236254320002589931' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/236254320002589931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/236254320002589931'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2010/07/my-recent-jetpack-presentations.html' title='My Recent Jetpack Presentations'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-6583468542975089893</id><published>2010-03-05T23:03:00.001-08:00</published><updated>2010-04-18T23:58:52.841-07:00</updated><title type='text'>This blog has moved</title><content type='html'>&lt;br /&gt;       This blog is now located at http://mykzilla.blogspot.com/.&lt;br /&gt;       You will be automatically redirected in 30 seconds, or you may click &lt;a href=&#39;http://mykzilla.blogspot.com/&#39;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;       For feed subscribers, please update your feed subscriptions to&lt;br /&gt;       http://mykzilla.blogspot.com/feeds/posts/default.&lt;br /&gt;  </content><link rel="related" href="http://mykzilla.blogspot.com/" title="This blog has moved"/><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/6583468542975089893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=6583468542975089893' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/6583468542975089893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/6583468542975089893'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2010/03/this-blog-has-moved.html' title='This blog has moved'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-7015776887411907934</id><published>2009-11-17T17:26:00.000-08:00</published><updated>2009-11-17T17:26:50.807-08:00</updated><title type='text'>The Skinny on Raindrop&#39;s Mailing List Extensions</title><content type='html'>Raindrop is an exploration of messaging innovation that strives to intelligently assist people in managing their flood of incoming messages. And mailing lists are a common source of messages you need to manage. So, with assistance from the Raindrop hackers, I wrote extensions that make it easier to deal with messages from mailing lists.&lt;br /&gt;&lt;br /&gt;Their goal is to soothe two particular pain points when dealing with mailing lists: grouping their messages together by list and unsubscribing from them once you&#39;re no longer interested in their subject matter.&lt;br /&gt;&lt;br /&gt;This post explains how the extensions do this; touches on some aspects of Raindrop&#39;s message processing and data storage models; and speculates about possible future directions for the extensions.&lt;br /&gt;&lt;h3&gt;Raindrop Extensibility&lt;/h3&gt;Raindrop is being built with the explicit goal of being broadly and deeply extensible, and it includes a number of APIs for adding and modifying functionality. The mailing list enhancements comprise two related extensions, one in the backend and one in the user interface.&lt;br /&gt;&lt;br /&gt;The backend extension plugs into Raindrop&#39;s incoming message processor, intercepting incoming email messages and extracting info about the mailing lists to which they belong. It also handles much of the work of unsubscribing from a list.&lt;br /&gt;&lt;br /&gt;The frontend extension plugs into Raindrop&#39;s Inflow application, modifying its interface to show you the most recent mailing list messages at a glance, group mailing list conversations together by list, and provide a button you can press to easily unsubscribe from a mailing list.&lt;br /&gt;&lt;h3&gt;Message Processing and Data Storage&lt;br /&gt;&lt;/h3&gt;Before getting into how the extensions work, it&#39;s useful to know a bit about how Raindrop processes and stores messages.&lt;br /&gt;&lt;br /&gt;Raindrop stores information using &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt;, a document-centric database whose principal unit of information storage and retrieval is the document (the equivalent of a record in SQL databases). Documents are just JSON blobs that can contain arbitrary name -&gt; value pairs (unlike SQL records, which can only contain values for predeclared columns).&lt;br /&gt;&lt;br /&gt;To distinguish between different kinds of documents, Raindrop assigns each a schema (similar to a table in SQL parlance) that describes (and may one day constrain) its properties. The &lt;tt&gt;rd.msg.email&lt;/tt&gt; schema is the primary schema representing an email message, while the &lt;tt&gt;rd.mailing-list&lt;/tt&gt; is the schema representing a mailing list, and the &lt;tt&gt;rd.msg.email.mailing-list&lt;/tt&gt; is a simple schema that associates messages with their lists.&lt;br /&gt;&lt;br /&gt;(In an SQL database, &lt;tt&gt;rd.msg.email&lt;/tt&gt; and &lt;tt&gt;rd.mailing-list&lt;/tt&gt; would be tables whose rows represent email messages and mailing lists, while &lt;tt&gt;rd.msg.email.mailing-list&lt;/tt&gt; would be a table whose rows map one to the other.)&lt;br /&gt;&lt;br /&gt;Note that there&#39;s a many-to-one relationship between messages and lists, since messages belong to a single list, although lists contain many messages, so &lt;tt&gt;rd.msg.email.mailing-list&lt;/tt&gt; isn&#39;t strictly necessary. Its &lt;tt&gt;list-id&lt;/tt&gt; property (which identifies the list to which the message belongs) could simply be a property of &lt;tt&gt;rd.msg.email&lt;/tt&gt; docs (or, in SQL terms, a foreign key in the &lt;tt&gt;rd.msg.email&lt;/tt&gt; table).&lt;br /&gt;&lt;br /&gt;But putting it into its own document has several advantages. First, it improves robustness, as it reduces the possibility of conflicts between extensions and core code writing to the same documents.&lt;br /&gt;&lt;br /&gt;It also improves write performance, as it&#39;s faster to add a document than to modify an existing one (although index generation and read performance can be an issue).&lt;br /&gt;&lt;br /&gt;Finally, it improves extensibility, because it makes it possible to write an extension that extends the backend mailing list extension.&lt;br /&gt;&lt;br /&gt;That&#39;s because Raindrop&#39;s incoming message processing model allows extensions to observe the creation of any kind of document, including those created by other extensions.&lt;br /&gt;&lt;br /&gt;So just as the mailing list extension observes the creation of &lt;tt&gt;rd.msg.email&lt;/tt&gt; documents, another extension can observe the creation of &lt;tt&gt;rd.msg.email.mailing-list&lt;/tt&gt; documents and process them further in some useful way. If the mailing list extension simply modified the original document instead of creating its own, that would require some additional and more complicated API.&lt;br /&gt;&lt;h3&gt;The Backend Extension&lt;/h3&gt;The primary function of the backend extension is to examine every incoming message and dress the ones from mailing lists with some additional structured information that the frontend can use to organize them.&lt;br /&gt;&lt;br /&gt;Backend extensions are accompanied by a JSON manifest that tells Raindrop what kinds of incoming documents it wants to intercept. The mailing list extension&#39;s manifest registers it as an observer of incoming &lt;tt&gt;rd.msg.email&lt;/tt&gt; documents, which get created when Raindrop retrieves an email message:&lt;br /&gt;&lt;pre style=&quot;background-color: rgb(238, 238, 238); border: 1px solid rgb(187, 187, 187); color: black; padding: 10px;&quot;&gt;&quot;schemas&quot; : {&lt;br /&gt;  &quot;rd.ext.workqueue&quot; : {&lt;br /&gt;      &quot;source_schemas&quot; : [&quot;rd.msg.email&quot;],&lt;br /&gt;...&lt;/pre&gt;&lt;br /&gt;The extension itself is a Python script with a &lt;tt&gt;handler&lt;/tt&gt; function that gets passed the &lt;tt&gt;rd.msg.email&lt;/tt&gt; document and looks to see if it contains a &lt;tt&gt;List-ID&lt;/tt&gt; header (or, in certain cases, another identifier) identifying the mailing list from which the message comes:&lt;br /&gt;&lt;pre style=&quot;background-color: rgb(238, 238, 238); border: 1px solid rgb(187, 187, 187); color: black; padding: 10px;&quot;&gt;def handler(message):&lt;br /&gt;  ...&lt;br /&gt;  if &#39;list-id&#39; in message[&#39;headers&#39;]:&lt;br /&gt;      # Extract the ID and name of the mailing list from the list-id header.&lt;br /&gt;      # Some mailing lists give only the ID, but others (Google Groups,&lt;br /&gt;      # Mailman) provide both using the format &#39;NAME &amp;lt;id&amp;gt;&#39;, so we extract them&lt;br /&gt;      # separately if we detect that format.&lt;br /&gt;      list_id = message[&#39;headers&#39;][&#39;list-id&#39;][0]&lt;br /&gt;  ...&lt;/pre&gt;&lt;br /&gt;If it doesn&#39;t find a list identifier, it simply returns, and Raindrop continues processing the message:&lt;br /&gt;&lt;pre style=&quot;background-color: rgb(238, 238, 238); border: 1px solid rgb(187, 187, 187); color: black; padding: 10px;&quot;&gt;if not list_id:&lt;br /&gt;    logger.debug(&quot;NO LIST ID; ignoring message %s&quot;, message_id)&lt;br /&gt;    return&lt;/pre&gt;&lt;br /&gt;Otherwise, it calls Raindrop&#39;s &lt;tt&gt;emit_schema&lt;/tt&gt; function to create an &lt;tt&gt;rd.msg.email.mailing-list&lt;/tt&gt; document linking the message document to an &lt;tt&gt;rd.mailing-list&lt;/tt&gt; document representing the mailing list:&lt;br /&gt;&lt;pre style=&quot;background-color: rgb(238, 238, 238); border: 1px solid rgb(187, 187, 187); color: black; padding: 10px;&quot;&gt;emit_schema(&#39;rd.msg.email.mailing-list&#39;, { &#39;list_id&#39;: list_id })&lt;/pre&gt;&lt;br /&gt;In this function call, &lt;tt&gt;rd.msg.email.mailing-list&lt;/tt&gt; is the type of document to create, while &lt;tt&gt;{ &#39;list_id&#39;: list_id }&lt;/tt&gt; is the document itself, written as Python that will get serialized to JSON.&lt;br /&gt;&lt;br /&gt;A document created inside a backend extension like this automatically gets a reference to the document the extension is processing (i.e. the &lt;tt&gt;rd.msg.email&lt;/tt&gt; document), so the only thing it has to explicitly include is a reference to the list document, in the form of a &lt;tt&gt;list_id&lt;/tt&gt; property whose value is the list identifier.&lt;br /&gt;&lt;br /&gt;The extension also checks if there&#39;s an &lt;tt&gt;rd.mailing-list&lt;/tt&gt; document in the database for the mailing list itself, and if not, it creates one, populating it with information from the message&#39;s &lt;tt&gt;List-*&lt;/tt&gt; headers, like how to unsubscribe from the list. Otherwise, it updates the existing mailing list document if the message&#39;s &lt;tt&gt;List-*&lt;/tt&gt; headers contain updates.&lt;br /&gt;&lt;h3&gt;The Frontend Extension&lt;/h3&gt;The frontend extension uses the information extracted by the backend to help users manage mailing lists in the Inflow application.&lt;br /&gt;&lt;br /&gt;It adds a widget to the Home view that shows you the last few messages from your lists at the bottom of the page, so you can keep an eye on those messages without having to give them your full attention:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://www.melez.com/mykzilla/uploaded_images/latest-list-messages-714113.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img src=&quot;http://www.melez.com/mykzilla/uploaded_images/latest-list-messages-714111.png&quot; height=&quot;176&quot; width=&quot;320&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It adds a list of your mailing lists to the Organizer widget:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://www.melez.com/mykzilla/uploaded_images/mailing-list-list-722772.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img src=&quot;http://www.melez.com/mykzilla/uploaded_images/mailing-list-list-722768.png&quot; height=&quot;320&quot; width=&quot;190&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And when you click on the name of a list, it shows you its conversations in the conversation pane:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://www.melez.com/mykzilla/uploaded_images/list-conversations-763392.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img src=&quot;http://www.melez.com/mykzilla/uploaded_images/list-conversations-763369.png&quot; height=&quot;201&quot; width=&quot;320&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In traditional mail clients, users who want to break out their list messages into separate buckets like this typically have to create a folder for each list to contain its messages and then a filter for each list to move incoming list messages into the appropriate folders. The extension does this for you automatically!&lt;br /&gt;&lt;br /&gt;Finally, while viewing list conversations, if the extension knows how to unsubscribe you from the list, it displays an Unsubscribe button:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://www.melez.com/mykzilla/uploaded_images/unsubscribe-button-794151.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img src=&quot;http://www.melez.com/mykzilla/uploaded_images/unsubscribe-button-794149.png&quot; height=&quot;201&quot; width=&quot;320&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Pressing the button (and then confirming your decision) unsubscribes you from the list. You don&#39;t have to do anything else, like remembering your username/password for some web page, sending an email, or confirming your request with the list admin. The extensions handle all those details for you so you don&#39;t have to know about them!&lt;br /&gt;&lt;h3&gt;List Unsubscription&lt;/h3&gt;In case you do want to know the details, however, it goes like this...&lt;br /&gt;&lt;br /&gt;First, the frontend extension sends a message to the list&#39;s admin address requesting unsubscription, with a certain command (like &quot;unsubscribe&quot;) in the subject or body of the message (lists often specify exactly what command to send in the &lt;tt&gt;mailto:&lt;/tt&gt; link they include in the &lt;tt&gt;List-Unsubscribe&lt;/tt&gt; header):&lt;br /&gt;&lt;pre style=&quot;background-color: rgb(238, 238, 238); border: 1px solid rgb(187, 187, 187); color: black; padding: 10px;&quot;&gt;From: Jan Reilly &lt;jan@example.com&gt;&lt;br /&gt;To: wasbigtalk-admin@example.com&lt;br /&gt;Subject: unsubscribe&lt;/jan@example.com&gt;&lt;/pre&gt;&lt;br /&gt;Then the server responds with a message requesting confirmation of the request, often putting a unique token into the Subject or Reply-To header to track the request:&lt;br /&gt;&lt;pre style=&quot;background-color: rgb(238, 238, 238); border: 1px solid rgb(187, 187, 187); color: black; padding: 10px;&quot;&gt;From: wasbigtalk-admin@example.com&lt;br /&gt;To: jan@example.com&lt;br /&gt;Subject: please confirm unsubscribe from wasbigtalk (4bc3b7e439fd)&lt;br /&gt;&lt;br /&gt;Hello jan@example.com,&lt;br /&gt;&lt;br /&gt;We have received a request to unsubscribe you from wasbigtalk.&lt;br /&gt;Please confirm this request to unsubscribe by replying to this email.&lt;br /&gt;...&lt;/pre&gt;&lt;br /&gt;Then the backend extension responds with a message confirming the request that includes the unique token:&lt;br /&gt;&lt;pre style=&quot;background-color: rgb(238, 238, 238); border: 1px solid rgb(187, 187, 187); color: black; padding: 10px;&quot;&gt;From: jan@example.com&lt;br /&gt;To: wasbigtalk-admin@example.com&lt;br /&gt;Subject: Re: please confirm unsubscribe from wasbigtalk (4bc3b7e439fd)&lt;/pre&gt;&lt;br /&gt;Finally, the server responds with a message confirming that the subscriber has, indeed, been unsubscribed:&lt;br /&gt;&lt;pre style=&quot;background-color: rgb(238, 238, 238); border: 1px solid rgb(187, 187, 187); color: black; padding: 10px;&quot;&gt;From: wasbigtalk-admin@example.com&lt;br /&gt;To: jan@example.com&lt;br /&gt;Subject: you have been unsubscribed from wasbigtalk&lt;br /&gt;&lt;br /&gt;Hello jan@example.com,&lt;br /&gt;&lt;br /&gt;Your unsubscription from wasbigtalk was successful.&lt;br /&gt;...&lt;/pre&gt;&lt;br /&gt;At this point, the backend extension marks the list unsubscribed in the database, and the frontend extension marks it unsubscribed in the user interface.&lt;br /&gt;&lt;br /&gt;This process matches the way much mailing list server software works, although there are daemons in the details, so the extensions have to be programmed to support each server individually.&lt;br /&gt;&lt;br /&gt;Currently, they know how to handle &lt;a href=&quot;http://groups.google.com/&quot;&gt;Google Groups&lt;/a&gt; and &lt;a href=&quot;http://www.gnu.org/software/mailman/&quot;&gt;Mailman&lt;/a&gt; lists. &lt;a href=&quot;http://www.mj2.org/&quot;&gt;Majordomo2&lt;/a&gt; (used by the &lt;a href=&quot;http://www.bugzilla.org/&quot;&gt;Bugzilla&lt;/a&gt; and &lt;a href=&quot;http://www.openbsd.org/&quot;&gt;OpenBSD&lt;/a&gt; projects, among others) is not supported, because it doesn&#39;t send &lt;tt&gt;List-*&lt;/tt&gt; headers (alhough supposedly it can be configured to do so). The &lt;a href=&quot;http://www.w3.org/&quot;&gt;W3C&lt;/a&gt;&#39;s list server is not yet supported, although it does send &lt;tt&gt;List-*&lt;/tt&gt; headers, and support should be fairly easy to add.&lt;br /&gt;&lt;br /&gt;Note that some of the processing the extension does is (locale-dependent) &quot;screen&quot;-scraping, as Google Groups and Mailman don&#39;t consistently identify the list ID and message type in some of their correspondence. In the long run, hopefully server software will improve in that regard. Perhaps someone can spearhead an effort to make it so?&lt;br /&gt;&lt;h3&gt;The Future&lt;/h3&gt;The extensions&#39; current features fit in well with Raindrop&#39;s goal of helping people better handle their flood of incoming messages. But there is surely much more they could do to help in this regard.&lt;br /&gt;&lt;br /&gt;Besides general improvements to reliability and robustness--like support for additional list servers and handling of localized admin messages--they could let you resubscribe to a mailing list from which you&#39;ve unsubscribed. And perhaps they could automatically fetch the messages you missed while you were away. Or even retrieve the entire archive of a list to which you&#39;re subscribed, so you can browse the archive in Raindrop!&lt;br /&gt;&lt;br /&gt;What bugs you about mailing lists? And how might Raindrop&#39;s mailing list extensions make them easier (and even funner) to use?</content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/7015776887411907934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=7015776887411907934' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7015776887411907934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7015776887411907934'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2009/11/skinny-on-raindrops-mailing-list.html' title='The Skinny on Raindrop&#39;s Mailing List Extensions'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18929277.post-7740719470656815276</id><published>2009-11-04T15:58:00.001-08:00</published><updated>2009-11-04T15:58:03.687-08:00</updated><title type='text'>Building/Releasing Personas</title><content type='html'>Want to know how a popular extension like Personas gets built and released? Neither do I! Yet I know anyway. And I&#39;ve written it down for your edification! So &lt;a  href=&quot;https://wiki.mozilla.org/Labs/Personas/Build&quot;&gt;check it out&lt;/a&gt;.&lt;br&gt; &lt;br&gt; </content><link rel='replies' type='application/atom+xml' href='http://mykzilla.blogspot.com/feeds/7740719470656815276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18929277&amp;postID=7740719470656815276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7740719470656815276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18929277/posts/default/7740719470656815276'/><link rel='alternate' type='text/html' href='http://mykzilla.blogspot.com/2009/11/buildingreleasing-personas.html' title='Building/Releasing Personas'/><author><name>Myk Melez</name><uri>http://www.blogger.com/profile/01837818348188071923</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-_YZppM5V97U/VedxzrpG9BI/AAAAAAAAAGA/wHrKKAgCoH0/s220/headshot-2014.jpg'/></author><thr:total>0</thr:total></entry></feed>