{"id":1959,"date":"2011-01-19T21:59:07","date_gmt":"2011-01-20T02:59:07","guid":{"rendered":"http:\/\/mikeconley.ca\/blog\/?p=1959"},"modified":"2023-12-20T16:25:14","modified_gmt":"2023-12-20T21:25:14","slug":"day-3-stream-of-consciousness","status":"publish","type":"post","link":"https:\/\/mikeconley.ca\/blog\/2011\/01\/19\/day-3-stream-of-consciousness\/","title":{"rendered":"Day 3:  Stream of consciousness"},"content":{"rendered":"<p>So, I just started my day off with a big bowl of Apple Cinnamon Cheerios and some fresh orange juice, c\/o Mozilla Messaging.\u00a0 Thanks, team.\u00a0 \ud83d\ude00<\/p>\n<p>Another great thing about Mozilla is that, since its spread out around the world, somebody is awake and working pretty much 24 hours a day.\u00a0 That means if I write a bunch of code and go to bed, there&#8217;s a chance that when I wake up the next morning, the code review is done and I have some feedback on my next steps.<\/p>\n<p>And that&#8217;s more or less what&#8217;s happened at the start of today.\u00a0 That <a href=\"http:\/\/mikeconley.ca\/blog\/2011\/01\/17\/day-1-at-mozilla-messaging-getting-my-hands-dirty\/\">add-ons manager grouping feature I was working on for Firefox<\/a> got looked at in the night, and I got some feedback on some changes I can make.\u00a0 Awesome.<\/p>\n<p>So here&#8217;s the scoop:<\/p>\n<p>First off, a conversation got started regarding where add-ons with pending <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=624808#c6\">installs<\/a> or <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=624808#c5\">uninstalls<\/a> go.\u00a0 The answer:\u00a0 <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=624808#c7\">pending installs should go into the group they&#8217;ll be in once the install is complete<\/a>, and <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=624808#c9\">pending uninstalls should stay in the group that they were in when the install happened<\/a> (in order to prevent the add-on from jumping around in the list).\u00a0 That&#8217;s good &#8211; that makes my job easier, I think.<\/p>\n<p>With regards to implementation, I don&#8217;t think my nifty <a href=\"http:\/\/en.wikipedia.org\/wiki\/Schwarzian_transform\">Shwarzian Transform<\/a> is gonna fly:<\/p>\n<blockquote><p>I don&#8217;t think that this is the right approach to take here. Instead the more straightforward way is to just make sortElements accept an array for aSortBy (and update all callers to pass one) of fields to sort by in order of preference. If the elements match by the first field then move onto the second and so on. For the non-search list views use a specially named field &#8220;uiState&#8221; and then use your function as the comparison function for that field.<\/p>\n<p><a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=624808#c10\">(from one of my reviewers)<\/a><\/p><\/blockquote>\n<p>So this approach involves me changing a bit more code.\u00a0 See, my original approach was to try to change as little as possible.\u00a0 I guess that&#8217;s just me being the &#8220;new guy&#8221;, and trying not to rock the boat.\u00a0 But clearly, they want me to go deeper.\u00a0 I&#8217;m happy to oblige!<\/p>\n<p>But there&#8217;s a bit more complication.\u00a0 According to the Bugzilla page, <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=624808\">this bug I&#8217;m working on<\/a> depends <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=623207\">on this other bug<\/a>, where <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=623207#c10\">somebody else is also tinkering with the sorting functions<\/a>.\u00a0 That means I have to be uuber careful, and make sure to base my work off of their patches.<\/p>\n<p>In particular, it looks like this patch is going to be altering the sorting tests, and removing the ability for Firefox users to sort add-ons by anything besides the add-on name.<\/p>\n<p>So what I&#8217;m going to do is download and apply this patch, and then start basing my work off of it.\u00a0 Each time the patch is updated in <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=623207\">Bug 623207<\/a>, I&#8217;ll just re-base my work off of it.\u00a0 Nice.<\/p>\n<p>Ok, so first of all, I wipe out my old work using hg strip (using <a href=\"http:\/\/bwinton.latte.ca\/Work\/branchRoots.py\">Blake&#8217;s handy script<\/a> to find the HEAD revision number of that branch).\u00a0 Next, I grab the patch for 623207, and use patch to apply it.\u00a0 Then, I use pnew to create a new pbranch with that change, and then create <em>another<\/em> pbranch on top of that.\u00a0 That second pbranch is where I&#8217;ll do my work.\u00a0 If\/when the patch to 623207 gets updated, I&#8217;ll update the first pbranch, and then merge it into the second.\u00a0 Awesome-sauce.<\/p>\n<p>Argh.\u00a0 It seems I have to recompile in order to get that 623207 patch to work.\u00a0 And not an incremental compile either, since &#8220;make&#8221; doesn&#8217;t seem to do much in toolkit\/mozapps\/extensions.\u00a0 *sigh*&#8230;<a href=\"http:\/\/xkcd.com\/303\/\">compiling<\/a>&#8230;<\/p>\n<p>Just stopped by UofT to drop off my old keys, and get my old computer wiped.\u00a0 Stopped by and talked to Karen, and helped two new <a href=\"http:\/\/www.markusproject.org\">MarkUs<\/a> students.\u00a0 Kind of bitter sweet moment.\u00a0 Goodbye school.\u00a0 It was a long battle.\u00a0 Well played.<\/p>\n<p>I&#8217;ve finished a draft of my add-on grouper\/stratifier.\u00a0 Now I&#8217;m going to check out these tests.\u00a0 Without my change, the tests in <a href=\"http:\/\/mxr.mozilla.org\/mozilla-central\/source\/toolkit\/mozapps\/extensions\/test\/browser\/browser_sorting.js\">browser_sorting.js<\/a> all pass.\u00a0 With my patch, 3 fail.\u00a0 Ok, so I think I&#8217;ve found the right tests.\u00a0 Lets see whats up&#8230;<\/p>\n<p>Ok, it looks like the tests were trying to call my new sorter, and didn&#8217;t know that it had to pass an Array instead of a string.\u00a0 Fixed that, and all tests are passing.\u00a0 Sweet.<\/p>\n<p>Now let me try <em>all<\/em> of the extension tests&#8230;ok, without my patch, 10 fail.\u00a0 With my patch&#8230; OH SHIT.\u00a0 194 failures.\u00a0 That&#8217;s a big deal.<\/p>\n<p>Ok, I think I&#8217;ve fixed those tests.\u00a0 But now when I run the extension tests, one of the tests seems to take forever&#8230;what&#8217;s the deal?\u00a0 Turns out, this test does this periodically, even without my patch.\u00a0 Hrm. So I guess I don&#8217;t have to worry about it.<\/p>\n<p>After a few runs, I&#8217;ve got the same number of passing tests as there were before my patch:\u00a0 only 10 fail.\u00a0 Nice.<\/p>\n<p>So now I have to try to write some new tests.<\/p>\n<p>Suite!\u00a0 Tests written.<\/p>\n<p>It takes me a while to run the Firefox Mochitests on my machine.\u00a0 If I were to do them all, it&#8217;d probably take at least an hour.\u00a0 Running the add-ons manager tests takes about 5 minutes.\u00a0 And in either case, I can&#8217;t use my machine, because Mochitest needs me to keep focus on Firefox while its running the tests.\u00a0 Basically, this means if I want to run the tests, I give up my machine, and go snack on something in the kitchen.\u00a0 That was cool at first, but after a while, giving up my machine for 5 minutes seemed pretty lame.<\/p>\n<p>So, luckily, there&#8217;s a machine in the office called TheFlash, and, as its name suggests, it&#8217;s SUPER fast.\u00a0 Like, lightning speed.\u00a0 Compiling Thunderbird from scratch?\u00a0 <strong>7 minutes flat<\/strong>.\u00a0 Jeebus.\u00a0 Anyhow, Blake got me an account on TheFlash, and I&#8217;ve pushed my changes to a Firefox instance over there.\u00a0 Firefox is compiling, and then I&#8217;ll try out my tests over there.\u00a0 Awesome.<\/p>\n<p>Tests pass!\u00a0 Lovely.\u00a0 And Blake just took a look at my code and showed me a neat trick:<\/p>\n<p>So I&#8217;ve got an Array of uiState&#8217;s, like so:<\/p>\n<pre>const UISTATE_ORDER = [\"enabled\", \"incompatible\", \"disabled\", \"blocked\"]<\/pre>\n<p>And I wanted to sort a collection of these values in order that they appear in that Array. So something like:<\/p>\n<pre>[\"disabled\", \"disabled\", \"blocked\", \"incompatible\", \"disabled\", \"enabled\", \"enabled\", \"blocked\", \"disabled\"]\r\n\r\n# Would become\r\n\r\n[\"enabled\", \"enabled\", \"incompatible\", \"disabled\", \"disabled\", \"disabled\", \"disabled\", \"blocked\", \"blocked\"]<\/pre>\n<p>(this sort of thing is useful if each of those original entries is associated with something like, I don&#8217;t know, a Firefox add-on&#8230;)<\/p>\n<p>In Javascript, we use a sort command, and we pass a function to do comparisons.\u00a0 Normally, I&#8217;d do something like:<\/p>\n<pre>function uiStateCompare(a, b) {\r\n if(UISTATE_ORDER.indexOf(a) &lt; UISTATE_ORDER.indexOf(b))\r\n   return -1;\r\n if(UISTATE_ORDER.indexOf(a) &gt; UISTATE_ORDER.indexOf(b))\r\n   return 1;\r\n return 0;\r\n}<\/pre>\n<p>But there&#8217;s a more concise way to say this:<\/p>\n<pre>function uiStateCompare(a, b) {\r\n  return (UISTATE_ORDER.indexOf(a) - UISTATE_ORDER.indexOf(b));\r\n}<\/pre>\n<p>Which makes total sense.\u00a0 If UISTATE_ORDER.indexOf(a) &lt; UISTATE_ORDER.indexOf(b), then of course the difference is less than 1.\u00a0 Anyhow, I thought this was a pretty neat trick.\u00a0 Thanks Blake.<\/p>\n<p>Alright, patch is scrubbed and ready for posting on Bugzilla&#8230;.here goes!<\/p>\n<p>Ok, patch posted.\u00a0 Home time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So, I just started my day off with a big bowl of Apple Cinnamon Cheerios and some fresh orange juice, c\/o Mozilla Messaging.\u00a0 Thanks, team.\u00a0 \ud83d\ude00 Another great thing about Mozilla is that, since its spread out around the world, somebody is awake and working pretty much 24 hours a day.\u00a0 That means if I [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[874,861],"tags":[897],"class_list":["post-1959","post","type-post","status-publish","format-standard","hentry","category-firefox-mozilla-2","category-mozilla-2","tag-stream-of-consciousness-at-mozilla-messaging"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/prmTy-vB","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts\/1959","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/comments?post=1959"}],"version-history":[{"count":21,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts\/1959\/revisions"}],"predecessor-version":[{"id":3145,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts\/1959\/revisions\/3145"}],"wp:attachment":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/media?parent=1959"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/categories?post=1959"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/tags?post=1959"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}