Created
July 3, 2012 03:42
-
-
Save johnable/3037460 to your computer and use it in GitHub Desktop.
web template(mongoid 3.0)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#https://raw.github.com/RailsApps/rails3-application-templates/master/rails3-mongoid-omniauth-template.rb | |
# >----------------------------[ Initial Setup ]------------------------------< | |
initializer 'generators.rb', <<-RUBY | |
Rails.application.config.generators do |g| | |
end | |
RUBY | |
@recipes = ["haml", "mongoid", "rspec", "guard", "omniauth", "home_page", "cleanup", "git"] | |
def recipes; @recipes end | |
def recipe?(name); @recipes.include?(name) end | |
def say_custom(tag, text); say "\033[1m\033[36m" + tag.to_s.rjust(10) + "\033[0m" + " #{text}" end | |
def say_recipe(name); say "\033[1m\033[36m" + "recipe".rjust(10) + "\033[0m" + " Running #{name} recipe..." end | |
def say_wizard(text); say_custom(@current_recipe || 'wizard', text) end | |
def ask_wizard(question) | |
ask "\033[1m\033[30m\033[46m" + (@current_recipe || "prompt").rjust(10) + "\033[0m\033[36m" + " #{question}\033[0m" | |
end | |
def yes_wizard?(question) | |
answer = ask_wizard(question + " \033[33m(y/n)\033[0m") | |
case answer.downcase | |
when "yes", "y" | |
true | |
when "no", "n" | |
false | |
else | |
yes_wizard?(question) | |
end | |
end | |
def no_wizard?(question); !yes_wizard?(question) end | |
def multiple_choice(question, choices) | |
say_custom('question', question) | |
values = {} | |
choices.each_with_index do |choice,i| | |
values[(i + 1).to_s] = choice[1] | |
say_custom (i + 1).to_s + ')', choice[0] | |
end | |
answer = ask_wizard("Enter your selection:") while !values.keys.include?(answer) | |
values[answer] | |
end | |
@current_recipe = nil | |
@configs = {} | |
@after_blocks = [] | |
def after_bundler(&block); @after_blocks << [@current_recipe, block]; end | |
@after_everything_blocks = [] | |
def after_everything(&block); @after_everything_blocks << [@current_recipe, block]; end | |
@before_configs = {} | |
def before_config(&block); @before_configs[@current_recipe] = block; end | |
# this application template only supports Rails version 3.1 and newer | |
case Rails::VERSION::MAJOR.to_s | |
when "3" | |
case Rails::VERSION::MINOR.to_s | |
when "2" | |
say_wizard "You are using Rails version #{Rails::VERSION::STRING}." | |
when "1" | |
say_wizard "You are using Rails version #{Rails::VERSION::STRING}." | |
when "0" | |
say_wizard "You are using Rails version #{Rails::VERSION::STRING} which is not supported. Try 3.1 or newer." | |
raise StandardError.new "Rails #{Rails::VERSION::STRING} is not supported. Try 3.1 or newer." | |
else | |
say_wizard "You are using Rails version #{Rails::VERSION::STRING}." | |
end | |
else | |
say_wizard "You are using Rails version #{Rails::VERSION::STRING} which is not supported. Try 3.1 or newer." | |
raise StandardError.new "Rails #{Rails::VERSION::STRING} is not supported. Try 3.1 or newer." | |
end | |
say_wizard "Checking configuration. Please confirm your preferences." | |
# >---------------------------[ Autoload Modules/Classes ]-----------------------------< | |
inject_into_file 'config/application.rb', :after => 'config.autoload_paths += %W(#{config.root}/extras)' do <<-'RUBY' | |
config.autoload_paths += %W(#{config.root}/lib) | |
RUBY | |
end | |
# >---------------------------------[ Recipes ]----------------------------------< | |
# >---------------------------------[ HAML ]----------------------------------< | |
@current_recipe = "haml" | |
@before_configs["haml"].call if @before_configs["haml"] | |
say_recipe 'HAML' | |
config = {} | |
config['haml'] = yes_wizard?("Would you like to use Haml instead of ERB?") if true && true unless config.key?('haml') | |
@configs[@current_recipe] = config | |
# Application template recipe for the rails_apps_composer. Check for a newer version here: | |
# https://github.com/RailsApps/rails_apps_composer/blob/master/recipes/haml.rb | |
if config['haml'] | |
gem 'haml', '>= 3.1.6' | |
gem 'haml-rails', '>= 0.3.4', :group => :development | |
else | |
recipes.delete('haml') | |
end | |
# >--------------------------------[ Mongoid ]--------------------------------< | |
@current_recipe = "mongoid" | |
@before_configs["mongoid"].call if @before_configs["mongoid"] | |
say_recipe 'Mongoid' | |
config = {} | |
config['mongoid'] = yes_wizard?("Would you like to use Mongoid to connect to a MongoDB database?") if true && true unless config.key?('mongoid') | |
@configs[@current_recipe] = config | |
# Application template recipe for the rails_apps_composer. Check for a newer version here: | |
# https://github.com/RailsApps/rails_apps_composer/blob/master/recipes/mongoid.rb | |
if config['mongoid'] | |
say_wizard "REMINDER: When creating a Rails app using Mongoid..." | |
say_wizard "you should add the '-O' flag to 'rails new'" | |
gem "mongoid", "~> 3.0.0.rc" | |
else | |
recipes.delete('mongoid') | |
end | |
if config['mongoid'] | |
after_bundler do | |
say_wizard "Mongoid recipe running 'after bundler'" | |
# note: the mongoid generator automatically modifies the config/application.rb file | |
# to remove the ActiveRecord dependency by commenting out "require active_record/railtie'" | |
generate 'mongoid:config' | |
# remove the unnecessary 'config/database.yml' file | |
remove_file 'config/database.yml' | |
end | |
end | |
# >---------------------------------[ RSpec ]---------------------------------< | |
@current_recipe = "rspec" | |
@before_configs["rspec"].call if @before_configs["rspec"] | |
say_recipe 'RSpec' | |
config = {} | |
config['rspec'] = yes_wizard?("Would you like to use RSpec instead of TestUnit?") if true && true unless config.key?('rspec') | |
config['factory_girl'] = yes_wizard?("Would you like to use factory_girl for test fixtures with RSpec?") if true && true unless config.key?('factory_girl') | |
config['machinist'] = yes_wizard?("Would you like to use machinist for test fixtures with RSpec?") if true && true unless config.key?('machinist') | |
@configs[@current_recipe] = config | |
# Application template recipe for the rails_apps_composer. Check for a newer version here: | |
# https://github.com/RailsApps/rails_apps_composer/blob/master/recipes/rspec.rb | |
if config['rspec'] | |
gem 'rspec-rails', '>= 2.10.1', :group => [:development, :test] | |
if recipes.include? 'mongoid' | |
# use the database_cleaner gem to reset the test database | |
gem 'database_cleaner', '>= 0.8.0', :group => :test | |
# include RSpec matchers from the mongoid-rspec gem | |
gem 'mongoid-rspec', '>= 1.4.6', :group => :test | |
end | |
if config['machinist'] | |
gem 'machinist', :group => :test | |
end | |
if config['factory_girl'] | |
gem 'factory_girl_rails', '>= 3.3.0', :group => [:development, :test] | |
end | |
else | |
recipes.delete('rspec') | |
end | |
# note: there is no need to specify the RSpec generator in the config/application.rb file | |
if config['rspec'] | |
after_bundler do | |
say_wizard "RSpec recipe running 'after bundler'" | |
generate 'rspec:install' | |
if config['machinist'] | |
say_wizard "Generating blueprints file for Machinist" | |
generate 'machinist:install' | |
end | |
say_wizard "Removing test folder (not needed for RSpec)" | |
run 'rm -rf test/' | |
inject_into_file 'config/application.rb', :after => "Rails::Application\n" do <<-RUBY | |
# don't generate RSpec tests for views and helpers | |
config.generators do |g| | |
g.view_specs false | |
g.helper_specs false | |
g.template_engine :haml | |
g.test_framework :rspec | |
g.stylesheets false | |
g.assets false | |
#{"g.fixture_replacement :machinist" if config['machinist']} | |
end | |
RUBY | |
end | |
if recipes.include? 'mongoid' | |
# remove ActiveRecord artifacts | |
gsub_file 'spec/spec_helper.rb', /config.fixture_path/, '# config.fixture_path' | |
gsub_file 'spec/spec_helper.rb', /config.use_transactional_fixtures/, '# config.use_transactional_fixtures' | |
# reset your application database to a pristine state during testing | |
inject_into_file 'spec/spec_helper.rb', :before => "\nend" do | |
<<-RUBY | |
\n | |
# Clean up the database | |
require 'database_cleaner' | |
config.before(:suite) do | |
DatabaseCleaner.strategy = :truncation | |
DatabaseCleaner.orm = "mongoid" | |
end | |
config.before(:each) do | |
DatabaseCleaner.clean | |
end | |
RUBY | |
end | |
# remove either possible occurrence of "require rails/test_unit/railtie" | |
gsub_file 'config/application.rb', /require 'rails\/test_unit\/railtie'/, '# require "rails/test_unit/railtie"' | |
gsub_file 'config/application.rb', /require "rails\/test_unit\/railtie"/, '# require "rails/test_unit/railtie"' | |
# configure RSpec to use matchers from the mongoid-rspec gem | |
create_file 'spec/support/mongoid.rb' do | |
<<-RUBY | |
RSpec.configure do |config| | |
config.include Mongoid::Matchers | |
end | |
RUBY | |
end | |
end | |
if recipes.include? 'devise' | |
# add Devise test helpers | |
create_file 'spec/support/devise.rb' do | |
<<-RUBY | |
RSpec.configure do |config| | |
config.include Devise::TestHelpers, :type => :controller | |
end | |
RUBY | |
end | |
end | |
end | |
end | |
# >---------------------------------[ guard ]---------------------------------< | |
@current_recipe = "guard" | |
@before_configs["guard"].call if @before_configs["guard"] | |
say_recipe 'guard' | |
config = {} | |
config['guard'] = multiple_choice("Would you like to use Guard to automate your workflow?", [["No", false], ["Guard default configuration", "standard"], ["Guard with LiveReload", "LiveReload"]]) if true && true unless config.key?('guard') | |
@configs[@current_recipe] = config | |
case config['guard'] | |
when 'no' | |
recipes.delete('guard') | |
say_wizard "Guard recipe skipped." | |
when 'standard' | |
# do nothing | |
when 'LiveReload' | |
recipes << 'guard-LiveReload' | |
else | |
recipes.delete('guard') | |
say_wizard "Guard recipe skipped." | |
end | |
if recipes.include? 'guard' | |
gem 'guard', '>= 0.6.2', :group => :development | |
prepend_file 'Gemfile' do <<-RUBY | |
require 'rbconfig' | |
HOST_OS = RbConfig::CONFIG['host_os'] | |
RUBY | |
end | |
append_file 'Gemfile' do <<-RUBY | |
# need newline here! | |
case HOST_OS | |
when /darwin/i | |
gem 'rb-fsevent', :group => :development | |
gem 'growl', :group => :development | |
when /linux/i | |
gem 'libnotify', :group => :development | |
gem 'rb-inotify', :group => :development | |
when /mswin|windows/i | |
gem 'rb-fchange', :group => :development | |
gem 'win32console', :group => :development | |
gem 'rb-notifu', :group => :development | |
end | |
RUBY | |
end | |
def guards | |
@guards ||= [] | |
end | |
def guard(name, version = nil) | |
args = [] | |
if version | |
args << version | |
end | |
args << { :group => :development } | |
gem "guard-#{name}", *args | |
guards << name | |
end | |
guard 'bundler', '>= 0.1.3' | |
guard 'pow', '>= 1.0.0' | |
if recipes.include? 'guard-LiveReload' | |
guard 'livereload', '>= 0.3.0' | |
end | |
if recipes.include? 'rspec' | |
guard 'rspec', '>= 0.4.3' | |
end | |
if recipes.include? 'cucumber' | |
guard 'cucumber', '>= 0.6.1' | |
end | |
after_bundler do | |
guards.each do |name| | |
run "guard init #{name}" | |
end | |
end | |
else | |
recipes.delete 'guard' | |
end | |
# >-------------------------------[ OmniAuth ]--------------------------------< | |
@current_recipe = "omniauth" | |
@before_configs["omniauth"].call if @before_configs["omniauth"] | |
say_recipe 'OmniAuth' | |
config = {} | |
config['omniauth'] = yes_wizard?("Would you like to use OmniAuth for authentication?") if true && true unless config.key?('omniauth') | |
#config['provider'] = multiple_choice("Which service provider will you use?", [["Twitter", "twitter"], ["Facebook", "facebook"], ["Weibo", "weibo"], ["Google", "google"], ["QQ", "qq_connect"]]) if true && true unless config.key?('provider') | |
@configs[@current_recipe] = config | |
# Application template recipe for the rails_apps_composer. Check for a newer version here: | |
# https://github.com/RailsApps/rails_apps_composer/blob/master/recipes/omniauth.rb | |
if config['omniauth'] | |
gem 'omniauth', '>= 1.1.0' | |
gem 'omniauth-twitter' | |
gem 'omniauth-facebook' | |
gem 'omniauth-weibo-oauth2' | |
gem 'omniauth-google-oauth2' | |
gem 'omniauth-qq-connect' | |
else | |
recipes.delete('omniauth') | |
end | |
if config['omniauth'] | |
after_bundler do | |
say_wizard "OmniAuth recipe running 'after bundler'" | |
# Don't use single-quote-style-heredoc: we want interpolation. | |
create_file 'config/initializers/omniauth.rb' do <<-RUBY | |
Rails.application.config.middleware.use OmniAuth::Builder do | |
provider :qq_connect, "key", "secret" | |
provider :twitter, "key", "secret" | |
provider :facebook, "key", "secret" | |
provider :weibo, "key", "secret" | |
provider :google_oauth2, "key", "secret" | |
end | |
RUBY | |
end | |
# add routes | |
route "match '/auth/failure' => 'sessions#failure'" | |
route "match '/signout' => 'sessions#destroy', :as => :signout" | |
route "match '/signin' => 'sessions#new', :as => :signin" | |
route "match '/auth/:provider/callback' => 'sessions#create'" | |
route "resources :users, :only => [ :show, :edit, :update ]" | |
# add a user model (unless another recipe did so already) | |
unless recipes.include? 'add_user' | |
generate(:model, "user provider:string uid:string name:string email:string") | |
gsub_file 'app/models/user.rb', /\bend\s*\Z/ do | |
<<-RUBY | |
attr_accessible :provider, :uid, :name, :email | |
end | |
RUBY | |
end | |
end | |
# modify the user model | |
inject_into_file 'app/models/user.rb', :before => 'end' do <<-RUBY | |
def self.create_with_omniauth(auth) | |
create! do |user| | |
user.provider = auth['provider'] | |
user.uid = auth['uid'] | |
if auth['info'] | |
user.name = auth['info']['name'] || "" | |
user.email = auth['info']['email'] || "" | |
end | |
end | |
end | |
RUBY | |
end | |
# We have to use single-quote-style-heredoc to avoid interpolation. | |
create_file 'app/controllers/sessions_controller.rb' do <<-'RUBY' | |
class SessionsController < ApplicationController | |
def create | |
auth = request.env["omniauth.auth"] | |
user = User.where(:provider => auth['provider'], | |
:uid => auth['uid']).first || User.create_with_omniauth(auth) | |
session[:user_id] = user.id | |
redirect_to root_url, :notice => 'Signed in!' | |
end | |
def destroy | |
reset_session | |
redirect_to root_url, :notice => 'Signed out!' | |
end | |
def failure | |
redirect_to root_url, :alert => "Authentication error: #{params[:message].humanize}" | |
end | |
end | |
RUBY | |
end | |
# Don't use single-quote-style-heredoc: we want interpolation. | |
inject_into_class 'app/controllers/sessions_controller.rb', 'SessionsController' do <<-RUBY | |
def new | |
redirect_to '/auth/#{config['provider']}' | |
end | |
RUBY | |
end | |
inject_into_file 'app/controllers/application_controller.rb', :before => 'end' do <<-RUBY | |
helper_method :current_user | |
helper_method :user_signed_in? | |
helper_method :correct_user? | |
private | |
def current_user | |
begin | |
@current_user ||= User.find(session[:user_id]) if session[:user_id] | |
rescue Mongoid::Errors::DocumentNotFound | |
nil | |
end | |
end | |
def user_signed_in? | |
return true if current_user | |
end | |
def correct_user? | |
@user = User.find(params[:id]) | |
unless current_user == @user | |
redirect_to root_url, :alert => "Access denied." | |
end | |
end | |
def authenticate_user! | |
if !current_user | |
redirect_to root_url, :alert => 'You need to sign in for access to this page.' | |
end | |
end | |
RUBY | |
end | |
end | |
after_everything do | |
say_wizard "OmniAuth recipe running 'after everything'" | |
if recipes.include? 'rspec' | |
say_wizard "Copying RSpec files from the rails3-mongoid-omniauth examples" | |
begin | |
# copy all the RSpec specs files from the rails3-mongoid-omniauth example app | |
# spec_helper | |
remove_file 'spec/spec_helper.rb' | |
create_file 'spec/spec_helper.rb' do | |
<<-RUBY | |
ENV["RAILS_ENV"] ||= 'test' | |
require File.expand_path("../../config/environment", __FILE__) | |
require 'rspec/rails' | |
require 'rspec/autorun' | |
require 'factory_girl' | |
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} | |
RSpec.configure do |config| | |
config.include FactoryGirl::Syntax::Methods | |
config.infer_base_class_for_anonymous_controllers = false | |
end | |
RUBY | |
end | |
empty_directory 'spec/routing' | |
# factories | |
remove_file 'spec/factories/users.rb' | |
# controllers | |
remove_file 'spec/controllers/home_controller_spec.rb' | |
remove_file 'spec/controllers/users_controller_spec.rb' | |
# models | |
remove_file 'spec/models/user_spec.rb' | |
get 'https://raw.github.com/RailsApps/rails3-mongoid-omniauth/master/spec/models/user_spec.rb', 'spec/models/user_spec.rb' | |
rescue OpenURI::HTTPError | |
say_wizard "Unable to obtain RSpec example files from the repo" | |
end | |
end | |
end | |
end | |
# >-------------------------------[ HomePage ]--------------------------------< | |
@current_recipe = "home_page" | |
@before_configs["home_page"].call if @before_configs["home_page"] | |
say_recipe 'HomePage' | |
@configs[@current_recipe] = config | |
# Application template recipe for the rails_apps_composer. Check for a newer version here: | |
# https://github.com/RailsApps/rails_apps_composer/blob/master/recipes/home_page.rb | |
after_bundler do | |
say_wizard "HomePage recipe running 'after bundler'" | |
# remove the default home page | |
remove_file 'public/index.html' | |
# create a home controller and view | |
generate(:controller, "home index") | |
# set up a simple home page (with placeholder content) | |
if recipes.include? 'haml' | |
remove_file 'app/views/home/index.html.haml' | |
# There is Haml code in this script. Changing the indentation is perilous between HAMLs. | |
# We have to use single-quote-style-heredoc to avoid interpolation. | |
create_file 'app/views/home/index.html.haml' do | |
<<-'HAML' | |
%h3 Home | |
HAML | |
end | |
elsif recipes.include? 'slim' | |
# skip | |
else | |
remove_file 'app/views/home/index.html.erb' | |
create_file 'app/views/home/index.html.erb' do | |
<<-ERB | |
<h3>Home</h3> | |
ERB | |
end | |
end | |
# set routes | |
gsub_file 'config/routes.rb', /get \"home\/index\"/, 'root :to => "home#index"' | |
if recipes.include? 'devise' | |
inject_into_file 'config/routes.rb', :before => " root :to" do | |
<<-RUBY | |
authenticated :user do | |
root :to => 'home#index' | |
end | |
\n | |
RUBY | |
end | |
end | |
end | |
# >--------------------------------[ Cleanup ]--------------------------------< | |
@current_recipe = "cleanup" | |
@before_configs["cleanup"].call if @before_configs["cleanup"] | |
say_recipe 'Cleanup' | |
@configs[@current_recipe] = config | |
# Application template recipe for the rails_apps_composer. Check for a newer version here: | |
# https://github.com/RailsApps/rails_apps_composer/blob/master/recipes/cleanup.rb | |
after_bundler do | |
say_wizard "Cleanup recipe running 'after bundler'" | |
# remove unnecessary files | |
%w{ | |
README.rdoc | |
doc/README_FOR_APP | |
public/index.html | |
app/assets/images/rails.png | |
}.each { |file| remove_file file } | |
# remove commented lines and multiple blank lines from Gemfile | |
# thanks to https://github.com/perfectline/template-bucket/blob/master/cleanup.rb | |
gsub_file 'Gemfile', /#.*\n/, "\n" | |
gsub_file 'Gemfile', /\n^\s*\n/, "\n" | |
# remove commented lines and multiple blank lines from config/routes.rb | |
gsub_file 'config/routes.rb', / #.*\n/, "\n" | |
gsub_file 'config/routes.rb', /\n^\s*\n/, "\n" | |
# add locate info into application.rb | |
inject_into_file 'config/application.rb', :after => "Rails::Application\n" do | |
<<-RUBY | |
config.time_zone = 'Beijing' | |
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**' ,'*.{rb,yml}').to_s] | |
config.i18n.default_locale = "zh-CN" | |
Time::DATE_FORMATS.merge!(:default => "%Y/%m/%d %H:%M:%S", :ymd => "%Y/%m/%d") | |
\n | |
RUBY | |
end | |
# add localize file | |
get "https://raw.github.com/svenfuchs/rails-i18n/master/rails/locale/zh-CN.yml", "config/locales/zh-CN.yml" | |
end | |
# >----------------------------------[ Git ]----------------------------------< | |
@current_recipe = "git" | |
@before_configs["git"].call if @before_configs["git"] | |
say_recipe 'Git' | |
@configs[@current_recipe] = config | |
# Application template recipe for the rails_apps_composer. Check for a newer version here: | |
# https://github.com/RailsApps/rails_apps_composer/blob/master/recipes/git.rb | |
after_everything do | |
say_wizard "Git recipe running 'after everything'" | |
# Git should ignore some files | |
remove_file '.gitignore' | |
get "https://raw.github.com/RailsApps/rails3-application-templates/master/files/gitignore.txt", ".gitignore" | |
if recipes.include? 'omniauth' | |
append_file '.gitignore' do <<-TXT | |
# keep OmniAuth service provider secrets out of the Git repo | |
config/initializers/omniauth.rb | |
TXT | |
end | |
end | |
# Initialize new Git repo | |
git :init | |
git :add => '.' | |
git :commit => "-aqm 'new Rails app generated by Rails Apps Composer gem'" | |
# Create a git branch | |
git :checkout => ' -b working_branch' | |
git :add => '.' | |
git :commit => "-m 'Initial commit of working_branch'" | |
git :checkout => 'master' | |
end | |
@current_recipe = nil | |
# >-----------------------------[ Run Bundler ]-------------------------------< | |
say_wizard "Running 'bundle install'. This will take a while." | |
run 'bundle install' | |
run 'bundle update' | |
say_wizard "Running 'after bundler' callbacks." | |
require 'bundler/setup' | |
@after_blocks.each{|b| config = @configs[b[0]] || {}; @current_recipe = b[0]; b[1].call} | |
@current_recipe = nil | |
say_wizard "Running 'after everything' callbacks." | |
@after_everything_blocks.each{|b| config = @configs[b[0]] || {}; @current_recipe = b[0]; b[1].call} | |
@current_recipe = nil | |
say_wizard "Finished running the rails_apps_composer app template." | |
say_wizard "Your new Rails app is ready." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment