# Template which configures a generic Rails app with Shoulda, Factory Girl, # HAML, etc while commiting each step into git. # # Make sure you have Rails 2.3rc1 or greater installed and run: # rails -d mysql -m http://gist.github.com/raw/57458/06345c42a92048e699af3140ccd28bbcd8915bc5/archfear.rb my_app # Helper methods def environment(data = nil, options = {}, &block) options = { :sentinel => 'Rails::Initializer.run do |config|' }.merge(options) data = block.call if !data && block_given? in_root do if options[:env].nil? gsub_file 'config/environment.rb', /(#{Regexp.escape(options[:sentinel])})/mi do |match| "#{match}\n " << data end else Array.wrap(options[:env]).each do|env| append_file "config/environments/#{env}.rb", "\n#{data}" end end end end # Modified version of the "gem" method which places the "config.gem..." lines # after the examples in config/environment.rb. def gem(name, options = {}) log 'gem', name env = options.delete(:env) gems_code = "config.gem '#{name}'" if options.any? opts = options.inject([]) {|result, h| result << [":#{h[0]} => '#{h[1]}'"] }.sort.join(", ") gems_code << ", #{opts}" end environment gems_code, :env => env, :sentinel => ' # config.gem "aws-s3", :lib => "aws/s3"' end # adds .gitignore files to any empty child directories so that # they can be tracked by git def touch_gitignore(path = '.') Dir[File.join(File.expand_path(path), '**')].each do |file| if File.directory?(file) && File.basename(file) != 'tmp' touch_gitignore(file) if Dir[File.join(file, '*')].empty? run "touch #{File.join(file, '.gitignore')}" end end end end # Setup basic Rails app SUDO_CMD = yes?("Does gem installation require sudo on your system? (yes/no)") ? "sudo" : "" run "rm public/index.html" run "rm public/favicon.ico" run "rm public/images/*" run "rm -rf test/fixtures" run "rm README" file 'README.markdown', <<-TEXT README ====== This is the app README. TEXT run "cp config/database.yml config/database.yml.example" file ".gitignore", <<-TEXT *.DS_Store /log/*.log /tmp/**/* /db/schema.rb /db/*.sqlite3 /doc/api /doc/plugins /doc/app /config/database.yml /coverage /public/stylesheets/screen.css /public/system *.swp TEXT touch_gitignore git :init git :add => "." git :commit => "-a -m 'Created empty Rails app'" rake "rails:freeze:gems" git :add => "vendor/rails" git :commit => "-a -m 'Froze Rails gems'" # Disable default routes gsub_file 'config/routes.rb', /^ map\.connect/ do |match| ' # map.connect' end git :add => "." git :commit => "-a -m 'Comment out default routes so that we have to explicitly define any routes that don''t map to a resource.'" # Return 404 for routing errors gsub_file 'app/controllers/application_controller.rb', /^end$/ do |match| <<-CODE unless RAILS_ENV == 'development' rescue_from ActiveRecord::RecordNotFound, :with => :render_404 rescue_from ActionController::UnknownController, :with => :render_404 rescue_from ActionController::UnknownAction, :with => :render_404 rescue_from ActionController::RoutingError, :with => :render_404 end def render_403 respond_to do |type| type.html { render :file => "\#{RAILS_ROOT}/public/403.html", :status => 403 } type.xml { render :xml => '', :status => 403 } type.all { render :nothing => true, :status => 403 } end end def render_404 respond_to do |type| type.html { render :file => "\#{RAILS_ROOT}/public/404.html", :status => 404 } type.xml { render :xml => '', :status => 404 } type.all { render :nothing => true, :status => 404 } end end end CODE end git :add => "." git :commit => "-a -m 'Render 404 page when there are routing errors in production'" # Setup testing framework - mocha, factory girl, shoulda # gem "mocha", :env => :test # run "#{SUDO_CMD} gem install mocha" # rake "gems:unpack GEM='mocha'" # git :add => "." # git :commit => "-a -m 'Installed Mocha gem'" gem "thoughtbot-factory_girl", :lib => "factory_girl", :source => "http://gems.github.com", :env => :test run "#{SUDO_CMD} gem install thoughtbot-factory_girl --source http://gems.github.com" run "rake gems:unpack GEM=thoughtbot-factory_girl RAILS_ENV=test" file "test/factories.rb", '' git :add => "." git :commit => "-a -m 'Installed Factory Girl gem'" run "#{SUDO_CMD} gem install ruby-prof" #Required by rake shouda:list gem "thoughtbot-shoulda", :lib => "shoulda", :source => "http://gems.github.com", :env => :test run "#{SUDO_CMD} gem install thoughtbot-shoulda --source http://gems.github.com" run "rake gems:unpack GEM=thoughtbot-shoulda RAILS_ENV=test" append_file "Rakefile", 'Dir["#{RAILS_ROOT}/vendor/gems/thoughtbot-shoulda-*/lib/shoulda/tasks/**/*.rake"].sort.each { |ext| load ext }' + "\n" git :add => "." git :commit => "-a -m 'Installed Shoulda gem'" file 'test/shoulda_macros/html_validation.rb', <<-RUBY class Test::Unit::TestCase # Shoulda macro that ensures output is well-formed HTML. def self.should_be_well_formed should 'be well formed' do assert_select 'html', true end end end RUBY git :add => "test/shoulda_macros" git :commit => "-a -m 'Added should_be_well_formed shoulda macro'" gsub_file 'config/initializers/backtrace_silencers.rb', /^#{Regexp.escape('# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }')}$/ do |match| <<-RUBY #{match} Rails.backtrace_cleaner.add_silencer do |line| %w( shoulda factory_girl ).any? { |dir| line.include?(dir) } end RUBY end run "#{SUDO_CMD} gem install redgreen" #Required by rake shouda:list environment "config.gem 'redgreen' if ENV['TM_FILENAME'].nil?\n", :env => :test run "rake gems:unpack GEM=redgreen RAILS_ENV=test" git :add => "." git :commit => "-a -m 'Installed redgreen gem for colorized test output'" # Install rcov and rcov rake tasks run "#{SUDO_CMD} gem install mergulhao-rcov" # Relevance's fork of rcov plugin "rcov_plugin", :git => 'git://github.com/commondream/rcov_plugin.git' git :add => "." git :commit => "-a -m 'Installed rcov rake tasks plugin'" # Setup HAML/SASS templates gsub_file 'app/helpers/application_helper.rb', /^end$/ do |match| ' def body_class "#{controller.controller_name} #{controller.controller_name}-#{controller.action_name}" end end' end git :add => "app/helpers/application_helper.rb" git :commit => "-a -m 'Added body_class helper'" gem "haml" run "#{SUDO_CMD} gem install haml" rake "gems:unpack GEM='haml'" run 'haml --rails .' initializer 'sass.rb', <<-CODE # Format CSS in standard, human-readable style. Sass::Plugin.options[:style] = :expanded # Override default template location of public/stylesheets/sass to something outside of # public so the raw templates won't be served up by the web server Sass::Plugin.options[:template_location] = RAILS_ROOT + "/app/views/stylesheets" CODE rake "" git :add => "." git :commit => "-a -m 'Installed HAML gem and plugin'" file 'app/views/layouts/application.html.haml', <<-HAML !!! Strict %html{ "xml:lang" => "en", :lang => "en-us", :xmlns => "http://www.w3.org/1999/xhtml" } %head %meta{ :content => "text/html; charset=utf-8", "http-equiv" => "content-type" } %title CHANGEME = stylesheet_link_tag 'screen', :media => 'all', :cache => true %body{ :class => body_class } = yield HAML file 'app/views/stylesheets/screen.sass', <<-SASS // Sitewide Stylesheet SASS git :add => "." git :commit => "-a -m 'Added basic layout and stylesheet.'" # Create DB schemas if yes?("Create DB schemas? (yes/no)") rake "db:create" rake "db:create", :env => 'test' rake "db:migrate" end