#!/usr/bin/env ruby $0="Plezi Builder" # count lines of code with: ^[ \t]*[\w\d\"\(\{\@\[\]\}\)\:\'\.\*\&]+.*$ require 'irb' require 'securerandom' ########## # this is the template writer # # you can update it by aliasing the old initialize and writing adding to it: # # if defined? BUILDING_PLEZI_TEMPLATE # class AppTemplate # alias :my_new_gem_old_init :initialize # def initialize # # start with the old initialize, to set the template up # my_new_gem_old_init appname # # add your gem to the gemfile # app_tree["Gemfile"] << "\n# feed GEMNAME to plezi" # app_tree["Gemfile"] << "\ngem 'GEMNAME'" # # make sure your folder exists, but don't overwrite!!! # # if you overwrite!!! you might destroy other gems additions. # app_tree["lib"] ||= {} # app_tree["MY_SPECIAL_GEM"] ||= {} # # once your folder exists, create your file # app_tree["lib]["MY_SPECIAL_GEM"]["filename.rb"] = "# code goes here..." # app_tree["file_without_folder.rb"] ||= "# more code goes here..." # end # end # end # class AppTemplate def initialize @end_comments = [] @app_tree ||= {} end def app_tree @app_tree ||= {} end def build_mini require 'plezi/version' @app_tree["#{ARGV[1]}"] ||= IO.read( ::File.expand_path(File.join("..", "..", "resources" ,"mini_exec.rb"), __FILE__)).gsub('appname', ARGV[1]) @app_tree["#{ARGV[1]}.rb"] ||= IO.read( ::File.expand_path(File.join("..", "..", "resources" ,"mini_app.rb"), __FILE__)).gsub('appname', ARGV[1]).gsub('appsecret', "#{ARGV[1]}_#{SecureRandom.hex}") app_tree["Procfile"] ||= "" app_tree["Procfile"] << "\nweb: bundle exec ruby ./#{ARGV[1]} -p $PORT\n" app_tree["Gemfile"] ||= '' app_tree["Gemfile"] << "source 'https://rubygems.org'\n\n####################\n# core gems\n\n# include the basic plezi framework and server\ngem 'plezi', '~> #{Plezi::VERSION}'\n" app_tree["Gemfile"] << "\n\n\nruby '#{RUBY_VERSION}'\n" app_tree["templates"] ||= {} app_tree["templates"]["404.html.erb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.erb"), __FILE__)) app_tree["templates"]["500.html.erb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.erb"), __FILE__)) app_tree["templates"]["welcome.html.erb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"mini_welcome_page.html"), __FILE__)).gsub('appname', ARGV[1]) app_tree["assets"] ||= {} app_tree["assets"]["websocket.js"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"websockets.js"), __FILE__)).gsub('appname', ARGV[1]) finalize end def build require 'plezi/version' # plezi run script @app_tree["#{ARGV[1]}"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"code.rb"), __FILE__) # set up application files app_tree["app"] ||= {} app_tree["app"]["controllers"] ||= {} app_tree["app"]["controllers"]["sample_controller.rb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"controller.rb"), __FILE__)) app_tree["app"]["models"] ||= {} app_tree["app"]["views"] ||= {} # set up templates for status error codes app_tree["app"]["views"]["404.html"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.html"), __FILE__)) app_tree["app"]["views"]["500.html"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.html"), __FILE__)) app_tree["app"]["views"]["404.html.erb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.erb"), __FILE__)) app_tree["app"]["views"]["500.html.erb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.erb"), __FILE__)) app_tree["app"]["views"]["404.html.slim"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.slim"), __FILE__)) app_tree["app"]["views"]["500.html.slim"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.slim"), __FILE__)) app_tree["app"]["views"]["404.html.haml"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.haml"), __FILE__)) app_tree["app"]["views"]["500.html.haml"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.haml"), __FILE__)) # set up the assets folder app_tree["assets"] ||= {} app_tree["assets"]["stylesheets"] ||= {} app_tree["assets"]["javascripts"] ||= {} app_tree["assets"]["javascripts"]["websocket.js"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"websockets.js"), __FILE__)).gsub('appname', ARGV[1]) app_tree["assets"]["welcome.html"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"welcome_page.html"), __FILE__)).gsub('appname', ARGV[1]) # app core files. app_tree["environment.rb"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"environment.rb"), __FILE__) app_tree["routes.rb"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"routes.rb"), __FILE__) app_tree["rakefile"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"rakefile"), __FILE__) app_tree["Procfile"] ||= "" app_tree["Procfile"] << "\nweb: bundle exec ruby ./#{ARGV[1]} -p $PORT\n" app_tree["Gemfile"] ||= '' app_tree["Gemfile"] << "source 'https://rubygems.org'\n\n####################\n# core gems\n\n# include the basic plezi framework and server\ngem 'plezi', '~> #{Plezi::VERSION}'\n" app_tree["Gemfile"] << IO.read( ::File.expand_path(File.join("..", "..", "resources" ,"Gemfile"), __FILE__)) app_tree["Gemfile"] << "\n\n\nruby '#{RUBY_VERSION}'\n" # set up config files app_tree["config"] ||= {} app_tree["config"]["oauth.rb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"oauth_config.rb"), __FILE__)) app_tree["config"]["active_record.rb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"db_ac_config.rb"), __FILE__)) app_tree["config"]["sequel.rb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"db_sequel_config.rb"), __FILE__)) app_tree["config"]["datamapper.rb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"db_dm_config.rb"), __FILE__)) app_tree["config"]["haml.rb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"haml_config.rb"), __FILE__)) app_tree["config"]["slim.rb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"slim_config.rb"), __FILE__)) app_tree["config"]["i18n.rb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"i18n_config.rb"), __FILE__)) app_tree["config"]["redis.rb"] ||= (IO.read(::File.expand_path(File.join("..", "..", "resources" ,"redis_config.rb"), __FILE__))).gsub('appsecret', "#{ARGV[1]}_#{SecureRandom.hex}") #set up database stub folders app_tree["db"] ||= {} app_tree["db"]["migrate"] ||= {} app_tree["db"]["fixtures"] ||= {} app_tree["db"]["config.yml"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"database.yml"), __FILE__)) #set up the extras folder, to be filled with future goodies. # app_tree["extras"] ||= {} # app_tree["extras"]["config.ru"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"config.ru"), __FILE__) #set up I18n stub app_tree["locales"] ||= {} app_tree["locales"]["en.yml"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"en.yml"), __FILE__) # create library, log and tmp folders app_tree["logs"] ||= {} app_tree["lib"] ||= {} app_tree["tmp"] ||= {} # set up a public folder for static file service app_tree["public"] ||= {} app_tree["public"]["assets"] ||= {} app_tree["public"]["assets"]["stylesheets"] ||= {} app_tree["public"]["assets"]["javascripts"] ||= {} app_tree["public"]["images"] ||= {} finalize end def finalize begin Dir.mkdir ARGV[1] puts "created the #{ARGV[1]} application directory.".green rescue Exception => e puts "the #{ARGV[1]} application directory exists - trying to rebuild (no overwrite).".pink end Dir.chdir ARGV[1] puts "starting to write template data...".red puts "" write_files app_tree File.chmod 0775, "#{ARGV[1]}" puts "tried to update execution permissions. this is system dependent and might have failed.".pink puts "use: chmod +x ./#{ARGV[1]} to set execution permissions on Unix machines." puts "" puts "done." puts "\n#{@end_comments.join("\n")}" unless @end_comments.empty? puts "" puts "please change directory into the app directory: cd #{ARGV[1]}" puts "" puts "run the #{ARGV[1]} app using: ./#{ARGV[1]} or using: plezi s" puts "" end def write_files files, parent = "." if files.is_a? Hash files.each do |k, v| if v.is_a? Hash begin Dir.mkdir k puts " created #{parent}/#{k}".green rescue Exception => e puts " exists #{parent}/#{k}".red end Dir.chdir k write_files v, (parent + "/" + k) Dir.chdir ".." elsif v.is_a? String if ::File.exists? k if false #%w{Gemfile rakefile.rb}.include? k # old = IO.read k # old = (old.lines.map {|l| "\##{l}"}).join # IO.write k, "#####################\n#\n# OLD DATA COMMENTED OUT - PLEASE REVIEW\n#\n##{old}\n#{v}" # puts " #{parent}/#{k} WAS OVERWRITTEN, old data was preserved by comenting it out.".pink # puts " #{parent}/#{k} PLEASE REVIEW.".pink # @end_comments << "#{parent}/#{k} WAS OVERWRITTEN, old data was preserved by comenting it out. PLEASE REVIEW." else puts " EXISTS(!) #{parent}/#{k}".red end else IO.write k, v puts " wrote #{parent}/#{k}".yellow end end end end end end ###################################################################### # tweek the string class for termial coloring options class String # colorization def colorize(color_code) "\e[#{color_code}m#{self}\e[0m" end def red colorize(31) end def green colorize(32) end def yellow colorize(33) end def pink colorize(35) end end ###################################################################### ###################################################################### ## ## Start the Build script ## ###################################################################### ###################################################################### # update with http://ruby-doc.org/stdlib-2.2.0/libdoc/optparse/rdoc/OptionParser.html # require 'optparser' if ARGV[0] == 'new' || ARGV[0] == 'n' || ARGV[0] == "force" || ARGV[0] == 'mini' || ARGV[0] == 'm' ######### ## set up building environment NO_PLEZI_AUTO_START = true ARGV[1] = ARGV[1].gsub /[^a-zA-Z0-9]/, '_' if Dir.exists?(ARGV[1]) && ARGV[0] != "force" puts "" puts "WARNING: app/folder alread exists, use `plezi fource #{ARGV[1]}` to attempt rebuild (no files will be overwritten).".red puts "" exit end if Dir.exists?(ARGV[1]) && ARGV[0] == "force" Dir.chdir ARGV[1] require ::File.expand_path(::Dir["."][0], ( ARGV[1] + ".rb") ) Dir.chdir '..' end # building template = AppTemplate.new (ARGV[0] == 'mini' || ARGV[0] == 'm' ) ? template.build_mini : template.build elsif ARGV[0] == 'server' || ARGV[0] == 'start' || ARGV[0] == 's' ARGV.shift load File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) rescue load( File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last ) ) ) elsif ARGV[0] == 'console' || ARGV[0] == 'c' NO_PLEZI_AUTO_START ||= true load File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) rescue load( File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) ) ARGV.clear IRB.setup nil IRB.conf[:MAIN_CONTEXT] = IRB::Irb.new.context require 'irb/ext/multi-irb' IRB.irb nil, self else puts "" puts "Plezi fast web app starter.".pink puts "use: plezi new appname" puts "or: plezi new appname with template-gem-to-put-in another-template-gem-to-put" puts "==============================".green puts "new app options:".pink puts "option description".yellow puts "new creates a new application called ." puts "n alias for new." puts "mini creates a new mini-application called ." puts "m alias for mini." puts "starting up an app:".pink puts "start attempts to run the app. accepts any parameters the app supports." puts "s alias for start/server." puts "start console innsead of services:".pink puts "console runs the app. accepts any parameters the app supports." puts "c alias for start/server." puts "==============================".green puts "" puts "Run the app using the app's script with an optional: -p {port number}. i.e." puts " cd ./appname".pink puts " ./appname -p 8080".pink puts "" end