I’m currently working as a consultant for an UN agency (IFAD) and we have a portfolio of ~15 Rails apps, developed in the last four years. The environment is heterogeneous and an half dozen of these projects are interfacing with legacy software and they are legacy themselves. As counterpart, the new apps we are developing are running on the latest bleeding edge technologies (Ruby 1.9.3, Rails 3.2, MongoDB, Redis, WebSockets etc..).

When I joined the team in last September, I had big problems to deal with all this amount of informations and to clone projects from GitHub then make them running on my dev machine. The most common issue is the missing and/or outdated documentation. Developers are lazy people and, in general, they just want to code. Documentation, UI/UX reviews are just an example of what they tend to avoid.

The post-git-clone syndrome became really frustrating for each project I needed to work on, so now I aim to document and create a single Rake task for setup.

Since we have several persistence options, to run all these databases as init.d services would be overkilling for my MacBook. So I went for the all-turned-off-by-default strategy and run only the processes that I actually need for a code session. I’m a big fan of Foreman, and it perfectly fits this need. Plus I don’t have to remind which is the database(s) needed for that specific project or if it needs a queue, everything is ready with just foreman start.

In our team we almost all use Mac (with Homebrew) as setup, but since a Foreman’s Procfile is too much coupled with the current machine is running on, I create a Procfile.example in each project and let my colleagues to customize their own configuration, according their machine, or completely skip it and use their own workflow. Remember, the goal isn’t about unify the development process, but to have the application running in less than 5 minutes, for people who never worked on that project before.

Here a complete and working example:

# lib/tasks/app.rake

namespace :app do
  desc 'Setup the application'
  task :setup do
    require 'fileutils'

    # ENVIRONMENT
    puts "\n** Configuring servers.\n"

    ## Foreman
    puts "*** Configuring Foreman."
    FileUtils.cp Rails.root.join('Procfile.example'),
      Rails.root.join('Procfile')

    ## Pow
    puts "*** Configuring Pow."
    FileUtils.ln_sf Rails.root, File.expand_path('~/.pow')
    FileUtils.touch Rails.root.join('tmp/always_restart.txt')

    # DATABASE

    ## Postgres
    puts "\n** Configuring database.\n"
    puts "*** Configuring Postgres: your current UNIX username is being used for connection."

    FileUtils.cp Rails.root.join('config', 'database.yml.example'),
      Rails.root.join('config', 'database.yml')

    ## Setup
    puts "*** Setting up the database."

    pids = %w( db ).map do |process|
      Kernel.spawn("foreman start #{process}")
    end
    sleep 4

    Thread.new do
      begin
        Rake::Task['db:setup'].invoke
      rescue Exception => e
        puts "*** [ ERROR ] failed to load the database: #{e.message}"
      end
    end.join

    pids.each do |pid|
      Process.kill('SIGTERM', pid)
    end
  end
end