Quick Setup for Your Rails Apps

https://pixabay.com/en/seemed-train-railway-1305938/

I was talking about wanting a bootstrap script for our Rails apps. We’ve taken to documenting in the README how to set up an app, but we need to make it even easier. Jason reminded me that he blogged about that.

Oh right! At the end he mentions Rails 4.2 and bin/setup so let’s look at what that does:

This is what Rails 4.2 generates for you:

#!/usr/bin/env ruby
require "pathname"

# path to your application root.
APP_ROOT = Pathname.new File.expand_path("../../",  __FILE__)

Dir.chdir APP_ROOT do
  # This script is a starting point to setup your application.
  # Add necessary setup steps to this file:

  puts "== Installing dependencies =="
  system "gem install bundler --conservative"
  system "bundle check || bundle install"

  # puts "\n== Copying sample files =="
  # unless File.exist?("config/database.yml")
  #   system "cp config/database.yml.sample config/database.yml"
  # end

  puts "\n== Preparing database =="
  system "bin/rake db:setup"

  puts "\n== Removing old logs and tempfiles =="
  system "rm -f log/*"
  system "rm -rf tmp/cache"

  puts "\n== Restarting application server =="
  system "touch tmp/restart.txt"
end

Not bad. Here’s the setup from the README on my project:

1. Install dependencies.

$ brew install postgresql # and follow instructions (or install another way)
$ brew install nodejs
$ brew install phantomjs # for running tests
$ npm install -g bower # for front-end dependencies

2. Set up the application.

$ git clone git@github.com:collectiveidea/my-app.git
$ cd my-app
$ cp config/application{.example,}.yml
$ cp config/database{.example,}.yml # modify as needed
$ bundle install
$ rake db:setup
$ rake bower:install

That’s pretty similar to what’s in our .travis.yml (for running tests on Travis CI):

before_script:
  - cp config/application{.example,}.yml
  - cp config/database{.example,}.yml
  - bundle exec rake db:setup
  - npm install bower
  - bundle exec rake bower:install

So let’s leverage bin/setup to do all of this in one spot. Here’s how I tweaked the generated one:

#!/usr/bin/env ruby
require "pathname"

# path to your application root.
APP_ROOT = Pathname.new File.expand_path("../../",  __FILE__)

Dir.chdir APP_ROOT do
  # This script is a starting point to setup your application.
  # Add necessary setup steps to this file:

  puts "== Installing dependencies =="
  system "gem install bundler --conservative"
  system "bundle check || bundle install"

  puts "\n== Copying sample files =="
  system "cp -n config/application.example.yml config/application.yml"
  system "cp -n config/database.example.yml config/database.yml"

  puts "\n== Preparing database =="
  system "bin/rake db:create"
  system "bin/rake db:migrate"

  puts "\n== Installing Bower =="
  system "npm install bower"
  system "bin/rake bower:install"
end

I originally used rake db:setup but that isn’t idempotent. (it wipes out your local DB). In Jason’s post he recommends idempotency and I agree. We should be able to run this at any time without side effects.

I’m using cp -n which doesn’t overwrite files if they already exists, again for idempotency.

Otherwise, this is pretty straightforward. I then simplified our README to:

1. Install dependencies.

$ brew install postgresql # and follow instructions (or install another way)
$ brew install nodejs
$ brew install phantomjs # for running tests

2. Set up the application.

$ git clone git@github.com:collectiveidea/my-app.git
$ cd my-app
$ bin/setup

and the .travis.yml was simplified to:

before_script:
  - bundle exec bin/setup

I hope we’ll use this pattern more universally going forward.


Seemed Train Railway is licensed under Creative Commons Zero

Photo of Daniel Morrison

Daniel founded Collective Idea in 2005 to put a name to his growing and already full-time freelance work. He works hard writing code, teaching, and mentoring.

Comments

Add a Comment

Hmm...that didn't work.

Something went wrong while adding your comment. If you don't mind, please try submitting it again.

Comment Added!

Your comment has been added to this post. Please refresh this page to view it.

Optional. If added, we will display a link to the website in your comment.
Optional. Never shared or displayed in your comment.