Class: Amp::Dispatch
Overview
Dispatch
This class handles parsing command-line options, finding commands, and running them.
Class Method Summary collapse
-
.find_ampfile(dir = Dir.pwd) ⇒ String
Gets the path to the Ampfile if there is one.
-
.pick_command(cmd, config) ⇒ Amp::Command
Picks a command from the list of all possible commands, based on a couple simple rules.
-
.run ⇒ Object
This method essentially runs the amp executable.
Class Method Details
.find_ampfile(dir = Dir.pwd) ⇒ String
Gets the path to the Ampfile if there is one.
139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/amp/commands/dispatch.rb', line 139 def self.find_ampfile(dir=Dir.pwd) rock_bottom = false begin rock_bottom = true if dir == "/" ["ampfile","Ampfile","ampfile.rb","Ampfile.rb"].each do |pos| file = File.join(dir, pos) return file if File.exist? file end dir = File.dirname(dir) end until rock_bottom end |
.pick_command(cmd, config) ⇒ Amp::Command
Picks a command from the list of all possible commands, based on a couple simple rules.
-
Look up the command by exact name. If no command is provided, supply “default”.
-
Check for “synonyms” - “remove” is synonym’d as “rm”. This check occurs inside
the call to Amp::Command[].
-
Check to see if there is only 1 command with our “cmd” as the prefix. For example,
if the user inputs "amp stat", and only one command starts with "stat" (ie "status"),
then return that command. If there is more than 1 match, then exit, showing an error
due to the ambiguity.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/amp/commands/dispatch.rb', line 165 def self.pick_command(cmd, config) my_flow = config["amp"]["workflow"] if c = Amp::Command.all_for_workflow(my_flow).keys.map {|k| k.to_s}.abbrev[cmd] Amp::Command.command_for_workflow(c, my_flow) else prefix_list = Amp::Command.all_for_workflow(my_flow).keys.map {|k| k.to_s}.select {|k| k.start_with? cmd.to_s } if prefix_list.size > 1 puts "Ambiguous command: #{cmd}. Could mean: #{prefix_list.join(", ")}" exit(-1) end nil end end |
.run ⇒ Object
This method essentially runs the amp executable. It first parses global options (–config) finds the subcommand (eg add, init, clone), parses the subcommand’s options, merges the two, and then runs the entire thing.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/amp/commands/dispatch.rb', line 17 def self.run # Get the subcommands so we can stop on them sub_commands = Amp::Command.all_commands.keys # Get the global options (everything before the subcommand) global_opts = Trollop:: do "Amp - some more crystal, sir?" version "Amp version #{Amp::VERSION} (#{Amp::VERSION_TITLE})" opt :debug_opts, "Debug the command-line options", :short => "-d", :default => false, :type => :boolean opt :verbose, "Verbose output" opt :profile, "Profile the command being run, running it the given number of times" opt :repository, "The path to the repository to use", :short => "-R", :type => :string, :default => Dir.pwd opt :"pure-ruby", "Use only pure ruby (no C-extensions)" opt :testing, "Running a test. Not for users to use" stop_on_unknown end global_opts = global_opts.first # we don't need the parser here # This loads the built-in ruby profiler - it's extremely slow. Use with care. if global_opts[:profile] require 'profile' end # Never load a C extension if we're in pure-ruby mode. if global_opts[:"pure-ruby"] $USE_RUBY = true end global_config = Amp::AmpConfig.new Amp::UI.config = global_config cmd = ARGV.shift # get the subcommand cmd ||= "default" opts_as_arr = ARGV.dup if global_opts[:debug_opts] global_config["debug", "messages"] = true end unless global_config["amp"]["workflow"] global_config["amp"]["workflow"] = :hg global_config.save! rescue Errno::EACCES end # the options to send to the command cmd_opts = {} # Load the repository #path_to_repo = find_repo(".", cmd_opts) unless global_opts[:repository] path_to_repo = "" if path_to_repo.empty? local_config = global_config else local_config = AmpConfig.new(:parent_config => global_config) local_config.read_file File.join(path_to_repo, ".hg", "hgrc") end begin cmd_opts[:repository] = Repositories.pick(local_config, global_opts[:repository]) rescue unless Command::NO_REPO_ALLOWED[cmd] || Command::MAYBE_REPO_ALLOWED[cmd] raise end end if cmd_opts[:repository].respond_to? :config cmd_opts[:repository].config && local_config = cmd_opts[:repository].config end workflow = local_config["amp"]["workflow"] if File.exists?(File.(File.join(File.dirname(__FILE__), "commands/workflows/#{workflow}/"))) require_dir { "amp/commands/commands/workflows/#{workflow}/**/*.rb" } end user_amprc = File.("~/.amprc") File.exist?(user_amprc) && load(user_amprc) path_to_ampfile = find_ampfile load path_to_ampfile if path_to_ampfile command = pick_command cmd, local_config unless command puts "Invalid command! #{cmd}" exit(-1) end # get the sub-command's options # if there's a conflict, check to see that the newest value isn't nil cmd_opts.merge!(command.) {|k, v1, v2| v2 || v1 } cmd_opts[:global_config] = local_config if global_opts[:debug_opts] require 'yaml' puts "Current directory: #{Dir.pwd}" puts "Global options: \n#{global_opts.inspect.to_yaml}" puts "Subcommand: #{cmd.inspect}" puts "Subcommand options: \n#{cmd_opts.to_yaml}" puts "Remaining arguments: #{ARGV.inspect}" puts "\n" puts "Parsed and merged global config files:" puts local_config.config.to_s puts end # Run that fucker!!! begin full_backtrace_please do command.run cmd_opts, ARGV end rescue AbortError => e puts e.to_s end #Amp::Support::Logger.outdent.info("</#{command.name}>") end |