Updating Open Source Software

Note — 2014-10-12 The bundle command for brew seems to have been deprecated, and thus, parts of this Rakefile won’t be of much use. I’ll be updating this post accordingly soon.

Keeping all of your Ruby gems, Homebrew packages and dotfiles up-to-date and organized can be a bit of a chore. I put together a little system that seems to be working well, and I wanted to share my system with the world. I suppose it should have a catchy name, but it doesn’t so oh well.

The linchpin in the system is Rake. I’ve got a Rakefile in my “~/Dropbox/dotfiles” directory that handles all the updating. My Rakefile looks like this:

task :default => :update

desc "Update packages"
task :update => [:rm_conflicted, :rcm, :brew, :gems, :vim]

namespace :brew do
  desc "Run setup Homebrew commands"
  task :setup do
    sh "brew bundle Setupfile"
  end

  desc "Install Homebrew packages"
  task :packages => ["brew:setup"] do
    sh "brew bundle Brewfile 2> /dev/null"
  end

  desc "Install Homebrew casks"
  task :cask => ["brew:setup"] do
    sh "brew bundle Caskfile 2> /dev/null"
  end

  desc "Clean up after Homebrew"
  task :teardown => ["brew:packages"] do
    sh "brew bundle Teardownfile"
  end
end

desc "Run all Homebrew tasks"
multitask :brew => ["brew:setup", "brew:packages", "brew:teardown"]

desc "Update rc files"
multitask :rcm do
  sh "rcdn && rcup"
end

desc "Update Vim plugins"
task :vim do
  sh "vim +PlugInstall +PlugUpdate +quit +quit; clear"
end

desc "Tidy conflicted Dropbox files"
task :rm_conflicted do
  sh "clear"
  sh "rm_conflict.sh"
end

desc "Install Minion"
task :minion do
  sh "cd ~; git clone https://github.com/edthedev/minion"
end

desc "Update installed gems"
multitask :gems do
  sh "gem update --no-document && gem update --system"
end

desc "Update npm packages"
multitask :npm do
  sh "sudo npm update -g"
end

namespace :install do
  desc "Install Homebrew"
  task :homebrew do
    sh "ruby -e \"$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)\""
    sh "brew bundle Brewfile Caskfile"
  end
  desc "Install rbenv"
  task :rbenv do
    sh "git clone https://github.com/sstephenson/rbenv.git ~/.rbenv"
    sh "git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build"
    sh "rbenv install #{RBENV_VERSION}"
    sh "rbenv global #{RBENV_VERSION}"
    sh "git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash"
    sh "git clone https://github.com/ianheggie/rbenv-binstubs.git ~/.rbenv/plugins/rbenv-binstubs"
    sh "gem install bundler"
    sh "bundle install"
  end
  desc "Install zsh"
  task :zsh do
    sh "git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh"
    sh "chsh -s /bin/zsh"
    sh "./defaults.sh"
  end
  desc "Install Plug.vim"
  task :plug do
    sh "mkdir -p ~/.vim/autoload"
    sh "curl -fLo ~/.vim/autoload/plug.vim https://raw.github.com/junegunn/vim-plug/master/plug.vim"
  end
  desc "Install FZF"
  task :fzf do
    sh "git clone https://github.com/junegunn/fzf.git ~/.fzf"
    sh "~/.fzf/install"
  end
  desc "Install Shellcheck"
  task :shellcheck do
    sh "cabal update"
    sh "cabal install cabal-install"
    sh "cabal install shellcheck"
  end
end

desc "Set up a new Mac"
task :setup_mac => ["install:homebrew", :rcm, "install:rbenv", "install:zsh", "install:plug", "install:fzf", "install:shellcheck", :vim]

There first thing that runs is rcup, which is the command for Thoughtbot’s rcm program that manages your dotfiles, this runs first, because I realized that if you’re changing settings and environment stuff, sometimes you’re dotfiles might get out of whack. Next, I’ve divvied up my Homebrew tasks into a Setupfile that does all the prep work for updating, then a Brewfile for Homebrew packages and a Caskfile for OS X apps installed with Homebrew Cask, and finally a Teardownfile that just cleans up everything after all the installs are finished. Dependencies are set with Rake and everything runs in the proper order. Lastly, RubyGems updates all my installed gems and then updates RubyGems itself. I wonder if it shouldn’t’ be the other way around though. I played with updating npm packages at the end as well, but I get so many errors with npm that I didn’t bother including it in the end.

I’ve aliased this to ru in my ~/.zshrc and that will cd into my dotfiles directory and simply run rake. I’ve been using this for a few weeks and it’s working out pretty well.

Published on May 27, 2014


Related Posts