require 'thor' require 'susanoo/generators' require 'susanoo/irb' module Susanoo module CLI class Project < Thor include ::Thor::Actions package_name 'Susanoo' map 's' => :server map 'g' => :generate map 'r' => :run_in map 'd' => :destroy map 'b' => :build map 'c' => :console # Set the project root def self.root=(path) @@root = path Susanoo::Project.path = path end # Set source paths for current generator def self.source_root "#{@@root}/src" end desc 'generate GENERATOR [options]', 'Run the given generator' def generate(generator_name = nil, *options) generator = get_the_generator_class generator_name # Run the generator with given options generator.start(options, behavior: :invoke, destination_root: Susanoo::Project.path) end desc 'destroy GENERATOR [options]', 'Destroy the given generator' def destroy(generator_name = nil, *options) generator = get_the_generator_class generator_name generator.start(options, behavior: :revoke, destination_root: Susanoo::Project.path) end method_option :debug, default: true method_option :built, default: false desc 'server', 'Run development server.' def server(port = 3000) project_root = Susanoo::Project.path if options[:built] unless File.directory? File.join(project_root, 'www') error "'www' directory is not present. Build you app first." return end app = Rack::Directory.new File.join(project_root, 'www') else require File.join(project_root, 'config/routes') # Set global debug flag Susanoo::Project.debug = options[:debug] app = ROUTER end Rack::Server.start(app: app, server: :thin, Port: port, debug: options[:debug]) end desc 'build', 'Build the application.' def build project_root = Susanoo::Project.path require File.join(project_root, 'config/routes') router = ROUTER.instance_variable_get('@router') build_dir = File.join(project_root, 'www') # setup build directory remove_file build_dir if File.exist? build_dir # Create the www directory if there isn't # WWW directory will be the build directory # which will contains the static files. # # NOTE: cordova only uses this directory # and we can't change it as far as I know empty_directory build_dir router.routes.each do |route| controller = route.dest if controller.respond_to? :build say_status 'build', "Controller: #{controller.__getobj__.class}" controller.build(self, route.dup) else say_status 'warning', "#{controller.__getobj__.class.to_s}' does not have 'build' method.", :yellow end end end desc 'run PLATFORM', 'Run application on PLATFORM.' def run_in(platform = :android) # Build the project first build inside Susanoo::Project.path do system "cordova run #{platform.to_s}" end end desc 'console', 'Run pry in environment of `Susanoo`. ' def console project_root = Susanoo::Project.path require File.join(project_root, 'config/routes') IRB.start_session(binding) end private # Private --------------------------- def get_the_generator_class(generator_name) # Print the generators list and exit if generator_name.nil? print_generator_list return end # Try to load and get the generator Class begin klass = generator_name.downcase.camelize generator = Susanoo::Generators.const_get(klass) rescue NameError say_status 'Error', "Generator `#{generator_name}` not found.", :red exit 1 end generator end def print_generator_list say 'Available generators:' say '---------------------------------------------------' Susanoo::Generators.constants.each do |g| generator = Susanoo::Generators.const_get(g) if generator.respond_to?(:global_generator?) && \ !generator.global_generator? generator_name = generator.to_s.split('::').last.underscore say "#{generator_name}\t\t #{generator.desc}\n" end end end end end end