This week Ben Orenstein is joined by Nick Quaranto, developer at 37signals and one of the maintainers of RubyGems.org. Nick and Ben discuss the just released Basecamp iOS app, the architecture of the app, the origins of the app and how it became what it is today, and RubyMotion in general. They then move on to discuss the recent RubyGems.org cracking, the mechanism behind it, the process of restoring the service, and how it might affect RubyGems going forward. They then circle back to talk more about RubyMotion, testing, working at 37signals, Co-work Buffalo, OpenHack, and good coffee.
In our protocol guide, we instruct new developers to set up an existing Rails app like this:
git clone git@github.com:organization/app.git
cd app
./bin/setup
The goal of the bin/setup script is quick, reliable, consistent setup. It is placed in the bin directory to match new Rails conventions about executables.
Here’s an example bin/setup:
#!/bin/sh
# Set up Rails app. Run this script immediately after cloning the codebase.
# https://github.com/thoughtbot/guides/tree/master/protocol
# Set up Ruby dependencies
bundle install --binstubs
# Set up staging and production git remotes
git remote add staging git@heroku.com:app-staging.git
git remote add production git@heroku.com:app-production.git
# Set up database
bundle exec rake db:setup
# Set up configurable environment variables for Foreman
if [ ! -f .env ]; then
echo "RACK_ENV=development" > .env
fi
echo "port: 7000" > .foreman
# Set up DNS through Pow
if [ -d ~/.pow ]
then
echo 7000 > ~/.pow/`basename $PWD`
else
echo "Pow not set up but the team uses it for this project. Setup: http://goo.gl/RaDPO"
fi
The first section uses Bundler’s binstubs.
The second section sets up git remotes for staging and production commands.
The third section creates the development and test databases, loads the schema, and initializes with the seed data. It does not need to run all the migrations.
The last two sections use Foreman as process manager, Pow as DNS server and HTTP proxy.
This is just an example bin/setup file. Each project will be different. Some might not use Pow. Some might test if Redis or MongoDB is installed and run, install, or print a message if not. Some might want to pull some ENV variables into .env from Heroku.
Regardless of the bin/setup file’s contents, a developer should be able to clone the project and run a single, consistent, reliable command to start contributing.
Written by Dan Croak.
I’m very pleased announce that our popular Intro to Ruby on Rails workshop is now available to take as a month-long online version.
The online workshop will run from February 4th to March 1st. After that, you get ongoing support from the thoughtbot team for any Ruby on Rails questions you have.
Our online workshops have been going very well, and in this latest round we’ve switched from text-based Campfire chat for office hours to full audio and video in Google Hangouts.
Register today for the upcoming online session of Intro to Ruby on Rails.
All email from the staging environment of a Rails app can be intercepted and delivered to a group email address. This avoids accidentally delivering staging email to production customers and lets the product team see all the emails that are being sent to customers.
Gemfile:
gem 'recipient_interceptor'
config/initializers/mail.rb:
if Rails.env.staging? || Rails.env.production?
MAIL_SETTINGS = {
address: 'smtp.sendgrid.net',
authentication: :plain,
domain: 'heroku.com',
password: ENV['SENDGRID_PASSWORD'],
port: '587',
user_name: ENV['SENDGRID_USERNAME']
}
end
config/environments/{staging,production}.rb:
require Rails.root.join('config/initializers/mail')
My::Application.configure do
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = MAIL_SETTINGS
end
Also in config/environments/staging.rb:
Mail.register_interceptor RecipientInterceptor.new(ENV['EMAIL_RECIPIENTS'])
Use the ENV['EMAIL_RECIPIENTS'] environment variable to update the list of email addresses that should receive staging emails. For example:
heroku config:add EMAIL_RECIPIENTS="staging@example.com" --remote staging
Depending on the app, this may generate thousands of emails a day. Avoid spamming yourself by setting up a Gmail filter for emails sent to staging@example.com.
Written by Dan Croak.
Zeus improves Rails boot time. Saving seconds is most important when running focused tests:
rspec spec/models/user_spec.rb
rspec spec/models/user_spec.rb:123
Those are times when a tight feedback loop make a meaningful difference.
Install the Zeus gem on your machine:
gem install zeus
Do not include it in your Gemfile. It is an external piece of software.
Initialize:
zeus init
This will create two files in your Rails app’s directory. Ignore them globally in ~/.gitignore:
custom_plan.rb
zeus.json
Edit zeus.json to include only the tasks for which you’ll use Zeus. Mine looks like this:
{
"command": "ruby -rubygems -r./custom_plan -eZeus.go",
"plan": {
"boot": {
"default_bundle": {
"development_environment": {
"prerake": {"rake": []},
"console": ["c"],
"generate": ["g"]
},
"test_environment": {
"test_helper": {"test": ["rspec"]}
}
}
}
}
}
I remove cucumber in favor of RSpec and Capybara. I remove server in favor of Foreman and Pow.
In spec/spec_helper.rb, change:
ENV['RAILS_ENV'] ||= 'test'
To:
ENV['RAILS_ENV'] = 'test'
The goal is to run tests in the context of Zeus. So, remove other similar systems.
From the RSpec docs:
> Generally, life is simpler if you just use the rspec command. If you
> must use the ruby command, however, you’ll want to do the following:
require 'rspec/autorun'
> This tells RSpec to run your examples.
We don’t need this behavior and can cause bugs when used with Zeus.
Remove either of these lines in spec/spec_helper.rb if they exist:
require 'rspec/autorun'
require 'rspec/autotest'
For the same reasons, if you’re using Spork and Guard, delete them from your Gemfile, delete your Guardfile, and delete any related Spork code in spec/spec_helper.rb or spec/support/.
Zeus will need to be running before you can use its commands:
zeus start
I usually run this, and other long-running processes in a tmux session.
Now, those original commands will have the benefit of Rails boot time in under a second:
zeus rspec spec/models/user_spec.rb
zeus rspec spec/models/user_spec.rb:123
Many of us are running specs directly from vim. If you edit your ~/.vimrc to use Zeus like in this commit, you can run focused specs with:
t
Enjoy!
Written by Dan Croak.