#! /usr/bin/env ruby # script to automate creation of new sinatra project require 'ostruct' require 'optparse' require 'fileutils' require 'colorize' class OptionParser def self.parse(args) # The options specified on the command line will be collected in *options*. # We set the default value here options = OpenStruct.new options.project_name = nil opts = OptionParser.new do |opts| opts.banner = "Usage: dindi [options]" opts.separator " " opts.separator "Specific options:" opts.on("-n", "--name PROJECT_NAME", "Specify your project name PROJECT_NAME that will be created") do |lib| options.project_name = lib end opts.on("-r", "--ruby RUBY_VERSION", "Set RUBY_VERSION to 1.9.1 for compatibility mode") do |ver| options.ruby_version = ver end # No argument, shows at tail. This will print an options summary. # Try it and see! opts.on_tail("-h", "--help", "Show this message") do puts opts exit! end end opts.parse!(args) options rescue Exception => e if e.message.match(/invalid option/i) or e.message.match(/missing argument/i) puts "ERROR: #{e.message}".red puts "" puts opts end exit end end # make sure ARGV has values if ARGV.size == 0 puts "ERROR: Parameters needed. Run with -h to view options".red exit end # parse option from command line options = OptionParser.parse(ARGV) # make sure project name is valid if options.project_name.nil? puts "ERROR: PROJECT_NAME is needed. Run with -h to view options" exit end # make sure ruby version is valid if options.ruby_version.nil? options.ruby_version = "1.9.2" else options.ruby_version = "1.9.1" end project_absolute_dir = FileUtils.pwd + "/" + options.project_name # create default directories # lib, log, public, push, routes, tmp, views %w(tmp log public push views routes extlibs models helpers).each do |dir| FileUtils.mkdir_p(project_absolute_dir + "/" + dir) end if options.ruby_version == "1.9.2" #================= # create Gemfile #================= gemfile_contents = <<-gemfile source "http://rubygems.org" gem "sinatra" gem "mysql2" gem "haml" gem "activesupport" gem "activerecord" gem "json" gem "pony" gem "compass" gemfile File.open("#{project_absolute_dir}/Gemfile", "w") do |file| file.puts gemfile_contents end #================= # create config.ru #================= config_ru_contents = <<-config_ru $: << "." # we use bundler require 'bundler/setup' # modular sinatra app require 'sinatra/base' # gems %w(logger json haml csv digest date time active_support pony).each {|lib| require lib} # load db config and models require 'models' # extra library Dir.glob("./extlibs/*.rb").each {|extlib| require extlib} # helpers Dir.glob("./helpers/*.rb").each {|helper| require helper} # controllers Dir.glob("./routes/*.rb").each {|route| require route} # app file require '#{options.project_name}' # custom app logger different from sintra logging $APP_LOG = ::Logger.new("log/#{options.project_name}.log") # app name $APP_NAME = "#{options.project_name.gsub(/(?:^|_)(.)/) { $1.upcase }}" class Sinatra::Base # helpers include DebugOn # set sinatra's variables set :root, File.dirname(__FILE__) set :environment, :production enable :sessions, :logging, :dump_errors, :show_exceptions disable :run, :reload end # app routes App = Rack::Builder.app do # routes # use Cms run #{options.project_name.gsub(/(?:^|_)(.)/) { $1.upcase }} end # finally run App config_ru File.open("#{project_absolute_dir}/config.ru", "w") do |file| file.puts config_ru_contents end #==================== # create database.yml #==================== database_yml_contents = <<-database_yml login: &login adapter: mysql2 username: root password: password host: localhost timezone: SGT reconnect: true production: <<: *login database: #{options.project_name} encoding: utf8 database_yml File.open("#{project_absolute_dir}/database.yml", "w") do |file| file.puts database_yml_contents end #======================= # create models.rb #======================= models_rb_contents = <<-models_rb require 'mysql2' require 'active_record' config = YAML.load_file('database.yml') ActiveRecord::Base.establish_connection(config["production"]) Dir.glob("#{project_absolute_dir}/models/*.rb").each {|model| require model} models_rb File.open("#{project_absolute_dir}/models.rb", "w") do |file| file.puts models_rb_contents end else #================= # create Gemfile.191 #================= gemfile191_contents = <<-gemfile191 source "http://rubygems.org" gem "rack", "1.2.2" gem "sinatra", "1.2.6" gem "haml" gem "activesupport", "=2.3.14" gem "activerecord", "=2.3.14" gem "json" gem "pony" gem "compass" gemfile191 File.open("#{project_absolute_dir}/Gemfile", "w") do |file| file.puts gemfile191_contents end #================= # create config.ru #================= config_ru_contents = <<-config_ru $: << "." # we use bundler require 'bundler/setup' # modular sinatra app require 'sinatra/base' # gems %w(logger json haml csv digest date time activesupport pony).each {|lib| require lib} # load db config and models require 'models' # extra library Dir.glob("./extlibs/*.rb").each {|extlib| require extlib} # helpers Dir.glob("./helpers/*.rb").each {|helper| require helper} # controllers Dir.glob("./routes/*.rb").each {|route| require route} # app file require '#{options.project_name}' # custom app logger different from sinatra logging $APP_LOG = ::Logger.new("log/#{options.project_name}.log") # app name $APP_NAME = "#{options.project_name.gsub(/(?:^|_)(.)/) { $1.upcase }}" class Sinatra::Base # helpers include DebugOn # set sinatra's variables set :root, File.dirname(__FILE__) set :environment, :production enable :sessions, :logging, :dump_errors, :show_exceptions disable :run, :reload end # app routes App = Rack::Builder.app do # routes # use Cms run #{options.project_name.gsub(/(?:^|_)(.)/) { $1.upcase }} end # finally run App config_ru File.open("#{project_absolute_dir}/config.ru", "w") do |file| file.puts config_ru_contents end #==================== # create database.yml #==================== database_yml_contents = <<-database_yml login: &login adapter: mysql username: root password: password host: localhost timezone: SGT reconnect: true production: <<: *login database: #{options.project_name} encoding: utf8 database_yml File.open("#{project_absolute_dir}/database.yml", "w") do |file| file.puts database_yml_contents end #======================= # create models.rb #======================= models_rb_contents = <<-models_rb require 'activerecord' config = YAML.load_file('database.yml') ActiveRecord::Base.establish_connection(config["production"]) Dir.glob("#{project_absolute_dir}/models/*.rb").each {|model| require model} models_rb File.open("#{project_absolute_dir}/models.rb", "w") do |file| file.puts models_rb_contents end end #================== # create helpers.rb #================== helpers_rb_contents = <<-helpers_rb module DebugOn def debug_on logger.info("===== START =====> #{Time.now.strftime("%d/%m/%Y %H:%M %p")}") logger.info(request.url) logger.info("Params:") params.each do |key, value| logger.info("\#{key} => \#{value}") end end def app_debug_on $APP_LOG.info("===== START =====> #{Time.now.strftime("%d/%m/%Y %H:%M %p")}") $APP_LOG.info(request.url) $APP_LOG.info("Params:") params.each do |key, value| $APP_LOG.info("\#{key} => \#{value}") end end def app_logger(text) $APP_LOG.info(text) end end helpers_rb File.open("#{project_absolute_dir}/helpers/debug_on.rb", "w") do |file| file.puts helpers_rb_contents end #======================= # create project_name.rb #======================= project_name_rb_contents = <<-project_name_rb class #{options.project_name.gsub(/(?:^|_)(.)/) { $1.upcase }} < Sinatra::Base # index get '/' do '#{options.project_name}' end # docs get '/docs' do @page_title = "Docs" haml :docs end end project_name_rb File.open("#{project_absolute_dir}/#{options.project_name}.rb", "w") do |file| file.puts project_name_rb_contents end #======================= # create docs.haml #======================= docs_haml_contents = <<-docs_haml %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :summary => "API Docs"} %caption %em API Docs %thead %tr %th.span-4 URL %th.span-4.last Description %tfoot %tr %td{:colspan => "2"} Change http://servername with the correct address %tbody %tr %td http://servername %td (GET) Returns app name docs_haml File.open("#{project_absolute_dir}/views/docs.haml", "w") do |file| file.puts docs_haml_contents end # Completion puts "Your project folder #{options.project_name} was successfully created".green puts "Running 'bundle install --path vendor/bundle' ......." bundler_result = system("cd #{project_absolute_dir}; bundle install --path vendor/bundle") if bundler_result puts "passed".green + " bundler install" else puts "failed".red + " bundler install" end