Created
February 19, 2012 21:37
-
-
Save jeriko/1865932 to your computer and use it in GitHub Desktop.
KICKSTART v1
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
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', git: 'git://github.com/plataformatec/simple_form.git' | |
@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