Running Thin and Sass using a single Rake task

I've been working with Sass lately on the redesigned MyFDB and figured would be good to learn how to implement it on my site where I use Sinatra.

Sinatra has the capability built in to process Sass but I wanted to compile the files locally so they don't have to be generated on each request. Since I'm running a Thin server I needed to run a second process but without having to open a new Terminal tab to start it. Not only is it an unnecessary extra step, I was afraid I'd forget to.

With Thin I found I can run it as a daemon and since I would be focusing on content and CSS updates, any Ruby related error output in Terminal wasn't vital. The trick is to start Thin first as a daemon and then the Sass watcher as it'll be the process that takes up that shell session. Once you quit (CTRL+C) a Rake task server:stop will run that terminates the Thin daemon and removes the tmp and log folders that Thin generated. Working Rakefile:

require 'fileutils'

namespace :server do

  desc "Starts the daemon Thin server and Sass watcher"
  task :processes do
    puts "Start Thin as a daemon and Sass normally"

    system "thin start -d"
    system "sass --watch assets/stylesheets:assets/stylesheets --style compressed"
  end

  desc "Stops the daemon Thin server"
  task :stop do
    file = File.open("tmp/pids/thin.pid", "rb")
    process_id = file.read

    puts "Stopping Thin server (process #{process_id})"

    system "kill #{process_id}"

    FileUtils.remove_dir("log") if File.directory? "log"
    FileUtils.remove_dir("tmp") if File.directory? "tmp"
  end

  desc "Starts server at localhost:3000 with Sass enabled"
  task :start => [:processes, :stop] do
    puts "Bye!"
  end

end

While I learned a lot from that approach it was a bit of a waste since the Foreman gem solves this problem and makes it super easy to implement. You just specify a unique name for each command (used as identifier for any command output in Terminal) in a Procfile. The following is what I use for my site:

web:  bundle exec shotgun --server=thin --port=3000
sass: bundle exec sass --watch assets/stylesheets:assets/stylesheets --style compressed

From there I just run foreman start and the gem handles the rest. I started off using Thin directly but switched to the Shotgun gem (which still uses Thin) as it reloads the entire Sinatra app on every request. If you ran the app with Thin directly you'd have to restart the server anytime you make Ruby/Sinatra related changes.

Using a Laptop Script to Install (and Document) Development Tools

Not to long ago I read Thoughbot's excellent Ruby guide to Mac OSX development that lists all the development tools they install on their laptops. The big takeaway for me was the last step their laptop script which is just a bash script that runs various install commands for Ruby Gems and other tools. While it may seem so simple I couldn't believe I didn't think about this before. What a useful tool. This inspired me to create my own laptop script.

You might ask "why bother?" as I wouldn't be going through laptops that often to have a need for this and you'd be right. The real motivator has always been documentation. Recently, I learned the hard way that the most important part isn't so much knowing what tools I have installed but how I installed them. Big difference.

This past summer I had installed Node.js when it was on version 0.4.x but didn't do much with it until this past December when Node was updated to version 0.6.7. I wanted to update but for the life of me I couldn't remember how I installed Node. Did I install using Homebrew? From source? From one of the downloadable installers? Honestly, I couldn't remember. Coming across Thoughtbot's post, I realized this wouldn't be an issue if I had with a simple shell script that would double as documentation.

I'd like to expand the script to account for tools that have been installed so as to not reinstall them or better yet to perform updates. For now though I'm pleased with it serving mainly as documentation.

Git tagging a forked Ruby gem project for Bundler

If you ever have to customize or patch a Ruby gem and you are using Bundler, its a good idea when forking that project to create a branch and then tag new releases.

I found this out recently as I used and patched two Ruby gems, databasedotcom and salesforce_bulk, to sync data to Salesforce for reporting. I ran into showstoppers with both but luckily they are hosted on GitHub so I was able to fork them and make the necessary changes to resolve the issues I encountered while being able to contribute those changes back.

The project Gemfile was updated with my two forked git branches and then I ran bundle install. While Bundler does support specifying a git branch I found that as I made further code updates and would run bundle install again, Bundler wouldn't download those changes. I figured out that I should be tagging releases of that branch instead as that would require the Gemfile to be updated with a new tag name. After that running bundle install would download the latest changes I made.

Avoiding sudo when installing command line tools from source

Recently, I came across an excellent and detailed Node.js installation post that caught my attention since it focused on how to avoid using sudo. The "Long Version" part proved most helped as it goes into detail on the what and why of every action you perform. A great read if command line isn't your strongest area.

I realized a lot of what was discussed I had done earlier for installing the excellent rbenv tool so I deviated a little from the instructions by installing Node.js into a hidden folder in my home directory (e.g. ~/.node) and then updating my path in my ~/.bash_profile file. That last step I had to change to the following:

$ echo 'export PATH="$HOME/.node/bin:$PATH"' >> ~/.bash_profile

I've grown used to installing from source lately where in the past I wouldn't have but with enough of the projects I'm interested being hosted on GitHub (which I love) the workflow I know well and remains consistent so it makes sense. Its worth the effort rather than installing from a third party like Homebrew where it might not have the latest version (which I encountered when attempting to install Node.js).

For some of you this might seem trivial but a lot of this I didn't take the time to understand. Now though I know the difference that by installing into my home directory I can avoid using sudo and take control of the tools I depend on.

A Leap of Faith for my iPhone

With the outpouring over Steve Jobs recent passing I've read some touching and moving stories. While I don't have any Steve run-ins or early Apple experiences to share I did have an incident with my iPhone a few years ago that reminded me of how much I love using that device and how important it is to me.

Whenever I'm on the subway platform waiting I pull out my phone and start reading articles I have saved with Instapaper. One day I was rather careless and the phone slipped out of my hands. It fell on the edge of the platform and then on the tracks below.

For that second my heart sank but I knew better since I was near the end of the platform where their is a small gate into the tunnel. I figured from there I could walk on to the tracks, pick up my phone and come back the same way. One problem. The train was arriving in less than 2 minutes. I wouldn't make it back in time.

While that thought came to mind, two men just a few feet away had a better idea. They told me to jump. I didn't have much time. Did you honestly think I was going to leave my phone there? No way! So I jumped down onto the subway tracks, picked up my phone and the two men lifted me back up on the platform. Two complete strangers were kind enough to help without asking. I was very grateful.

What I left out though is that was an iPhone 3G. I have an iPhone 4 now. I dread finding out what crazy thing I'll do next if something happens to it. I love the iPhone. Thanks Steve.

Fork me on GitHub