lib/csd.rb in csd-0.1.18 vs lib/csd.rb in csd-0.2.0

- old
+ new

@@ -1,6 +1,7 @@ #-- encoding: UTF-8 +require 'net/http' # Loading all files in the subdirectory `csdĀ“ Dir[File.join(File.dirname(__FILE__), 'csd', '*.rb')].sort.each { |path| require "csd/#{File.basename(path, '.rb')}" } # The CSD namespace is given to the entire gem. @@ -15,30 +16,66 @@ # This method "runs" the whole CSD gem, so to speak. # def bootstrap(options={}) @executable = options[:executable] Options.parse! + respond_to_internal_ai_options respond_to_incomplete_arguments - UI.debug "#{self}.bootstrap initializes the task #{Options.action.enquote} of the application #{Applications.current.name.to_s.enquote} now" - Applications.current.instance.send("#{Options.action}".to_sym) + UI.debug "#{self}.bootstrap initializes the task #{Options.action.to_s.enquote if Options.action} of the application #{Applications.current.name.to_s.enquote if Applications.current} now" + Applications.current.instance.send("#{Options.action}".to_sym) if Applications.current end private - + + def respond_to_internal_ai_options + if !Applications.current and ARGV.include?('update') + update_ai_using_rubygems + elsif !Applications.current and ARGV.include?('edge') + update_ai_to_cutting_edge + end + end + + # Updating the AI + # + def update_ai_using_rubygems + UI.info "Updating the AI to the newest version".green.bold + Cmd.run "sudo gem update csd --no-ri --no-rdoc", :announce_pwd => false, :verbose => true + exit! + end + + # This method is used to conveniently update the AI without officially publishing it on RubyGems. + # This can be handy when testing many things on many machines at the same time :) + # + def update_ai_to_cutting_edge + UI.info "Updating the AI to the cutting-edge experimental version".green.bold + # Create a temporary working directory + Path.edge_tmp = Dir.mktmpdir + Path.edge_file = File.join(Path.edge_tmp, 'edge.gem') + # Retrieve list of possible locations for edge versions + # Note that you can just modify that list to add your own locations + # You can modify the list at http://github.com/csd/csd/downloads + # Note that the Amazon G3 cache used by Github takes about 12 hours to refresh the file, though! + for location in Net::HTTP.get_response(URI.parse('http://cloud.github.com/downloads/csd/csd/edge.txt')).body.split.each do + # See if there is a downloadable edge version at this location. If not, move on to the next location + next unless Cmd.download(location, Path.edge_file).success? + # If the download was successful here, let's update the AI from that downloaded gem-file and exit + updated = Cmd.run("sudo gem install #{Path.edge_file} --no-ri --no-rdoc", :announce_pwd => false, :verbose => true).success? + break + end + UI.info "Currently there is no edge version published.".green.bold unless updated + # Cleaning up the temporary directory + FileUtils.rm_r Path.edge_tmp + exit! + end + # This method check the arguments the user has provided and terminates the AI with # some helpful message if the arguments are invalid. # def respond_to_incomplete_arguments - if !Applications.current and ARGV.include?('update') - # Updating the AI - UI.info "Updating the AI to the newest version".green.bold - Cmd.run "sudo gem update csd --no-ri --no-rdoc", :announce_pwd => false, :verbose => true - exit # The only smooth status code 0 exit in this whole application :) - else - choose_application unless Applications.current - choose_action unless Options.valid_action? - end + choose_application unless Applications.current + choose_action unless Options.valid_action? + choose_scope if Options.scope and not Options.valid_scope? end # This methods lists all available applications # def choose_application @@ -51,11 +88,10 @@ Applications.all { |app| opts.list_item(app.name, app.description) } UI.info opts.help end UI.separator UI.info ' For more information type: '.green.bold + "#{executable} [APPLICATION NAME]".cyan.bold + " Example: #{executable} minisip".dark - #UI.info ' For example: '.green.bold + "#{executable} minisip".cyan.bold UI.separator UI.warn "You did not specify a valid application name." raise Error::Argument::NoApplication end @@ -63,22 +99,45 @@ # def choose_action UI.separator UI.info " Automated Installer assistance for #{Applications.current.human}".green.bold UI.separator - UI.info " The AI can assist you with the following tasks regarding #{Applications.current.human}: " + UI.info " The AI can assist you with the following tasks regarding #{Applications.current.human}:" OptionParser.new do |opts| opts.banner = '' actions = Applications.current.actions['public'] actions << Applications.current.actions['developer'] if Options.developer actions.flatten.each { |action| opts.list_item(action.keys.first, action.values.first) } UI.info opts.help end UI.separator - UI.info ' To execute a task: '.green.bold + "#{executable} [TASK] #{Applications.current.name}".cyan.bold + " Example: #{executable} compile minisip".dark - UI.info ' For more details: '.green.bold + "#{executable} help [TASK] #{Applications.current.name}".cyan.bold + " Example: #{executable} help compile minisip".dark + example_action = Options.actions_names.empty? ? 'install' : Options.actions_names.first + UI.info ' To execute a task: '.green.bold + "#{executable} [TASK] #{Applications.current.name}".cyan.bold + " Example: #{executable} #{example_action} #{Applications.current.name}".dark + UI.info ' For more details: '.green.bold + "#{executable} help [TASK] #{Applications.current.name}".cyan.bold + " Example: #{executable} help #{example_action} #{Applications.current.name}".dark UI.separator UI.warn "You did not specify a valid task name." + raise Error::Argument::NoAction + end + + # This methods lists all available scopes for a specific application and action + # + def choose_scope + UI.separator + UI.info " Automated Installer assistance to #{Options.action} #{Applications.current.human}".green.bold + UI.separator + UI.info " The AI can #{Options.action} the following #{Applications.current.human} components:" + OptionParser.new do |opts| + opts.banner = '' + scopes = Applications.current.scopes(Options.action) + scopes.flatten.each { |scope| opts.list_item(scope.keys.first, scope.values.first) } + UI.info opts.help + end + UI.separator + example_scope = Options.scopes_names.empty? ? 'myscope' : Options.scopes_names.first + UI.info ' To choose all components: '.green.bold + "#{executable} #{Options.action} #{Applications.current.name}".cyan.bold + " Example: #{executable} #{Options.action} #{Applications.current.name}".dark + UI.info ' To choose one component: '.green.bold + "#{executable} #{Options.action} #{Applications.current.name} [COMPONENT]".cyan.bold + " Example: #{executable} #{Options.action} #{Applications.current.name} #{example_scope}".dark + UI.separator + UI.warn "You did not specify a valid scope." raise Error::Argument::NoAction end end end