Skip to content

Instantly share code, notes, and snippets.

@BinaryMuse
Created November 21, 2010 17:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save BinaryMuse/708939 to your computer and use it in GitHub Desktop.
Save BinaryMuse/708939 to your computer and use it in GitHub Desktop.
My Rails application template - under development! See comments for info.
# ============================================================================
# Info class
# ============================================================================
class ApplicationInfo < Rails::Generators::AppGenerator
attr_reader :notices, :errors, :options, :data
def initialize
@notices = [] # Array of notices to display to the user at the end
@errors = [] # Array of errors to display to the user at the end
@options = [] # Array of options selected throughout the template
@data = {} # Hash of data to use for configuration.
end
def option(text, option)
if yes? " #{text}"
self.options << option
if block_given?
yield
end
end
end
def option?(option)
@options.include? option
end
def prompt(text, option, key)
self.data[option] = {} if self.data[:option].nil?
self.data[option][key] = ask " #{text}"
end
end
appinfo = ApplicationInfo.new
# ============================================================================
# Helper methods
# ============================================================================
def git_remove_file(file)
git :rm => "#{file}"
end
def git_update(message)
git :add => ".", :commit => "-m \"#{message}\""
end
def info(message)
puts " #{message}"
end
# ============================================================================
# Prompt for everything in the beginning.
# ============================================================================
if yes? "Do you use RVM?"
rvm_info = `rvm info` # run() no longer appears to return the output from the call
match = rvm_info.split("\n").first.match(/(.*)\:/)
unless match.nil?
gemset = match[1]
info "Your current gemset is: #{gemset}"
appinfo.option "Would you like to generate an .rvmrc file based on your current gemset?", :rvmrc
else
appinfo.errors << "Could not determine your RVM/gemset info. Skipped creating .rvmrc."
end
end
appinfo.option "Use Haml?", :haml
appinfo.option "Use Compass?", :compass do
appinfo.option "Use Blueprint CSS?", :blueprint
end
appinfo.option "Use OmniAuth?", :omniauth
appinfo.option "Use Devise?", :devise do
appinfo.option "Automatically run rake db:migrate after generating default Devise model?", :devise_migrate
end
appinfo.option "Use CanCan?", :cancan
# ============================================================================
# Get the Git repository running first thing
# ============================================================================
git :init
git_update "Initial commit"
# ============================================================================
# RVM
# ============================================================================
if appinfo.option? :rvmrc
run "echo 'rvm use #{gemset} --create' > .rvmrc"
git_update "Add .rvmrc"
end
# ============================================================================
# Basic Gems
# ============================================================================
gem "annotate-models", :group => [:development, :test]
gem "factory_girl_rails", :group => [:development, :test]
gem "faker", :group => [:development, :test]
gem "rspec", :group => [:development, :test]
gem "rspec-rails", :group => [:development, :test]
# ============================================================================
# Autentication/Authorization Gems
# ============================================================================
if appinfo.option? :haml
gem "haml"
gem "haml-rails"
end
if appinfo.option? :compass
gem "compass"
end
if appinfo.option? :omniauth
gem "omniauth"
end
if appinfo.option? :devise
gem "devise"
end
if appinfo.option? :cancan
gem "cancan"
end
# ============================================================================
# Install Gems and run any necessary scripts
# ============================================================================
begin
require "bundler"
rescue Bundler::GemNotFound => e
STDERR.puts e.message
exit!
end
run "bundle install"
generate "rspec:install"
# ============================================================================
# No fixtures
# ============================================================================
gsub_file 'spec/spec_helper.rb', 'config.fixture_path = "#{::Rails.root}/spec/fixtures"', '# config.fixture_path = "#{::Rails.root}/spec/fixtures"'
gsub_file 'spec/spec_helper.rb', 'config.use_transactional_fixtures = true', 'config.use_transactional_fixtures = false'
# ============================================================================
# Add generator config to application.rb
# ============================================================================
generators = <<-GENERATORS
config.generators do |g|
g.test_framework :rspec, :fixture => false, :views => false
g.integration_tool :rspec, :fixture => false, :views => true
g.template_engine :haml
end
GENERATORS
application generators
gsub_file "config/application.rb", /^ $/, "" # Hate trailing whitespace >.<
git_update "Standard application setup"
# ============================================================================
# Handle database.yml
# ============================================================================
run "cp config/database.yml config/database.yml.example"
# ============================================================================
# Remove Prototype even if the option wasn't passed
# ============================================================================
if !options["skip_prototype"]
[
"public/javascripts/controls.js",
"public/javascripts/dragdrop.js",
"public/javascripts/effects.js",
"public/javascripts/prototype.js",
"public/javascripts/rails.js"
].each { |f| git_remove_file f }
end
# ============================================================================
# Get jQuery and install jQuery for rails
# modify settings to add it to :defaults
# ============================================================================
get "http://code.jquery.com/jquery-1.4.4.min.js", "public/javascripts/jquery.js"
get "https://github.com/rails/jquery-ujs/raw/master/src/rails.js", "public/javascripts/rails.js"
gsub_file "public/javascripts/jquery.js", "\r\n", "\n"
gsub_file "public/javascripts/rails.js", "\r\n", "\n"
gsub_file "config/application.rb", '# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)', 'config.action_view.javascript_expansions[:defaults] = %w(jquery rails)'
git_update "Add jQuery"
# ============================================================================
# Basic application layout and helpers
# ============================================================================
basic_layout = <<-LAYOUT
!!!
%html
%head
%title= yield(:title) || "Untitled"
= stylesheet_link_tag :all
= javascript_include_tag :defaults
= csrf_meta_tag
= yield(:head)
%body
#container
- flash.each do |type, msg|
= content_tag :div, msg, :id => "flash_\#\{type\}", :class => "flash \#\{type\}"
%nav
= link_to "Home", root_url
%header
- if show_title?
%h1= yield :title
%content
= yield
%footer
LAYOUT
layout_helper = <<-LAYOUTHELPER
# These helper methods can be called in your template to set variables to be
# used in the layout. This module should be included in all views globally,
# to do so you may need to add this line to your ApplicationController
# helper :layout
module LayoutHelper
def title(page_title, show_title = true)
content_for(:title) { page_title.to_s }
@show_title = show_title
end
def show_title?
@show_title
end
def stylesheet(*args)
content_for(:head) { stylesheet_link_tag(*args) }
end
def javascript(*args)
content_for(:head) { javascript_include_tag(*args) }
end
end
LAYOUTHELPER
git_remove_file "README"
git_remove_file "public/index.html"
git_remove_file "public/images/rails.png"
git_remove_file "app/views/layouts/application.html.erb"
create_file "README"
create_file "app/views/layouts/application.html.haml", basic_layout
create_file "app/helpers/layout_helper.rb", layout_helper
git_update "Set up basic layout and helper"
# ============================================================================
# Compass and Blueprint
# ============================================================================
if appinfo.option? :compass
compass_command = "compass init rails . --css-dir=public/stylesheets/compiled --sass-dir=app/stylesheets"
if appinfo.option? :blueprint
extra_scss = <<-EXTRA_SCSS
.alert {
@include error;
}
body {
margin: 10px;
}
EXTRA_SCSS
compass_command = compass_command + " --using blueprint/semantic"
end
run compass_command
additional_layout = <<-ADDTL_LAYOUT
= stylesheet_link_tag 'compiled/screen.css', :media => 'screen, projection'
= stylesheet_link_tag 'compiled/print.css', :media => 'print'
/[if lt IE 8]
= stylesheet_link_tag 'compiled/ie.css', :media => 'screen, projection'
ADDTL_LAYOUT
inject_into_file "app/views/layouts/application.html.haml", additional_layout, :after => " = stylesheet_link_tag :all\n"
if appinfo.option? :blueprint
append_to_file "app/stylesheets/partials/_page.scss", extra_scss
gsub_file "app/views/layouts/application.html.haml", " %body", " %body.bp"
end
end
# ============================================================================
# Stuff for root layout
# ============================================================================
welcome_controller = <<-WELCOME_CONTROLLER
class WelcomeController < ApplicationController
def index
end
end
WELCOME_CONTROLLER
welcome_view = <<-WELCOME_VIEW
%h1 Welcome
Oh hai gusy lol
WELCOME_VIEW
create_file "app/controllers/welcome_controller.rb", welcome_controller
create_file "app/views/welcome/index.html.haml", welcome_view
route 'root :to => "welcome#index"'
git_update "Add welcome_controller and root route"
# ============================================================================
# OmniAuth configuration
# ============================================================================
## Todo
# ============================================================================
# Devise configuration
# ============================================================================
if appinfo.option? :devise
generate "devise:install"
devise_config = <<-DEVISE_CONFIG
# Devise configuration
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
DEVISE_CONFIG
inject_into_file "config/environments/development.rb", devise_config, :after => "# Settings specified here will take precedence over those in config/application.rb\n"
appinfo.notices << "Set up Devise's config.action_mailer.default_url_options in all environments."
generate "devise User"
if appinfo.option? :devise_migrate
rake "db:migrate"
else
appinfo.notices << "Customize Devise's initializer, user model, and migration, and run rake db:migrate."
end
inject_into_file "spec/spec_helper.rb", "\n config.include Devise::TestHelpers, :type => :controller\n", :after => "config.use_transactional_fixtures = false\n"
additional_layout = <<-ADDTL_LAYOUT
- if user_signed_in?
= "| Hi, \#\{current_user.email\}."
= link_to "Sign out", destroy_user_session_path
- else
|
= link_to "Sign in", new_user_session_path
or
= link_to "Sign up", new_user_registration_path
ADDTL_LAYOUT
inject_into_file "app/views/layouts/application.html.haml", additional_layout, :after => " = link_to \"Home\", root_url\n"
git_update "Set up Devise"
end
# ============================================================================
# CanCan configuration
# ============================================================================
if appinfo.option? :cancan
ability = <<-ABILITY
class Ability
include CanCan::Ability
def initialize(user)
# Default permission; everyone can :read everything
can :read, :all
# Example permission check, depends on an admin? function in your User model
# if user.admin?
# can :manage, :all
# else
# can :read, :all
# end
end
end
ABILITY
create_file "app/models/ability.rb", ability
git_update "Set up CanCan"
end
# ============================================================================
# Final reporting
# ============================================================================
if appinfo.notices.any?
puts
puts "=" * 80
puts "===== Before you continue:"
appinfo.notices.each { |notice| puts " * #{notice}" }
end
if appinfo.errors.any?
puts
puts "=" * 80
puts "===== Errors:"
appinfo.errors.each { |error| puts " * #{error}" }
end
puts
@BinaryMuse
Copy link
Author

My Ruby on Rails 3 application template. Still workin' on it.

Sets up a Git repository by default, with an initial commit that contains the vanilla Rails install. Installs Annotate, factory_girl, Faker, and RSpec. Optionally installs Devise, OmniAuth, CanCan, Haml, and Compass (optinally with Blueprint). Also optionally sets up an .rvmrc file based on your current RVM gemset--be sure to create this gemset and switch to it before running rails new.

Choosing to install Devices allows the template to set up a default user model; you have the option of postponing the database migration if you prefer to customize this model (or it's migration) by hand.

The template also removes Prototype (if -J wasn't passed) and installs jQuery.

Thanks to LeFnord and his template at https://gist.github.com/674468 for the inspiration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment