Time Travel Toaster http://timetraveltoaster.com Sending household appliances twirling through the 4th dimension since twenty aught five posterous.com Thu, 24 May 2012 16:30:00 -0700 All text editors are terrible http://timetraveltoaster.com/all-text-editors-are-terrible http://timetraveltoaster.com/all-text-editors-are-terrible

I’m pretty frustrated by the available Mac text editors out there these days. I prefer Vi-style keymappings, which I’m willing to give up if it’s really worth it, but currently I’m fastest with those. I also want it to be a real Mac app and look sorta nice and modern, not like it was coded in the 80’s. Other hard-to-live-without items are the ability to save all open files when the window loses focus, and of course the no-brainers like reliable syntax highlighting and some handy language-aware auto-completions for the main Rails languages (Ruby, CoffeeScript, JavaScript, HTML, ERb, CSS, Sass, etc.). Again, I’m willing to compromise those if I get something really good in exchange.

  • (Mac)Vim – Needs lots of configuration and plugins to be awesome. Something like Janus or yadr is pretty nice, but also very complex and brittle. Getting ctags to work consistently, as one example, is a pain. It’s so big and patched-together, there’s always something not working quite right. It can also be pretty slow at times once you’ve got all the plugins and config setup. Doesn’t look very nice either.
  • Vico – Very cool concept, but updates are often slow to materialize with little communication from the author in between. And it’s not open source, so there’s not much anyone can do about it. It’s very new and so a lot of things don’t work quite right (syntax highlighting is somewhat inconsistent, for example). At least it looks semi-nice. Probably the one I hate the least currently.
  • Emacs – Very awesome editor that can do a LOT. But also extremely complex to configure and get working well (needs lots of plugins like Vim) and seemingly can’t do some simple things that I have a hard time living without (such as saving all open files when the window loses focus). And I just cannot see how its keybindings could ever be as pleasant or efficient to use as Vim’s. Also, it’s ugly as hell. /me dons his Stallman attack suit.
  • Sublime Text 2 – I’ve tried it a couple times, but the Vi emulation is pretty flaky and the configuration is a terrible mess of text files. There are already two hard-to-configure editors in the world, we don’t need another.
  • TextMate 1 or 2 – 1 is old and busted, and 2 is still pre-release. Not enough of a win to make me give up Vi keybindings. Is there any sort of Vi emulation for TM1 or 2?
  • Coda 1 or 2 – This blog post sums up the situation perfectly: http://jeffcroft.com/blog/2012/may/22/on-coda-2-and-diet-coda/
  • BBEdit – Not great language support. Doesn’t seem to be aging well.
  • Kod – Doesn’t seem to be maturing very quickly. Still at version 0.0.3.
  • Any Java app – No. Just no. Ugly, slow, crashy, and awful.

I really wish there were something clean, simple, and powerful out there. Right now I’m going to continue to keep my eye on Vico while every once in a while popping back into MacVim (with yadr).

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Fri, 18 May 2012 17:50:00 -0700 welcome to fog contributor-dom! http://timetraveltoaster.com/welcome-to-fog-contributor-dom http://timetraveltoaster.com/welcome-to-fog-contributor-dom

Now THIS is how you make open source contributors feel awesome. This was in response to a simple GitHub pull request.

Very cool.

Begin forwarded message:

From: Wesley Beary <redacted>
Subject: welcome to fog contributor-dom!
Date: May 17, 2012 1:33:19 PM PDT
To: <redacted>

High five! Thanks for joining the ranks of fog contributors, I really appreciate the help.
 
Now comes the fun parts.

@fog follows all contributors on twitter, so what is your twitter username?

I send tshirts out to all the contributors.  They are grey American Apparel shirts with the fog logo across the chest.  So I'll need to know what size to get and where to send it to.  (note that I only reorder from time to time so there may be a little delay on this part)

Thanks again for your help!
wes

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Wed, 25 Apr 2012 08:24:00 -0700 How to REALLY fix the "hostname does not match the server certificate" in Ruby 1.9 apps http://timetraveltoaster.com/how-to-really-fix-the-hostname-does-not-match http://timetraveltoaster.com/how-to-really-fix-the-hostname-does-not-match

I’ve seen a lot of advice around the web to disable TLS or turn off certificate verification when using Ruby 1.9 and the openssl gem. This is motivated by seeing the error “hostname does not match the server certificate” in log files and application crashes.

What’s happening is that OpenSSL is trying to establish a secure connection (using SSL/TLS just like your web browser when accessing a URL that starts with “https://”) but it fails because the hostname the certificate claims to be for doesn’t match the hostname of the server you’re connecting to. Now, when this happens in your web browser, it means something really bad could be happening and you should NOT proceed. Someone could be impersonating your bank, for example, ready to intercept your access credentials and steal your money. So why on earth are so many people recommending circumventing basic security in Ruby 1.9* apps?

Here’s how you REALLY fix this problem:

Figure out what hostname OpenSSL is trying to connect to. I’ve submitted a pull request to the Ruby Github mirror to address this, but until or unless they actually incorporate that into a released version of Ruby, here’s how you can make openssl a little more forthcoming with the details:

Open up the file lib/ruby/1.9.1/openssl/ssl-internal.rb in your favorite text editor. Go to line #121 which should look like this:

def post_connection_check(hostname)
  unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
    raise SSLError, "hostname does not match the server certificate" # <= line 121
  end
  return true
end

Now edit that line to say this:

raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"

(Add the \“#{hostname}\” part. The backslashes are important.)

Now do whatever you were doing to trigger the SSLError before, and you’ll see what hostname OpenSSL was expecting the certificate to match.

If it says “localhost”, then you can probably safely disable SSL/TLS like everyone else is recommending. If it says anything else, you probably want to keep it secure. The Internet is a weird, wild place.

If you’ve decided to go the secure route, then the next steps are just like securing a website. You need an SSL certificate for the exact hostname you’re trying to secure (the same hostname output by OpenSSL’s new error message you just created). You can get those from a variety of sources around the web. If you don’t know where or how to get one, just Google around a bit. You then need to install that certificate into whatever server is on the other end of that connection. So, for example, if you’re trying to send email via ActionMailer, then you need to install the cert into the mail server listening on the host and port you’re connecting to. You’ll have to consult the docs for your mail server software for the details.

*Ruby 1.8 defaulted to not caring if the hostname matched or not. That’s why this is a new error message for those converting from 1.8 to 1.9. In 1.9, the Ruby devs decided to be “secure by default,” and I applaud them for it.

Update

My pull request has been accepted into Ruby core, but I don’t know when it will actually show up in a released version of Ruby. Maybe 1.9.3-p[next], maybe 1.9.4, maybe 2.0. Who knows!?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Fri, 06 Apr 2012 10:03:00 -0700 Beware of mass-assigning GitHub Issue labels http://timetraveltoaster.com/beware-of-mass-assigning-github-issue-labels http://timetraveltoaster.com/beware-of-mass-assigning-github-issue-labels

I just tried to assign a label to each of my GitHub issues, and wow, was that a mistake. When you select more than one issue and then click the Label dropdown, it pre-selects every label that any of your selected issues has. So when I added one more label and hit Update, it assigned every label that was assigned to any issue to every issue. My labels are useless now and I have to start over. What a mess.

While I certainly share some of the blame for not noticing that before clicking the Update button, that is a pretty braindead system that GitHub has built. There is never a time when I want to assign the union of every issue's labels to all selected issues. But I do often want to assign one label to many issues. Terrible.

UPDATE: Here's GitHub's response to the problem:

From: Petros Amiridis (GitHub Staff)

Subject: Rollback Issue labels?

 

Ooops! That sucks! I am sorry about that, but this is how it works currently. I don't think you can add one label to all issues currently.

So yeah, watch out for that!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Thu, 19 Jan 2012 11:26:00 -0800 Rails app, continuous integration, your database, and you http://timetraveltoaster.com/rails-app-continuous-integration-your-databas http://timetraveltoaster.com/rails-app-continuous-integration-your-databas

I recently setup a Jenkins CI server for a client and put their Rails app in it. When someone committed a change, it ran a CI build. However, when someone committed a migration, rake would abort with the dreaded "pending migrations" error. So I just added a db:migrate step to the ci:build task, and all was well…

…or so I thought. In this particular case, the CI server builds anytime someone pushes code to either the "develop" or "master" branch (using git). Pushes to develop happen much more often than master, because master is the "stable production release branch" and develop is the "push everything here when it's ready to be shared with the rest of the team and integrated into the bleeding edge version of the app" branch. One consequence of this is that master builds will often assume an older database schema than develop builds because those migrations haven't been merged with the master branch yet.

So running "rake db:migrate" in the ci:build task broke. The migrate task doesn't understand moving the schema backwards and forwards unless you explicitly tell it what to do. However, there's a much better way to do this. The file db/schema.rb is a current snapshot of your database and it should be checked into your code repo. So if you just load that into the test DB before each CI build (via the handy "rake db:schema:load" task), then you're golden. Master has its snapshot, and develop has its snapshot. Everything's fixed! Er...

Here's the wrinkle: When you run rake spec after doing that (within the same rake ci:build über-task), it executes the following tasks:

** Invoke spec (first_time)
** Invoke db:test:prepare (first_time)
** Invoke db:abort_if_pending_migrations (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:abort_if_pending_migrations
** Execute db:test:prepare
** Invoke db:test:load (first_time)
** Invoke db:test:purge (first_time)
** Invoke environment** Execute db:test:purge
** Execute db:test:load
** Invoke db:schema:load
** Invoke environment** Execute spec


So what? It runs db:schema:load again, no big deal. Nope. Chuck Testa. If you look closely, you'll see that while db:schema:load is *invoked*, it is never actually *executed*. And that's because rake remembers that it has already been executed when we ran it manually before. So the last thing that's been done to your test database is db:test:purge. If you look at your test database at this point, you'll see that is has no tables. And your tests will fail (at least they better).

Why are there no tables? Why didn't the manual db:schema:load put all the tables into the test database? Because it put them into the development database. Remember that most tasks default to the development environment when you don't specify one. So we loaded the DB schema snapshot into the development database, and then later when rake is asked to run db:schema:load on the test database, it doesn't run it.

So what's the solution? We need to tell rake to re-run db:schema:load. (Don't be tempted here to force Rails.env = 'test' and use the test database for everything. This comes with its own issues and you'll be fighting against the way rake spec is designed to work.)

Here's what my final rake ci:build task looks like:

namespace :ci do
  desc 'Setup CI environment'
  task :env do
    ENV['CI_BUILD'] = 'true'
    ENV['RSPEC_FORMAT'] = 'progress'
    ENV['CUCUMBER_FORMAT'] = 'progress'
    ENV.delete('http_proxy') # need cukes to be able to connect to localhost
  end

  desc 'Run a continuous integration build'
  task :build => ['ci:env'] do
    Rake::Task['db:reset'].invoke # drops, re-creates, loads schema.rb
    Rake::Task['db:schema:load'].reenable # so it can be run later on the test db
    Rake::Task['spec'].invoke
    Rake::Task['cucumber'].invoke
  end
end

That line "Rake::Task['db:schema:load'].reenable" is the key. Once you add that, rake spec will happily resume loading up your test DB's schema and you'll be off to the races.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Tue, 30 Aug 2011 11:12:00 -0700 Be the Change http://timetraveltoaster.com/be-the-change http://timetraveltoaster.com/be-the-change

"Be the Change you wish to see in the world" is a common quote attributed to Mahatma Gandhi. But he never said it, and in fact didn't believe the smug, apolitical sentiment it communicates. That and other awesome gems in this NYT article.

My favorite excerpt on the fake Gandhi quote:

Here, Gandhi is telling us that personal and social transformation go hand in hand, but there is no suggestion in his words that personal transformation is enough. In fact, for Gandhi, the struggle to bring about a better world involved not only stringent self-denial and rigorous adherence to the philosophy of nonviolence; it also involved a steady awareness that one person, alone, can’t change anything, an awareness that unjust authority can be overturned only by great numbers of people working together with discipline and persistence.

Hmm, great numbers of people working together with discipline and persistence. Why, that almost sounds like organizing!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Mon, 30 May 2011 19:38:00 -0700 WTF? No, I don't. http://timetraveltoaster.com/wtf-no-i-dont http://timetraveltoaster.com/wtf-no-i-dont

Screen_shot_2011-05-30_at_10

 

Hey Earbits, heard of HTML5 audio? It's a big hit with the modern browser kids. And it works, these guys are streaming audio with no Flash whatsoever.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Fri, 27 May 2011 08:39:00 -0700 If you don't have an integration test, you haven't tested it http://timetraveltoaster.com/if-you-dont-have-an-integration-test-you-have http://timetraveltoaster.com/if-you-dont-have-an-integration-test-you-have
People doing test-driven development talk a lot about mocking, stubbing, FakeWeb, unit tests, and other mechanisms for testing code in isolation. But that conversation drowns out a fundamental truth: If you don't have an integration test, you haven't tested it. And by integration test, I mean that it hits all the live third party services the production app hits, it hits your database, it runs your daemons (forked in the background, not running in the foreground), and it doesn't mock, stub, or fake anything. If you haven't done that, then your code isn't tested. Period.

I've been running into this a lot lately at my day job. In the first instance, I refactored a bit of code to simplify it (by sending it a piece of information already encoded for the API it was headed to), but I neglected to notice (and no test caught) the fact that one line of code in that method (also, don't write long methods) depended on the old format of that datum. This caused reporting records to not be created because they silently failed to validate. No test caught this because all the tests were mocked and stubbed with successful responses. Had there been an actual integration test, it would have tested for the one thing that actually mattered: the damn records get created in the fucking database.

I have other recent examples, but I won't belabor the point. Write integration tests first. Write integration tests only, if you have to. But write 'em.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Wed, 18 May 2011 13:34:00 -0700 Hashed method args http://timetraveltoaster.com/hashed-method-args http://timetraveltoaster.com/hashed-method-args
Is there a reason Ruby can't work like this:

def do_something(first_arg, second_arg)
  puts "First: #{first_arg}"
  puts "Second: #{second_arg}"
end

do_something(:second_arg => 'blah', :first_arg => 'yeah') =>
First: yeah
Second: blah

...while still supporting this:

do_something('yeah', 'blah') =>
First: yeah
Second: blah

It sure seems like it would be the best of both worlds.
Instead you have to do this:
def do_something(params)
  puts "First: #{params[:first_arg]}"
  puts "Second: #{params[:second_arg]}"
end
...but that's stupid and terrible because then your method signature tells you nothing (NOTHING!) about what arguments you can give it. And that makes me sad.

And positional parameters are a major pain in the tukhus once you have more than three or so. Does the database_mode argument go here? Or is it the address hash? Yeah, fun times.

There's probably some reason it can't work the way I want it to.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Wed, 13 Apr 2011 08:13:00 -0700 Object#tap considered less readable http://timetraveltoaster.com/objecttap-considered-less-readable http://timetraveltoaster.com/objecttap-considered-less-readable
Boy am I tired of seeing this in Ruby 1.9 code:

find(:id => id).tap { |foo|
  foo.do_things
  something_else(foo)
  if foo.has_bar?
    this_thing(foo)
  else
    that_other
  end
}

When writing this:

foo = find(:id => id)
foo.do_things
something_else(foo)
if foo.has_bar?
  this_thing(foo)
else
  that_other
end
foo
...is both the same number of lines of code and WAY more readable. Friends don't let friends use Object#tap.

(But seriously, if you've ever seen a use for it that makes code better--i.e. more succinct and more readable--then I'd love to see it.)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Fri, 08 Apr 2011 10:16:00 -0700 Lots of users is not enough http://timetraveltoaster.com/lots-of-users-is-not-enough http://timetraveltoaster.com/lots-of-users-is-not-enough
The tech startup world is very focused on building things that attract a large number of users. Startups like this one: http://likealittle.com/ are full of talented programmers and are recruiting madly. Their appeal to fellow entrepreneurial geeks is that they are coding fast and furious and deploying an app that is growing like crazy. Wow, sounds like a cool job, right?

But, what does the app *do*? It lets college students flirt anonymously with each other.

Yeah. Not interested, thanks.

I've spent nearly my entire (post-college) technology career working for political organizations. These places are _not_ geek meccas. They are top-down, management and process-driven dinosaurs. However, they try to actually impact the world for the better. I'll take that any day over interesting technology for an uninteresting purpose.

But man, I sure would love to find a place that had both. A tech startup culture with a focus on real, positive social impact. That would be my dream job.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Fri, 11 Feb 2011 15:13:00 -0800 GNOME 3 releases alpha live CDs http://timetraveltoaster.com/gnome-3-releases-alpha-live-cds http://timetraveltoaster.com/gnome-3-releases-alpha-live-cds http://gnome3.org/tryit.html

Hacker News downvoted that shit, because they're stupid. I totally want to try this out. High five for open source innovative desktop paradigms.


Update: The live CD didn't work. It loaded a standard-looking GNOME desktop in OpenSuSE. Guess that's why they call it alpha.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Tue, 01 Feb 2011 11:49:00 -0800 Testing exceptions in Cucumber http://timetraveltoaster.com/testing-exceptions-in-cucumber http://timetraveltoaster.com/testing-exceptions-in-cucumber
Here's a handy step for testing exceptions in Cucumber:

Then /^it should raise (.+?) when (.+)$/ do |exception,when_step|
  lambda {
    When when_step
  }.should raise_error(eval(exception))
end

Then you can test that any When step raises any exception of your choosing. Handy!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Sun, 28 Nov 2010 03:36:01 -0800 The new deficit hawks http://timetraveltoaster.com/the-new-deficit-hawks http://timetraveltoaster.com/the-new-deficit-hawks From today's New York Times: "The federal deficit cannot be closed simply by rooting out waste and fraud, and Mr. Issa readily acknowledges that many examples he cites will save what amounts to relative pennies in a $3.5 trillion budget."

You get what you vote for, America.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Fri, 26 Nov 2010 15:29:00 -0800 Global warming hits the East Coast http://timetraveltoaster.com/global-warming-hits-the-east-coast http://timetraveltoaster.com/global-warming-hits-the-east-coast http://nyti.ms/dFFxLm

I've heard so many times that Americans won't really "get" global
warming until it comes to our shores. Well, it looks like it has.
Something tells me, given the current political climate (pun very much
intended), that this won't really change many minds.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Fri, 26 Nov 2010 10:06:00 -0800 Webmail http://timetraveltoaster.com/webmail http://timetraveltoaster.com/webmail What would email be like if it had been invented after the web? Pretty freaking great.
  • Every message and thread would have a URL. Easy linking and sharing.
  • Messages would be sender-stored and pulled by the recipient. Makes life harder for spammers, easier for legitimate bulk emailers.
  • Since messages are stored all over the web, new message notifications will have to push realtime. Push email is no longer a luxury feature.
  • Using semantic markup (not necessarily HTML), reply/quoting order is a reader preference, no matter how the author wrote it. No more top posts.
  • Blogging becomes emailing "everyone." No recipient means everyone can see the message at its URL.
  • Forwarding a large email just gives new recipients access to the existing message. No more re-uploading big attachments.
  • Mailing lists are web archived as a free side effect. Messages can link to each other. Free wiki?
  • A thread can be re-constructed from any individual message because it links to its parent via a URL Messages can be un-sent. And you can reliably determine whether the recipient has seen it yet or not.
  • Email analytics becomes web analytics. No more messy embedded tracking images.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Tue, 29 Jun 2010 17:15:00 -0700 Smoke-free(dom) http://timetraveltoaster.com/smoke-freedom http://timetraveltoaster.com/smoke-freedom

As more U.S. cities and states fall into the smoke-free camp (i.e. they ban smoking in workplaces, such as bars and restaurants), you hear the same refrains over and over from the non-smoker, "pro-freedom" crowd. Things along the lines of, "It should be up to the business owners whether or not to allow it, and then I can choose whether or not I want to go there," followed by some pronouncement of how the government ruins everything when it tries to be everyone's nanny and make things illegal because "some people don't like it."

Frankly, given the amount of time most people will spend thinking about issues like this, the above is a pretty compelling argument. Freedom of choice, private enterprise, and free-market capitalism are the ingredients of a big, fat America sandwich. Yum.

Let's set aside most of the compelling arguments in favor of workplace smoking bans (such as the relative difficulty for the employees to just "go somewhere else") and focus on the principle behind the anti-ban sentiment. Essentially it says that government shouldn't get involved because different businesses will adopt different policies and they'll be in line with the preferences of their customers and employees who will vote with their feet. Right?

Wrong. This exact same principle can be used to justify segregation at restaurants in the South. Since almost none of the anti-ban folks would claim to be in favor of that, the principle must be flawed. I have yet to hear another principle that does hold up, but if you have one, please comment.

"OK, fine," you say. "The principle needs work, but segregation in the South was a unique situation and deserved an exception to an otherwise sound principle. Smoking in bars and restaurants does not deserve a similar exception." Alright, I'll bite.

Here's the problem with that: "Segregation is bad and it's OK for the government to ban it" is a non-controversial standpoint because we've all lived with it being illegal for decades now and the vast majority of us were raised to believe that it's morally wrong. Many of us would be adversely affected by its return, and/or have friends, family, and neighbors who would be. But it hasn't been gone so long that we don't have valid reason to fear its return if the law were changed today.

Smoking, however, is something many of us do all the time. Almost everyone has a friend or family member who smokes. He/she who has never smoked a cigarette at least once in their lives is a rare specimen. So despite all the health warnings we're familiar with, smoking doesn't feel morally wrong or that harmful to any of us. Certainly not so much that the government should ban it.

But step back from the familiar for a second. Let's pretend humans have to abandon the Earth for one of two new life-supporting planets we've discovered. On one planet, the existing alien culture requires that humans live in slums and go to humans-only restaurants, use humans-only bathrooms, and drink from humans-only water fountains. All of these are sub-standard, dirty, and generally unpleasant compared to the ones the aliens of that world enjoy. On the second world, segregation isn't an issue but there is a strange cultural custom where the aliens like to carry around these devices that emit a green-colored gas. They enjoy watching it curl and flow in the breeze or something. Who knows, it's a crazy alien custom. Unfortunately, this green gas causes cancer in humans and aliens alike. So any humans going there are warned that they should avoid these devices. Others who have gone before you have reported that the bars and restaurants are just awful there because they're filled with the carcinogenic gas, and the aliens just don't seem to care because they enjoy the gas so much. Humans on this world are getting cancer left and right. Which world would you choose?

They're both pretty terrible, right? Neither is a place you really want to be. Now imagine there's a third world where the alien government, in an attempt to welcome the human refugees, has outlawed both of these practices in public places and private workplaces, including bars and restaurants. I don't know about you, but that's the planet I'd choose to go to.

That's not government overreach, that's government doing it's job. Sometimes we get so used to things that we forget how stupid they really are. Filling your lungs with carcinogens is your choice, but you shouldn't be allowed to do it anywhere near a place that I or anyone else has to be to make a living.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Sat, 26 Jun 2010 22:42:43 -0700 Luke & Emily's First Dance http://timetraveltoaster.com/luke-and-emilys-first-dance http://timetraveltoaster.com/luke-and-emilys-first-dance
IMG_0371.MOV Watch on Posterous

My friends Luke & Emily's first dance as husband & wife. They're super adorable.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Tue, 25 May 2010 18:22:00 -0700 Keeping your skeletons in the closet when open sourcing code in git http://timetraveltoaster.com/2010/05/keeping-your-skeletons-in-closet-when.html http://timetraveltoaster.com/2010/05/keeping-your-skeletons-in-closet-when.html In my day job (DNC Innovation Lab), my team and I received approval to open-source some code that was started well before I arrived there. It was all stored on an internal git server, so no one thought it would be that hard to do. You get cocky after slinging code around with git for awhile. That's what good tools do.

Unfortunately there were already passwords, API keys, and other things we couldn't release publicly in our git commit history.

No problem, we thought, we'll just take a snapshot of the code, remove the bits we can't open source, and then upload that to github as a new repo, devoid of all that messy history. Easy peasy.

Er, not so much. The problem is we wanted to maintain our internal branch, complete with git history, but open up development on the open source version (which comprised >99% of all the code) to github and thus outside collaborators. So we were going to be pushing and pulling to/from github, as well as merging into our internal branch. We couldn't let non-open-source code leak into github, but we also needed to merge the open sources changes into the internal version.

Git took a look at these two branches and decided they didn't have anything to do with each other because they had no common ancestry in the commit history. This was the appropriate response from git because we had purposefully removed the commit history of the github version.

I tried various methods of merging the two codebases, but git always generated conflicts left and right because it was attempting to merge two almost-but-not-quite identical codebases with no common ancestor commits.

Here's how I solved it (I hope). Let's say the internal branch is called "internal" and the open source branch is called "opensource". The commit history of the open source branch is one über-commit (X) followed by a couple small changes (Y & Z), which we'll represent as X <-- Y <-- Z. The commit history of the internal branch is pretty long, so we'll just abbreviate it as the three most recent commits, A <-- B <-- C. So here's how our two branches start out:

internal:   A <-- B <-- C
opensource: X <-- Y <-- Z


I decided to try merging the opensource branch with the internal branch using the "ours" merge strategy on the X commit. This merge strategy just discards the changes in the other branch and considers the two branches merged anyway. So I ran:


git checkout internal
git merge -s ours (sha1 of the X commit)


Then my commit history looked like this:


internal:   A <-- B <-- C <-- D
                             /
opensource:                 X <-- Y <-- Z


The new D commit was the "merge" between C and X, but a couple quick git diffs showed that my working tree was exactly the same as the C commit, and thus had discarded the changes from X. This is what I wanted because X represented almost the exact same codebase, except for the minor changes required to open source it.


Now I was in a position to merge new commits to the opensource branch into the internal branch. I ran this (still on the internal branch):

git merge opensource


Then my commit history looked like this:





internal:   A <-- B <-- C <-- D    <--    E
                             /           /
opensource:                 X <-- Y <-- Z

So now I can merge new commits to the opensource branch (coming from github or others on my internal team) into the internal branch, and changes that are internal only can be made directly to that branch.

I'll update this post if I run into any breakage due to this.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan
Wed, 07 Apr 2010 16:47:00 -0700 DC Transit Fail http://timetraveltoaster.com/2010/04/dc-transit-fail.html http://timetraveltoaster.com/2010/04/dc-transit-fail.html Public transit is pretty nice in DC. You have trains and busses all over town, and they run pretty frequently. By all accounts, it's a world-class city with a word-class transit system. Except that the people in charge of it are really, really stupid when it comes to technology.

That's a bold claim, but I'm prepared to back it up:

1. Google Maps knows nothing about Metro trains, and is generally confused about bus routes too. WMATA publishes the data that Google needs--in the format Google needs it in--to make Google Maps Metro-aware (you can find it here under "GTFS Download"). But they've published it under a draconian license that reserves the right to charge for it or remove it in the future. So, as you might imagine, that's not cool w/ Google. Way to do all the work and then drown at the shore, guys. More background on this here.

2. For a long time, WMATA didn't even provide this bullet-pre-installed-in-foot non-solution. Originally they refused to play along at all, saying:

Metro staff did explore some possibilities with Google, but ultimately we decided that forming a partnership with Google was not in our best interest from a business perspective. We do believe that Metro's newly redesigned Web site, at www.wmata.com, improves customers' access to information about the Metro system. In addition, customers may get real-time information and bus and rail schedules directly on their cell phones or PDAs.


Oh right, you mean the website whose trip planner determined that a co-worker of mine should use the following Metro rail route between Union Station and Shady Grove (two stops on the red line--the same freaking line):


Media_http3bpblogspot_eeqve

Notice that round trip in the middle where they have you take the blue line from Metro Center to McPherson Square, then take the orange line back to Metro Center once you get there? Not all red line trains go to Shady Grove, but they should know that and their tool should be able to handle that extremely common situation. And apparently this sort of thing happens pretty often with the WMATA Trip Roulette Machine.


3. Notice how it also doesn't show you a map of your trip (like this other tool called GOOGLE MAPS does). They just want you to trust them that it's all correct. Inspiring a lot of confidence there, guys.


4. Google will always be better at this than you are, Metro tech team. I'm sorry, but it's true. You can't and shouldn't try to compete with their resources, experience, and technology. Feel free to continue banging out your trip planner tool, but please, for the love of Jeebus, let Google use your freaking transit data so those of us who prefer useful tools can get on with our lives. Please?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/600530/me.jpg http://posterous.com/users/5AqqXkL91D1v Wes Morgan wesmorgan Wes Morgan