Skip to content

Instantly share code, notes, and snippets.

@awmichel
Last active December 18, 2015 05:39
Show Gist options
  • Save awmichel/5733939 to your computer and use it in GitHub Desktop.
Save awmichel/5733939 to your computer and use it in GitHub Desktop.
Preferred blend of Rubies and Gems on Rails.
#!/usr/bin/env ruby -w
#
# Rails App Template by @awmichel
# Uses:
# Unicorn
# PostgreSQL
# RSpec
# Capybara
# Guard
# Simple Form
# Twitter Bootstrap
#
# rails new APP_NAME -d postgresql -T --skip-bundle -m https://raw.github.com/gist/5733939/rails_app_template.rb
#
# Define Gems
gem 'unicorn'
gem 'simple_form'
gem_group :assets do
gem 'bootstrap-sass'
gem 'therubyracer'
end
gem_group :development do
gem 'mailcatcher'
gem 'better_errors'
gem 'binding_of_caller'
gem 'pry-remote'
gem 'capistrano'
gem 'meta_request'
end
gem_group :test do
gem 'faker'
gem 'capybara'
gem 'poltergeist'
gem 'guard-rspec'
gem 'shoulda-matchers'
gem 'database_cleaner'
end
gem_group :test, :development do
gem 'pry'
gem 'rspec-nc'
gem 'rb-fsevent', '~> 0.9', require: false
gem 'factory_girl_rails'
gem 'rspec-rails', '~> 2.0'
end
# Bundle
run 'bundle install'
# Database Config
username = ENV['USER']
gsub_file 'config/database.yml', /^( username: ).*$/, '\1%s' % username
run 'bundle exec rake db:create'
# App Config
application <<-RUBY
# Configure generators
config.generators do |g|
g.test_framework :rspec,
:fixtures => true,
:view_specs => false,
:helper_specs => false,
:routing_specs => false,
:controller_specs => true,
:request_specs => false
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
g.stylesheets = false
g.javascripts = false
g.helper = false
end
RUBY
gsub_file 'config/application.rb', "# config.time_zone = 'Central Time (US & Canada)'", "config.time_zone = 'Eastern Time (US & Canada)'"
# Generate Stuff
generate 'rspec:install'
generate 'simple_form:install --bootstrap'
# RSpec and Test Configuration
append_file '.rspec', <<-CONFIG
--format documentation
--format Nc
CONFIG
create_file 'bin/chrome.sh', <<-BASH
#!/bin/bash
open '/Applications/Google Chrome.app' $@
BASH
create_file 'spec/support/capybara.rb', <<-RUBY
require 'capybara/rspec'
require 'capybara/rails'
require 'capybara/poltergeist'
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, :inspector => 'bin/chrome.sh', :js_errors => true)
end
Capybara.javascript_driver = :poltergeist
RUBY
create_file 'spec/support/shoulda.rb', <<-RUBY
require 'shoulda/matchers/integrations/rspec'
RUBY
create_file 'spec/support/database_cleaner.rb', <<-RUBY
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
RUBY
create_file 'spec/support/pry.rb', <<-RUBY
require 'pry'
RUBY
# RSpec Focus Filter and Deferred Garbage
inject_into_file 'spec/spec_helper.rb', after: "RSpec.configure do |config|\n" do
<<-RUBY
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run focus: true
config.run_all_when_everything_filtered = true
config.before(:all) { DeferredGarbageCollection.start }
config.after(:all) { DeferredGarbageCollection.reconsider }
RUBY
end
comment_lines 'spec/spec_helper.rb', /config\.fixture_path/
comment_lines 'spec/spec_helper.rb', /rspec\/autorun/
gsub_file 'spec/spec_helper.rb', 'config.use_transactional_fixtures = true', 'config.use_transactional_fixtures = false'
# RSpec Deferred Garbage Collection
create_file 'spec/support/deferred_garbage_collection.rb', <<-RUBY
class DeferredGarbageCollection
DEFERRED_GC_THRESHOLD = (ENV['DEFER_GC'] || 15.0).to_f
@@last_gc_run = Time.now
def self.start
GC.disable if DEFERRED_GC_THRESHOLD > 0
end
def self.reconsider
if DEFERRED_GC_THRESHOLD > 0 && Time.now - @@last_gc_run >= DEFERRED_GC_THRESHOLD
GC.enable
GC.start
GC.disable
@@last_gc_run = Time.now
end
end
end
RUBY
# RSpec Factory Girl
create_file 'spec/models/factories_spec.rb', <<-'RUBY'
require 'spec_helper'
describe 'validate FactoryGirl factories' do
FactoryGirl.factories.each do |factory|
context "with factory for :#{factory.name}" do
subject { FactoryGirl.build(factory.name) }
it "is valid" do
is_valid = subject.valid?
is_valid.should be_true, subject.errors.full_messages.join(',')
end
end
end
end
RUBY
# Guard RSpec
run 'bundle exec guard init rspec'
gsub_file 'Guardfile', 'guard :rspec do', 'guard \'rspec\', all_on_start: false, all_after_pass: false, zeus: true, bundler: false do'
inject_into_file 'Guardfile', before: '# Turnip features and steps' do
<<-RUBY
# FactoryGirl factory specs
watch(%r{^spec/factories/(.*)\.rb$}) { |m| "spec/models/factories_spec.rb" }
RUBY
end
# Unicorn Config
create_file 'config/unicorn.rb', <<-'RUBY'
rails_env = ENV['RAILS_ENV'] || 'development'
worker_processes (rails_env == 'development' ? 1 : 4)
listen "/tmp/APP_NAME.socket", :backlog => 64
timeout 30
preload_app true
pid "/tmp/unicorn.APP_NAME.pid"
before_fork do |server, worker|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.disconnect!
end
old_pid = "/tmp/unicorn.APP_NAME.pid.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
after_fork do |server,worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
if rails_env == "production"
working_directory "/home/app/apps/APP_NAME/current"
user 'app', 'app'
shared_path = "/home/app/apps/APP_NAME/shared"
stderr_path "#{shared_path}/log/unicorn.stderr.log"
stdout_path "#{shared_path}/log/unicorn.stdout.log"
end
RUBY
gsub_file 'config/unicorn.rb', 'APP_NAME', @app_name.underscore
# Remove Docs
run 'rm README.rdoc'
run 'rm -rf doc'
# Initialize Git
git :init
git add: '.'
# Capify!
capify!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment