libgems 0.0.1

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