Skip to content

Instantly share code, notes, and snippets.

@kmckelvin
Forked from jeriko/gist:1865932
Created February 20, 2012 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmckelvin/1871125 to your computer and use it in GitHub Desktop.
Save kmckelvin/1871125 to your computer and use it in GitHub Desktop.
KICKSTART v1
class AppBuilder < Rails::AppBuilder
include Thor::Actions
include Thor::Shell
# Express app templating for Rails
# ------------------------------------
# USAGE:
# 1. Add gems to `gem_dependencies`
# 2. Methods listed in SCRIPTS will be run after bundling, so make sure they each have a declaration
# 3. run: `rails new app_name --builder=path/to/builder.rb` (URI's work here too)
# 4. ???
# 5. PROFIT!
# This method will be run as soon as the builder takes control
def init
say 'Code monkey ready to work!', :green
@use_thin = yes?('Use thin-rails as the default server?')
@use_slim = yes?('Swap out ERB with SLIM?')
@use_bootstrap = yes?('Install twitter_bootstrap?')
if @use_bootstrap
@use_bootstrap_responsive = yes?('Install responsive twitter_bootstrap?')
end
@use_chosen = yes?('Install jQuery-chosen?')
end
# Add your gem dependencies here
def gem_dependencies
# thin
@generator.gem 'thin-rails' if @use_thin
# slim
@generator.gem 'slim-rails' if @use_slim
# inherited_resources
@generator.gem 'inherited_resources'
# simple_form
@generator.gem 'simple_form'
@generator.gem 'country_select'
# compass-sass + bootstrap
@generator.gem_group :assets do
gem 'therubyracer'
gem 'compass-rails'
gem 'compass_twitter_bootstrap'
end
# test framework
@generator.gem_group :test, :development do
gem 'rspec-rails'
gem 'factory_girl_rails'
# TODO the rest
end
# chosen
@generator.gem 'chosen-rails' if @use_chosen
end
# Add any script declarations here, and make sure you build their corresponding methods
SCRIPTS = [
:spec, :sass, :coffeescript,
:bootstrap, :chosen, :css_utils, # asset plugins
:simple_form, :app_index_slim, # views
:rvm_gemset, # rvm
:file_cleanup, # general
:git_init # git
]
def spec
generate 'rspec:install'
end
def sass
# sets up app/assets/stylesheets/application.css.sass as required, with hooks for `manifest` and `import`s
css_asset_path = File.join %w(app assets stylesheets application.css)
@generator.remove_file(css_asset_path)
@sass_asset_path = File.join %w(app assets stylesheets application.css.sass)
@generator.create_file @sass_asset_path, <<-SASS
// MANIFEST: start
// MANIFEST: end
// IMPORTS: start
// IMPORTS: end
SASS
sass_add_manifest 'require_self'
sass_add_import 'compass'
end
def coffeescript
# sets up app/assets/javascripts/application.js.coffee as required, with hooks for `manifest` and `jquery onready`
js_asset_path = File.join %w(app assets javascripts application.js)
@generator.remove_file(js_asset_path)
@coffee_asset_path = File.join %w(app assets javascripts application.js.coffee)
@generator.create_file @coffee_asset_path, <<-COFFEE
// MANIFEST: start
// MANIFEST: end
$(document).ready ->
# ONREADY: start
# ONREADY: end
COFFEE
coffee_add_manifest require: 'jquery'
coffee_add_manifest require: 'jquery_ujs'
coffee_add_manifest 'require_tree .'
end
def bootstrap
return unless @use_bootstrap
sass_add_import 'compass_twitter_bootstrap'
sass_add_import 'compass_twitter_bootstrap_responsive'
# TODO bootstrap js imports...
end
def chosen
return unless @use_chosen
sass_add_manifest require: 'chosen'
coffee_add_manifest require: 'chosen-jquery'
coffee_add_ready "$('.chzn-select').chosen();"
end
def css_utils
# TODO sticky_footer etc.
end
def simple_form
generate "simple_form:install #{'--bootstrap' if @use_bootstrap}"
end
def app_index_slim
return unless @use_slim
# sets up app/views/layouts/index.html.slim as required
erb_index_path = File.join %w(app views layouts application.html.erb)
@generator.remove_file(erb_index_path)
slim_index_path = File.join %w(app views layouts application.html.slim)
@generator.create_file slim_index_path,
<<-SLIM
doctype 5
html
head
title #{app_name}
= stylesheet_link_tag 'application', :media => 'all'
= javascript_include_tag 'application'
= csrf_meta_tags
body class='\#{controller_name}'
= yield
SLIM
end
# TODO nifty generators
# TODO nifty config
# TODO carrierwave
# TODO airbrake
# TODO rails-best-practices (and the other outputter gem for development)
# TODO newrelic etc.
# TODO jquery shims
def rvm_gemset
# TODO
end
def file_cleanup
@generator.remove_file File.join %w(public index.html)
@generator.remove_file File.join %w(app assets images rails.png)
@generator.remove_file File.join %w(README.rdoc)
# remove the finder-tags in application.js.coffee
@generator.gsub_file(@coffee_asset_path, '// MANIFEST: start', '')
@generator.gsub_file(@coffee_asset_path, '// MANIFEST: end', '')
@generator.gsub_file(@coffee_asset_path, ' # ONREADY: start', '')
@generator.gsub_file(@coffee_asset_path, ' # ONREADY: end', '')
# remove the finder-tags in application.css.sass
@generator.gsub_file(@sass_asset_path, '// MANIFEST: start', '')
@generator.gsub_file(@sass_asset_path, '// MANIFEST: end', '')
@generator.gsub_file(@sass_asset_path, '// IMPORTS: start', '')
@generator.gsub_file(@sass_asset_path, '// IMPORTS: end', '')
end
def git_init
git :init
git add: '.'
git commit: "-m \"AppBuilder: #{app_name}\""
end
# ---------------------------------------------------
# - v You can safely ignore below this line v -
# ---------------------------------------------------
def gemfile
# `gemfile` is the first method called on Rails::AppBuilder, so let's hook into the process for config
init
# invoke default behaviour via `super`
# alternatively, use `template 'Gemfile'`, but let's not step on toes
super
# add dependencies to Gemfile
say 'Adding gem dependencies to Gemfile', :yellow
gem_dependencies
# we need dependencies installed right away, so their generators can be run BEFORE
# the scheduled run of bundler (at end of app generation)
# This dirty hack will have to do until I can figure out how to hook in commands AFTER bundler actually runs
say 'Running bundler', :yellow
run_bundle
# stop bundler running in future:
@generator.options = @generator.options.dup
@generator.options[:skip_bundle] = true
@generator.options.freeze
end
def test
return
# TODO
# skips test framework, but we can probably just bastardize the options in the same way as with :skip_bundle
# either make `test` build the actual directories etc., or use a script
# either way, this method is stupid.
end
def leftovers
SCRIPTS.each { |g|
say "Script: #{g}", :red
send(g)
}
say "Finished generating #{app_name}!", :green
say 'Saving Daniel time testing...', :blue
generate "scaffold people name dob:date"
rake "db:migrate"
say "She's all yours, sparky!\n\n", :green
end
# ASSET PIPELINE HELPERS:
def add_manifest(path, directive)
r = directive.is_a?(String) ? directive : "require #{directive.delete(:require)}"
@generator.inject_into_file path, before: '// MANIFEST: end' do
"//= #{r}\n"
end
end
def sass_add_manifest(directive)
add_manifest(@sass_asset_path, directive)
end
def coffee_add_manifest(directive)
add_manifest(@coffee_asset_path, directive)
end
def sass_add_import(i)
@generator.inject_into_file @sass_asset_path, before: '// IMPORTS: end' do
"@import '#{i}'\n"
end
end
def coffee_add_ready(js)
@generator.inject_into_file @coffee_asset_path, before: ' # ONREADY: end' do
" #{js}\n"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment