#!/usr/bin/env ruby require 'flok' require 'thor' require 'fileutils' require 'webrick' require_relative '../spec/lib/helpers.rb' class FlokCLI < Thor desc "new ", "Create a new flok project and/or module, you may supply an absolute path or relative, the last entry in the path will be the module name and folder name of the project" def new path #Name of this project name = File.basename(path) #Get the directory of the given path, if path is only 'foo', then this will go into '.' (nop) Dir.chdir File.dirname(path) do Flok::Project.create name end end desc "build ", "Build the products for a platform" def build platform #Create a products folder if it dosen't already exist Dir.mkdir("./products") unless File.exists?("./products") ENV["PLATFORM"] = platform #Go into the flok gem project local_products_path = File.join(Dir.pwd, "products") Dir.chdir(File.join(File.dirname(__FILE__), "../")) do #1. Use the rake task system('rake build:world') #2. Copy everything in the gems ./flok/products/$PLATFORM -> $PROJECT/products/$PLATFORM FileUtils.cp_r "./products/#{platform}", local_products_path end #3. Build the client's ./app/controllers/*.rb into './products/$PLATFORM/user_compiler.js' controller_glob_path = "#{local_products_path}/#{platform}/glob/controllers.rb" Flok.src_glob("rb", './app/controllers', controller_glob_path) user_compiler_js = Flok::UserCompiler.compile File.read(controller_glob_path) Dir.chdir File.join(local_products_path, platform) do #3. Put user_compiler_js in glob folder File.write "glob/user_compiler.js", user_compiler_js #4. Move application.js to the glob folder FileUtils.cp "application.js", "glob/application.js" FileUtils.rm "application.js" #5. Combine application.js and user_compiler.js.erb File.open "glob/application_user.js.erb", "w" do |f| f.puts File.read("glob/application.js") f.puts File.read("glob/user_compiler.js") end #6. The `erb` files is then sent to `./products/$PLATFORM/glob/application_user.js` with the below `ERB` variables allowable. erb_src = File.read "glob/application_user.js.erb" renderr = ERB.new(erb_src) context = ERBUserApplicationContext.new() new_src = renderr.result(context.get_binding) File.write "application_user.js", new_src end end desc "server", "Monitors for changes within your flok application and triggers an automatic rebuild of ./products/* for a PLATFORM when something in ./app changes" include SpecHelpers #Contains sh2 def server platform File.write "Guardfile", %{ guard :shell, :all_on_start => true do watch %r{^app/.*} do |m| system("#{$0} build #{platform}") res = system("#{$0} build #{platform}"); $stdout.puts "BUILD RAN" end end } #Ensure puts does something because it's on another thread $stdout.sync = true ########################################################################### #We execute two tasks that run at the same time, (1) the webrick hoster #and (2) the guard reloader that triggers build ########################################################################### #1) Launch webrick server server = WEBrick::HTTPServer.new :Port => 9992, :DocumentRoot => "./products/#{platform}", :StartCallback => Proc.new { } server_started = false #2) Wait for initial build to launch (all_on_start) sh2("guard") do |inp, out| loop do res = out.readline if res =~ /BUILD RAN/ #Start server Thread.new { server.start } unless server_started server_started = true puts "BUILD RAN" else $stderr.puts res end end end end #Part of the build command class ERBUserApplicationContext def get_binding return binding end def initialize #Debug / Release @debug = (ENV['FLOK_ENV'] == "DEBUG") @release = (ENV['FLOK_ENV'] == "RELEASE") end end end FlokCLI.start(ARGV)