diff options
Diffstat (limited to 'trunk/lib/rubygems/command.rb')
-rw-r--r-- | trunk/lib/rubygems/command.rb | 406 |
1 files changed, 0 insertions, 406 deletions
diff --git a/trunk/lib/rubygems/command.rb b/trunk/lib/rubygems/command.rb deleted file mode 100644 index 860764e6d5..0000000000 --- a/trunk/lib/rubygems/command.rb +++ /dev/null @@ -1,406 +0,0 @@ -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - -require 'optparse' - -require 'rubygems/user_interaction' - -module Gem - - # Base class for all Gem commands. When creating a new gem command, define - # #arguments, #defaults_str, #description and #usage (as appropriate). - class Command - - include UserInteraction - - # The name of the command. - attr_reader :command - - # The options for the command. - attr_reader :options - - # The default options for the command. - attr_accessor :defaults - - # The name of the command for command-line invocation. - attr_accessor :program_name - - # A short description of the command. - attr_accessor :summary - - # Initializes a generic gem command named +command+. +summary+ is a short - # description displayed in `gem help commands`. +defaults+ are the - # default options. Defaults should be mirrored in #defaults_str, unless - # there are none. - # - # Use add_option to add command-line switches. - def initialize(command, summary=nil, defaults={}) - @command = command - @summary = summary - @program_name = "gem #{command}" - @defaults = defaults - @options = defaults.dup - @option_groups = Hash.new { |h,k| h[k] = [] } - @parser = nil - @when_invoked = nil - end - - # True if +long+ begins with the characters from +short+. - def begins?(long, short) - return false if short.nil? - long[0, short.length] == short - end - - # Override to provide command handling. - def execute - fail "Generic command has no actions" - end - - # Get all gem names from the command line. - def get_all_gem_names - args = options[:args] - - if args.nil? or args.empty? then - raise Gem::CommandLineError, - "Please specify at least one gem name (e.g. gem build GEMNAME)" - end - - gem_names = args.select { |arg| arg !~ /^-/ } - end - - # Get the single gem name from the command line. Fail if there is no gem - # name or if there is more than one gem name given. - def get_one_gem_name - args = options[:args] - - if args.nil? or args.empty? then - raise Gem::CommandLineError, - "Please specify a gem name on the command line (e.g. gem build GEMNAME)" - end - - if args.size > 1 then - raise Gem::CommandLineError, - "Too many gem names (#{args.join(', ')}); please specify only one" - end - - args.first - end - - # Get a single optional argument from the command line. If more than one - # argument is given, return only the first. Return nil if none are given. - def get_one_optional_argument - args = options[:args] || [] - args.first - end - - # Override to provide details of the arguments a command takes. - # It should return a left-justified string, one argument per line. - def arguments - "" - end - - # Override to display the default values of the command - # options. (similar to +arguments+, but displays the default - # values). - def defaults_str - "" - end - - # Override to display a longer description of what this command does. - def description - nil - end - - # Override to display the usage for an individual gem command. - def usage - program_name - end - - # Display the help message for the command. - def show_help - parser.program_name = usage - say parser - end - - # Invoke the command with the given list of arguments. - def invoke(*args) - handle_options(args) - if options[:help] - show_help - elsif @when_invoked - @when_invoked.call(options) - else - execute - end - end - - # Call the given block when invoked. - # - # Normal command invocations just executes the +execute+ method of - # the command. Specifying an invocation block allows the test - # methods to override the normal action of a command to determine - # that it has been invoked correctly. - def when_invoked(&block) - @when_invoked = block - end - - # Add a command-line option and handler to the command. - # - # See OptionParser#make_switch for an explanation of +opts+. - # - # +handler+ will be called with two values, the value of the argument and - # the options hash. - def add_option(*opts, &handler) # :yields: value, options - group_name = Symbol === opts.first ? opts.shift : :options - - @option_groups[group_name] << [opts, handler] - end - - # Remove previously defined command-line argument +name+. - def remove_option(name) - @option_groups.each do |_, option_list| - option_list.reject! { |args, _| args.any? { |x| x =~ /^#{name}/ } } - end - end - - # Merge a set of command options with the set of default options - # (without modifying the default option hash). - def merge_options(new_options) - @options = @defaults.clone - new_options.each do |k,v| @options[k] = v end - end - - # True if the command handles the given argument list. - def handles?(args) - begin - parser.parse!(args.dup) - return true - rescue - return false - end - end - - # Handle the given list of arguments by parsing them and recording - # the results. - def handle_options(args) - args = add_extra_args(args) - @options = @defaults.clone - parser.parse!(args) - @options[:args] = args - end - - def add_extra_args(args) - result = [] - s_extra = Command.specific_extra_args(@command) - extra = Command.extra_args + s_extra - while ! extra.empty? - ex = [] - ex << extra.shift - ex << extra.shift if extra.first.to_s =~ /^[^-]/ - result << ex if handles?(ex) - end - result.flatten! - result.concat(args) - result - end - - private - - # Create on demand parser. - def parser - create_option_parser if @parser.nil? - @parser - end - - def create_option_parser - @parser = OptionParser.new - - @parser.separator("") - regular_options = @option_groups.delete :options - - configure_options "", regular_options - - @option_groups.sort_by { |n,_| n.to_s }.each do |group_name, option_list| - configure_options group_name, option_list - end - - configure_options "Common", Command.common_options - - @parser.separator("") - unless arguments.empty? - @parser.separator(" Arguments:") - arguments.split(/\n/).each do |arg_desc| - @parser.separator(" #{arg_desc}") - end - @parser.separator("") - end - - @parser.separator(" Summary:") - wrap(@summary, 80 - 4).split("\n").each do |line| - @parser.separator(" #{line.strip}") - end - - if description then - formatted = description.split("\n\n").map do |chunk| - wrap(chunk, 80 - 4) - end.join("\n") - - @parser.separator "" - @parser.separator " Description:" - formatted.split("\n").each do |line| - @parser.separator " #{line.rstrip}" - end - end - - unless defaults_str.empty? - @parser.separator("") - @parser.separator(" Defaults:") - defaults_str.split(/\n/).each do |line| - @parser.separator(" #{line}") - end - end - end - - def configure_options(header, option_list) - return if option_list.nil? or option_list.empty? - - header = header.to_s.empty? ? '' : "#{header} " - @parser.separator " #{header}Options:" - - option_list.each do |args, handler| - dashes = args.select { |arg| arg =~ /^-/ } - @parser.on(*args) do |value| - handler.call(value, @options) - end - end - - @parser.separator '' - end - - # Wraps +text+ to +width+ - def wrap(text, width) - text.gsub(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n") - end - - ################################################################## - # Class methods for Command. - class << self - def common_options - @common_options ||= [] - end - - def add_common_option(*args, &handler) - Gem::Command.common_options << [args, handler] - end - - def extra_args - @extra_args ||= [] - end - - def extra_args=(value) - case value - when Array - @extra_args = value - when String - @extra_args = value.split - end - end - - # Return an array of extra arguments for the command. The extra - # arguments come from the gem configuration file read at program - # startup. - def specific_extra_args(cmd) - specific_extra_args_hash[cmd] - end - - # Add a list of extra arguments for the given command. +args+ - # may be an array or a string to be split on white space. - def add_specific_extra_args(cmd,args) - args = args.split(/\s+/) if args.kind_of? String - specific_extra_args_hash[cmd] = args - end - - # Accessor for the specific extra args hash (self initializing). - def specific_extra_args_hash - @specific_extra_args_hash ||= Hash.new do |h,k| - h[k] = Array.new - end - end - end - - # ---------------------------------------------------------------- - # Add the options common to all commands. - - add_common_option('-h', '--help', - 'Get help on this command') do - |value, options| - options[:help] = true - end - - add_common_option('-V', '--[no-]verbose', - 'Set the verbose level of output') do |value, options| - # Set us to "really verbose" so the progress meter works - if Gem.configuration.verbose and value then - Gem.configuration.verbose = 1 - else - Gem.configuration.verbose = value - end - end - - add_common_option('-q', '--quiet', 'Silence commands') do |value, options| - Gem.configuration.verbose = false - end - - # Backtrace and config-file are added so they show up in the help - # commands. Both options are actually handled before the other - # options get parsed. - - add_common_option('--config-file FILE', - "Use this config file instead of default") do - end - - add_common_option('--backtrace', - 'Show stack backtrace on errors') do - end - - add_common_option('--debug', - 'Turn on Ruby debugging') do - end - - # :stopdoc: - HELP = %{ - RubyGems is a sophisticated package manager for Ruby. This is a - basic help message containing pointers to more information. - - Usage: - gem -h/--help - gem -v/--version - gem command [arguments...] [options...] - - Examples: - gem install rake - gem list --local - gem build package.gemspec - gem help install - - Further help: - gem help commands list all 'gem' commands - gem help examples show some examples of usage - gem help platforms show information about platforms - gem help <COMMAND> show help on COMMAND - (e.g. 'gem help install') - Further information: - http://rubygems.rubyforge.org - }.gsub(/^ /, "") - - # :startdoc: - - end # class - - # This is where Commands will be placed in the namespace - module Commands; end - -end |