rubygems-update 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubygems-update might be problematic. Click here for more details.

Files changed (128) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.autotest +24 -0
  3. data/.document +4 -3
  4. data/ChangeLog +382 -1
  5. data/Manifest.txt +214 -0
  6. data/README +1 -49
  7. data/Rakefile +124 -191
  8. data/bin/gem +1 -4
  9. data/cruise_config.rb +22 -0
  10. data/doc/release_notes/rel_1_3_1.rdoc +3 -3
  11. data/doc/release_notes/rel_1_3_2.rdoc +119 -0
  12. data/lib/gauntlet_rubygems.rb +50 -0
  13. data/lib/rubygems.rb +250 -25
  14. data/lib/rubygems/builder.rb +62 -60
  15. data/lib/rubygems/command.rb +421 -319
  16. data/lib/rubygems/command_manager.rb +153 -125
  17. data/lib/rubygems/commands/check_command.rb +12 -7
  18. data/lib/rubygems/commands/cleanup_command.rb +11 -2
  19. data/lib/rubygems/commands/contents_command.rb +42 -18
  20. data/lib/rubygems/commands/generate_index_command.rb +91 -15
  21. data/lib/rubygems/commands/install_command.rb +33 -47
  22. data/lib/rubygems/commands/query_command.rb +36 -20
  23. data/lib/rubygems/commands/rdoc_command.rb +62 -68
  24. data/lib/rubygems/commands/search_command.rb +26 -32
  25. data/lib/rubygems/commands/setup_command.rb +353 -0
  26. data/lib/rubygems/commands/sources_command.rb +5 -0
  27. data/lib/rubygems/commands/specification_command.rb +23 -3
  28. data/lib/rubygems/commands/uninstall_command.rb +71 -61
  29. data/lib/rubygems/commands/unpack_command.rb +14 -12
  30. data/lib/rubygems/commands/update_command.rb +26 -5
  31. data/lib/rubygems/defaults.rb +16 -3
  32. data/lib/rubygems/dependency.rb +38 -7
  33. data/lib/rubygems/dependency_installer.rb +7 -4
  34. data/lib/rubygems/digest/digest_adapter.rb +42 -33
  35. data/lib/rubygems/digest/sha1.rb +6 -1
  36. data/lib/rubygems/digest/sha2.rb +5 -0
  37. data/lib/rubygems/doc_manager.rb +31 -11
  38. data/lib/rubygems/ext/ext_conf_builder.rb +2 -1
  39. data/lib/rubygems/ext/rake_builder.rb +6 -2
  40. data/lib/rubygems/format.rb +63 -63
  41. data/lib/rubygems/gem_openssl.rb +14 -2
  42. data/lib/rubygems/gem_path_searcher.rb +7 -3
  43. data/lib/rubygems/gem_runner.rb +59 -39
  44. data/lib/rubygems/indexer.rb +450 -109
  45. data/lib/rubygems/install_update_options.rb +13 -1
  46. data/lib/rubygems/installer.rb +25 -22
  47. data/lib/rubygems/local_remote_options.rb +5 -3
  48. data/lib/rubygems/old_format.rb +124 -120
  49. data/lib/rubygems/package/tar_header.rb +25 -3
  50. data/lib/rubygems/package/tar_input.rb +5 -5
  51. data/lib/rubygems/package/tar_output.rb +2 -0
  52. data/lib/rubygems/package/tar_reader.rb +19 -0
  53. data/lib/rubygems/package/tar_reader/entry.rb +43 -0
  54. data/lib/rubygems/package/tar_writer.rb +65 -3
  55. data/lib/rubygems/package_task.rb +117 -0
  56. data/lib/rubygems/platform.rb +12 -8
  57. data/lib/rubygems/remote_fetcher.rb +43 -24
  58. data/lib/rubygems/require_paths_builder.rb +14 -12
  59. data/lib/rubygems/requirement.rb +15 -6
  60. data/lib/rubygems/rubygems_version.rb +14 -1
  61. data/lib/rubygems/source_index.rb +38 -16
  62. data/lib/rubygems/source_info_cache_entry.rb +2 -2
  63. data/lib/rubygems/spec_fetcher.rb +43 -20
  64. data/lib/rubygems/specification.rb +1122 -947
  65. data/lib/rubygems/text.rb +30 -0
  66. data/lib/rubygems/timer.rb +14 -11
  67. data/lib/rubygems/uninstaller.rb +25 -5
  68. data/lib/rubygems/user_interaction.rb +294 -264
  69. data/lib/rubygems/validator.rb +70 -36
  70. data/lib/rubygems/version.rb +97 -33
  71. data/lib/rubygems/version_option.rb +1 -0
  72. data/setup.rb +11 -306
  73. data/test/foo/discover.rb +0 -0
  74. data/test/gem_installer_test_case.rb +22 -11
  75. data/test/gem_package_tar_test_case.rb +0 -14
  76. data/test/gemutilities.rb +89 -8
  77. data/test/mockgemui.rb +2 -1
  78. data/test/rubygems_plugin.rb +16 -0
  79. data/test/test_gem.rb +107 -36
  80. data/test/test_gem_command.rb +3 -13
  81. data/test/test_gem_command_manager.rb +1 -14
  82. data/test/test_gem_commands_cert_command.rb +1 -1
  83. data/test/test_gem_commands_contents_command.rb +63 -0
  84. data/test/test_gem_commands_environment_command.rb +1 -1
  85. data/test/test_gem_commands_generate_index_command.rb +104 -1
  86. data/test/test_gem_commands_install_command.rb +95 -0
  87. data/test/test_gem_commands_pristine_command.rb +3 -3
  88. data/test/test_gem_commands_query_command.rb +46 -0
  89. data/test/test_gem_commands_sources_command.rb +9 -5
  90. data/test/test_gem_commands_specification_command.rb +31 -0
  91. data/test/test_gem_commands_uninstall_command.rb +3 -2
  92. data/test/test_gem_commands_unpack_command.rb +3 -2
  93. data/test/test_gem_commands_update_command.rb +12 -7
  94. data/test/test_gem_dependency.rb +62 -11
  95. data/test/test_gem_dependency_installer.rb +18 -5
  96. data/test/test_gem_dependency_list.rb +6 -6
  97. data/test/test_gem_doc_manager.rb +7 -1
  98. data/test/test_gem_ext_configure_builder.rb +8 -10
  99. data/test/test_gem_ext_ext_conf_builder.rb +14 -8
  100. data/test/test_gem_gem_path_searcher.rb +1 -1
  101. data/test/test_gem_gem_runner.rb +11 -0
  102. data/test/test_gem_indexer.rb +398 -21
  103. data/test/test_gem_install_update_options.rb +20 -6
  104. data/test/test_gem_installer.rb +22 -14
  105. data/test/test_gem_local_remote_options.rb +2 -1
  106. data/test/test_gem_package_tar_header.rb +3 -3
  107. data/test/test_gem_package_tar_input.rb +3 -3
  108. data/test/test_gem_package_tar_output.rb +2 -2
  109. data/test/test_gem_package_task.rb +70 -0
  110. data/test/test_gem_platform.rb +12 -6
  111. data/test/test_gem_remote_fetcher.rb +23 -1
  112. data/test/test_gem_source_index.rb +32 -21
  113. data/test/test_gem_spec_fetcher.rb +77 -5
  114. data/test/test_gem_specification.rb +274 -1
  115. data/test/test_gem_uninstaller.rb +34 -4
  116. data/test/test_gem_version.rb +94 -4
  117. data/test/test_gem_version_option.rb +13 -0
  118. data/test/test_kernel.rb +4 -4
  119. data/util/CL2notes +56 -0
  120. data/util/gem_prelude.rb.template +251 -0
  121. metadata +30 -20
  122. metadata.gz.sig +3 -4
  123. data/TODO +0 -1
  124. data/scripts/buildtests.rb +0 -31
  125. data/scripts/gemdoc.rb +0 -67
  126. data/scripts/runtest.rb +0 -40
  127. data/scripts/specdoc.rb +0 -171
  128. data/scripts/upload_gemdoc.rb +0 -140
@@ -4,81 +4,83 @@
4
4
  # See LICENSE.txt for permissions.
5
5
  #++
6
6
 
7
- module Gem
7
+ ##
8
+ # The Builder class processes RubyGem specification files
9
+ # to produce a .gem file.
8
10
 
11
+ class Gem::Builder
12
+
13
+ include Gem::UserInteraction
9
14
  ##
10
- # The Builder class processes RubyGem specification files
11
- # to produce a .gem file.
15
+ # Constructs a builder instance for the provided specification
12
16
  #
13
- class Builder
14
-
15
- include UserInteraction
16
- ##
17
- # Constructs a builder instance for the provided specification
18
- #
19
- # spec:: [Gem::Specification] The specification instance
20
- #
21
- def initialize(spec)
22
- require "yaml"
23
- require "rubygems/package"
24
- require "rubygems/security"
25
-
26
- @spec = spec
27
- end
17
+ # spec:: [Gem::Specification] The specification instance
28
18
 
29
- ##
30
- # Builds the gem from the specification. Returns the name of the file
31
- # written.
32
- #
33
- def build
34
- @spec.mark_version
35
- @spec.validate
36
- @signer = sign
37
- write_package
38
- say success
39
- @spec.file_name
40
- end
41
-
42
- def success
43
- <<-EOM
19
+ def initialize(spec)
20
+ require "yaml"
21
+ require "rubygems/package"
22
+ require "rubygems/security"
23
+
24
+ @spec = spec
25
+ end
26
+
27
+ ##
28
+ # Builds the gem from the specification. Returns the name of the file
29
+ # written.
30
+
31
+ def build
32
+ @spec.mark_version
33
+ @spec.validate
34
+ @signer = sign
35
+ write_package
36
+ say success
37
+ @spec.file_name
38
+ end
39
+
40
+ def success
41
+ <<-EOM
44
42
  Successfully built RubyGem
45
43
  Name: #{@spec.name}
46
44
  Version: #{@spec.version}
47
45
  File: #{@spec.full_name+'.gem'}
48
46
  EOM
49
- end
47
+ end
50
48
 
51
- private
52
-
53
- def sign
54
- # if the signing key was specified, then load the file, and swap
55
- # to the public key (TODO: we should probably just omit the
56
- # signing key in favor of the signing certificate, but that's for
57
- # the future, also the signature algorithm should be configurable)
58
- signer = nil
59
- if @spec.respond_to?(:signing_key) && @spec.signing_key
60
- signer = Gem::Security::Signer.new(@spec.signing_key, @spec.cert_chain)
61
- @spec.signing_key = nil
62
- @spec.cert_chain = signer.cert_chain.map { |cert| cert.to_s }
63
- end
64
- signer
49
+ private
50
+
51
+ ##
52
+ # If the signing key was specified, then load the file, and swap to the
53
+ # public key (TODO: we should probably just omit the signing key in favor of
54
+ # the signing certificate, but that's for the future, also the signature
55
+ # algorithm should be configurable)
56
+
57
+ def sign
58
+ signer = nil
59
+
60
+ if @spec.respond_to?(:signing_key) and @spec.signing_key then
61
+ signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain
62
+ @spec.signing_key = nil
63
+ @spec.cert_chain = signer.cert_chain.map { |cert| cert.to_s }
65
64
  end
66
65
 
67
- def write_package
68
- open @spec.file_name, 'wb' do |gem_io|
69
- Gem::Package.open gem_io, 'w', @signer do |pkg|
70
- pkg.metadata = @spec.to_yaml
66
+ signer
67
+ end
68
+
69
+ def write_package
70
+ open @spec.file_name, 'wb' do |gem_io|
71
+ Gem::Package.open gem_io, 'w', @signer do |pkg|
72
+ pkg.metadata = @spec.to_yaml
71
73
 
72
- @spec.files.each do |file|
73
- next if File.directory? file
74
+ @spec.files.each do |file|
75
+ next if File.directory? file
76
+ next if file == @spec.file_name # Don't add gem onto itself
74
77
 
75
- stat = File.stat file
76
- mode = stat.mode & 0777
77
- size = stat.size
78
+ stat = File.stat file
79
+ mode = stat.mode & 0777
80
+ size = stat.size
78
81
 
79
- pkg.add_file_simple file, mode, size do |tar_io|
80
- tar_io.write open(file, "rb") { |f| f.read }
81
- end
82
+ pkg.add_file_simple file, mode, size do |tar_io|
83
+ tar_io.write open(file, "rb") { |f| f.read }
82
84
  end
83
85
  end
84
86
  end
@@ -5,402 +5,504 @@
5
5
  #++
6
6
 
7
7
  require 'optparse'
8
-
9
8
  require 'rubygems/user_interaction'
10
9
 
11
- module Gem
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
12
16
 
13
- # Base class for all Gem commands. When creating a new gem command, define
14
- # #arguments, #defaults_str, #description and #usage (as appropriate).
15
- class Command
17
+ class Gem::Command
16
18
 
17
- include UserInteraction
19
+ include Gem::UserInteraction
18
20
 
19
- # The name of the command.
20
- attr_reader :command
21
+ ##
22
+ # The name of the command.
21
23
 
22
- # The options for the command.
23
- attr_reader :options
24
+ attr_reader :command
24
25
 
25
- # The default options for the command.
26
- attr_accessor :defaults
26
+ ##
27
+ # The options for the command.
27
28
 
28
- # The name of the command for command-line invocation.
29
- attr_accessor :program_name
29
+ attr_reader :options
30
30
 
31
- # A short description of the command.
32
- attr_accessor :summary
31
+ ##
32
+ # The default options for the command.
33
33
 
34
- # Initializes a generic gem command named +command+. +summary+ is a short
35
- # description displayed in `gem help commands`. +defaults+ are the
36
- # default options. Defaults should be mirrored in #defaults_str, unless
37
- # there are none.
38
- #
39
- # Use add_option to add command-line switches.
40
- def initialize(command, summary=nil, defaults={})
41
- @command = command
42
- @summary = summary
43
- @program_name = "gem #{command}"
44
- @defaults = defaults
45
- @options = defaults.dup
46
- @option_groups = Hash.new { |h,k| h[k] = [] }
47
- @parser = nil
48
- @when_invoked = nil
49
- end
34
+ attr_accessor :defaults
50
35
 
51
- # True if +long+ begins with the characters from +short+.
52
- def begins?(long, short)
53
- return false if short.nil?
54
- long[0, short.length] == short
55
- end
36
+ ##
37
+ # The name of the command for command-line invocation.
56
38
 
57
- # Override to provide command handling.
58
- def execute
59
- fail "Generic command has no actions"
60
- end
39
+ attr_accessor :program_name
61
40
 
62
- # Get all gem names from the command line.
63
- def get_all_gem_names
64
- args = options[:args]
41
+ ##
42
+ # A short description of the command.
65
43
 
66
- if args.nil? or args.empty? then
67
- raise Gem::CommandLineError,
68
- "Please specify at least one gem name (e.g. gem build GEMNAME)"
69
- end
44
+ attr_accessor :summary
70
45
 
71
- gem_names = args.select { |arg| arg !~ /^-/ }
72
- end
46
+ ##
47
+ # Arguments used when building gems
73
48
 
74
- # Get the single gem name from the command line. Fail if there is no gem
75
- # name or if there is more than one gem name given.
76
- def get_one_gem_name
77
- args = options[:args]
49
+ def self.build_args
50
+ @build_args ||= []
51
+ end
52
+
53
+ def self.build_args=(value)
54
+ @build_args = value
55
+ end
78
56
 
79
- if args.nil? or args.empty? then
80
- raise Gem::CommandLineError,
81
- "Please specify a gem name on the command line (e.g. gem build GEMNAME)"
82
- end
57
+ def self.common_options
58
+ @common_options ||= []
59
+ end
83
60
 
84
- if args.size > 1 then
85
- raise Gem::CommandLineError,
86
- "Too many gem names (#{args.join(', ')}); please specify only one"
87
- end
61
+ def self.add_common_option(*args, &handler)
62
+ Gem::Command.common_options << [args, handler]
63
+ end
88
64
 
89
- args.first
90
- end
65
+ def self.extra_args
66
+ @extra_args ||= []
67
+ end
91
68
 
92
- # Get a single optional argument from the command line. If more than one
93
- # argument is given, return only the first. Return nil if none are given.
94
- def get_one_optional_argument
95
- args = options[:args] || []
96
- args.first
69
+ def self.extra_args=(value)
70
+ case value
71
+ when Array
72
+ @extra_args = value
73
+ when String
74
+ @extra_args = value.split
97
75
  end
76
+ end
98
77
 
99
- # Override to provide details of the arguments a command takes.
100
- # It should return a left-justified string, one argument per line.
101
- def arguments
102
- ""
103
- end
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.
104
81
 
105
- # Override to display the default values of the command
106
- # options. (similar to +arguments+, but displays the default
107
- # values).
108
- def defaults_str
109
- ""
110
- end
82
+ def self.specific_extra_args(cmd)
83
+ specific_extra_args_hash[cmd]
84
+ end
111
85
 
112
- # Override to display a longer description of what this command does.
113
- def description
114
- nil
115
- end
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.
116
89
 
117
- # Override to display the usage for an individual gem command.
118
- def usage
119
- program_name
120
- end
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
121
94
 
122
- # Display the help message for the command.
123
- def show_help
124
- parser.program_name = usage
125
- say parser
126
- end
95
+ ##
96
+ # Accessor for the specific extra args hash (self initializing).
127
97
 
128
- # Invoke the command with the given list of arguments.
129
- def invoke(*args)
130
- handle_options(args)
131
- if options[:help]
132
- show_help
133
- elsif @when_invoked
134
- @when_invoked.call(options)
135
- else
136
- execute
137
- end
98
+ def self.specific_extra_args_hash
99
+ @specific_extra_args_hash ||= Hash.new do |h,k|
100
+ h[k] = Array.new
138
101
  end
139
-
140
- # Call the given block when invoked.
141
- #
142
- # Normal command invocations just executes the +execute+ method of
143
- # the command. Specifying an invocation block allows the test
144
- # methods to override the normal action of a command to determine
145
- # that it has been invoked correctly.
146
- def when_invoked(&block)
147
- @when_invoked = block
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
+ def initialize(command, summary=nil, defaults={})
114
+ @command = command
115
+ @summary = summary
116
+ @program_name = "gem #{command}"
117
+ @defaults = defaults
118
+ @options = defaults.dup
119
+ @option_groups = Hash.new { |h,k| h[k] = [] }
120
+ @parser = nil
121
+ @when_invoked = nil
122
+ end
123
+
124
+ ##
125
+ # True if +long+ begins with the characters from +short+.
126
+
127
+ def begins?(long, short)
128
+ return false if short.nil?
129
+ long[0, short.length] == short
130
+ end
131
+
132
+ ##
133
+ # Override to provide command handling.
134
+ #
135
+ # #options will be filled in with your parsed options, unparsed options will
136
+ # be left in <tt>options[:args]</tt>.
137
+ #
138
+ # See also: #get_all_gem_names, #get_one_gem_name,
139
+ # #get_one_optional_argument
140
+
141
+ def execute
142
+ raise Gem::Exception, "generic command has no actions"
143
+ end
144
+
145
+ ##
146
+ # Get all gem names from the command line.
147
+
148
+ def get_all_gem_names
149
+ args = options[:args]
150
+
151
+ if args.nil? or args.empty? then
152
+ raise Gem::CommandLineError,
153
+ "Please specify at least one gem name (e.g. gem build GEMNAME)"
148
154
  end
149
155
 
150
- # Add a command-line option and handler to the command.
151
- #
152
- # See OptionParser#make_switch for an explanation of +opts+.
153
- #
154
- # +handler+ will be called with two values, the value of the argument and
155
- # the options hash.
156
- def add_option(*opts, &handler) # :yields: value, options
157
- group_name = Symbol === opts.first ? opts.shift : :options
156
+ gem_names = args.select { |arg| arg !~ /^-/ }
157
+ end
158
158
 
159
- @option_groups[group_name] << [opts, handler]
160
- end
159
+ ##
160
+ # Get the single gem name from the command line. Fail if there is no gem
161
+ # name or if there is more than one gem name given.
161
162
 
162
- # Remove previously defined command-line argument +name+.
163
- def remove_option(name)
164
- @option_groups.each do |_, option_list|
165
- option_list.reject! { |args, _| args.any? { |x| x =~ /^#{name}/ } }
166
- end
167
- end
163
+ def get_one_gem_name
164
+ args = options[:args]
168
165
 
169
- # Merge a set of command options with the set of default options
170
- # (without modifying the default option hash).
171
- def merge_options(new_options)
172
- @options = @defaults.clone
173
- new_options.each do |k,v| @options[k] = v end
166
+ if args.nil? or args.empty? then
167
+ raise Gem::CommandLineError,
168
+ "Please specify a gem name on the command line (e.g. gem build GEMNAME)"
174
169
  end
175
170
 
176
- # True if the command handles the given argument list.
177
- def handles?(args)
178
- begin
179
- parser.parse!(args.dup)
180
- return true
181
- rescue
182
- return false
183
- end
171
+ if args.size > 1 then
172
+ raise Gem::CommandLineError,
173
+ "Too many gem names (#{args.join(', ')}); please specify only one"
184
174
  end
185
175
 
186
- # Handle the given list of arguments by parsing them and recording
187
- # the results.
188
- def handle_options(args)
189
- args = add_extra_args(args)
190
- @options = @defaults.clone
191
- parser.parse!(args)
192
- @options[:args] = args
176
+ args.first
177
+ end
178
+
179
+ ##
180
+ # Get a single optional argument from the command line. If more than one
181
+ # argument is given, return only the first. Return nil if none are given.
182
+
183
+ def get_one_optional_argument
184
+ args = options[:args] || []
185
+ args.first
186
+ end
187
+
188
+ ##
189
+ # Override to provide details of the arguments a command takes. It should
190
+ # return a left-justified string, one argument per line.
191
+ #
192
+ # For example:
193
+ #
194
+ # def usage
195
+ # "#{program_name} FILE [FILE ...]"
196
+ # end
197
+ #
198
+ # def arguments
199
+ # "FILE name of file to find"
200
+ # end
201
+
202
+ def arguments
203
+ ""
204
+ end
205
+
206
+ ##
207
+ # Override to display the default values of the command options. (similar to
208
+ # +arguments+, but displays the default values).
209
+ #
210
+ # For example:
211
+ #
212
+ # def defaults_str
213
+ # --no-gems-first --no-all
214
+ # end
215
+
216
+ def defaults_str
217
+ ""
218
+ end
219
+
220
+ ##
221
+ # Override to display a longer description of what this command does.
222
+
223
+ def description
224
+ nil
225
+ end
226
+
227
+ ##
228
+ # Override to display the usage for an individual gem command.
229
+ #
230
+ # The text "[options]" is automatically appended to the usage text.
231
+
232
+ def usage
233
+ program_name
234
+ end
235
+
236
+ ##
237
+ # Display the help message for the command.
238
+
239
+ def show_help
240
+ parser.program_name = usage
241
+ say parser
242
+ end
243
+
244
+ ##
245
+ # Invoke the command with the given list of arguments.
246
+
247
+ def invoke(*args)
248
+ handle_options(args)
249
+ if options[:help]
250
+ show_help
251
+ elsif @when_invoked
252
+ @when_invoked.call(options)
253
+ else
254
+ execute
193
255
  end
194
-
195
- def add_extra_args(args)
196
- result = []
197
- s_extra = Command.specific_extra_args(@command)
198
- extra = Command.extra_args + s_extra
199
- while ! extra.empty?
200
- ex = []
201
- ex << extra.shift
202
- ex << extra.shift if extra.first.to_s =~ /^[^-]/
203
- result << ex if handles?(ex)
204
- end
205
- result.flatten!
206
- result.concat(args)
207
- result
256
+ end
257
+
258
+ ##
259
+ # Call the given block when invoked.
260
+ #
261
+ # Normal command invocations just executes the +execute+ method of the
262
+ # command. Specifying an invocation block allows the test methods to
263
+ # override the normal action of a command to determine that it has been
264
+ # invoked correctly.
265
+
266
+ def when_invoked(&block)
267
+ @when_invoked = block
268
+ end
269
+
270
+ ##
271
+ # Add a command-line option and handler to the command.
272
+ #
273
+ # See OptionParser#make_switch for an explanation of +opts+.
274
+ #
275
+ # +handler+ will be called with two values, the value of the argument and
276
+ # the options hash.
277
+ #
278
+ # If the first argument of +add_option+ is a Symbol, it's used to group
279
+ # options in output. See `gem help list` for an example.
280
+
281
+ def add_option(*opts, &handler) # :yields: value, options
282
+ group_name = Symbol === opts.first ? opts.shift : :options
283
+
284
+ @option_groups[group_name] << [opts, handler]
285
+ end
286
+
287
+ ##
288
+ # Remove previously defined command-line argument +name+.
289
+
290
+ def remove_option(name)
291
+ @option_groups.each do |_, option_list|
292
+ option_list.reject! { |args, _| args.any? { |x| x =~ /^#{name}/ } }
208
293
  end
209
-
210
- private
211
-
212
- # Create on demand parser.
213
- def parser
214
- create_option_parser if @parser.nil?
215
- @parser
294
+ end
295
+
296
+ ##
297
+ # Merge a set of command options with the set of default options (without
298
+ # modifying the default option hash).
299
+
300
+ def merge_options(new_options)
301
+ @options = @defaults.clone
302
+ new_options.each do |k,v| @options[k] = v end
303
+ end
304
+
305
+ ##
306
+ # True if the command handles the given argument list.
307
+
308
+ def handles?(args)
309
+ begin
310
+ parser.parse!(args.dup)
311
+ return true
312
+ rescue
313
+ return false
216
314
  end
315
+ end
217
316
 
218
- def create_option_parser
219
- @parser = OptionParser.new
220
-
221
- @parser.separator("")
222
- regular_options = @option_groups.delete :options
223
-
224
- configure_options "", regular_options
225
-
226
- @option_groups.sort_by { |n,_| n.to_s }.each do |group_name, option_list|
227
- configure_options group_name, option_list
228
- end
229
-
230
- configure_options "Common", Command.common_options
317
+ ##
318
+ # Handle the given list of arguments by parsing them and recording the
319
+ # results.
231
320
 
232
- @parser.separator("")
233
- unless arguments.empty?
234
- @parser.separator(" Arguments:")
235
- arguments.split(/\n/).each do |arg_desc|
236
- @parser.separator(" #{arg_desc}")
237
- end
238
- @parser.separator("")
239
- end
321
+ def handle_options(args)
322
+ args = add_extra_args(args)
323
+ @options = @defaults.clone
324
+ parser.parse!(args)
325
+ @options[:args] = args
326
+ end
240
327
 
241
- @parser.separator(" Summary:")
242
- wrap(@summary, 80 - 4).split("\n").each do |line|
243
- @parser.separator(" #{line.strip}")
244
- end
328
+ ##
329
+ # Adds extra args from ~/.gemrc
245
330
 
246
- if description then
247
- formatted = description.split("\n\n").map do |chunk|
248
- wrap(chunk, 80 - 4)
249
- end.join("\n")
331
+ def add_extra_args(args)
332
+ result = []
250
333
 
251
- @parser.separator ""
252
- @parser.separator " Description:"
253
- formatted.split("\n").each do |line|
254
- @parser.separator " #{line.rstrip}"
255
- end
256
- end
334
+ s_extra = Gem::Command.specific_extra_args(@command)
335
+ extra = Gem::Command.extra_args + s_extra
257
336
 
258
- unless defaults_str.empty?
259
- @parser.separator("")
260
- @parser.separator(" Defaults:")
261
- defaults_str.split(/\n/).each do |line|
262
- @parser.separator(" #{line}")
263
- end
264
- end
337
+ until extra.empty? do
338
+ ex = []
339
+ ex << extra.shift
340
+ ex << extra.shift if extra.first.to_s =~ /^[^-]/
341
+ result << ex if handles?(ex)
265
342
  end
266
343
 
267
- def configure_options(header, option_list)
268
- return if option_list.nil? or option_list.empty?
344
+ result.flatten!
345
+ result.concat(args)
346
+ result
347
+ end
269
348
 
270
- header = header.to_s.empty? ? '' : "#{header} "
271
- @parser.separator " #{header}Options:"
349
+ private
272
350
 
273
- option_list.each do |args, handler|
274
- dashes = args.select { |arg| arg =~ /^-/ }
275
- @parser.on(*args) do |value|
276
- handler.call(value, @options)
277
- end
278
- end
351
+ ##
352
+ # Create on demand parser.
279
353
 
280
- @parser.separator ''
281
- end
354
+ def parser
355
+ create_option_parser if @parser.nil?
356
+ @parser
357
+ end
282
358
 
283
- # Wraps +text+ to +width+
284
- def wrap(text, width)
285
- text.gsub(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n")
286
- end
287
-
288
- ##################################################################
289
- # Class methods for Command.
290
- class << self
291
- def common_options
292
- @common_options ||= []
293
- end
359
+ def create_option_parser
360
+ @parser = OptionParser.new
294
361
 
295
- def add_common_option(*args, &handler)
296
- Gem::Command.common_options << [args, handler]
297
- end
362
+ @parser.separator("")
363
+ regular_options = @option_groups.delete :options
298
364
 
299
- def extra_args
300
- @extra_args ||= []
301
- end
302
-
303
- def extra_args=(value)
304
- case value
305
- when Array
306
- @extra_args = value
307
- when String
308
- @extra_args = value.split
309
- end
310
- end
365
+ configure_options "", regular_options
311
366
 
312
- # Return an array of extra arguments for the command. The extra
313
- # arguments come from the gem configuration file read at program
314
- # startup.
315
- def specific_extra_args(cmd)
316
- specific_extra_args_hash[cmd]
317
- end
367
+ @option_groups.sort_by { |n,_| n.to_s }.each do |group_name, option_list|
368
+ configure_options group_name, option_list
369
+ end
318
370
 
319
- # Add a list of extra arguments for the given command. +args+
320
- # may be an array or a string to be split on white space.
321
- def add_specific_extra_args(cmd,args)
322
- args = args.split(/\s+/) if args.kind_of? String
323
- specific_extra_args_hash[cmd] = args
324
- end
371
+ configure_options "Common", Gem::Command.common_options
325
372
 
326
- # Accessor for the specific extra args hash (self initializing).
327
- def specific_extra_args_hash
328
- @specific_extra_args_hash ||= Hash.new do |h,k|
329
- h[k] = Array.new
330
- end
373
+ @parser.separator("")
374
+ unless arguments.empty?
375
+ @parser.separator(" Arguments:")
376
+ arguments.split(/\n/).each do |arg_desc|
377
+ @parser.separator(" #{arg_desc}")
331
378
  end
379
+ @parser.separator("")
332
380
  end
333
381
 
334
- # ----------------------------------------------------------------
335
- # Add the options common to all commands.
336
-
337
- add_common_option('-h', '--help',
338
- 'Get help on this command') do
339
- |value, options|
340
- options[:help] = true
382
+ @parser.separator(" Summary:")
383
+ wrap(@summary, 80 - 4).split("\n").each do |line|
384
+ @parser.separator(" #{line.strip}")
341
385
  end
342
386
 
343
- add_common_option('-V', '--[no-]verbose',
344
- 'Set the verbose level of output') do |value, options|
345
- # Set us to "really verbose" so the progress meter works
346
- if Gem.configuration.verbose and value then
347
- Gem.configuration.verbose = 1
348
- else
349
- Gem.configuration.verbose = value
387
+ if description then
388
+ formatted = description.split("\n\n").map do |chunk|
389
+ wrap(chunk, 80 - 4)
390
+ end.join("\n")
391
+
392
+ @parser.separator ""
393
+ @parser.separator " Description:"
394
+ formatted.split("\n").each do |line|
395
+ @parser.separator " #{line.rstrip}"
350
396
  end
351
397
  end
352
398
 
353
- add_common_option('-q', '--quiet', 'Silence commands') do |value, options|
354
- Gem.configuration.verbose = false
399
+ unless defaults_str.empty?
400
+ @parser.separator("")
401
+ @parser.separator(" Defaults:")
402
+ defaults_str.split(/\n/).each do |line|
403
+ @parser.separator(" #{line}")
404
+ end
355
405
  end
406
+ end
356
407
 
357
- # Backtrace and config-file are added so they show up in the help
358
- # commands. Both options are actually handled before the other
359
- # options get parsed.
408
+ def configure_options(header, option_list)
409
+ return if option_list.nil? or option_list.empty?
360
410
 
361
- add_common_option('--config-file FILE',
362
- "Use this config file instead of default") do
363
- end
411
+ header = header.to_s.empty? ? '' : "#{header} "
412
+ @parser.separator " #{header}Options:"
364
413
 
365
- add_common_option('--backtrace',
366
- 'Show stack backtrace on errors') do
414
+ option_list.each do |args, handler|
415
+ dashes = args.select { |arg| arg =~ /^-/ }
416
+ @parser.on(*args) do |value|
417
+ handler.call(value, @options)
418
+ end
367
419
  end
368
420
 
369
- add_common_option('--debug',
370
- 'Turn on Ruby debugging') do
371
- end
421
+ @parser.separator ''
422
+ end
372
423
 
373
- # :stopdoc:
374
- HELP = %{
375
- RubyGems is a sophisticated package manager for Ruby. This is a
376
- basic help message containing pointers to more information.
424
+ ##
425
+ # Wraps +text+ to +width+
377
426
 
378
- Usage:
379
- gem -h/--help
380
- gem -v/--version
381
- gem command [arguments...] [options...]
427
+ def wrap(text, width) # :doc:
428
+ text.gsub(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n")
429
+ end
382
430
 
383
- Examples:
384
- gem install rake
385
- gem list --local
386
- gem build package.gemspec
387
- gem help install
431
+ # ----------------------------------------------------------------
432
+ # Add the options common to all commands.
388
433
 
389
- Further help:
390
- gem help commands list all 'gem' commands
391
- gem help examples show some examples of usage
392
- gem help platforms show information about platforms
393
- gem help <COMMAND> show help on COMMAND
394
- (e.g. 'gem help install')
395
- Further information:
396
- http://rubygems.rubyforge.org
397
- }.gsub(/^ /, "")
434
+ add_common_option('-h', '--help',
435
+ 'Get help on this command') do |value, options|
436
+ options[:help] = true
437
+ end
398
438
 
399
- # :startdoc:
439
+ add_common_option('-V', '--[no-]verbose',
440
+ 'Set the verbose level of output') do |value, options|
441
+ # Set us to "really verbose" so the progress meter works
442
+ if Gem.configuration.verbose and value then
443
+ Gem.configuration.verbose = 1
444
+ else
445
+ Gem.configuration.verbose = value
446
+ end
447
+ end
448
+
449
+ add_common_option('-q', '--quiet', 'Silence commands') do |value, options|
450
+ Gem.configuration.verbose = false
451
+ end
452
+
453
+ # Backtrace and config-file are added so they show up in the help
454
+ # commands. Both options are actually handled before the other
455
+ # options get parsed.
456
+
457
+ add_common_option('--config-file FILE',
458
+ 'Use this config file instead of default') do
459
+ end
460
+
461
+ add_common_option('--backtrace',
462
+ 'Show stack backtrace on errors') do
463
+ end
464
+
465
+ add_common_option('--debug',
466
+ 'Turn on Ruby debugging') do
467
+ end
468
+
469
+ # :stopdoc:
470
+
471
+ HELP = %{
472
+ RubyGems is a sophisticated package manager for Ruby. This is a
473
+ basic help message containing pointers to more information.
474
+
475
+ Usage:
476
+ gem -h/--help
477
+ gem -v/--version
478
+ gem command [arguments...] [options...]
479
+
480
+ Examples:
481
+ gem install rake
482
+ gem list --local
483
+ gem build package.gemspec
484
+ gem help install
485
+
486
+ Further help:
487
+ gem help commands list all 'gem' commands
488
+ gem help examples show some examples of usage
489
+ gem help platforms show information about platforms
490
+ gem help <COMMAND> show help on COMMAND
491
+ (e.g. 'gem help install')
492
+ gem server present a web page at
493
+ http://localhost:8808/
494
+ with info about installed gems
495
+ Further information:
496
+ http://rubygems.rubyforge.org
497
+ }.gsub(/^ /, '')
498
+
499
+ # :startdoc:
400
500
 
401
- end # class
501
+ end
402
502
 
403
- # This is where Commands will be placed in the namespace
404
- module Commands; end
503
+ ##
504
+ # This is where Commands will be placed in the namespace
405
505
 
506
+ module Gem::Commands
406
507
  end
508
+