Geminstaller C0 Coverage Information - RCov

spec/fixture/rubygems_dist/rubygems-trunk/lib/rubygems/command.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
spec/fixture/rubygems_dist/rubygems-trunk/lib/rubygems/command.rb 526 275
85.74%
74.18%

Key

Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.

Coverage Details

1 #--
2 # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
3 # All rights reserved.
4 # See LICENSE.txt for permissions.
5 #++
6 
7 require 'optparse'
8 require 'rubygems/user_interaction'
9 
10 ##
11 # Base class for all Gem commands.  When creating a new gem command, define
12 # #new, #execute, #arguments, #defaults_str, #description and #usage
13 # (as appropriate).  See the above mentioned methods for details.
14 #
15 # A very good example to look at is Gem::Commands::ContentsCommand
16 
17 class Gem::Command
18 
19   include Gem::UserInteraction
20 
21   ##
22   # The name of the command.
23 
24   attr_reader :command
25 
26   ##
27   # The options for the command.
28 
29   attr_reader :options
30 
31   ##
32   # The default options for the command.
33 
34   attr_accessor :defaults
35 
36   ##
37   # The name of the command for command-line invocation.
38 
39   attr_accessor :program_name
40 
41   ##
42   # A short description of the command.
43 
44   attr_accessor :summary
45 
46   ##
47   # Arguments used when building gems
48 
49   def self.build_args
50     @build_args ||= []
51   end
52 
53   def self.build_args=(value)
54     @build_args = value
55   end
56 
57   def self.common_options
58     @common_options ||= []
59   end
60 
61   def self.add_common_option(*args, &handler)
62     Gem::Command.common_options << [args, handler]
63   end
64 
65   def self.extra_args
66     @extra_args ||= []
67   end
68 
69   def self.extra_args=(value)
70     case value
71     when Array
72       @extra_args = value
73     when String
74       @extra_args = value.split
75     end
76   end
77 
78   ##
79   # Return an array of extra arguments for the command.  The extra arguments
80   # come from the gem configuration file read at program startup.
81 
82   def self.specific_extra_args(cmd)
83     specific_extra_args_hash[cmd]
84   end
85 
86   ##
87   # Add a list of extra arguments for the given command.  +args+ may be an
88   # array or a string to be split on white space.
89 
90   def self.add_specific_extra_args(cmd,args)
91     args = args.split(/\s+/) if args.kind_of? String
92     specific_extra_args_hash[cmd] = args
93   end
94 
95   ##
96   # Accessor for the specific extra args hash (self initializing).
97 
98   def self.specific_extra_args_hash
99     @specific_extra_args_hash ||= Hash.new do |h,k|
100       h[k] = Array.new
101     end
102   end
103 
104   ##
105   # Initializes a generic gem command named +command+.  +summary+ is a short
106   # description displayed in `gem help commands`.  +defaults+ are the default
107   # options.  Defaults should be mirrored in #defaults_str, unless there are
108   # none.
109   #
110   # When defining a new command subclass, use add_option to add command-line
111   # switches.
112   #
113   # Unhandled arguments (gem names, files, etc.) are left in
114   # <tt>options[:args]</tt>.
115 
116   def initialize(command, summary=nil, defaults={})
117     @command = command
118     @summary = summary
119     @program_name = "gem #{command}"
120     @defaults = defaults
121     @options = defaults.dup
122     @option_groups = Hash.new { |h,k| h[k] = [] }
123     @parser = nil
124     @when_invoked = nil
125   end
126 
127   ##
128   # True if +long+ begins with the characters from +short+.
129 
130   def begins?(long, short)
131     return false if short.nil?
132     long[0, short.length] == short
133   end
134 
135   ##
136   # Override to provide command handling.
137   #
138   # #options will be filled in with your parsed options, unparsed options will
139   # be left in <tt>options[:args]</tt>.
140   #
141   # See also: #get_all_gem_names, #get_one_gem_name,
142   # #get_one_optional_argument
143 
144   def execute
145     raise Gem::Exception, "generic command has no actions"
146   end
147 
148   ##
149   #
150   # Display to the user that a gem couldn't be found and reasons why
151   def show_lookup_failure(gem_name, version, errors=nil)
152     if errors and !errors.empty?
153       alert_error "Could not find a valid gem '#{gem_name}' (#{version}), here is why:"
154       errors.each { |x| say "          #{x.wordy}" }
155     else
156       alert_error "Could not find a valid gem '#{gem_name}' (#{version}) in any repository"
157     end
158   end
159 
160   ##
161   # Get all gem names from the command line.
162 
163   def get_all_gem_names
164     args = options[:args]
165 
166     if args.nil? or args.empty? then
167       raise Gem::CommandLineError,
168             "Please specify at least one gem name (e.g. gem build GEMNAME)"
169     end
170 
171     gem_names = args.select { |arg| arg !~ /^-/ }
172   end
173 
174   ##
175   # Get a single gem name from the command line.  Fail if there is no gem name
176   # or if there is more than one gem name given.
177 
178   def get_one_gem_name
179     args = options[:args]
180 
181     if args.nil? or args.empty? then
182       raise Gem::CommandLineError,
183             "Please specify a gem name on the command line (e.g. gem build GEMNAME)"
184     end
185 
186     if args.size > 1 then
187       raise Gem::CommandLineError,
188             "Too many gem names (#{args.join(', ')}); please specify only one"
189     end
190 
191     args.first
192   end
193 
194   ##
195   # Get a single optional argument from the command line.  If more than one
196   # argument is given, return only the first. Return nil if none are given.
197 
198   def get_one_optional_argument
199     args = options[:args] || []
200     args.first
201   end
202 
203   ##
204   # Override to provide details of the arguments a command takes.  It should
205   # return a left-justified string, one argument per line.
206   #
207   # For example:
208   #
209   #   def usage
210   #     "#{program_name} FILE [FILE ...]"
211   #   end
212   #
213   #   def arguments
214   #     "FILE          name of file to find"
215   #   end
216 
217   def arguments
218     ""
219   end
220 
221   ##
222   # Override to display the default values of the command options. (similar to
223   # +arguments+, but displays the default values).
224   #
225   # For example:
226   #
227   #   def defaults_str
228   #     --no-gems-first --no-all
229   #   end
230 
231   def defaults_str
232     ""
233   end
234 
235   ##
236   # Override to display a longer description of what this command does.
237 
238   def description
239     nil
240   end
241 
242   ##
243   # Override to display the usage for an individual gem command.
244   #
245   # The text "[options]" is automatically appended to the usage text.
246 
247   def usage
248     program_name
249   end
250 
251   ##
252   # Display the help message for the command.
253 
254   def show_help
255     parser.program_name = usage
256     say parser
257   end
258 
259   ##
260   # Invoke the command with the given list of arguments.
261 
262   def invoke(*args)
263     handle_options args
264 
265     if options[:help] then
266       show_help
267     elsif @when_invoked then
268       @when_invoked.call options
269     else
270       execute
271     end
272   end
273 
274   ##
275   # Call the given block when invoked.
276   #
277   # Normal command invocations just executes the +execute+ method of the
278   # command.  Specifying an invocation block allows the test methods to
279   # override the normal action of a command to determine that it has been
280   # invoked correctly.
281 
282   def when_invoked(&block)
283     @when_invoked = block
284   end
285 
286   ##
287   # Add a command-line option and handler to the command.
288   #
289   # See OptionParser#make_switch for an explanation of +opts+.
290   #
291   # +handler+ will be called with two values, the value of the argument and
292   # the options hash.
293   #
294   # If the first argument of add_option is a Symbol, it's used to group
295   # options in output.  See `gem help list` for an example.
296 
297   def add_option(*opts, &handler) # :yields: value, options
298     group_name = Symbol === opts.first ? opts.shift : :options
299 
300     @option_groups[group_name] << [opts, handler]
301   end
302 
303   ##
304   # Remove previously defined command-line argument +name+.
305 
306   def remove_option(name)
307     @option_groups.each do |_, option_list|
308       option_list.reject! { |args, _| args.any? { |x| x =~ /^#{name}/ } }
309     end
310   end
311 
312   ##
313   # Merge a set of command options with the set of default options (without
314   # modifying the default option hash).
315 
316   def merge_options(new_options)
317     @options = @defaults.clone
318     new_options.each do |k,v| @options[k] = v end
319   end
320 
321   ##
322   # True if the command handles the given argument list.
323 
324   def handles?(args)
325     begin
326       parser.parse!(args.dup)
327       return true
328     rescue
329       return false
330     end
331   end
332 
333   ##
334   # Handle the given list of arguments by parsing them and recording the
335   # results.
336 
337   def handle_options(args)
338     args = add_extra_args(args)
339     @options = @defaults.clone
340     parser.parse!(args)
341     @options[:args] = args
342   end
343 
344   ##
345   # Adds extra args from ~/.gemrc
346 
347   def add_extra_args(args)
348     result = []
349 
350     s_extra = Gem::Command.specific_extra_args(@command)
351     extra = Gem::Command.extra_args + s_extra
352 
353     until extra.empty? do
354       ex = []
355       ex << extra.shift
356       ex << extra.shift if extra.first.to_s =~ /^[^-]/
357       result << ex if handles?(ex)
358     end
359 
360     result.flatten!
361     result.concat(args)
362     result
363   end
364 
365   private
366 
367   ##
368   # Create on demand parser.
369 
370   def parser
371     create_option_parser if @parser.nil?
372     @parser
373   end
374 
375   def create_option_parser
376     @parser = OptionParser.new
377 
378     @parser.separator nil
379     regular_options = @option_groups.delete :options
380 
381     configure_options "", regular_options
382 
383     @option_groups.sort_by { |n,_| n.to_s }.each do |group_name, option_list|
384       @parser.separator nil
385       configure_options group_name, option_list
386     end
387 
388     @parser.separator nil
389     configure_options "Common", Gem::Command.common_options
390 
391     unless arguments.empty?
392       @parser.separator nil
393       @parser.separator "  Arguments:"
394       arguments.split(/\n/).each do |arg_desc|
395         @parser.separator "    #{arg_desc}"
396       end
397     end
398 
399     @parser.separator nil
400     @parser.separator "  Summary:"
401     wrap(@summary, 80 - 4).split("\n").each do |line|
402       @parser.separator "    #{line.strip}"
403     end
404 
405     if description then
406       formatted = description.split("\n\n").map do |chunk|
407         wrap chunk, 80 - 4
408       end.join "\n"
409 
410       @parser.separator nil
411       @parser.separator "  Description:"
412       formatted.split("\n").each do |line|
413         @parser.separator "    #{line.rstrip}"
414       end
415     end
416 
417     unless defaults_str.empty?
418       @parser.separator nil
419       @parser.separator "  Defaults:"
420       defaults_str.split(/\n/).each do |line|
421         @parser.separator "    #{line}"
422       end
423     end
424   end
425 
426   def configure_options(header, option_list)
427     return if option_list.nil? or option_list.empty?
428 
429     header = header.to_s.empty? ? '' : "#{header} "
430     @parser.separator "  #{header}Options:"
431 
432     option_list.each do |args, handler|
433       dashes = args.select { |arg| arg =~ /^-/ }
434       @parser.on(*args) do |value|
435         handler.call(value, @options)
436       end
437     end
438 
439     @parser.separator ''
440   end
441 
442   ##
443   # Wraps +text+ to +width+
444 
445   def wrap(text, width) # :doc:
446     text.gsub(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n")
447   end
448 
449   # ----------------------------------------------------------------
450   # Add the options common to all commands.
451 
452   add_common_option('-h', '--help',
453                     'Get help on this command') do |value, options|
454     options[:help] = true
455   end
456 
457   add_common_option('-V', '--[no-]verbose',
458                     'Set the verbose level of output') do |value, options|
459     # Set us to "really verbose" so the progress meter works
460     if Gem.configuration.verbose and value then
461       Gem.configuration.verbose = 1
462     else
463       Gem.configuration.verbose = value
464     end
465   end
466 
467   add_common_option('-q', '--quiet', 'Silence commands') do |value, options|
468     Gem.configuration.verbose = false
469   end
470 
471   # Backtrace and config-file are added so they show up in the help
472   # commands.  Both options are actually handled before the other
473   # options get parsed.
474 
475   add_common_option('--config-file FILE',
476                     'Use this config file instead of default') do
477   end
478 
479   add_common_option('--backtrace',
480                     'Show stack backtrace on errors') do
481   end
482 
483   add_common_option('--debug',
484                     'Turn on Ruby debugging') do
485   end
486 
487   # :stopdoc:
488 
489   HELP = <<-HELP
490 RubyGems is a sophisticated package manager for Ruby.  This is a
491 basic help message containing pointers to more information.
492 
493   Usage:
494     gem -h/--help
495     gem -v/--version
496     gem command [arguments...] [options...]
497 
498   Examples:
499     gem install rake
500     gem list --local
501     gem build package.gemspec
502     gem help install
503 
504   Further help:
505     gem help commands            list all 'gem' commands
506     gem help examples            show some examples of usage
507     gem help platforms           show information about platforms
508     gem help <COMMAND>           show help on COMMAND
509                                    (e.g. 'gem help install')
510     gem server                   present a web page at
511                                  http://localhost:8808/
512                                  with info about installed gems
513   Further information:
514     http://rubygems.rubyforge.org
515   HELP
516 
517   # :startdoc:
518 
519 end
520 
521 ##
522 # This is where Commands will be placed in the namespace
523 
524 module Gem::Commands
525 end
526 

Generated on Mon May 10 23:40:28 -0700 2010 with rcov 0.9.8