#!/usr/bin/env ruby module InlineForms require File.join(File.dirname(__FILE__), "../lib/inline_forms/version.rb") require 'rvm' if not RVM.current puts "ruby or rvm not found" exit 2 end # what is this? Signal.trap("INT") { puts; exit } require 'thor' class Creator < Thor include Thor::Actions String.class_eval do def strip_heredoc_with_indent(indent=0) new_indent = ( self.empty? ? 0 : ( scan(/^[ \t]*(?=\S)/).min.size - indent ) ) gsub(/^[ \t]{#{new_indent}}/, '') end end def self.source_root File.dirname(__FILE__)+"/.." end desc "create APP", "create an application with inline_forms v#{VERSION}" DATABASE_OPTIONS = %w(sqlite mysql) method_option :database, :aliases => "-d", :default => DATABASE_OPTIONS.first, :banner => DATABASE_OPTIONS.join('|'), :desc => 'specify development database' method_option :dry, :type => :boolean, :desc => 'dry run. Do not do most things. Only useful for development of inline_forms' method_option :example, :type => :boolean, :desc => 'install the example app. incompatible with --dry and uses sqlite as development database' method_option :email, :aliases => "-e", :default => "admin@example.com", :desc => 'specify admin email' method_option :password, :aliases => "-p", :default => "admin999", :desc => 'specify admin password' def create(app_name) def self.dry_run? options[:dry] end def self.install_example? options[:example] end def self.database DATABASE_OPTIONS.include?(options[:database]) ? options[:database] : 'sqlite' end def self.using_sqlite? database == 'sqlite' end def self.email options[:email] end def self.password options[:password] end if install_example? && dry_run? say "--example and --dry-run can not be used together", :red exit 1 end if install_example? && !using_sqlite? say "--example can only be used with an sqlite development database", :red exit 1 end say "This is a dry run. I hope you know what you are doing...", :red if dry_run? say "Creating #{app_name} with inline_forms v#{VERSION} and development database #{database}...", :green regex = /\A[0-9a-zA-Z][0-9a-zA-Z_-]+[0-9a-zA-Z]\Z/ if ! regex.match(app_name) say "Error: APP must match #{regex.source}", :red exit 1 end if File.exists?(app_name) say "Error: APP exists", :red exit 1 end say "- Generating Rails app '#{app_name}'..." dry_run? ? empty_directory(app_name) : RVM.run("rails new #{app_name}") say "- Creating and trusting .rvmrc..." ruby_version = (%x[rvm current]).gsub(/@.*/,'') create_file "#{app_name}/.rvmrc", "rvm use #{ruby_version.chop}@#{app_name} --create" say ("- " + %x[cd #{app_name} && rvm rvmrc trust .rvmrc]).chop say "- Changing to '#{app_name}' with RVM..." RVM.chdir(app_name) do say "- Working directory is now #{`pwd`}" RVM.use_from_path! '.' rvm_gemset = %x[rvm current] say "- RVM gemset is now #{rvm_gemset}" say "- Recreating Gemfile..." remove_file "#{app_name}/Gemfile" # the one that 'rails new' created create_file "#{app_name}/Gemfile", <<-END_GEMFILE.strip_heredoc_with_indent # generated by inline_forms v#{VERSION} source 'http://rubygems.org' gem 'test-unit' gem 'rails' gem 'rake' gem 'jquery-rails' gem 'capistrano' gem 'will_paginate', :git => 'git://github.com/acesuares/will_paginate.git' gem 'tabs_on_rails', :git => 'git://github.com/acesuares/tabs_on_rails.git', :branch => 'update_remote' gem 'ckeditor', :git => 'git://github.com/acesuares/ckeditor.git', :branch => 'master' gem 'cancan', :git => 'git://github.com/acesuares/cancan.git', :branch => '2.0' gem 'carrierwave' gem 'remotipart', '~> 1.0' gem 'paper_trail' gem 'devise' gem 'inline_forms' gem 'validation_hints' gem 'mini_magick' gem 'jquery_datepicker' gem 'yaml_db' gem 'rails-i18n' gem 'i18n-active_record', :git => 'git://github.com/acesuares/i18n-active_record.git' gem 'unicorn' gem 'rvm' gem 'rvm-capistrano' # Include everything needed to run rake, tests, features, etc. group :development do gem 'sqlite3' gem 'rspec-rails' gem 'shoulda', '>= 0' gem 'bundler' gem 'jeweler' # gem 'rcov', '>= 0' end # these are just for production group :production do gem 'mysql2' gem 'therubyracer' gem 'uglifier' end END_GEMFILE say "- Running bundle..." system "bundle install" unless dry_run? say "- Database setup: creating config/database.yml with development database #{database}" remove_file "#{app_name}/config/database.yml" # the one that 'rails new' created if using_sqlite? create_file "#{app_name}/config/database.yml", <<-END_DATABASEYML.strip_heredoc_with_indent development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 END_DATABASEYML else create_file "#{app_name}/config/database.yml", <<-END_DATABASEYML.strip_heredoc_with_indent development: adapter: mysql2 database: #{app_name}_dev username: #{app_name} password: #{app_name} END_DATABASEYML end append_file "#{app_name}/config/database.yml", <<-END_DATABASEYML.strip_heredoc_with_indent production: adapter: mysql2 database: #{app_name}_p username: #{app_name} password: #{app_name}444 END_DATABASEYML say "- Devise install..." RVM.run "bundle exec rails g devise:install" unless dry_run? say "- Devise User model install with added name and locale field..." RVM.run "bundle exec rails g devise User name:string locale:string" unless dry_run? say "- Replace Devise route and add path_prefix..." gsub_file "#{app_name}/config/routes.rb", /devise_for :users/, "devise_for :users, :path_prefix => 'auth'" insert_into_file "#{app_name}/config/routes.rb", <<-ROUTE.strip_heredoc_with_indent(2), :after => "devise_for :users, :path_prefix => 'auth'\n" resources :users do post 'revert', :on => :member end ROUTE say "- Create User Controller..." create_file "#{app_name}/app/controllers/users_controller.rb", <<-USERS_CONTROLLER.strip_heredoc_with_indent class UsersController < InlineFormsController set_tab :user end USERS_CONTROLLER say "- Recreate User Model..." remove_file "#{app_name}/app/models/user.rb" # the one that 'devise:install' created create_file "#{app_name}/app/models/user.rb", <<-USER_MODEL.strip_heredoc_with_indent class User < ActiveRecord::Base # devise options devise :database_authenticatable # devise :registerable # uncomment this if you want people to be able to register devise :recoverable devise :rememberable devise :trackable devise :validatable # devise :token_authenticatable # devise :confirmable, # devise :lockable # devise :timeoutable # devise :omniauthable # Setup accessible (or protected) attributes for your model attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :locale attr_writer :inline_forms_attribute_list # validations validates :name, :presence => true # pagination attr_reader :per_page @per_page = 7 has_paper_trail def _presentation "\#{name}" end def inline_forms_attribute_list @inline_forms_attribute_list ||= [ [ :name , 'name', :text_field ], [ :email , 'email', :text_field ], [ :password , 'Nieuw wachtwoord', :devise_password_field ], [ :encrypted_password , 'encrypted_password', :info ], [ :reset_password_token , 'reset_password_token', :info ], [ :reset_password_sent_at , 'reset_password_sent_at', :info], [ :remember_created_at , 'remember_created_at', :info ], [ :sign_in_count , 'sign_in_count', :info ], [ :current_sign_in_at , 'current_sign_in_at', :info ], [ :last_sign_in_at , 'last_sign_in_at', :info ], [ :current_sign_in_ip , 'current_sign_in_ip', :info ], [ :last_sign_in_ip , 'last_sign_in_ip', :info ], [ :created_at , 'created_at', :info ], [ :updated_at , 'updated_at', :info ], ] end def self.not_accessible_through_html? false end def self.order_by_clause 'name' end end USER_MODEL say "- Install ckeditor..." RVM.run "bundle exec rails g ckeditor:install" unless dry_run? say "- Create ckeditor config.js" copy_file "lib/app/assets/javascripts/ckeditor/config.js", "#{app_name}/app/assets/javascripts/ckeditor/config.js" say "- Add remotipart to application.js..." create_file "#{app_name}/app/assets/javascripts/application.js", "//= require_tree .\n" if dry_run? insert_into_file "#{app_name}/app/assets/javascripts/application.js", "//= require jquery.remotipart\n", :before => "//= require_tree .\n" say "- Paper_trail install..." RVM.run "bundle exec rails g paper_trail:install" unless dry_run? say "- Generate models and tables and views for translations..." RVM.run 'rails g inline_forms InlineFormsLocale name:string inline_forms_translations:belongs_to _enabled:yes _presentation:\'#{name}\'' RVM.run 'rails g inline_forms InlineFormsKey name:string inline_forms_translations:has_many inline_forms_translations:associated _enabled:yes _presentation:\'#{name}\'' RVM.run 'rails g inline_forms InlineFormsTranslation inline_forms_key:belongs_to inline_forms_locale:dropdown value:text interpolations:text is_proc:boolean _presentation:\'#{value}\'' sleep 1 # to get unique migration number create_file "#{app_name}/db/migrate/" + Time.now.utc.strftime("%Y%m%d%H%M%S") + "_" + "inline_forms_create_view_for_translations.rb", <<-VIEW_MIGRATION.strip_heredoc_with_indent class InlineFormsCreateViewForTranslations < ActiveRecord::Migration def self.up execute 'CREATE VIEW translations AS SELECT L.name AS locale, K.name AS thekey, T.value AS value, T.interpolations AS interpolations, T.is_proc AS is_proc FROM inline_forms_keys K, inline_forms_locales L, inline_forms_translations T WHERE T.inline_forms_key_id = K.id AND T.inline_forms_locale_id = L.id ' end def self.down execute 'DROP VIEW translations' end end VIEW_MIGRATION say "- Migrating Database" RVM.run "bundle exec rake db:migrate" unless (dry_run? || !using_sqlite?) say "- Adding admin user with email: #{email}, password: #{password} to seeds.rb" append_to_file "#{app_name}/db/seeds.rb", "User.new({ :email => '#{email}', :name => 'Admin', :password => '#{password}', :password_confirmation => '#{password}'}).save" say "- Seeding the database" RVM.run "bundle exec rake db:seed" unless (dry_run? || !using_sqlite?) say "- Creating header in app/views/inline_forms/_header.html.erb..." create_file "#{app_name}/app/views/inline_forms/_header.html.erb", <<-END_HEADER.strip_heredoc_with_indent END_HEADER say "- Recreating ApplicationHelper to set application_name and application_title..." remove_file "#{app_name}/app/helpers/application_helper.rb" # the one that 'rails new' created create_file "#{app_name}/app/helpers/application_helper.rb", <<-END_APPHELPER.strip_heredoc_with_indent module ApplicationHelper def application_name '#{app_name}' end def application_title '#{app_name}' end end END_APPHELPER say "- Recreating ApplicationController to add devise, cancan, I18n stuff..." remove_file "#{app_name}/app/controllers/application_controller.rb" # the one that 'rails new' created create_file "#{app_name}/app/controllers/application_controller.rb", <<-END_APPCONTROLLER.strip_heredoc_with_indent class ApplicationController < InlineFormsApplicationController protect_from_forgery # Comment next two lines if you don't want Devise authentication before_filter :authenticate_user! layout 'devise' if :devise_controller? # Comment next 6 lines if you want CanCan authorization enable_authorization :unless => :devise_controller? rescue_from CanCan::Unauthorized do |exception| sign_out :user if user_signed_in? redirect_to new_user_session_path, :alert => exception.message end # Uncomment next line if you want I18n (based on subdomain) # before_filter :set_locale # Uncomment next line and specify default locale # I18n.default_locale = :en # Uncomment next line and specify available locales # I18n.available_locales = [ :en, :nl, :pp ] # Uncomment next nine line if you want locale based on subdomain, like 'it.example.com, de.example.com' # def set_locale # I18n.locale = extract_locale_from_subdomain || I18n.default_locale # end # # def extract_locale_from_subdomain # locale = request.subdomains.first # return nil if locale.nil? # I18n.available_locales.include?(locale.to_sym) ? locale.to_s : nil # end end END_APPCONTROLLER say "- Creating Ability model so that the user with id = 1 can access all..." create_file "#{app_name}/app/models/ability.rb", <<-END_ABILITY.strip_heredoc_with_indent class Ability include CanCan::Ability def initialize(user) # See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities user ||= user.new # guest user if user.id == 1 #quick hack can :access, :all else # put restrictions for other users here end end end END_ABILITY # create environments/production.rb if it's a dry run create_file "#{app_name}/config/environments/production.rb", " # config.assets.precompile += %w( search.js )\nend\n" if dry_run? say "- Injecting precompile assets stuff in environments/production.rb..." insert_into_file "#{app_name}/config/environments/production.rb", " config.assets.precompile += %w(inline_forms_application.js inline_forms_application.css devise.css)\n", :after => " # config.assets.precompile += %w( search.js )\n" say "- Injecting devise mailer stuff in environments/production.rb..." insert_into_file "#{app_name}/config/environments/production.rb", <<-DEVISE_MAILER_STUFF.strip_heredoc_with_indent(2), :before => "end\n" # for devise config.action_mailer.default_url_options = { :protocol => 'https', :host => 'YOURHOSTNAME' } config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { :address => 'YOURMAILSERVER', :enable_starttls_auto => true, :password => 'YOURPASSWORD', :user_name => 'YOURUSERNAME' } DEVISE_MAILER_STUFF say "- Setting config.assets.compile to true in environments/production.rb (needed for ckeditor)..." insert_into_file "#{app_name}/config/environments/production.rb", " config.assets.compile = false\n", :before => "end\n" if dry_run? gsub_file "#{app_name}/config/environments/production.rb", /config.assets.compile = false/, "config.assets.compile = true" say "- Capify..." RVM.run 'capify .' remove_file "#{app_name}/config/deploy.rb" # remove the file capify created! copy_file "lib/generators/templates/deploy.rb", "#{app_name}/config/deploy.rb" say "- Unicorn Config..." copy_file "lib/generators/templates/unicorn.rb", "#{app_name}/config/unicorn.rb" say "- Initializing git..." RVM.run 'git init' create_file "#{app_name}/.gitignore", "/tmp\n" if dry_run? insert_into_file "#{app_name}/.gitignore", <<-GITIGNORE.strip_heredoc_with_indent, :after => "/tmp\n" # netbeans nbproject # remotipart uploads public/uploads GITIGNORE RVM.run 'git add .' RVM.run 'git commit -a -m " * Initial"' if install_example? say "\nInstalling example application..." RVM.run 'rails g inline_forms Picture name:string caption:string image:image_field description:text apartment:belongs_to _presentation:\'#{name}\'' RVM.run 'rails generate uploader Image' RVM.run 'rails g inline_forms Apartment name:string title:string description:text pictures:has_many pictures:associated _enabled:yes _presentation:\'#{name}\'' RVM.run 'bundle exec rake db:migrate' say "\nDone! Now point your browser to http://localhost:3000/apartments !", :yellow say "\nPress ctlr-C to quit...", :yellow RVM.run 'rails s' else say "\nDone! Now make your tables with 'rails g inline_forms ...", :yellow #say "- Don't forget: edit .rvmrc, config/{routes.rb, deploy.rb}, .git/config, delete public/index.html\n" end end end Creator.start end end