Skip to content

Instantly share code, notes, and snippets.

@bnadlerjr
Created December 28, 2010 16:17
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bnadlerjr/757372 to your computer and use it in GitHub Desktop.
Save bnadlerjr/757372 to your computer and use it in GitHub Desktop.
Rails Application Template Generator
require 'yaml'
snippets = ::YAML.load <<-'TEXT'
- name: ActiveRecord
type: Database / ORM
pre_bundle:
post_bundle:
- name: RSpec
type: Unit Test Framework
pre_bundle: |
gem 'rspec-rails', '~> 2.12.0', :group => [:development, :test]
post_bundle: |
generate 'rspec:install'
insert_into_file 'config/application.rb', :after => "config.generators do |g|\n" do
" g.view_specs = false\n"
end
remove_dir 'test'
add_file './script/specs' do
"#!/bin/bash\n" +
"#\n" +
"# From Destroy All Software screencast #10, at:\n" +
"# http://destroyallsoftware.com/screencasts/catalog/fast-tests-with-and-without-rails\n" +
"#\n" +
"# Put this in the script/ directory of your Rails app, then run it with a spec\n" +
"# filename. If the spec uses spec_helper, it'll be run inside Bundler.\n" +
"# Otherwise, it'll be run directly with whatever `rspec` executable is on the\n" +
"# path.\n\n" +
"set -e\n\n" +
"need_rails=1\n\n" +
"if [ $# -gt 0 ]; then # we have args\n" +
" filename=$1\n" +
" # Remove trailing line numbers from filename, e.g. spec/my_spec.rb:33\n" +
" grep_filename=`echo $1 | sed 's/:.*$//g'`\n\n" +
" (set +e; grep -r '\bspec_helper\b' $grep_filename) > /dev/null\n" +
" if [ $? -eq 1 ]; then # no match; we have a stand-alone spec\n" +
" need_rails=''\n" +
" fi\n" +
"else # we have no args\n" +
" filename='spec'\n" +
"fi\n\n" +
"command='rspec'\n\n" +
"if [ $need_rails ]; then\n" +
' command="ruby -S bundle exec $command"' + "\n" +
"fi\n\n" +
"time RAILS_ENV=test $command $filename"
end
chmod "./script/specs", 0755
add_file 'lib/tasks/overrides.rake' do
"%w(test test:recent test:single test:uncommitted).each do |t|\n" +
" Rake::Task[t].clear\n" +
" task t do\n" +
" puts \"test unit tasks are disabled; use './script/specs' instead\"\n" +
" end\n" +
" end\n"
end
add_file 'spec/support/have_errors_on_matcher.rb' do
"RSpec::Matchers.define :have_errors_on do |attribute|\n" +
" chain :with_message do |message|\n" +
" @message = message\n" +
" end\n\n" +
" match do |model|\n" +
" model.valid?\n\n" +
" @has_errors = model.errors.include?(attribute)\n\n" +
" if @message\n" +
" @has_errors && model.errors[attribute].include?(@message)\n" +
" else\n" +
" @has_errors\n" +
" end\n" +
" end\n\n" +
" failure_message_for_should do |model|\n" +
" if @message\n" +
" \"Validation errors \#{model.errors[attribute].inspect} should include \#{@message.inspect}\"\n" +
" else\n" +
" \"\#{model.class} should have errors on attribute \#{attribute.inspect}\"\n" +
" end\n" +
" end\n\n" +
" failure_message_for_should_not do |model|\n" +
" \"\#{model.class} should not have an error attribute on \#{attribute.inspect}\"\n" +
" end\n" +
"end\n"
end
add_file 'spec/support/allow_value_matcher.rb' do
"RSpec::Matchers.define :allow_value do |value|\n" +
" chain :for do |attribute|\n" +
" @attribute = attribute\n" +
" end\n\n" +
" match do |model|\n" +
" raise \"You must specify a 'for' attribute\" unless @attribute\n\n" +
" model.send(\"\#{@attribute}=\", value)\n" +
" model.valid?\n" +
" model.errors.exclude?(@attribute)\n" +
" end\n\n" +
" failure_message_for_should do |model|\n" +
" \"\#{model.class} should not have an error attribute on \#{@attribute.inspect}\"\n" +
" end\n\n" +
" failure_message_for_should_not do |model|\n" +
" \"\#{model.class} should have errors on attribute \#{@attribute.inspect}\"\n" +
" end\n" +
"end\n"
end
- name: Test::Unit
type: Unit Test Framework
pre_bundle:
gem 'minitest', '~> 4.3.3', :group => :test
post_bundle:
- name: Factory Girl
type: Fixtures
pre_bundle:
gem 'factory_girl_rails', '~> 4.1.0', :group => [:development, :test]
post_bundle: |
fixture_dir = Dir.exists?('test') ? 'test/factories' : 'spec/factories'
insert_into_file 'config/application.rb', :after => "config.generators do |g|\n" do
" g.fixture_replacement :factory_girl, :dir => '#{fixture_dir}'\n"
end
- name: YAML Fixtures
type: Fixtures
pre_bundle:
post_bundle:
- name: Capybara
type: Integration Test Framework
pre_bundle:
gem 'capybara', '~> 2.0.1', :group => [:development, :test]
post_bundle:
- name: Test::Unit Integration Framework
type: Integration Test Framework
pre_bundle:
post_bundle:
- name: Simple Form
type: Form Helper
pre_bundle:
gem 'simple_form', '~> 2.0.4'
post_bundle:
generate 'simple_form:install'
- name: No Custom Form Helper
type: Form Helper
pre_bundle:
post_bundle:
- name: Devise
type: Authentication
pre_bundle:
gem 'devise', '~> 2.1.2'
post_bundle: |
generate 'devise:install'
generate 'devise user'
generate 'devise:views'
insert_into_file 'config/routes.rb', :before => " devise_for :users\n" do
" devise_scope :user do\n" +
" root :to => 'devise/sessions#new'\n" +
" end\n"
end
- name: No Authentication Framework
type: Authentication
pre_bundle:
post_bundle:
- name: HAML
type: Templating Engine
pre_bundle: |
gem 'haml-rails', '~> 0.3.5'
post_bundle:
- name: ERB
type: Templating Engine
pre_bundle:
post_bundle:
TEXT
say <<-TEXT
======================================================================================
####### ### ### / /
/ ### ### ### #/ #/
/ ## ## ## ## ##
## # ## ## ## ##
### ## ## ## ##
## ### /### /## ## ## ## /### /### /### ## /##
### ### / ### / / ### ## ## ##/ ### / / ### / / ### / ## / ###
### ### / ###/ / ### ## ## ## ###/ / ###/ / ###/ ##/ /
### /## ## ## ## ### ## ## ## ## ## ## ## ## ## /
#/ /## ## ## ######## ## ## ## ## ## ## ## ## ## /
#/ ## ## ## ####### ## ## ## ## ## ## ## ## ## ##
# / ## ## ## ## ## ## ## ## ## ## ## ######
/## / ## ## #### / ## ## ## /# ## ## ## ## ## ###
/ ########/ ####### ######/ ### / ### / ####/ ###### ###### ## ### /
/ ##### ###### ##### ##/ ##/ ### #### #### ## ##/
| ##
\) ##
##
##
Rails App Template Generator by Bob Nadler (bnadlerjr@gmail.com)
======================================================================================
TEXT
# Get choices
types = snippets.map { |s| s['type'] }.uniq
choices = types.map do |type|
snippets_for_type = snippets.find_all { |s| s['type'] == type }
say("\nSelect #{type}:")
snippets_for_type.each_with_index { |s, i| say(" #{i}) #{s['name']}") }
while (snippet = snippets_for_type[ask("\n Choice? ", :yellow).to_i]) == nil; end
snippet
end
# Apply general templates
remove_file 'README.rdoc'
remove_file 'doc/README_FOR_APP'
remove_file 'public/index.html'
remove_file 'public/images/rails.png'
create_file 'README.rdoc' do
<<-TEXT
= <NAME OF APP>
<BRIEF DESCRIPTION>
== Getting Started
=== Installation
=== Running Tests
=== Running Locally
== Deploying
== Project Layout
Uses standard Ruby on Rails directory structure.
TEXT
end
if yes?('Would you like to ban spiders from your site? (yes/no)')
gsub_file 'public/robots.txt', /# User-Agent/, 'User-Agent'
gsub_file 'public/robots.txt', /# Disallow/, 'Disallow'
end
if yes?('Would you like to use an in memory SQLite3 database for testing? (yes/no)')
insert_into_file 'config/database.yml', :after => " database: db/test.sqlite3\n" do
<<-RUBY
database: ":memory:"
verbosity: quiet
RUBY
end
gsub_file 'config/database.yml', / database: db\/test.sqlite3\n/, ''
create_file 'config/initializers/in_memory_database.rb' do
"if Rails.env == \"test\" and\n" +
" ActiveRecord::Base.connection.class == ActiveRecord::ConnectionAdapters::SQLite3Adapter and\n" +
" Rails.configuration.database_configuration['test']['database'] == ':memory:'\n\n" +
" puts \"creating sqlite3 in memory database\"\n" +
' load "#{Rails.root}/db/schema.rb"' + "\n" +
"end"
end
end
if yes?('Would you like to set up Heroku as a deploy target? (yes/no)')
gsub_file 'Gemfile', /gem 'sqlite3'/, "gem 'sqlite3', '~> 1.3.6', :group => [:development, :test]"
gem 'pg', '~> 0.14.1', :group => :production
create_file 'Procfile', 'web: bundle exec rails server thin -p $PORT -e $RACK_ENV'
gsub_file 'config/database.yml', /^production:.+/m, "production:\n # Managed by Heroku"
insert_into_file 'config/application.rb', :after => "config.assets.enabled = true\n" do
" config.assets.initialize_on_precompile = false\n"
end
create_file '.slugignore' do
['/spec', '/test', '/doc', '/log', '/script'].join("\n")
end
append_file '.gitignore', "\n# Heroku will precompile assets\npublic/assets\n"
else
gsub_file 'Gemfile', /gem 'sqlite3'/, "gem 'sqlite3', '~> 1.3.6'"
end
if yes?("Would you like to add a helper for displaying flash messages? (yes/no)")
insert_into_file 'app/helpers/application_helper.rb', :after => "Helper\n" do
" # Shows any flash messages.\n" +
" def show_flash\n" +
" return unless flash.any?\n" +
" flash.map do |k, v|\n" +
" content_tag(:p, v, :class => \"flash \#{k}\")\n" +
" end.join('').html_safe\n" +
" end\n"
end
end
say "Setting Thin as default webserver"
gem 'thin', '~> 1.5.0'
create_file '.rvmrc' do
version = ask('Which Ruby version?(i.e. "ree" or "1.9.2")')
"rvm #{version}"
end
insert_into_file 'config/application.rb', :after => "config.filter_parameters += [:password]\n" do
<<-RUBY
# Configure generators values. Many other options are available, be sure to check the documentation.
config.generators do |g|
g.helper = false # Don't create helpers when generating controllers.
end
RUBY
end
# Apply user chosen templates
choices.each { |c| eval(c['pre_bundle']) unless c['pre_bundle'].nil? }
run 'bundle install'
choices.each { |c| eval(c['post_bundle']) unless c['post_bundle'].nil? }
# Stylesheet overrides
remove_file 'app/assets/stylesheets/application.css'
create_file 'app/assets/stylesheets/application.css.scss' do
'@import "normalize";'
end
run 'curl https://raw.github.com/necolas/normalize.css/master/normalize.css > app/assets/stylesheets/_normalize.scss'
# Clean up Gemfile
gsub_file 'Gemfile', /#.+.$/, ''
gsub_file 'Gemfile', /^\n/, ''
# Finish up by applying git templates
append_file '.gitignore', "\n" + %w[.env].join("\n")
git :init
git :add => "."
git :commit => "-am 'Initial commit.'"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment