rubygems-update 3.0.3 → 3.4.7

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 (795) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5556 -0
  3. data/CODE_OF_CONDUCT.md +62 -24
  4. data/CONTRIBUTING.md +111 -21
  5. data/MAINTAINERS.txt +1 -6
  6. data/Manifest.txt +209 -101
  7. data/POLICIES.md +65 -22
  8. data/README.md +23 -15
  9. data/UPGRADING.md +5 -81
  10. data/bin/gem +2 -16
  11. data/bin/update_rubygems +5 -5
  12. data/bundler/CHANGELOG.md +2619 -1256
  13. data/bundler/LICENSE.md +18 -19
  14. data/bundler/README.md +11 -12
  15. data/bundler/UPGRADING.md +222 -0
  16. data/bundler/bundler.gemspec +13 -33
  17. data/bundler/exe/bundle +26 -11
  18. data/bundler/exe/bundler +1 -1
  19. data/bundler/lib/bundler/.document +1 -0
  20. data/bundler/lib/bundler/build_metadata.rb +5 -13
  21. data/bundler/lib/bundler/capistrano.rb +4 -4
  22. data/bundler/lib/bundler/cli/add.rb +28 -16
  23. data/bundler/lib/bundler/cli/binstubs.rb +11 -3
  24. data/bundler/lib/bundler/cli/cache.rb +24 -17
  25. data/bundler/lib/bundler/cli/check.rb +5 -3
  26. data/bundler/lib/bundler/cli/clean.rb +1 -1
  27. data/bundler/lib/bundler/cli/common.rb +41 -13
  28. data/bundler/lib/bundler/cli/config.rb +170 -86
  29. data/bundler/lib/bundler/cli/console.rb +3 -3
  30. data/bundler/lib/bundler/cli/doctor.rb +27 -10
  31. data/bundler/lib/bundler/cli/exec.rb +8 -25
  32. data/bundler/lib/bundler/cli/fund.rb +36 -0
  33. data/bundler/lib/bundler/cli/gem.rb +261 -48
  34. data/bundler/lib/bundler/cli/info.rb +52 -8
  35. data/bundler/lib/bundler/cli/init.rb +7 -3
  36. data/bundler/lib/bundler/cli/inject.rb +1 -1
  37. data/bundler/lib/bundler/cli/install.rb +38 -66
  38. data/bundler/lib/bundler/cli/issue.rb +8 -7
  39. data/bundler/lib/bundler/cli/list.rb +19 -11
  40. data/bundler/lib/bundler/cli/lock.rb +11 -4
  41. data/bundler/lib/bundler/cli/open.rb +14 -9
  42. data/bundler/lib/bundler/cli/outdated.rb +152 -121
  43. data/bundler/lib/bundler/cli/platform.rb +2 -2
  44. data/bundler/lib/bundler/cli/plugin.rb +19 -2
  45. data/bundler/lib/bundler/cli/pristine.rb +6 -1
  46. data/bundler/lib/bundler/cli/remove.rb +1 -2
  47. data/bundler/lib/bundler/cli/show.rb +3 -3
  48. data/bundler/lib/bundler/cli/update.rb +49 -18
  49. data/bundler/lib/bundler/cli/viz.rb +1 -1
  50. data/bundler/lib/bundler/cli.rb +269 -165
  51. data/bundler/lib/bundler/compact_index_client/cache.rb +7 -24
  52. data/bundler/lib/bundler/compact_index_client/gem_parser.rb +28 -0
  53. data/bundler/lib/bundler/compact_index_client/updater.rb +58 -57
  54. data/bundler/lib/bundler/compact_index_client.rb +28 -18
  55. data/bundler/lib/bundler/constants.rb +1 -1
  56. data/bundler/lib/bundler/current_ruby.rb +26 -11
  57. data/bundler/lib/bundler/definition.rb +359 -441
  58. data/bundler/lib/bundler/dependency.rb +29 -71
  59. data/bundler/lib/bundler/deployment.rb +1 -1
  60. data/bundler/lib/bundler/digest.rb +71 -0
  61. data/bundler/lib/bundler/dsl.rb +84 -116
  62. data/bundler/lib/bundler/endpoint_specification.rb +20 -14
  63. data/bundler/lib/bundler/env.rb +10 -15
  64. data/bundler/lib/bundler/environment_preserver.rb +30 -3
  65. data/bundler/lib/bundler/errors.rb +31 -14
  66. data/bundler/lib/bundler/feature_flag.rb +13 -33
  67. data/bundler/lib/bundler/fetcher/base.rb +7 -9
  68. data/bundler/lib/bundler/fetcher/compact_index.rb +46 -39
  69. data/bundler/lib/bundler/fetcher/dependency.rb +2 -2
  70. data/bundler/lib/bundler/fetcher/downloader.rb +15 -12
  71. data/bundler/lib/bundler/fetcher/index.rb +4 -30
  72. data/bundler/lib/bundler/fetcher.rb +39 -41
  73. data/bundler/lib/bundler/force_platform.rb +18 -0
  74. data/bundler/lib/bundler/friendly_errors.rb +49 -54
  75. data/bundler/lib/bundler/gem_helper.rb +79 -43
  76. data/bundler/lib/bundler/gem_helpers.rb +44 -28
  77. data/bundler/lib/bundler/gem_tasks.rb +1 -1
  78. data/bundler/lib/bundler/gem_version_promoter.rb +54 -99
  79. data/bundler/lib/bundler/graph.rb +5 -5
  80. data/bundler/lib/bundler/index.rb +14 -52
  81. data/bundler/lib/bundler/injector.rb +50 -16
  82. data/bundler/lib/bundler/inline.rb +28 -29
  83. data/bundler/lib/bundler/installer/gem_installer.rb +22 -23
  84. data/bundler/lib/bundler/installer/parallel_installer.rb +51 -51
  85. data/bundler/lib/bundler/installer/standalone.rb +62 -12
  86. data/bundler/lib/bundler/installer.rb +46 -97
  87. data/bundler/lib/bundler/lazy_specification.rb +88 -48
  88. data/bundler/lib/bundler/lockfile_generator.rb +3 -3
  89. data/bundler/lib/bundler/lockfile_parser.rb +30 -62
  90. data/bundler/{man → lib/bundler/man}/bundle-add.1 +29 -5
  91. data/bundler/{man/bundle-add.ronn → lib/bundler/man/bundle-add.1.ronn} +22 -4
  92. data/bundler/{man → lib/bundler/man}/bundle-binstubs.1 +6 -4
  93. data/bundler/{man/bundle-binstubs.ronn → lib/bundler/man/bundle-binstubs.1.ronn} +3 -5
  94. data/bundler/lib/bundler/man/bundle-cache.1 +61 -0
  95. data/bundler/{man/bundle-package.ronn → lib/bundler/man/bundle-cache.1.ronn} +22 -15
  96. data/bundler/{man → lib/bundler/man}/bundle-check.1 +1 -1
  97. data/bundler/{man → lib/bundler/man}/bundle-clean.1 +2 -2
  98. data/bundler/{man/bundle-clean.ronn → lib/bundler/man/bundle-clean.1.ronn} +1 -1
  99. data/bundler/{man → lib/bundler/man}/bundle-config.1 +78 -60
  100. data/bundler/{man/bundle-config.ronn → lib/bundler/man/bundle-config.1.ronn} +96 -85
  101. data/bundler/lib/bundler/man/bundle-console.1 +53 -0
  102. data/bundler/lib/bundler/man/bundle-console.1.ronn +44 -0
  103. data/bundler/{man → lib/bundler/man}/bundle-doctor.1 +1 -1
  104. data/bundler/{man → lib/bundler/man}/bundle-exec.1 +6 -6
  105. data/bundler/{man/bundle-exec.ronn → lib/bundler/man/bundle-exec.1.ronn} +6 -6
  106. data/bundler/lib/bundler/man/bundle-gem.1 +105 -0
  107. data/bundler/lib/bundler/man/bundle-gem.1.ronn +117 -0
  108. data/bundler/lib/bundler/man/bundle-help.1 +13 -0
  109. data/bundler/lib/bundler/man/bundle-help.1.ronn +12 -0
  110. data/bundler/{man → lib/bundler/man}/bundle-info.1 +1 -1
  111. data/bundler/{man → lib/bundler/man}/bundle-init.1 +6 -2
  112. data/bundler/{man/bundle-init.ronn → lib/bundler/man/bundle-init.1.ronn} +3 -1
  113. data/bundler/{man → lib/bundler/man}/bundle-inject.1 +5 -2
  114. data/bundler/{man/bundle-inject.ronn → lib/bundler/man/bundle-inject.1.ronn} +3 -1
  115. data/bundler/{man → lib/bundler/man}/bundle-install.1 +42 -37
  116. data/bundler/{man/bundle-install.ronn → lib/bundler/man/bundle-install.1.ronn} +42 -38
  117. data/bundler/{man → lib/bundler/man}/bundle-list.1 +7 -7
  118. data/bundler/{man/bundle-list.ronn → lib/bundler/man/bundle-list.1.ronn} +6 -6
  119. data/bundler/{man → lib/bundler/man}/bundle-lock.1 +1 -1
  120. data/bundler/{man → lib/bundler/man}/bundle-open.1 +22 -2
  121. data/bundler/{man/bundle-open.ronn → lib/bundler/man/bundle-open.1.ronn} +9 -1
  122. data/bundler/{man → lib/bundler/man}/bundle-outdated.1 +3 -10
  123. data/bundler/{man/bundle-outdated.ronn → lib/bundler/man/bundle-outdated.1.ronn} +1 -10
  124. data/bundler/{man → lib/bundler/man}/bundle-platform.1 +16 -6
  125. data/bundler/{man/bundle-platform.ronn → lib/bundler/man/bundle-platform.1.ronn} +14 -7
  126. data/bundler/lib/bundler/man/bundle-plugin.1 +81 -0
  127. data/bundler/lib/bundler/man/bundle-plugin.1.ronn +59 -0
  128. data/bundler/{man → lib/bundler/man}/bundle-pristine.1 +1 -1
  129. data/bundler/{man → lib/bundler/man}/bundle-remove.1 +1 -1
  130. data/bundler/{man → lib/bundler/man}/bundle-show.1 +1 -1
  131. data/bundler/{man → lib/bundler/man}/bundle-update.1 +8 -8
  132. data/bundler/{man/bundle-update.ronn → lib/bundler/man/bundle-update.1.ronn} +8 -7
  133. data/bundler/lib/bundler/man/bundle-version.1 +35 -0
  134. data/bundler/lib/bundler/man/bundle-version.1.ronn +24 -0
  135. data/bundler/{man → lib/bundler/man}/bundle-viz.1 +4 -1
  136. data/bundler/{man/bundle-viz.ronn → lib/bundler/man/bundle-viz.1.ronn} +2 -0
  137. data/bundler/{man → lib/bundler/man}/bundle.1 +17 -12
  138. data/bundler/{man/bundle.ronn → lib/bundler/man/bundle.1.ronn} +14 -9
  139. data/bundler/lib/bundler/man/gemfile.5 +723 -0
  140. data/bundler/{man → lib/bundler/man}/gemfile.5.ronn +112 -95
  141. data/bundler/lib/bundler/man/index.txt +29 -0
  142. data/bundler/lib/bundler/match_metadata.rb +13 -0
  143. data/bundler/lib/bundler/match_platform.rb +1 -2
  144. data/bundler/lib/bundler/match_remote_metadata.rb +29 -0
  145. data/bundler/lib/bundler/mirror.rb +10 -12
  146. data/bundler/lib/bundler/plugin/api/source.rb +29 -15
  147. data/bundler/lib/bundler/plugin/api.rb +1 -1
  148. data/bundler/lib/bundler/plugin/dsl.rb +1 -1
  149. data/bundler/lib/bundler/plugin/index.rb +31 -8
  150. data/bundler/lib/bundler/plugin/installer/git.rb +0 -4
  151. data/bundler/lib/bundler/plugin/installer/rubygems.rb +1 -9
  152. data/bundler/lib/bundler/plugin/installer.rb +35 -22
  153. data/bundler/lib/bundler/plugin/source_list.rb +5 -1
  154. data/bundler/lib/bundler/plugin.rb +102 -42
  155. data/bundler/lib/bundler/process_lock.rb +1 -1
  156. data/bundler/lib/bundler/remote_specification.rb +15 -8
  157. data/bundler/lib/bundler/resolver/base.rb +77 -0
  158. data/bundler/lib/bundler/resolver/candidate.rb +94 -0
  159. data/bundler/lib/bundler/resolver/incompatibility.rb +15 -0
  160. data/bundler/lib/bundler/resolver/package.rb +72 -0
  161. data/bundler/lib/bundler/resolver/root.rb +25 -0
  162. data/bundler/lib/bundler/resolver/spec_group.rb +49 -73
  163. data/bundler/lib/bundler/resolver.rb +343 -300
  164. data/bundler/lib/bundler/retry.rb +4 -4
  165. data/bundler/lib/bundler/ruby_dsl.rb +1 -1
  166. data/bundler/lib/bundler/ruby_version.rb +9 -37
  167. data/bundler/lib/bundler/rubygems_ext.rb +235 -92
  168. data/bundler/lib/bundler/rubygems_gem_installer.rb +87 -21
  169. data/bundler/lib/bundler/rubygems_integration.rb +179 -515
  170. data/bundler/lib/bundler/runtime.rb +25 -40
  171. data/bundler/lib/bundler/self_manager.rb +168 -0
  172. data/bundler/lib/bundler/settings.rb +162 -118
  173. data/bundler/lib/bundler/setup.rb +11 -12
  174. data/bundler/lib/bundler/shared_helpers.rb +61 -102
  175. data/bundler/lib/bundler/similarity_detector.rb +3 -3
  176. data/bundler/lib/bundler/source/git/git_proxy.rb +257 -128
  177. data/bundler/lib/bundler/source/git.rb +84 -61
  178. data/bundler/lib/bundler/source/metadata.rb +9 -9
  179. data/bundler/lib/bundler/source/path/installer.rb +11 -32
  180. data/bundler/lib/bundler/source/path.rb +28 -17
  181. data/bundler/lib/bundler/source/rubygems/remote.rb +3 -4
  182. data/bundler/lib/bundler/source/rubygems.rb +171 -197
  183. data/bundler/lib/bundler/source/rubygems_aggregate.rb +68 -0
  184. data/bundler/lib/bundler/source.rb +30 -10
  185. data/bundler/lib/bundler/source_list.rb +112 -67
  186. data/bundler/lib/bundler/source_map.rb +71 -0
  187. data/bundler/lib/bundler/spec_set.rb +86 -72
  188. data/bundler/lib/bundler/stub_specification.rb +45 -37
  189. data/bundler/lib/bundler/templates/Executable +3 -5
  190. data/bundler/lib/bundler/templates/Executable.bundler +21 -17
  191. data/bundler/lib/bundler/templates/Executable.standalone +4 -4
  192. data/bundler/lib/bundler/templates/Gemfile +0 -2
  193. data/bundler/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  194. data/bundler/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +57 -47
  195. data/bundler/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
  196. data/bundler/lib/bundler/templates/newgem/Gemfile.tt +22 -2
  197. data/bundler/lib/bundler/templates/newgem/README.md.tt +13 -15
  198. data/bundler/lib/bundler/templates/newgem/Rakefile.tt +33 -5
  199. data/bundler/lib/bundler/templates/newgem/bin/console.tt +1 -0
  200. data/bundler/lib/bundler/templates/newgem/circleci/config.yml.tt +25 -0
  201. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
  202. data/bundler/lib/bundler/templates/newgem/ext/newgem/{extconf.rb.tt → extconf-c.rb.tt} +2 -0
  203. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  204. data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
  205. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +37 -0
  206. data/bundler/lib/bundler/templates/newgem/gitignore.tt +3 -0
  207. data/bundler/lib/bundler/templates/newgem/gitlab-ci.yml.tt +18 -0
  208. data/bundler/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +2 -0
  209. data/bundler/lib/bundler/templates/newgem/lib/newgem.rb.tt +4 -2
  210. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +36 -41
  211. data/bundler/lib/bundler/templates/newgem/rubocop.yml.tt +13 -0
  212. data/bundler/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  213. data/bundler/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +2 -0
  214. data/bundler/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -1
  215. data/bundler/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  216. data/bundler/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt +6 -0
  217. data/bundler/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/test_newgem.rb.tt} +3 -1
  218. data/bundler/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  219. data/bundler/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  220. data/bundler/lib/bundler/ui/rg_proxy.rb +1 -1
  221. data/bundler/lib/bundler/ui/shell.rb +39 -20
  222. data/bundler/lib/bundler/ui/silent.rb +21 -5
  223. data/bundler/lib/bundler/ui.rb +3 -3
  224. data/bundler/lib/bundler/uri_credentials_filter.rb +10 -4
  225. data/bundler/lib/bundler/vendor/.document +1 -0
  226. data/bundler/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  227. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +174 -0
  228. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  229. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +56 -0
  230. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +128 -0
  231. data/bundler/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  232. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +1493 -425
  233. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  234. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
  235. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
  236. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
  237. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +302 -462
  238. data/bundler/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  239. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  240. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
  241. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  242. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +155 -0
  243. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  244. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  245. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  246. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  247. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +60 -0
  248. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  249. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  250. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
  251. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +411 -0
  252. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +243 -0
  253. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  254. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  255. data/bundler/lib/bundler/vendor/thor/LICENSE.md +20 -0
  256. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
  257. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +3 -2
  258. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +7 -17
  259. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +25 -14
  260. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +20 -10
  261. data/bundler/lib/bundler/vendor/thor/lib/thor/actions.rb +34 -15
  262. data/bundler/lib/bundler/vendor/thor/lib/thor/base.rb +63 -43
  263. data/bundler/lib/bundler/vendor/thor/lib/thor/command.rb +21 -14
  264. data/bundler/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  265. data/bundler/lib/bundler/vendor/thor/lib/thor/error.rb +83 -0
  266. data/bundler/lib/bundler/vendor/thor/lib/thor/group.rb +3 -3
  267. data/bundler/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -0
  268. data/bundler/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +1 -1
  269. data/bundler/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +6 -6
  270. data/bundler/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
  271. data/bundler/lib/bundler/vendor/thor/lib/thor/nested_context.rb +29 -0
  272. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +7 -3
  273. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/option.rb +20 -7
  274. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/options.rb +40 -6
  275. data/bundler/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
  276. data/bundler/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +1 -0
  277. data/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb +15 -14
  278. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +88 -13
  279. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +10 -2
  280. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb +3 -3
  281. data/bundler/lib/bundler/vendor/thor/lib/thor/shell.rb +5 -5
  282. data/bundler/lib/bundler/vendor/thor/lib/thor/util.rb +18 -2
  283. data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  284. data/bundler/lib/bundler/vendor/thor/lib/thor.rb +16 -9
  285. data/bundler/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  286. data/bundler/lib/bundler/vendor/tsort/lib/tsort.rb +452 -0
  287. data/bundler/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  288. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +729 -0
  289. data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +100 -0
  290. data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
  291. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +1587 -0
  292. data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +125 -0
  293. data/bundler/lib/bundler/vendor/uri/lib/uri/https.rb +23 -0
  294. data/bundler/lib/bundler/vendor/uri/lib/uri/ldap.rb +261 -0
  295. data/bundler/lib/bundler/vendor/uri/lib/uri/ldaps.rb +22 -0
  296. data/bundler/lib/bundler/vendor/uri/lib/uri/mailto.rb +293 -0
  297. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +539 -0
  298. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +119 -0
  299. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
  300. data/bundler/lib/bundler/vendor/uri/lib/uri/ws.rb +83 -0
  301. data/bundler/lib/bundler/vendor/uri/lib/uri/wss.rb +23 -0
  302. data/bundler/lib/bundler/vendor/uri/lib/uri.rb +104 -0
  303. data/bundler/lib/bundler/vendored_fileutils.rb +1 -6
  304. data/bundler/lib/bundler/vendored_persistent.rb +2 -39
  305. data/bundler/lib/bundler/{vendored_molinillo.rb → vendored_pub_grub.rb} +1 -1
  306. data/bundler/lib/bundler/vendored_thor.rb +2 -2
  307. data/bundler/lib/bundler/vendored_tsort.rb +4 -0
  308. data/bundler/lib/bundler/vendored_uri.rb +4 -0
  309. data/bundler/lib/bundler/version.rb +5 -20
  310. data/bundler/lib/bundler/vlad.rb +2 -2
  311. data/bundler/lib/bundler/worker.rb +26 -15
  312. data/bundler/lib/bundler/yaml_serializer.rb +3 -4
  313. data/bundler/lib/bundler.rb +285 -183
  314. data/hide_lib_for_update/note.txt +0 -4
  315. data/lib/rubygems/available_set.rb +7 -8
  316. data/lib/rubygems/basic_specification.rb +44 -31
  317. data/lib/rubygems/bundler_version_finder.rb +28 -50
  318. data/lib/rubygems/command.rb +104 -46
  319. data/lib/rubygems/command_manager.rb +35 -16
  320. data/lib/rubygems/commands/build_command.rb +77 -26
  321. data/lib/rubygems/commands/cert_command.rb +78 -76
  322. data/lib/rubygems/commands/check_command.rb +20 -22
  323. data/lib/rubygems/commands/cleanup_command.rb +36 -32
  324. data/lib/rubygems/commands/contents_command.rb +16 -18
  325. data/lib/rubygems/commands/dependency_command.rb +39 -50
  326. data/lib/rubygems/commands/environment_command.rb +11 -13
  327. data/lib/rubygems/commands/fetch_command.rb +33 -16
  328. data/lib/rubygems/commands/generate_index_command.rb +18 -17
  329. data/lib/rubygems/commands/help_command.rb +7 -7
  330. data/lib/rubygems/commands/info_command.rb +11 -6
  331. data/lib/rubygems/commands/install_command.rb +45 -79
  332. data/lib/rubygems/commands/list_command.rb +9 -8
  333. data/lib/rubygems/commands/lock_command.rb +7 -9
  334. data/lib/rubygems/commands/mirror_command.rb +3 -4
  335. data/lib/rubygems/commands/open_command.rb +11 -14
  336. data/lib/rubygems/commands/outdated_command.rb +5 -6
  337. data/lib/rubygems/commands/owner_command.rb +29 -22
  338. data/lib/rubygems/commands/pristine_command.rb +61 -51
  339. data/lib/rubygems/commands/push_command.rb +26 -63
  340. data/lib/rubygems/commands/query_command.rb +21 -337
  341. data/lib/rubygems/commands/rdoc_command.rb +26 -26
  342. data/lib/rubygems/commands/search_command.rb +8 -8
  343. data/lib/rubygems/commands/server_command.rb +16 -77
  344. data/lib/rubygems/commands/setup_command.rb +282 -241
  345. data/lib/rubygems/commands/signin_command.rb +9 -10
  346. data/lib/rubygems/commands/signout_command.rb +7 -9
  347. data/lib/rubygems/commands/sources_command.rb +42 -26
  348. data/lib/rubygems/commands/specification_command.rb +25 -20
  349. data/lib/rubygems/commands/stale_command.rb +3 -3
  350. data/lib/rubygems/commands/uninstall_command.rb +58 -49
  351. data/lib/rubygems/commands/unpack_command.rb +15 -44
  352. data/lib/rubygems/commands/update_command.rb +133 -81
  353. data/lib/rubygems/commands/which_command.rb +8 -11
  354. data/lib/rubygems/commands/yank_command.rb +22 -19
  355. data/lib/rubygems/compatibility.rb +7 -5
  356. data/lib/rubygems/config_file.rb +101 -47
  357. data/lib/rubygems/core_ext/kernel_gem.rb +8 -12
  358. data/lib/rubygems/core_ext/kernel_require.rb +124 -83
  359. data/lib/rubygems/core_ext/kernel_warn.rb +35 -30
  360. data/lib/rubygems/core_ext/tcpsocket_init.rb +52 -0
  361. data/lib/rubygems/defaults.rb +131 -55
  362. data/lib/rubygems/dependency.rb +44 -27
  363. data/lib/rubygems/dependency_installer.rb +49 -205
  364. data/lib/rubygems/dependency_list.rb +24 -25
  365. data/lib/rubygems/deprecate.rb +106 -12
  366. data/lib/rubygems/doctor.rb +22 -22
  367. data/lib/rubygems/errors.rb +8 -14
  368. data/lib/rubygems/exceptions.rb +35 -33
  369. data/lib/rubygems/ext/build_error.rb +2 -0
  370. data/lib/rubygems/ext/builder.rb +71 -95
  371. data/lib/rubygems/ext/cargo_builder/link_flag_converter.rb +27 -0
  372. data/lib/rubygems/ext/cargo_builder.rb +360 -0
  373. data/lib/rubygems/ext/cmake_builder.rb +6 -7
  374. data/lib/rubygems/ext/configure_builder.rb +5 -8
  375. data/lib/rubygems/ext/ext_conf_builder.rb +45 -65
  376. data/lib/rubygems/ext/rake_builder.rb +7 -10
  377. data/lib/rubygems/ext.rb +7 -6
  378. data/lib/rubygems/gem_runner.rb +15 -26
  379. data/lib/rubygems/gemcutter_utilities.rb +179 -54
  380. data/lib/rubygems/indexer.rb +38 -53
  381. data/lib/rubygems/install_default_message.rb +2 -2
  382. data/lib/rubygems/install_message.rb +2 -2
  383. data/lib/rubygems/install_update_options.rb +73 -64
  384. data/lib/rubygems/installer.rb +230 -173
  385. data/lib/rubygems/installer_uninstaller_utils.rb +29 -0
  386. data/lib/rubygems/local_remote_options.rb +22 -24
  387. data/lib/rubygems/mock_gem_ui.rb +2 -5
  388. data/lib/rubygems/name_tuple.rb +10 -14
  389. data/lib/rubygems/openssl.rb +7 -0
  390. data/lib/rubygems/optparse/.document +1 -0
  391. data/lib/rubygems/optparse/COPYING +56 -0
  392. data/lib/rubygems/optparse/lib/optionparser.rb +2 -0
  393. data/lib/rubygems/optparse/lib/optparse/ac.rb +54 -0
  394. data/lib/rubygems/optparse/lib/optparse/date.rb +18 -0
  395. data/lib/rubygems/optparse/lib/optparse/kwargs.rb +22 -0
  396. data/lib/rubygems/optparse/lib/optparse/shellwords.rb +7 -0
  397. data/lib/rubygems/optparse/lib/optparse/time.rb +11 -0
  398. data/lib/rubygems/optparse/lib/optparse/uri.rb +7 -0
  399. data/lib/rubygems/optparse/lib/optparse/version.rb +71 -0
  400. data/lib/rubygems/optparse/lib/optparse.rb +2308 -0
  401. data/lib/rubygems/optparse.rb +3 -0
  402. data/lib/rubygems/package/digest_io.rb +0 -2
  403. data/lib/rubygems/package/file_source.rb +2 -4
  404. data/lib/rubygems/package/io_source.rb +4 -2
  405. data/lib/rubygems/package/old.rb +9 -11
  406. data/lib/rubygems/package/tar_header.rb +73 -66
  407. data/lib/rubygems/package/tar_reader/entry.rb +8 -9
  408. data/lib/rubygems/package/tar_reader.rb +16 -13
  409. data/lib/rubygems/package/tar_writer.rb +12 -22
  410. data/lib/rubygems/package.rb +142 -125
  411. data/lib/rubygems/package_task.rb +5 -11
  412. data/lib/rubygems/path_support.rb +3 -8
  413. data/lib/rubygems/platform.rb +113 -73
  414. data/lib/rubygems/psych_tree.rb +1 -1
  415. data/lib/rubygems/query_utils.rb +351 -0
  416. data/lib/rubygems/rdoc.rb +4 -16
  417. data/lib/rubygems/remote_fetcher.rb +64 -136
  418. data/lib/rubygems/request/connection_pools.rb +7 -11
  419. data/lib/rubygems/request/http_pool.rb +2 -3
  420. data/lib/rubygems/request.rb +31 -32
  421. data/lib/rubygems/request_set/gem_dependency_api.rb +135 -136
  422. data/lib/rubygems/request_set/lockfile/parser.rb +28 -28
  423. data/lib/rubygems/request_set/lockfile/tokenizer.rb +5 -5
  424. data/lib/rubygems/request_set/lockfile.rb +21 -20
  425. data/lib/rubygems/request_set.rb +30 -43
  426. data/lib/rubygems/requirement.rb +42 -64
  427. data/lib/rubygems/resolver/activation_request.rb +29 -53
  428. data/lib/rubygems/resolver/api_set/gem_parser.rb +20 -0
  429. data/lib/rubygems/resolver/api_set.rb +33 -26
  430. data/lib/rubygems/resolver/api_specification.rb +30 -16
  431. data/lib/rubygems/resolver/best_set.rb +9 -11
  432. data/lib/rubygems/resolver/composed_set.rb +3 -5
  433. data/lib/rubygems/resolver/conflict.rb +12 -19
  434. data/lib/rubygems/resolver/current_set.rb +0 -2
  435. data/lib/rubygems/resolver/dependency_request.rb +3 -5
  436. data/lib/rubygems/resolver/git_set.rb +2 -4
  437. data/lib/rubygems/resolver/git_specification.rb +6 -8
  438. data/lib/rubygems/resolver/index_set.rb +4 -6
  439. data/lib/rubygems/resolver/index_specification.rb +38 -7
  440. data/lib/rubygems/resolver/installed_specification.rb +4 -6
  441. data/lib/rubygems/resolver/installer_set.rb +69 -27
  442. data/lib/rubygems/resolver/local_specification.rb +2 -4
  443. data/lib/rubygems/resolver/lock_set.rb +7 -9
  444. data/lib/rubygems/resolver/lock_specification.rb +6 -8
  445. data/lib/rubygems/resolver/molinillo/LICENSE +9 -0
  446. data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb +7 -0
  447. data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb +8 -0
  448. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb +1 -0
  449. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +2 -1
  450. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +2 -1
  451. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +2 -1
  452. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +2 -1
  453. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb +7 -6
  454. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb +2 -1
  455. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb +4 -3
  456. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb +51 -12
  457. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +42 -9
  458. data/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +82 -8
  459. data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +2 -1
  460. data/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb +13 -1
  461. data/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb +3 -1
  462. data/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb +510 -165
  463. data/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb +3 -2
  464. data/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb +8 -4
  465. data/lib/rubygems/resolver/molinillo/lib/molinillo.rb +6 -5
  466. data/lib/rubygems/resolver/molinillo.rb +1 -1
  467. data/lib/rubygems/resolver/requirement_list.rb +0 -1
  468. data/lib/rubygems/resolver/set.rb +0 -3
  469. data/lib/rubygems/resolver/source_set.rb +0 -2
  470. data/lib/rubygems/resolver/spec_specification.rb +14 -2
  471. data/lib/rubygems/resolver/specification.rb +14 -3
  472. data/lib/rubygems/resolver/vendor_set.rb +1 -3
  473. data/lib/rubygems/resolver/vendor_specification.rb +3 -5
  474. data/lib/rubygems/resolver.rb +58 -54
  475. data/lib/rubygems/s3_uri_signer.rb +175 -0
  476. data/lib/rubygems/safe_yaml.rb +14 -16
  477. data/lib/rubygems/security/policies.rb +47 -47
  478. data/lib/rubygems/security/policy.rb +25 -29
  479. data/lib/rubygems/security/signer.rb +16 -18
  480. data/lib/rubygems/security/trust_dir.rb +5 -6
  481. data/lib/rubygems/security.rb +90 -69
  482. data/lib/rubygems/security_option.rb +7 -8
  483. data/lib/rubygems/source/git.rb +30 -30
  484. data/lib/rubygems/source/installed.rb +1 -3
  485. data/lib/rubygems/source/local.rb +4 -6
  486. data/lib/rubygems/source/lock.rb +0 -2
  487. data/lib/rubygems/source/specific_file.rb +1 -3
  488. data/lib/rubygems/source/vendor.rb +0 -2
  489. data/lib/rubygems/source.rb +50 -38
  490. data/lib/rubygems/source_list.rb +9 -13
  491. data/lib/rubygems/spec_fetcher.rb +52 -64
  492. data/lib/rubygems/specification.rb +432 -463
  493. data/lib/rubygems/specification_policy.rb +185 -87
  494. data/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem +21 -0
  495. data/lib/rubygems/stub_specification.rb +24 -29
  496. data/lib/rubygems/text.rb +21 -21
  497. data/lib/rubygems/tsort/.document +1 -0
  498. data/lib/rubygems/tsort/LICENSE.txt +22 -0
  499. data/lib/rubygems/tsort/lib/tsort.rb +452 -0
  500. data/lib/rubygems/tsort.rb +3 -0
  501. data/lib/rubygems/uninstaller.rb +110 -57
  502. data/lib/rubygems/unknown_command_spell_checker.rb +21 -0
  503. data/lib/rubygems/update_suggestion.rb +69 -0
  504. data/lib/rubygems/uri.rb +126 -0
  505. data/lib/rubygems/uri_formatter.rb +2 -4
  506. data/lib/rubygems/user_interaction.rb +46 -49
  507. data/lib/rubygems/util/licenses.rb +511 -404
  508. data/lib/rubygems/util.rb +40 -56
  509. data/lib/rubygems/validator.rb +15 -37
  510. data/lib/rubygems/version.rb +48 -29
  511. data/lib/rubygems/version_option.rb +11 -5
  512. data/lib/rubygems.rb +305 -332
  513. data/rubygems-update.gemspec +6 -13
  514. data/setup.rb +11 -22
  515. data/test/rubygems/alternate_cert.pem +14 -14
  516. data/test/rubygems/alternate_cert_32.pem +15 -15
  517. data/test/rubygems/alternate_key.pem +25 -25
  518. data/test/rubygems/bundler_test_gem.rb +419 -0
  519. data/test/rubygems/ca_cert.pem +74 -65
  520. data/test/rubygems/child_cert.pem +15 -16
  521. data/test/rubygems/child_cert_32.pem +15 -16
  522. data/test/rubygems/child_key.pem +25 -25
  523. data/test/rubygems/client.pem +103 -45
  524. data/test/rubygems/data/excon-0.7.7.gemspec.rz +0 -0
  525. data/test/rubygems/data/null-required-ruby-version.gemspec.rz +0 -0
  526. data/test/rubygems/data/null-required-rubygems-version.gemspec.rz +0 -0
  527. data/test/rubygems/data/pry-0.4.7.gemspec.rz +0 -0
  528. data/test/rubygems/encrypted_private_key.pem +26 -26
  529. data/test/rubygems/expired_cert.pem +15 -15
  530. data/test/rubygems/future_cert.pem +15 -15
  531. data/test/rubygems/future_cert_32.pem +15 -15
  532. data/test/rubygems/grandchild_cert.pem +15 -16
  533. data/test/rubygems/grandchild_cert_32.pem +15 -16
  534. data/test/rubygems/grandchild_key.pem +25 -25
  535. data/{lib/rubygems/test_case.rb → test/rubygems/helper.rb} +505 -507
  536. data/{lib → test}/rubygems/installer_test_case.rb +115 -53
  537. data/test/rubygems/invalid_issuer_cert.pem +16 -16
  538. data/test/rubygems/invalid_issuer_cert_32.pem +16 -16
  539. data/test/rubygems/invalid_key.pem +25 -25
  540. data/test/rubygems/invalid_signer_cert.pem +15 -15
  541. data/test/rubygems/invalid_signer_cert_32.pem +15 -15
  542. data/test/rubygems/invalidchild_cert.pem +15 -16
  543. data/test/rubygems/invalidchild_cert_32.pem +15 -16
  544. data/test/rubygems/invalidchild_key.pem +25 -25
  545. data/{lib → test}/rubygems/package/tar_test_case.rb +4 -6
  546. data/test/rubygems/packages/Bluebie-legs-0.6.2.gem +0 -0
  547. data/test/rubygems/packages/ascii_binder-0.1.10.1.gem +0 -0
  548. data/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem +0 -0
  549. data/test/rubygems/plugin/exception/rubygems_plugin.rb +1 -1
  550. data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +1 -1
  551. data/test/rubygems/private_ec_key.pem +9 -0
  552. data/test/rubygems/private_key.pem +25 -25
  553. data/test/rubygems/public_cert.pem +16 -16
  554. data/test/rubygems/public_cert_32.pem +15 -15
  555. data/test/rubygems/public_key.pem +7 -7
  556. data/test/rubygems/rubygems/commands/crash_command.rb +0 -2
  557. data/test/rubygems/rubygems_plugin.rb +2 -4
  558. data/test/rubygems/specifications/bar-0.0.2.gemspec +0 -2
  559. data/test/rubygems/specifications/rubyforge-0.0.1.gemspec +12 -0
  560. data/test/rubygems/ssl_cert.pem +78 -17
  561. data/test/rubygems/ssl_key.pem +25 -13
  562. data/test/rubygems/test_bundled_ca.rb +44 -47
  563. data/test/rubygems/test_config.rb +5 -7
  564. data/test/rubygems/test_deprecate.rb +90 -10
  565. data/test/rubygems/test_exit.rb +17 -0
  566. data/test/rubygems/test_gem.rb +679 -885
  567. data/test/rubygems/test_gem_available_set.rb +24 -25
  568. data/test/rubygems/test_gem_bundler_version_finder.rb +42 -42
  569. data/test/rubygems/test_gem_command.rb +186 -39
  570. data/test/rubygems/test_gem_command_manager.rb +166 -36
  571. data/test/rubygems/test_gem_commands_build_command.rb +436 -52
  572. data/test/rubygems/test_gem_commands_cert_command.rb +193 -124
  573. data/test/rubygems/test_gem_commands_check_command.rb +9 -11
  574. data/test/rubygems/test_gem_commands_cleanup_command.rb +87 -62
  575. data/test/rubygems/test_gem_commands_contents_command.rb +73 -42
  576. data/test/rubygems/test_gem_commands_dependency_command.rb +39 -41
  577. data/test/rubygems/test_gem_commands_environment_command.rb +60 -48
  578. data/test/rubygems/test_gem_commands_fetch_command.rb +163 -32
  579. data/test/rubygems/test_gem_commands_generate_index_command.rb +39 -9
  580. data/test/rubygems/test_gem_commands_help_command.rb +34 -19
  581. data/test/rubygems/test_gem_commands_info_command.rb +34 -9
  582. data/test/rubygems/test_gem_commands_install_command.rb +600 -173
  583. data/test/rubygems/test_gem_commands_list_command.rb +5 -7
  584. data/test/rubygems/test_gem_commands_lock_command.rb +11 -13
  585. data/test/rubygems/test_gem_commands_mirror.rb +3 -4
  586. data/test/rubygems/test_gem_commands_open_command.rb +16 -19
  587. data/test/rubygems/test_gem_commands_outdated_command.rb +24 -7
  588. data/test/rubygems/test_gem_commands_owner_command.rb +183 -49
  589. data/test/rubygems/test_gem_commands_pristine_command.rb +222 -89
  590. data/test/rubygems/test_gem_commands_push_command.rb +178 -69
  591. data/test/rubygems/test_gem_commands_query_command.rb +114 -89
  592. data/test/rubygems/test_gem_commands_search_command.rb +2 -4
  593. data/test/rubygems/test_gem_commands_server_command.rb +6 -46
  594. data/test/rubygems/test_gem_commands_setup_command.rb +334 -157
  595. data/test/rubygems/test_gem_commands_signin_command.rb +187 -27
  596. data/test/rubygems/test_gem_commands_signout_command.rb +3 -10
  597. data/test/rubygems/test_gem_commands_sources_command.rb +266 -33
  598. data/test/rubygems/test_gem_commands_specification_command.rb +81 -55
  599. data/test/rubygems/test_gem_commands_stale_command.rb +4 -6
  600. data/test/rubygems/test_gem_commands_uninstall_command.rb +230 -95
  601. data/test/rubygems/test_gem_commands_unpack_command.rb +32 -34
  602. data/test/rubygems/test_gem_commands_update_command.rb +412 -102
  603. data/test/rubygems/test_gem_commands_which_command.rb +12 -14
  604. data/test/rubygems/test_gem_commands_yank_command.rb +107 -26
  605. data/test/rubygems/test_gem_config_file.rb +120 -96
  606. data/test/rubygems/test_gem_dependency.rb +94 -86
  607. data/test/rubygems/test_gem_dependency_installer.rb +305 -388
  608. data/test/rubygems/test_gem_dependency_list.rb +66 -61
  609. data/test/rubygems/test_gem_dependency_resolution_error.rb +5 -7
  610. data/test/rubygems/test_gem_doctor.rb +73 -47
  611. data/test/rubygems/test_gem_ext_builder.rb +116 -106
  612. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore +1 -0
  613. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +8 -0
  614. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock +233 -0
  615. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml +10 -0
  616. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs +27 -0
  617. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb +1 -0
  618. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore +1 -0
  619. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +233 -0
  620. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +10 -0
  621. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +8 -0
  622. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +51 -0
  623. data/test/rubygems/test_gem_ext_cargo_builder.rb +166 -0
  624. data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +33 -0
  625. data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +60 -0
  626. data/test/rubygems/test_gem_ext_cmake_builder.rb +32 -37
  627. data/test/rubygems/test_gem_ext_configure_builder.rb +23 -31
  628. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +75 -79
  629. data/test/rubygems/test_gem_ext_rake_builder.rb +49 -30
  630. data/test/rubygems/test_gem_gem_runner.rb +52 -7
  631. data/test/rubygems/test_gem_gemcutter_utilities.rb +91 -76
  632. data/test/rubygems/test_gem_impossible_dependencies_error.rb +4 -6
  633. data/test/rubygems/test_gem_indexer.rb +120 -105
  634. data/test/rubygems/test_gem_install_update_options.rb +57 -33
  635. data/test/rubygems/test_gem_installer.rb +1230 -644
  636. data/test/rubygems/test_gem_local_remote_options.rb +11 -13
  637. data/test/rubygems/test_gem_name_tuple.rb +4 -6
  638. data/test/rubygems/test_gem_package.rb +396 -266
  639. data/test/rubygems/test_gem_package_old.rb +57 -56
  640. data/test/rubygems/test_gem_package_tar_header.rb +108 -50
  641. data/test/rubygems/test_gem_package_tar_reader.rb +8 -10
  642. data/test/rubygems/test_gem_package_tar_reader_entry.rb +77 -20
  643. data/test/rubygems/test_gem_package_tar_writer.rb +107 -101
  644. data/test/rubygems/test_gem_package_task.rb +58 -25
  645. data/test/rubygems/test_gem_path_support.rb +29 -29
  646. data/test/rubygems/test_gem_platform.rb +388 -199
  647. data/test/rubygems/test_gem_rdoc.rb +20 -155
  648. data/test/rubygems/test_gem_remote_fetcher.rb +474 -303
  649. data/test/rubygems/test_gem_request.rb +128 -85
  650. data/test/rubygems/test_gem_request_connection_pools.rb +32 -32
  651. data/test/rubygems/test_gem_request_set.rb +186 -110
  652. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +280 -261
  653. data/test/rubygems/test_gem_request_set_lockfile.rb +93 -94
  654. data/test/rubygems/test_gem_request_set_lockfile_parser.rb +68 -69
  655. data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +136 -136
  656. data/test/rubygems/test_gem_requirement.rb +140 -55
  657. data/test/rubygems/test_gem_resolver.rb +224 -115
  658. data/test/rubygems/test_gem_resolver_activation_request.rb +9 -40
  659. data/test/rubygems/test_gem_resolver_api_set.rb +79 -78
  660. data/test/rubygems/test_gem_resolver_api_specification.rb +47 -49
  661. data/test/rubygems/test_gem_resolver_best_set.rb +43 -22
  662. data/test/rubygems/test_gem_resolver_composed_set.rb +1 -3
  663. data/test/rubygems/test_gem_resolver_conflict.rb +12 -18
  664. data/test/rubygems/test_gem_resolver_dependency_request.rb +15 -17
  665. data/test/rubygems/test_gem_resolver_git_set.rb +22 -24
  666. data/test/rubygems/test_gem_resolver_git_specification.rb +22 -22
  667. data/test/rubygems/test_gem_resolver_index_set.rb +14 -16
  668. data/test/rubygems/test_gem_resolver_index_specification.rb +21 -18
  669. data/test/rubygems/test_gem_resolver_installed_specification.rb +5 -8
  670. data/test/rubygems/test_gem_resolver_installer_set.rb +106 -44
  671. data/test/rubygems/test_gem_resolver_local_specification.rb +7 -9
  672. data/test/rubygems/test_gem_resolver_lock_set.rb +15 -17
  673. data/test/rubygems/test_gem_resolver_lock_specification.rb +17 -19
  674. data/test/rubygems/test_gem_resolver_requirement_list.rb +1 -3
  675. data/test/rubygems/test_gem_resolver_specification.rb +8 -10
  676. data/test/rubygems/test_gem_resolver_vendor_set.rb +9 -11
  677. data/test/rubygems/test_gem_resolver_vendor_specification.rb +10 -12
  678. data/test/rubygems/test_gem_security.rb +109 -79
  679. data/test/rubygems/test_gem_security_policy.rb +102 -107
  680. data/test/rubygems/test_gem_security_signer.rb +51 -52
  681. data/test/rubygems/test_gem_security_trust_dir.rb +14 -16
  682. data/test/rubygems/test_gem_silent_ui.rb +47 -42
  683. data/test/rubygems/test_gem_source.rb +66 -51
  684. data/test/rubygems/test_gem_source_fetch_problem.rb +17 -8
  685. data/test/rubygems/test_gem_source_git.rb +74 -74
  686. data/test/rubygems/test_gem_source_installed.rb +16 -18
  687. data/test/rubygems/test_gem_source_list.rb +5 -5
  688. data/test/rubygems/test_gem_source_local.rb +15 -16
  689. data/test/rubygems/test_gem_source_lock.rb +31 -33
  690. data/test/rubygems/test_gem_source_specific_file.rb +18 -19
  691. data/test/rubygems/test_gem_source_subpath_problem.rb +49 -0
  692. data/test/rubygems/test_gem_source_vendor.rb +13 -15
  693. data/test/rubygems/test_gem_spec_fetcher.rb +74 -67
  694. data/test/rubygems/test_gem_specification.rb +1051 -1071
  695. data/test/rubygems/test_gem_stream_ui.rb +25 -23
  696. data/test/rubygems/test_gem_stub_specification.rb +39 -56
  697. data/test/rubygems/test_gem_text.rb +8 -3
  698. data/test/rubygems/test_gem_uninstaller.rb +269 -100
  699. data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +3 -5
  700. data/test/rubygems/test_gem_update_suggestion.rb +208 -0
  701. data/test/rubygems/test_gem_uri.rb +39 -0
  702. data/test/rubygems/test_gem_uri_formatter.rb +14 -16
  703. data/test/rubygems/test_gem_util.rb +46 -34
  704. data/test/rubygems/test_gem_validator.rb +12 -15
  705. data/test/rubygems/test_gem_version.rb +49 -34
  706. data/test/rubygems/test_gem_version_option.rb +16 -18
  707. data/test/rubygems/test_kernel.rb +61 -53
  708. data/test/rubygems/test_project_sanity.rb +20 -0
  709. data/test/rubygems/test_remote_fetch_error.rb +7 -8
  710. data/test/rubygems/test_require.rb +415 -121
  711. data/test/rubygems/test_rubygems.rb +74 -0
  712. data/{lib/rubygems/test_utilities.rb → test/rubygems/utilities.rb} +74 -50
  713. data/test/rubygems/wrong_key_cert.pem +15 -15
  714. data/test/rubygems/wrong_key_cert_32.pem +15 -15
  715. data/test/test_changelog_generator.rb +17 -0
  716. metadata +218 -244
  717. data/.rubocop.yml +0 -66
  718. data/.travis.yml +0 -38
  719. data/History.txt +0 -3965
  720. data/Rakefile +0 -372
  721. data/appveyor.yml +0 -43
  722. data/bundler/CODE_OF_CONDUCT.md +0 -42
  723. data/bundler/CONTRIBUTING.md +0 -17
  724. data/bundler/exe/bundle_ruby +0 -60
  725. data/bundler/lib/bundler/cli/package.rb +0 -49
  726. data/bundler/lib/bundler/compatibility_guard.rb +0 -14
  727. data/bundler/lib/bundler/dep_proxy.rb +0 -48
  728. data/bundler/lib/bundler/gem_remote_fetcher.rb +0 -43
  729. data/bundler/lib/bundler/gemdeps.rb +0 -29
  730. data/bundler/lib/bundler/psyched_yaml.rb +0 -37
  731. data/bundler/lib/bundler/ssl_certs/certificate_manager.rb +0 -66
  732. data/bundler/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
  733. data/bundler/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
  734. data/bundler/lib/bundler/templates/gems.rb +0 -8
  735. data/bundler/lib/bundler/templates/newgem/test/test_helper.rb.tt +0 -4
  736. data/bundler/lib/bundler/templates/newgem/travis.yml.tt +0 -7
  737. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +0 -26
  738. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  739. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -81
  740. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
  741. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
  742. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
  743. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
  744. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
  745. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
  746. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
  747. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
  748. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -136
  749. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -223
  750. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +0 -143
  751. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  752. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -101
  753. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
  754. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +0 -837
  755. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
  756. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +0 -58
  757. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -12
  758. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +0 -27
  759. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +0 -129
  760. data/bundler/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +0 -12
  761. data/bundler/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -129
  762. data/bundler/lib/bundler/version_ranges.rb +0 -76
  763. data/bundler/man/bundle-gem.1 +0 -80
  764. data/bundler/man/bundle-gem.ronn +0 -78
  765. data/bundler/man/bundle-package.1 +0 -55
  766. data/lib/rubygems/psych_additions.rb +0 -10
  767. data/lib/rubygems/server.rb +0 -878
  768. data/lib/rubygems/source_local.rb +0 -7
  769. data/lib/rubygems/source_specific_file.rb +0 -6
  770. data/lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +0 -21
  771. data/lib/rubygems/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
  772. data/lib/rubygems/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
  773. data/lib/rubygems/syck_hack.rb +0 -77
  774. data/lib/ubygems.rb +0 -14
  775. data/test/rubygems/bogussources.rb +0 -9
  776. data/test/rubygems/data/null-type.gemspec.rz +0 -0
  777. data/test/rubygems/test_gem_server.rb +0 -607
  778. data/util/CL2notes +0 -55
  779. data/util/ci +0 -77
  780. data/util/create_certs.rb +0 -171
  781. data/util/create_encrypted_key.rb +0 -16
  782. data/util/generate_spdx_license_list.rb +0 -61
  783. data/util/patch_with_prs.rb +0 -77
  784. data/util/rubocop +0 -8
  785. data/util/update_bundled_ca_certificates.rb +0 -139
  786. data/util/update_changelog.rb +0 -67
  787. /data/bundler/lib/bundler/{ssl_certs → man}/.document +0 -0
  788. /data/bundler/{man/bundle-check.ronn → lib/bundler/man/bundle-check.1.ronn} +0 -0
  789. /data/bundler/{man/bundle-doctor.ronn → lib/bundler/man/bundle-doctor.1.ronn} +0 -0
  790. /data/bundler/{man/bundle-info.ronn → lib/bundler/man/bundle-info.1.ronn} +0 -0
  791. /data/bundler/{man/bundle-lock.ronn → lib/bundler/man/bundle-lock.1.ronn} +0 -0
  792. /data/bundler/{man/bundle-pristine.ronn → lib/bundler/man/bundle-pristine.1.ronn} +0 -0
  793. /data/bundler/{man/bundle-remove.ronn → lib/bundler/man/bundle-remove.1.ronn} +0 -0
  794. /data/bundler/{man/bundle-show.ronn → lib/bundler/man/bundle-show.1.ronn} +0 -0
  795. /data/{bundler/lib/bundler/ssl_certs/index.rubygems.org → lib/rubygems/ssl_certs/rubygems.org}/GlobalSignRootCA.pem +0 -0
@@ -0,0 +1,2308 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # optparse.rb - command-line option analysis with the Gem::OptionParser class.
4
+ #
5
+ # Author:: Nobu Nakada
6
+ # Documentation:: Nobu Nakada and Gavin Sinclair.
7
+ #
8
+ # See Gem::OptionParser for documentation.
9
+ #
10
+
11
+
12
+ #--
13
+ # == Developer Documentation (not for RDoc output)
14
+ #
15
+ # === Class tree
16
+ #
17
+ # - Gem::OptionParser:: front end
18
+ # - Gem::OptionParser::Switch:: each switches
19
+ # - Gem::OptionParser::List:: options list
20
+ # - Gem::OptionParser::ParseError:: errors on parsing
21
+ # - Gem::OptionParser::AmbiguousOption
22
+ # - Gem::OptionParser::NeedlessArgument
23
+ # - Gem::OptionParser::MissingArgument
24
+ # - Gem::OptionParser::InvalidOption
25
+ # - Gem::OptionParser::InvalidArgument
26
+ # - Gem::OptionParser::AmbiguousArgument
27
+ #
28
+ # === Object relationship diagram
29
+ #
30
+ # +--------------+
31
+ # | Gem::OptionParser |<>-----+
32
+ # +--------------+ | +--------+
33
+ # | ,-| Switch |
34
+ # on_head -------->+---------------+ / +--------+
35
+ # accept/reject -->| List |<|>-
36
+ # | |<|>- +----------+
37
+ # on ------------->+---------------+ `-| argument |
38
+ # : : | class |
39
+ # +---------------+ |==========|
40
+ # on_tail -------->| | |pattern |
41
+ # +---------------+ |----------|
42
+ # Gem::OptionParser.accept ->| DefaultList | |converter |
43
+ # reject |(shared between| +----------+
44
+ # | all instances)|
45
+ # +---------------+
46
+ #
47
+ #++
48
+ #
49
+ # == Gem::OptionParser
50
+ #
51
+ # === New to \Gem::OptionParser?
52
+ #
53
+ # See the {Tutorial}[optparse/tutorial.rdoc].
54
+ #
55
+ # === Introduction
56
+ #
57
+ # Gem::OptionParser is a class for command-line option analysis. It is much more
58
+ # advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented
59
+ # solution.
60
+ #
61
+ # === Features
62
+ #
63
+ # 1. The argument specification and the code to handle it are written in the
64
+ # same place.
65
+ # 2. It can output an option summary; you don't need to maintain this string
66
+ # separately.
67
+ # 3. Optional and mandatory arguments are specified very gracefully.
68
+ # 4. Arguments can be automatically converted to a specified class.
69
+ # 5. Arguments can be restricted to a certain set.
70
+ #
71
+ # All of these features are demonstrated in the examples below. See
72
+ # #make_switch for full documentation.
73
+ #
74
+ # === Minimal example
75
+ #
76
+ # require 'rubygems/optparse/lib/optparse'
77
+ #
78
+ # options = {}
79
+ # Gem::OptionParser.new do |parser|
80
+ # parser.banner = "Usage: example.rb [options]"
81
+ #
82
+ # parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
83
+ # options[:verbose] = v
84
+ # end
85
+ # end.parse!
86
+ #
87
+ # p options
88
+ # p ARGV
89
+ #
90
+ # === Generating Help
91
+ #
92
+ # Gem::OptionParser can be used to automatically generate help for the commands you
93
+ # write:
94
+ #
95
+ # require 'rubygems/optparse/lib/optparse'
96
+ #
97
+ # Options = Struct.new(:name)
98
+ #
99
+ # class Parser
100
+ # def self.parse(options)
101
+ # args = Options.new("world")
102
+ #
103
+ # opt_parser = Gem::OptionParser.new do |parser|
104
+ # parser.banner = "Usage: example.rb [options]"
105
+ #
106
+ # parser.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
107
+ # args.name = n
108
+ # end
109
+ #
110
+ # parser.on("-h", "--help", "Prints this help") do
111
+ # puts parser
112
+ # exit
113
+ # end
114
+ # end
115
+ #
116
+ # opt_parser.parse!(options)
117
+ # return args
118
+ # end
119
+ # end
120
+ # options = Parser.parse %w[--help]
121
+ #
122
+ # #=>
123
+ # # Usage: example.rb [options]
124
+ # # -n, --name=NAME Name to say hello to
125
+ # # -h, --help Prints this help
126
+ #
127
+ # === Required Arguments
128
+ #
129
+ # For options that require an argument, option specification strings may include an
130
+ # option name in all caps. If an option is used without the required argument,
131
+ # an exception will be raised.
132
+ #
133
+ # require 'rubygems/optparse/lib/optparse'
134
+ #
135
+ # options = {}
136
+ # Gem::OptionParser.new do |parser|
137
+ # parser.on("-r", "--require LIBRARY",
138
+ # "Require the LIBRARY before executing your script") do |lib|
139
+ # puts "You required #{lib}!"
140
+ # end
141
+ # end.parse!
142
+ #
143
+ # Used:
144
+ #
145
+ # $ ruby optparse-test.rb -r
146
+ # optparse-test.rb:9:in `<main>': missing argument: -r (Gem::OptionParser::MissingArgument)
147
+ # $ ruby optparse-test.rb -r my-library
148
+ # You required my-library!
149
+ #
150
+ # === Type Coercion
151
+ #
152
+ # Gem::OptionParser supports the ability to coerce command line arguments
153
+ # into objects for us.
154
+ #
155
+ # Gem::OptionParser comes with a few ready-to-use kinds of type
156
+ # coercion. They are:
157
+ #
158
+ # - Date -- Anything accepted by +Date.parse+
159
+ # - DateTime -- Anything accepted by +DateTime.parse+
160
+ # - Time -- Anything accepted by +Time.httpdate+ or +Time.parse+
161
+ # - URI -- Anything accepted by +URI.parse+
162
+ # - Shellwords -- Anything accepted by +Shellwords.shellwords+
163
+ # - String -- Any non-empty string
164
+ # - Integer -- Any integer. Will convert octal. (e.g. 124, -3, 040)
165
+ # - Float -- Any float. (e.g. 10, 3.14, -100E+13)
166
+ # - Numeric -- Any integer, float, or rational (1, 3.4, 1/3)
167
+ # - DecimalInteger -- Like +Integer+, but no octal format.
168
+ # - OctalInteger -- Like +Integer+, but no decimal format.
169
+ # - DecimalNumeric -- Decimal integer or float.
170
+ # - TrueClass -- Accepts '+, yes, true, -, no, false' and
171
+ # defaults as +true+
172
+ # - FalseClass -- Same as +TrueClass+, but defaults to +false+
173
+ # - Array -- Strings separated by ',' (e.g. 1,2,3)
174
+ # - Regexp -- Regular expressions. Also includes options.
175
+ #
176
+ # We can also add our own coercions, which we will cover below.
177
+ #
178
+ # ==== Using Built-in Conversions
179
+ #
180
+ # As an example, the built-in +Time+ conversion is used. The other built-in
181
+ # conversions behave in the same way.
182
+ # Gem::OptionParser will attempt to parse the argument
183
+ # as a +Time+. If it succeeds, that time will be passed to the
184
+ # handler block. Otherwise, an exception will be raised.
185
+ #
186
+ # require 'rubygems/optparse/lib/optparse'
187
+ # require 'rubygems/optparse/lib/optparse/time'
188
+ # Gem::OptionParser.new do |parser|
189
+ # parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
190
+ # p time
191
+ # end
192
+ # end.parse!
193
+ #
194
+ # Used:
195
+ #
196
+ # $ ruby optparse-test.rb -t nonsense
197
+ # ... invalid argument: -t nonsense (Gem::OptionParser::InvalidArgument)
198
+ # $ ruby optparse-test.rb -t 10-11-12
199
+ # 2010-11-12 00:00:00 -0500
200
+ # $ ruby optparse-test.rb -t 9:30
201
+ # 2014-08-13 09:30:00 -0400
202
+ #
203
+ # ==== Creating Custom Conversions
204
+ #
205
+ # The +accept+ method on Gem::OptionParser may be used to create converters.
206
+ # It specifies which conversion block to call whenever a class is specified.
207
+ # The example below uses it to fetch a +User+ object before the +on+ handler receives it.
208
+ #
209
+ # require 'rubygems/optparse/lib/optparse'
210
+ #
211
+ # User = Struct.new(:id, :name)
212
+ #
213
+ # def find_user id
214
+ # not_found = ->{ raise "No User Found for id #{id}" }
215
+ # [ User.new(1, "Sam"),
216
+ # User.new(2, "Gandalf") ].find(not_found) do |u|
217
+ # u.id == id
218
+ # end
219
+ # end
220
+ #
221
+ # op = Gem::OptionParser.new
222
+ # op.accept(User) do |user_id|
223
+ # find_user user_id.to_i
224
+ # end
225
+ #
226
+ # op.on("--user ID", User) do |user|
227
+ # puts user
228
+ # end
229
+ #
230
+ # op.parse!
231
+ #
232
+ # Used:
233
+ #
234
+ # $ ruby optparse-test.rb --user 1
235
+ # #<struct User id=1, name="Sam">
236
+ # $ ruby optparse-test.rb --user 2
237
+ # #<struct User id=2, name="Gandalf">
238
+ # $ ruby optparse-test.rb --user 3
239
+ # optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
240
+ #
241
+ # === Store options to a Hash
242
+ #
243
+ # The +into+ option of +order+, +parse+ and so on methods stores command line options into a Hash.
244
+ #
245
+ # require 'rubygems/optparse/lib/optparse'
246
+ #
247
+ # options = {}
248
+ # Gem::OptionParser.new do |parser|
249
+ # parser.on('-a')
250
+ # parser.on('-b NUM', Integer)
251
+ # parser.on('-v', '--verbose')
252
+ # end.parse!(into: options)
253
+ #
254
+ # p options
255
+ #
256
+ # Used:
257
+ #
258
+ # $ ruby optparse-test.rb -a
259
+ # {:a=>true}
260
+ # $ ruby optparse-test.rb -a -v
261
+ # {:a=>true, :verbose=>true}
262
+ # $ ruby optparse-test.rb -a -b 100
263
+ # {:a=>true, :b=>100}
264
+ #
265
+ # === Complete example
266
+ #
267
+ # The following example is a complete Ruby program. You can run it and see the
268
+ # effect of specifying various options. This is probably the best way to learn
269
+ # the features of +optparse+.
270
+ #
271
+ # require 'rubygems/optparse/lib/optparse'
272
+ # require 'rubygems/optparse/lib/optparse/time'
273
+ # require 'ostruct'
274
+ # require 'pp'
275
+ #
276
+ # class OptparseExample
277
+ # Version = '1.0.0'
278
+ #
279
+ # CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
280
+ # CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
281
+ #
282
+ # class ScriptOptions
283
+ # attr_accessor :library, :inplace, :encoding, :transfer_type,
284
+ # :verbose, :extension, :delay, :time, :record_separator,
285
+ # :list
286
+ #
287
+ # def initialize
288
+ # self.library = []
289
+ # self.inplace = false
290
+ # self.encoding = "utf8"
291
+ # self.transfer_type = :auto
292
+ # self.verbose = false
293
+ # end
294
+ #
295
+ # def define_options(parser)
296
+ # parser.banner = "Usage: example.rb [options]"
297
+ # parser.separator ""
298
+ # parser.separator "Specific options:"
299
+ #
300
+ # # add additional options
301
+ # perform_inplace_option(parser)
302
+ # delay_execution_option(parser)
303
+ # execute_at_time_option(parser)
304
+ # specify_record_separator_option(parser)
305
+ # list_example_option(parser)
306
+ # specify_encoding_option(parser)
307
+ # optional_option_argument_with_keyword_completion_option(parser)
308
+ # boolean_verbose_option(parser)
309
+ #
310
+ # parser.separator ""
311
+ # parser.separator "Common options:"
312
+ # # No argument, shows at tail. This will print an options summary.
313
+ # # Try it and see!
314
+ # parser.on_tail("-h", "--help", "Show this message") do
315
+ # puts parser
316
+ # exit
317
+ # end
318
+ # # Another typical switch to print the version.
319
+ # parser.on_tail("--version", "Show version") do
320
+ # puts Version
321
+ # exit
322
+ # end
323
+ # end
324
+ #
325
+ # def perform_inplace_option(parser)
326
+ # # Specifies an optional option argument
327
+ # parser.on("-i", "--inplace [EXTENSION]",
328
+ # "Edit ARGV files in place",
329
+ # "(make backup if EXTENSION supplied)") do |ext|
330
+ # self.inplace = true
331
+ # self.extension = ext || ''
332
+ # self.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
333
+ # end
334
+ # end
335
+ #
336
+ # def delay_execution_option(parser)
337
+ # # Cast 'delay' argument to a Float.
338
+ # parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
339
+ # self.delay = n
340
+ # end
341
+ # end
342
+ #
343
+ # def execute_at_time_option(parser)
344
+ # # Cast 'time' argument to a Time object.
345
+ # parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
346
+ # self.time = time
347
+ # end
348
+ # end
349
+ #
350
+ # def specify_record_separator_option(parser)
351
+ # # Cast to octal integer.
352
+ # parser.on("-F", "--irs [OCTAL]", Gem::OptionParser::OctalInteger,
353
+ # "Specify record separator (default \\0)") do |rs|
354
+ # self.record_separator = rs
355
+ # end
356
+ # end
357
+ #
358
+ # def list_example_option(parser)
359
+ # # List of arguments.
360
+ # parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
361
+ # self.list = list
362
+ # end
363
+ # end
364
+ #
365
+ # def specify_encoding_option(parser)
366
+ # # Keyword completion. We are specifying a specific set of arguments (CODES
367
+ # # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
368
+ # # the shortest unambiguous text.
369
+ # code_list = (CODE_ALIASES.keys + CODES).join(', ')
370
+ # parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
371
+ # "(#{code_list})") do |encoding|
372
+ # self.encoding = encoding
373
+ # end
374
+ # end
375
+ #
376
+ # def optional_option_argument_with_keyword_completion_option(parser)
377
+ # # Optional '--type' option argument with keyword completion.
378
+ # parser.on("--type [TYPE]", [:text, :binary, :auto],
379
+ # "Select transfer type (text, binary, auto)") do |t|
380
+ # self.transfer_type = t
381
+ # end
382
+ # end
383
+ #
384
+ # def boolean_verbose_option(parser)
385
+ # # Boolean switch.
386
+ # parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
387
+ # self.verbose = v
388
+ # end
389
+ # end
390
+ # end
391
+ #
392
+ # #
393
+ # # Return a structure describing the options.
394
+ # #
395
+ # def parse(args)
396
+ # # The options specified on the command line will be collected in
397
+ # # *options*.
398
+ #
399
+ # @options = ScriptOptions.new
400
+ # @args = Gem::OptionParser.new do |parser|
401
+ # @options.define_options(parser)
402
+ # parser.parse!(args)
403
+ # end
404
+ # @options
405
+ # end
406
+ #
407
+ # attr_reader :parser, :options
408
+ # end # class OptparseExample
409
+ #
410
+ # example = OptparseExample.new
411
+ # options = example.parse(ARGV)
412
+ # pp options # example.options
413
+ # pp ARGV
414
+ #
415
+ # === Shell Completion
416
+ #
417
+ # For modern shells (e.g. bash, zsh, etc.), you can use shell
418
+ # completion for command line options.
419
+ #
420
+ # === Further documentation
421
+ #
422
+ # The above examples, along with the accompanying
423
+ # {Tutorial}[optparse/tutorial.rdoc],
424
+ # should be enough to learn how to use this class.
425
+ # If you have any questions, file a ticket at http://bugs.ruby-lang.org.
426
+ #
427
+ class Gem::OptionParser
428
+ Gem::OptionParser::Version = "0.3.0"
429
+
430
+ # :stopdoc:
431
+ NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
432
+ RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze
433
+ OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze
434
+ # :startdoc:
435
+
436
+ #
437
+ # Keyword completion module. This allows partial arguments to be specified
438
+ # and resolved against a list of acceptable values.
439
+ #
440
+ module Completion
441
+ def self.regexp(key, icase)
442
+ Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'), icase)
443
+ end
444
+
445
+ def self.candidate(key, icase = false, pat = nil, &block)
446
+ pat ||= Completion.regexp(key, icase)
447
+ candidates = []
448
+ block.call do |k, *v|
449
+ (if Regexp === k
450
+ kn = ""
451
+ k === key
452
+ else
453
+ kn = defined?(k.id2name) ? k.id2name : k
454
+ pat === kn
455
+ end) or next
456
+ v << k if v.empty?
457
+ candidates << [k, v, kn]
458
+ end
459
+ candidates
460
+ end
461
+
462
+ def candidate(key, icase = false, pat = nil)
463
+ Completion.candidate(key, icase, pat, &method(:each))
464
+ end
465
+
466
+ public
467
+ def complete(key, icase = false, pat = nil)
468
+ candidates = candidate(key, icase, pat, &method(:each)).sort_by {|k, v, kn| kn.size}
469
+ if candidates.size == 1
470
+ canon, sw, * = candidates[0]
471
+ elsif candidates.size > 1
472
+ canon, sw, cn = candidates.shift
473
+ candidates.each do |k, v, kn|
474
+ next if sw == v
475
+ if String === cn and String === kn
476
+ if cn.rindex(kn, 0)
477
+ canon, sw, cn = k, v, kn
478
+ next
479
+ elsif kn.rindex(cn, 0)
480
+ next
481
+ end
482
+ end
483
+ throw :ambiguous, key
484
+ end
485
+ end
486
+ if canon
487
+ block_given? or return key, *sw
488
+ yield(key, *sw)
489
+ end
490
+ end
491
+
492
+ def convert(opt = nil, val = nil, *)
493
+ val
494
+ end
495
+ end
496
+
497
+
498
+ #
499
+ # Map from option/keyword string to object with completion.
500
+ #
501
+ class OptionMap < Hash
502
+ include Completion
503
+ end
504
+
505
+
506
+ #
507
+ # Individual switch class. Not important to the user.
508
+ #
509
+ # Defined within Switch are several Switch-derived classes: NoArgument,
510
+ # RequiredArgument, etc.
511
+ #
512
+ class Switch
513
+ attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block
514
+
515
+ #
516
+ # Guesses argument style from +arg+. Returns corresponding
517
+ # Gem::OptionParser::Switch class (OptionalArgument, etc.).
518
+ #
519
+ def self.guess(arg)
520
+ case arg
521
+ when ""
522
+ t = self
523
+ when /\A=?\[/
524
+ t = Switch::OptionalArgument
525
+ when /\A\s+\[/
526
+ t = Switch::PlacedArgument
527
+ else
528
+ t = Switch::RequiredArgument
529
+ end
530
+ self >= t or incompatible_argument_styles(arg, t)
531
+ t
532
+ end
533
+
534
+ def self.incompatible_argument_styles(arg, t)
535
+ raise(ArgumentError, "#{arg}: incompatible argument styles\n #{self}, #{t}",
536
+ ParseError.filter_backtrace(caller(2)))
537
+ end
538
+
539
+ def self.pattern
540
+ NilClass
541
+ end
542
+
543
+ def initialize(pattern = nil, conv = nil,
544
+ short = nil, long = nil, arg = nil,
545
+ desc = ([] if short or long), block = nil, &_block)
546
+ raise if Array === pattern
547
+ block ||= _block
548
+ @pattern, @conv, @short, @long, @arg, @desc, @block =
549
+ pattern, conv, short, long, arg, desc, block
550
+ end
551
+
552
+ #
553
+ # Parses +arg+ and returns rest of +arg+ and matched portion to the
554
+ # argument pattern. Yields when the pattern doesn't match substring.
555
+ #
556
+ def parse_arg(arg) # :nodoc:
557
+ pattern or return nil, [arg]
558
+ unless m = pattern.match(arg)
559
+ yield(InvalidArgument, arg)
560
+ return arg, []
561
+ end
562
+ if String === m
563
+ m = [s = m]
564
+ else
565
+ m = m.to_a
566
+ s = m[0]
567
+ return nil, m unless String === s
568
+ end
569
+ raise InvalidArgument, arg unless arg.rindex(s, 0)
570
+ return nil, m if s.length == arg.length
571
+ yield(InvalidArgument, arg) # didn't match whole arg
572
+ return arg[s.length..-1], m
573
+ end
574
+ private :parse_arg
575
+
576
+ #
577
+ # Parses argument, converts and returns +arg+, +block+ and result of
578
+ # conversion. Yields at semi-error condition instead of raising an
579
+ # exception.
580
+ #
581
+ def conv_arg(arg, val = []) # :nodoc:
582
+ if conv
583
+ val = conv.call(*val)
584
+ else
585
+ val = proc {|v| v}.call(*val)
586
+ end
587
+ return arg, block, val
588
+ end
589
+ private :conv_arg
590
+
591
+ #
592
+ # Produces the summary text. Each line of the summary is yielded to the
593
+ # block (without newline).
594
+ #
595
+ # +sdone+:: Already summarized short style options keyed hash.
596
+ # +ldone+:: Already summarized long style options keyed hash.
597
+ # +width+:: Width of left side (option part). In other words, the right
598
+ # side (description part) starts after +width+ columns.
599
+ # +max+:: Maximum width of left side -> the options are filled within
600
+ # +max+ columns.
601
+ # +indent+:: Prefix string indents all summarized lines.
602
+ #
603
+ def summarize(sdone = {}, ldone = {}, width = 1, max = width - 1, indent = "")
604
+ sopts, lopts = [], [], nil
605
+ @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
606
+ @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
607
+ return if sopts.empty? and lopts.empty? # completely hidden
608
+
609
+ left = [sopts.join(', ')]
610
+ right = desc.dup
611
+
612
+ while s = lopts.shift
613
+ l = left[-1].length + s.length
614
+ l += arg.length if left.size == 1 && arg
615
+ l < max or sopts.empty? or left << +''
616
+ left[-1] << (left[-1].empty? ? ' ' * 4 : ', ') << s
617
+ end
618
+
619
+ if arg
620
+ left[0] << (left[1] ? arg.sub(/\A(\[?)=/, '\1') + ',' : arg)
621
+ end
622
+ mlen = left.collect {|ss| ss.length}.max.to_i
623
+ while mlen > width and l = left.shift
624
+ mlen = left.collect {|ss| ss.length}.max.to_i if l.length == mlen
625
+ if l.length < width and (r = right[0]) and !r.empty?
626
+ l = l.to_s.ljust(width) + ' ' + r
627
+ right.shift
628
+ end
629
+ yield(indent + l)
630
+ end
631
+
632
+ while begin l = left.shift; r = right.shift; l or r end
633
+ l = l.to_s.ljust(width) + ' ' + r if r and !r.empty?
634
+ yield(indent + l)
635
+ end
636
+
637
+ self
638
+ end
639
+
640
+ def add_banner(to) # :nodoc:
641
+ unless @short or @long
642
+ s = desc.join
643
+ to << " [" + s + "]..." unless s.empty?
644
+ end
645
+ to
646
+ end
647
+
648
+ def match_nonswitch?(str) # :nodoc:
649
+ @pattern =~ str unless @short or @long
650
+ end
651
+
652
+ #
653
+ # Main name of the switch.
654
+ #
655
+ def switch_name
656
+ (long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
657
+ end
658
+
659
+ def compsys(sdone, ldone) # :nodoc:
660
+ sopts, lopts = [], []
661
+ @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
662
+ @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
663
+ return if sopts.empty? and lopts.empty? # completely hidden
664
+
665
+ (sopts+lopts).each do |opt|
666
+ # "(-x -c -r)-l[left justify]"
667
+ if /^--\[no-\](.+)$/ =~ opt
668
+ o = $1
669
+ yield("--#{o}", desc.join(""))
670
+ yield("--no-#{o}", desc.join(""))
671
+ else
672
+ yield("#{opt}", desc.join(""))
673
+ end
674
+ end
675
+ end
676
+
677
+ def pretty_print_contents(q) # :nodoc:
678
+ if @block
679
+ q.text ":" + @block.source_location.join(":") + ":"
680
+ first = false
681
+ else
682
+ first = true
683
+ end
684
+ [@short, @long].each do |list|
685
+ list.each do |opt|
686
+ if first
687
+ q.text ":"
688
+ first = false
689
+ end
690
+ q.breakable
691
+ q.text opt
692
+ end
693
+ end
694
+ end
695
+
696
+ def pretty_print(q) # :nodoc:
697
+ q.object_group(self) {pretty_print_contents(q)}
698
+ end
699
+
700
+ #
701
+ # Switch that takes no arguments.
702
+ #
703
+ class NoArgument < self
704
+
705
+ #
706
+ # Raises an exception if any arguments given.
707
+ #
708
+ def parse(arg, argv)
709
+ yield(NeedlessArgument, arg) if arg
710
+ conv_arg(arg)
711
+ end
712
+
713
+ def self.incompatible_argument_styles(*)
714
+ end
715
+
716
+ def self.pattern
717
+ Object
718
+ end
719
+
720
+ def pretty_head # :nodoc:
721
+ "NoArgument"
722
+ end
723
+ end
724
+
725
+ #
726
+ # Switch that takes an argument.
727
+ #
728
+ class RequiredArgument < self
729
+
730
+ #
731
+ # Raises an exception if argument is not present.
732
+ #
733
+ def parse(arg, argv)
734
+ unless arg
735
+ raise MissingArgument if argv.empty?
736
+ arg = argv.shift
737
+ end
738
+ conv_arg(*parse_arg(arg, &method(:raise)))
739
+ end
740
+
741
+ def pretty_head # :nodoc:
742
+ "Required"
743
+ end
744
+ end
745
+
746
+ #
747
+ # Switch that can omit argument.
748
+ #
749
+ class OptionalArgument < self
750
+
751
+ #
752
+ # Parses argument if given, or uses default value.
753
+ #
754
+ def parse(arg, argv, &error)
755
+ if arg
756
+ conv_arg(*parse_arg(arg, &error))
757
+ else
758
+ conv_arg(arg)
759
+ end
760
+ end
761
+
762
+ def pretty_head # :nodoc:
763
+ "Optional"
764
+ end
765
+ end
766
+
767
+ #
768
+ # Switch that takes an argument, which does not begin with '-' or is '-'.
769
+ #
770
+ class PlacedArgument < self
771
+
772
+ #
773
+ # Returns nil if argument is not present or begins with '-' and is not '-'.
774
+ #
775
+ def parse(arg, argv, &error)
776
+ if !(val = arg) and (argv.empty? or /\A-./ =~ (val = argv[0]))
777
+ return nil, block, nil
778
+ end
779
+ opt = (val = parse_arg(val, &error))[1]
780
+ val = conv_arg(*val)
781
+ if opt and !arg
782
+ argv.shift
783
+ else
784
+ val[0] = nil
785
+ end
786
+ val
787
+ end
788
+
789
+ def pretty_head # :nodoc:
790
+ "Placed"
791
+ end
792
+ end
793
+ end
794
+
795
+ #
796
+ # Simple option list providing mapping from short and/or long option
797
+ # string to Gem::OptionParser::Switch and mapping from acceptable argument to
798
+ # matching pattern and converter pair. Also provides summary feature.
799
+ #
800
+ class List
801
+ # Map from acceptable argument types to pattern and converter pairs.
802
+ attr_reader :atype
803
+
804
+ # Map from short style option switches to actual switch objects.
805
+ attr_reader :short
806
+
807
+ # Map from long style option switches to actual switch objects.
808
+ attr_reader :long
809
+
810
+ # List of all switches and summary string.
811
+ attr_reader :list
812
+
813
+ #
814
+ # Just initializes all instance variables.
815
+ #
816
+ def initialize
817
+ @atype = {}
818
+ @short = OptionMap.new
819
+ @long = OptionMap.new
820
+ @list = []
821
+ end
822
+
823
+ def pretty_print(q) # :nodoc:
824
+ q.group(1, "(", ")") do
825
+ @list.each do |sw|
826
+ next unless Switch === sw
827
+ q.group(1, "(" + sw.pretty_head, ")") do
828
+ sw.pretty_print_contents(q)
829
+ end
830
+ end
831
+ end
832
+ end
833
+
834
+ #
835
+ # See Gem::OptionParser.accept.
836
+ #
837
+ def accept(t, pat = /.*/m, &block)
838
+ if pat
839
+ pat.respond_to?(:match) or
840
+ raise TypeError, "has no `match'", ParseError.filter_backtrace(caller(2))
841
+ else
842
+ pat = t if t.respond_to?(:match)
843
+ end
844
+ unless block
845
+ block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
846
+ end
847
+ @atype[t] = [pat, block]
848
+ end
849
+
850
+ #
851
+ # See Gem::OptionParser.reject.
852
+ #
853
+ def reject(t)
854
+ @atype.delete(t)
855
+ end
856
+
857
+ #
858
+ # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+.
859
+ #
860
+ # +sw+:: Gem::OptionParser::Switch instance to be added.
861
+ # +sopts+:: Short style option list.
862
+ # +lopts+:: Long style option list.
863
+ # +nlopts+:: Negated long style options list.
864
+ #
865
+ def update(sw, sopts, lopts, nsw = nil, nlopts = nil) # :nodoc:
866
+ sopts.each {|o| @short[o] = sw} if sopts
867
+ lopts.each {|o| @long[o] = sw} if lopts
868
+ nlopts.each {|o| @long[o] = nsw} if nsw and nlopts
869
+ used = @short.invert.update(@long.invert)
870
+ @list.delete_if {|o| Switch === o and !used[o]}
871
+ end
872
+ private :update
873
+
874
+ #
875
+ # Inserts +switch+ at the head of the list, and associates short, long
876
+ # and negated long options. Arguments are:
877
+ #
878
+ # +switch+:: Gem::OptionParser::Switch instance to be inserted.
879
+ # +short_opts+:: List of short style options.
880
+ # +long_opts+:: List of long style options.
881
+ # +nolong_opts+:: List of long style options with "no-" prefix.
882
+ #
883
+ # prepend(switch, short_opts, long_opts, nolong_opts)
884
+ #
885
+ def prepend(*args)
886
+ update(*args)
887
+ @list.unshift(args[0])
888
+ end
889
+
890
+ #
891
+ # Appends +switch+ at the tail of the list, and associates short, long
892
+ # and negated long options. Arguments are:
893
+ #
894
+ # +switch+:: Gem::OptionParser::Switch instance to be inserted.
895
+ # +short_opts+:: List of short style options.
896
+ # +long_opts+:: List of long style options.
897
+ # +nolong_opts+:: List of long style options with "no-" prefix.
898
+ #
899
+ # append(switch, short_opts, long_opts, nolong_opts)
900
+ #
901
+ def append(*args)
902
+ update(*args)
903
+ @list.push(args[0])
904
+ end
905
+
906
+ #
907
+ # Searches +key+ in +id+ list. The result is returned or yielded if a
908
+ # block is given. If it isn't found, nil is returned.
909
+ #
910
+ def search(id, key)
911
+ if list = __send__(id)
912
+ val = list.fetch(key) {return nil}
913
+ block_given? ? yield(val) : val
914
+ end
915
+ end
916
+
917
+ #
918
+ # Searches list +id+ for +opt+ and the optional patterns for completion
919
+ # +pat+. If +icase+ is true, the search is case insensitive. The result
920
+ # is returned or yielded if a block is given. If it isn't found, nil is
921
+ # returned.
922
+ #
923
+ def complete(id, opt, icase = false, *pat, &block)
924
+ __send__(id).complete(opt, icase, *pat, &block)
925
+ end
926
+
927
+ def get_candidates(id)
928
+ yield __send__(id).keys
929
+ end
930
+
931
+ #
932
+ # Iterates over each option, passing the option to the +block+.
933
+ #
934
+ def each_option(&block)
935
+ list.each(&block)
936
+ end
937
+
938
+ #
939
+ # Creates the summary table, passing each line to the +block+ (without
940
+ # newline). The arguments +args+ are passed along to the summarize
941
+ # method which is called on every option.
942
+ #
943
+ def summarize(*args, &block)
944
+ sum = []
945
+ list.reverse_each do |opt|
946
+ if opt.respond_to?(:summarize) # perhaps Gem::OptionParser::Switch
947
+ s = []
948
+ opt.summarize(*args) {|l| s << l}
949
+ sum.concat(s.reverse)
950
+ elsif !opt or opt.empty?
951
+ sum << ""
952
+ elsif opt.respond_to?(:each_line)
953
+ sum.concat([*opt.each_line].reverse)
954
+ else
955
+ sum.concat([*opt.each].reverse)
956
+ end
957
+ end
958
+ sum.reverse_each(&block)
959
+ end
960
+
961
+ def add_banner(to) # :nodoc:
962
+ list.each do |opt|
963
+ if opt.respond_to?(:add_banner)
964
+ opt.add_banner(to)
965
+ end
966
+ end
967
+ to
968
+ end
969
+
970
+ def compsys(*args, &block) # :nodoc:
971
+ list.each do |opt|
972
+ if opt.respond_to?(:compsys)
973
+ opt.compsys(*args, &block)
974
+ end
975
+ end
976
+ end
977
+ end
978
+
979
+ #
980
+ # Hash with completion search feature. See Gem::OptionParser::Completion.
981
+ #
982
+ class CompletingHash < Hash
983
+ include Completion
984
+
985
+ #
986
+ # Completion for hash key.
987
+ #
988
+ def match(key)
989
+ *values = fetch(key) {
990
+ raise AmbiguousArgument, catch(:ambiguous) {return complete(key)}
991
+ }
992
+ return key, *values
993
+ end
994
+ end
995
+
996
+ # :stopdoc:
997
+
998
+ #
999
+ # Enumeration of acceptable argument styles. Possible values are:
1000
+ #
1001
+ # NO_ARGUMENT:: The switch takes no arguments. (:NONE)
1002
+ # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED)
1003
+ # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL)
1004
+ #
1005
+ # Use like --switch=argument (long style) or -Xargument (short style). For
1006
+ # short style, only portion matched to argument pattern is treated as
1007
+ # argument.
1008
+ #
1009
+ ArgumentStyle = {}
1010
+ NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument}
1011
+ RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument}
1012
+ OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument}
1013
+ ArgumentStyle.freeze
1014
+
1015
+ #
1016
+ # Switches common used such as '--', and also provides default
1017
+ # argument classes
1018
+ #
1019
+ DefaultList = List.new
1020
+ DefaultList.short['-'] = Switch::NoArgument.new {}
1021
+ DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}
1022
+
1023
+
1024
+ COMPSYS_HEADER = <<'XXX' # :nodoc:
1025
+
1026
+ typeset -A opt_args
1027
+ local context state line
1028
+
1029
+ _arguments -s -S \
1030
+ XXX
1031
+
1032
+ def compsys(to, name = File.basename($0)) # :nodoc:
1033
+ to << "#compdef #{name}\n"
1034
+ to << COMPSYS_HEADER
1035
+ visit(:compsys, {}, {}) {|o, d|
1036
+ to << %Q[ "#{o}[#{d.gsub(/[\"\[\]]/, '\\\\\&')}]" \\\n]
1037
+ }
1038
+ to << " '*:file:_files' && return 0\n"
1039
+ end
1040
+
1041
+ #
1042
+ # Default options for ARGV, which never appear in option summary.
1043
+ #
1044
+ Officious = {}
1045
+
1046
+ #
1047
+ # --help
1048
+ # Shows option summary.
1049
+ #
1050
+ Officious['help'] = proc do |parser|
1051
+ Switch::NoArgument.new do |arg|
1052
+ puts parser.help
1053
+ exit
1054
+ end
1055
+ end
1056
+
1057
+ #
1058
+ # --*-completion-bash=WORD
1059
+ # Shows candidates for command line completion.
1060
+ #
1061
+ Officious['*-completion-bash'] = proc do |parser|
1062
+ Switch::RequiredArgument.new do |arg|
1063
+ puts parser.candidate(arg)
1064
+ exit
1065
+ end
1066
+ end
1067
+
1068
+ #
1069
+ # --*-completion-zsh[=NAME:FILE]
1070
+ # Creates zsh completion file.
1071
+ #
1072
+ Officious['*-completion-zsh'] = proc do |parser|
1073
+ Switch::OptionalArgument.new do |arg|
1074
+ parser.compsys(STDOUT, arg)
1075
+ exit
1076
+ end
1077
+ end
1078
+
1079
+ #
1080
+ # --version
1081
+ # Shows version string if Version is defined.
1082
+ #
1083
+ Officious['version'] = proc do |parser|
1084
+ Switch::OptionalArgument.new do |pkg|
1085
+ if pkg
1086
+ begin
1087
+ require 'rubygems/optparse/lib/optparse/version'
1088
+ rescue LoadError
1089
+ else
1090
+ show_version(*pkg.split(/,/)) or
1091
+ abort("#{parser.program_name}: no version found in package #{pkg}")
1092
+ exit
1093
+ end
1094
+ end
1095
+ v = parser.ver or abort("#{parser.program_name}: version unknown")
1096
+ puts v
1097
+ exit
1098
+ end
1099
+ end
1100
+
1101
+ # :startdoc:
1102
+
1103
+ #
1104
+ # Class methods
1105
+ #
1106
+
1107
+ #
1108
+ # Initializes a new instance and evaluates the optional block in context
1109
+ # of the instance. Arguments +args+ are passed to #new, see there for
1110
+ # description of parameters.
1111
+ #
1112
+ # This method is *deprecated*, its behavior corresponds to the older #new
1113
+ # method.
1114
+ #
1115
+ def self.with(*args, &block)
1116
+ opts = new(*args)
1117
+ opts.instance_eval(&block)
1118
+ opts
1119
+ end
1120
+
1121
+ #
1122
+ # Returns an incremented value of +default+ according to +arg+.
1123
+ #
1124
+ def self.inc(arg, default = nil)
1125
+ case arg
1126
+ when Integer
1127
+ arg.nonzero?
1128
+ when nil
1129
+ default.to_i + 1
1130
+ end
1131
+ end
1132
+ def inc(*args)
1133
+ self.class.inc(*args)
1134
+ end
1135
+
1136
+ #
1137
+ # Initializes the instance and yields itself if called with a block.
1138
+ #
1139
+ # +banner+:: Banner message.
1140
+ # +width+:: Summary width.
1141
+ # +indent+:: Summary indent.
1142
+ #
1143
+ def initialize(banner = nil, width = 32, indent = ' ' * 4)
1144
+ @stack = [DefaultList, List.new, List.new]
1145
+ @program_name = nil
1146
+ @banner = banner
1147
+ @summary_width = width
1148
+ @summary_indent = indent
1149
+ @default_argv = ARGV
1150
+ @require_exact = false
1151
+ @raise_unknown = true
1152
+ add_officious
1153
+ yield self if block_given?
1154
+ end
1155
+
1156
+ def add_officious # :nodoc:
1157
+ list = base()
1158
+ Officious.each do |opt, block|
1159
+ list.long[opt] ||= block.call(self)
1160
+ end
1161
+ end
1162
+
1163
+ #
1164
+ # Terminates option parsing. Optional parameter +arg+ is a string pushed
1165
+ # back to be the first non-option argument.
1166
+ #
1167
+ def terminate(arg = nil)
1168
+ self.class.terminate(arg)
1169
+ end
1170
+ def self.terminate(arg = nil)
1171
+ throw :terminate, arg
1172
+ end
1173
+
1174
+ @stack = [DefaultList]
1175
+ def self.top() DefaultList end
1176
+
1177
+ #
1178
+ # Directs to accept specified class +t+. The argument string is passed to
1179
+ # the block in which it should be converted to the desired class.
1180
+ #
1181
+ # +t+:: Argument class specifier, any object including Class.
1182
+ # +pat+:: Pattern for argument, defaults to +t+ if it responds to match.
1183
+ #
1184
+ # accept(t, pat, &block)
1185
+ #
1186
+ def accept(*args, &blk) top.accept(*args, &blk) end
1187
+ #
1188
+ # See #accept.
1189
+ #
1190
+ def self.accept(*args, &blk) top.accept(*args, &blk) end
1191
+
1192
+ #
1193
+ # Directs to reject specified class argument.
1194
+ #
1195
+ # +t+:: Argument class specifier, any object including Class.
1196
+ #
1197
+ # reject(t)
1198
+ #
1199
+ def reject(*args, &blk) top.reject(*args, &blk) end
1200
+ #
1201
+ # See #reject.
1202
+ #
1203
+ def self.reject(*args, &blk) top.reject(*args, &blk) end
1204
+
1205
+ #
1206
+ # Instance methods
1207
+ #
1208
+
1209
+ # Heading banner preceding summary.
1210
+ attr_writer :banner
1211
+
1212
+ # Program name to be emitted in error message and default banner,
1213
+ # defaults to $0.
1214
+ attr_writer :program_name
1215
+
1216
+ # Width for option list portion of summary. Must be Numeric.
1217
+ attr_accessor :summary_width
1218
+
1219
+ # Indentation for summary. Must be String (or have + String method).
1220
+ attr_accessor :summary_indent
1221
+
1222
+ # Strings to be parsed in default.
1223
+ attr_accessor :default_argv
1224
+
1225
+ # Whether to require that options match exactly (disallows providing
1226
+ # abbreviated long option as short option).
1227
+ attr_accessor :require_exact
1228
+
1229
+ # Whether to raise at unknown option.
1230
+ attr_accessor :raise_unknown
1231
+
1232
+ #
1233
+ # Heading banner preceding summary.
1234
+ #
1235
+ def banner
1236
+ unless @banner
1237
+ @banner = +"Usage: #{program_name} [options]"
1238
+ visit(:add_banner, @banner)
1239
+ end
1240
+ @banner
1241
+ end
1242
+
1243
+ #
1244
+ # Program name to be emitted in error message and default banner, defaults
1245
+ # to $0.
1246
+ #
1247
+ def program_name
1248
+ @program_name || File.basename($0, '.*')
1249
+ end
1250
+
1251
+ # for experimental cascading :-)
1252
+ alias set_banner banner=
1253
+ alias set_program_name program_name=
1254
+ alias set_summary_width summary_width=
1255
+ alias set_summary_indent summary_indent=
1256
+
1257
+ # Version
1258
+ attr_writer :version
1259
+ # Release code
1260
+ attr_writer :release
1261
+
1262
+ #
1263
+ # Version
1264
+ #
1265
+ def version
1266
+ (defined?(@version) && @version) || (defined?(::Version) && ::Version)
1267
+ end
1268
+
1269
+ #
1270
+ # Release code
1271
+ #
1272
+ def release
1273
+ (defined?(@release) && @release) || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
1274
+ end
1275
+
1276
+ #
1277
+ # Returns version string from program_name, version and release.
1278
+ #
1279
+ def ver
1280
+ if v = version
1281
+ str = +"#{program_name} #{[v].join('.')}"
1282
+ str << " (#{v})" if v = release
1283
+ str
1284
+ end
1285
+ end
1286
+
1287
+ def warn(mesg = $!)
1288
+ super("#{program_name}: #{mesg}")
1289
+ end
1290
+
1291
+ def abort(mesg = $!)
1292
+ super("#{program_name}: #{mesg}")
1293
+ end
1294
+
1295
+ #
1296
+ # Subject of #on / #on_head, #accept / #reject
1297
+ #
1298
+ def top
1299
+ @stack[-1]
1300
+ end
1301
+
1302
+ #
1303
+ # Subject of #on_tail.
1304
+ #
1305
+ def base
1306
+ @stack[1]
1307
+ end
1308
+
1309
+ #
1310
+ # Pushes a new List.
1311
+ #
1312
+ def new
1313
+ @stack.push(List.new)
1314
+ if block_given?
1315
+ yield self
1316
+ else
1317
+ self
1318
+ end
1319
+ end
1320
+
1321
+ #
1322
+ # Removes the last List.
1323
+ #
1324
+ def remove
1325
+ @stack.pop
1326
+ end
1327
+
1328
+ #
1329
+ # Puts option summary into +to+ and returns +to+. Yields each line if
1330
+ # a block is given.
1331
+ #
1332
+ # +to+:: Output destination, which must have method <<. Defaults to [].
1333
+ # +width+:: Width of left side, defaults to @summary_width.
1334
+ # +max+:: Maximum length allowed for left side, defaults to +width+ - 1.
1335
+ # +indent+:: Indentation, defaults to @summary_indent.
1336
+ #
1337
+ def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)
1338
+ nl = "\n"
1339
+ blk ||= proc {|l| to << (l.index(nl, -1) ? l : l + nl)}
1340
+ visit(:summarize, {}, {}, width, max, indent, &blk)
1341
+ to
1342
+ end
1343
+
1344
+ #
1345
+ # Returns option summary string.
1346
+ #
1347
+ def help; summarize("#{banner}".sub(/\n?\z/, "\n")) end
1348
+ alias to_s help
1349
+
1350
+ def pretty_print(q) # :nodoc:
1351
+ q.object_group(self) do
1352
+ first = true
1353
+ if @stack.size > 2
1354
+ @stack.each_with_index do |s, i|
1355
+ next if i < 2
1356
+ next if s.list.empty?
1357
+ if first
1358
+ first = false
1359
+ q.text ":"
1360
+ end
1361
+ q.breakable
1362
+ s.pretty_print(q)
1363
+ end
1364
+ end
1365
+ end
1366
+ end
1367
+
1368
+ def inspect # :nodoc:
1369
+ require 'pp'
1370
+ pretty_print_inspect
1371
+ end
1372
+
1373
+ #
1374
+ # Returns option summary list.
1375
+ #
1376
+ def to_a; summarize("#{banner}".split(/^/)) end
1377
+
1378
+ #
1379
+ # Checks if an argument is given twice, in which case an ArgumentError is
1380
+ # raised. Called from Gem::OptionParser#switch only.
1381
+ #
1382
+ # +obj+:: New argument.
1383
+ # +prv+:: Previously specified argument.
1384
+ # +msg+:: Exception message.
1385
+ #
1386
+ def notwice(obj, prv, msg) # :nodoc:
1387
+ unless !prv or prv == obj
1388
+ raise(ArgumentError, "argument #{msg} given twice: #{obj}",
1389
+ ParseError.filter_backtrace(caller(2)))
1390
+ end
1391
+ obj
1392
+ end
1393
+ private :notwice
1394
+
1395
+ SPLAT_PROC = proc {|*a| a.length <= 1 ? a.first : a} # :nodoc:
1396
+
1397
+ # :call-seq:
1398
+ # make_switch(params, block = nil)
1399
+ #
1400
+ # :include: ../doc/optparse/creates_option.rdoc
1401
+ #
1402
+ def make_switch(opts, block = nil)
1403
+ short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
1404
+ ldesc, sdesc, desc, arg = [], [], []
1405
+ default_style = Switch::NoArgument
1406
+ default_pattern = nil
1407
+ klass = nil
1408
+ q, a = nil
1409
+ has_arg = false
1410
+
1411
+ opts.each do |o|
1412
+ # argument class
1413
+ next if search(:atype, o) do |pat, c|
1414
+ klass = notwice(o, klass, 'type')
1415
+ if not_style and not_style != Switch::NoArgument
1416
+ not_pattern, not_conv = pat, c
1417
+ else
1418
+ default_pattern, conv = pat, c
1419
+ end
1420
+ end
1421
+
1422
+ # directly specified pattern(any object possible to match)
1423
+ if (!(String === o || Symbol === o)) and o.respond_to?(:match)
1424
+ pattern = notwice(o, pattern, 'pattern')
1425
+ if pattern.respond_to?(:convert)
1426
+ conv = pattern.method(:convert).to_proc
1427
+ else
1428
+ conv = SPLAT_PROC
1429
+ end
1430
+ next
1431
+ end
1432
+
1433
+ # anything others
1434
+ case o
1435
+ when Proc, Method
1436
+ block = notwice(o, block, 'block')
1437
+ when Array, Hash
1438
+ case pattern
1439
+ when CompletingHash
1440
+ when nil
1441
+ pattern = CompletingHash.new
1442
+ conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
1443
+ else
1444
+ raise ArgumentError, "argument pattern given twice"
1445
+ end
1446
+ o.each {|pat, *v| pattern[pat] = v.fetch(0) {pat}}
1447
+ when Module
1448
+ raise ArgumentError, "unsupported argument type: #{o}", ParseError.filter_backtrace(caller(4))
1449
+ when *ArgumentStyle.keys
1450
+ style = notwice(ArgumentStyle[o], style, 'style')
1451
+ when /^--no-([^\[\]=\s]*)(.+)?/
1452
+ q, a = $1, $2
1453
+ o = notwice(a ? Object : TrueClass, klass, 'type')
1454
+ not_pattern, not_conv = search(:atype, o) unless not_style
1455
+ not_style = (not_style || default_style).guess(arg = a) if a
1456
+ default_style = Switch::NoArgument
1457
+ default_pattern, conv = search(:atype, FalseClass) unless default_pattern
1458
+ ldesc << "--no-#{q}"
1459
+ (q = q.downcase).tr!('_', '-')
1460
+ long << "no-#{q}"
1461
+ nolong << q
1462
+ when /^--\[no-\]([^\[\]=\s]*)(.+)?/
1463
+ q, a = $1, $2
1464
+ o = notwice(a ? Object : TrueClass, klass, 'type')
1465
+ if a
1466
+ default_style = default_style.guess(arg = a)
1467
+ default_pattern, conv = search(:atype, o) unless default_pattern
1468
+ end
1469
+ ldesc << "--[no-]#{q}"
1470
+ (o = q.downcase).tr!('_', '-')
1471
+ long << o
1472
+ not_pattern, not_conv = search(:atype, FalseClass) unless not_style
1473
+ not_style = Switch::NoArgument
1474
+ nolong << "no-#{o}"
1475
+ when /^--([^\[\]=\s]*)(.+)?/
1476
+ q, a = $1, $2
1477
+ if a
1478
+ o = notwice(NilClass, klass, 'type')
1479
+ default_style = default_style.guess(arg = a)
1480
+ default_pattern, conv = search(:atype, o) unless default_pattern
1481
+ end
1482
+ ldesc << "--#{q}"
1483
+ (o = q.downcase).tr!('_', '-')
1484
+ long << o
1485
+ when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/
1486
+ q, a = $1, $2
1487
+ o = notwice(Object, klass, 'type')
1488
+ if a
1489
+ default_style = default_style.guess(arg = a)
1490
+ default_pattern, conv = search(:atype, o) unless default_pattern
1491
+ else
1492
+ has_arg = true
1493
+ end
1494
+ sdesc << "-#{q}"
1495
+ short << Regexp.new(q)
1496
+ when /^-(.)(.+)?/
1497
+ q, a = $1, $2
1498
+ if a
1499
+ o = notwice(NilClass, klass, 'type')
1500
+ default_style = default_style.guess(arg = a)
1501
+ default_pattern, conv = search(:atype, o) unless default_pattern
1502
+ end
1503
+ sdesc << "-#{q}"
1504
+ short << q
1505
+ when /^=/
1506
+ style = notwice(default_style.guess(arg = o), style, 'style')
1507
+ default_pattern, conv = search(:atype, Object) unless default_pattern
1508
+ else
1509
+ desc.push(o) if o && !o.empty?
1510
+ end
1511
+ end
1512
+
1513
+ default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
1514
+ if !(short.empty? and long.empty?)
1515
+ if has_arg and default_style == Switch::NoArgument
1516
+ default_style = Switch::RequiredArgument
1517
+ end
1518
+ s = (style || default_style).new(pattern || default_pattern,
1519
+ conv, sdesc, ldesc, arg, desc, block)
1520
+ elsif !block
1521
+ if style or pattern
1522
+ raise ArgumentError, "no switch given", ParseError.filter_backtrace(caller)
1523
+ end
1524
+ s = desc
1525
+ else
1526
+ short << pattern
1527
+ s = (style || default_style).new(pattern,
1528
+ conv, nil, nil, arg, desc, block)
1529
+ end
1530
+ return s, short, long,
1531
+ (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
1532
+ nolong
1533
+ end
1534
+
1535
+ # :call-seq:
1536
+ # define(*params, &block)
1537
+ #
1538
+ # :include: ../doc/optparse/creates_option.rdoc
1539
+ #
1540
+ def define(*opts, &block)
1541
+ top.append(*(sw = make_switch(opts, block)))
1542
+ sw[0]
1543
+ end
1544
+
1545
+ # :call-seq:
1546
+ # on(*params, &block)
1547
+ #
1548
+ # :include: ../doc/optparse/creates_option.rdoc
1549
+ #
1550
+ def on(*opts, &block)
1551
+ define(*opts, &block)
1552
+ self
1553
+ end
1554
+ alias def_option define
1555
+
1556
+ # :call-seq:
1557
+ # define_head(*params, &block)
1558
+ #
1559
+ # :include: ../doc/optparse/creates_option.rdoc
1560
+ #
1561
+ def define_head(*opts, &block)
1562
+ top.prepend(*(sw = make_switch(opts, block)))
1563
+ sw[0]
1564
+ end
1565
+
1566
+ # :call-seq:
1567
+ # on_head(*params, &block)
1568
+ #
1569
+ # :include: ../doc/optparse/creates_option.rdoc
1570
+ #
1571
+ # The new option is added at the head of the summary.
1572
+ #
1573
+ def on_head(*opts, &block)
1574
+ define_head(*opts, &block)
1575
+ self
1576
+ end
1577
+ alias def_head_option define_head
1578
+
1579
+ # :call-seq:
1580
+ # define_tail(*params, &block)
1581
+ #
1582
+ # :include: ../doc/optparse/creates_option.rdoc
1583
+ #
1584
+ def define_tail(*opts, &block)
1585
+ base.append(*(sw = make_switch(opts, block)))
1586
+ sw[0]
1587
+ end
1588
+
1589
+ #
1590
+ # :call-seq:
1591
+ # on_tail(*params, &block)
1592
+ #
1593
+ # :include: ../doc/optparse/creates_option.rdoc
1594
+ #
1595
+ # The new option is added at the tail of the summary.
1596
+ #
1597
+ def on_tail(*opts, &block)
1598
+ define_tail(*opts, &block)
1599
+ self
1600
+ end
1601
+ alias def_tail_option define_tail
1602
+
1603
+ #
1604
+ # Add separator in summary.
1605
+ #
1606
+ def separator(string)
1607
+ top.append(string, nil, nil)
1608
+ end
1609
+
1610
+ #
1611
+ # Parses command line arguments +argv+ in order. When a block is given,
1612
+ # each non-option argument is yielded. When optional +into+ keyword
1613
+ # argument is provided, the parsed option values are stored there via
1614
+ # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
1615
+ # similar object).
1616
+ #
1617
+ # Returns the rest of +argv+ left unparsed.
1618
+ #
1619
+ def order(*argv, into: nil, &nonopt)
1620
+ argv = argv[0].dup if argv.size == 1 and Array === argv[0]
1621
+ order!(argv, into: into, &nonopt)
1622
+ end
1623
+
1624
+ #
1625
+ # Same as #order, but removes switches destructively.
1626
+ # Non-option arguments remain in +argv+.
1627
+ #
1628
+ def order!(argv = default_argv, into: nil, &nonopt)
1629
+ setter = ->(name, val) {into[name.to_sym] = val} if into
1630
+ parse_in_order(argv, setter, &nonopt)
1631
+ end
1632
+
1633
+ def parse_in_order(argv = default_argv, setter = nil, &nonopt) # :nodoc:
1634
+ opt, arg, val, rest = nil
1635
+ nonopt ||= proc {|a| throw :terminate, a}
1636
+ argv.unshift(arg) if arg = catch(:terminate) {
1637
+ while arg = argv.shift
1638
+ case arg
1639
+ # long option
1640
+ when /\A--([^=]*)(?:=(.*))?/m
1641
+ opt, rest = $1, $2
1642
+ opt.tr!('_', '-')
1643
+ begin
1644
+ sw, = complete(:long, opt, true)
1645
+ if require_exact && !sw.long.include?(arg)
1646
+ throw :terminate, arg unless raise_unknown
1647
+ raise InvalidOption, arg
1648
+ end
1649
+ rescue ParseError
1650
+ throw :terminate, arg unless raise_unknown
1651
+ raise $!.set_option(arg, true)
1652
+ end
1653
+ begin
1654
+ opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)}
1655
+ val = cb.call(val) if cb
1656
+ setter.call(sw.switch_name, val) if setter
1657
+ rescue ParseError
1658
+ raise $!.set_option(arg, rest)
1659
+ end
1660
+
1661
+ # short option
1662
+ when /\A-(.)((=).*|.+)?/m
1663
+ eq, rest, opt = $3, $2, $1
1664
+ has_arg, val = eq, rest
1665
+ begin
1666
+ sw, = search(:short, opt)
1667
+ unless sw
1668
+ begin
1669
+ sw, = complete(:short, opt)
1670
+ # short option matched.
1671
+ val = arg.delete_prefix('-')
1672
+ has_arg = true
1673
+ rescue InvalidOption
1674
+ raise if require_exact
1675
+ # if no short options match, try completion with long
1676
+ # options.
1677
+ sw, = complete(:long, opt)
1678
+ eq ||= !rest
1679
+ end
1680
+ end
1681
+ rescue ParseError
1682
+ throw :terminate, arg unless raise_unknown
1683
+ raise $!.set_option(arg, true)
1684
+ end
1685
+ begin
1686
+ opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}
1687
+ rescue ParseError
1688
+ raise $!.set_option(arg, arg.length > 2)
1689
+ else
1690
+ raise InvalidOption, arg if has_arg and !eq and arg == "-#{opt}"
1691
+ end
1692
+ begin
1693
+ argv.unshift(opt) if opt and (!rest or (opt = opt.sub(/\A-*/, '-')) != '-')
1694
+ val = cb.call(val) if cb
1695
+ setter.call(sw.switch_name, val) if setter
1696
+ rescue ParseError
1697
+ raise $!.set_option(arg, arg.length > 2)
1698
+ end
1699
+
1700
+ # non-option argument
1701
+ else
1702
+ catch(:prune) do
1703
+ visit(:each_option) do |sw0|
1704
+ sw = sw0
1705
+ sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg)
1706
+ end
1707
+ nonopt.call(arg)
1708
+ end
1709
+ end
1710
+ end
1711
+
1712
+ nil
1713
+ }
1714
+
1715
+ visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern}
1716
+
1717
+ argv
1718
+ end
1719
+ private :parse_in_order
1720
+
1721
+ #
1722
+ # Parses command line arguments +argv+ in permutation mode and returns
1723
+ # list of non-option arguments. When optional +into+ keyword
1724
+ # argument is provided, the parsed option values are stored there via
1725
+ # <code>[]=</code> method (so it can be Hash, or OpenStruct, or other
1726
+ # similar object).
1727
+ #
1728
+ def permute(*argv, into: nil)
1729
+ argv = argv[0].dup if argv.size == 1 and Array === argv[0]
1730
+ permute!(argv, into: into)
1731
+ end
1732
+
1733
+ #
1734
+ # Same as #permute, but removes switches destructively.
1735
+ # Non-option arguments remain in +argv+.
1736
+ #
1737
+ def permute!(argv = default_argv, into: nil)
1738
+ nonopts = []
1739
+ order!(argv, into: into, &nonopts.method(:<<))
1740
+ argv[0, 0] = nonopts
1741
+ argv
1742
+ end
1743
+
1744
+ #
1745
+ # Parses command line arguments +argv+ in order when environment variable
1746
+ # POSIXLY_CORRECT is set, and in permutation mode otherwise.
1747
+ # When optional +into+ keyword argument is provided, the parsed option
1748
+ # values are stored there via <code>[]=</code> method (so it can be Hash,
1749
+ # or OpenStruct, or other similar object).
1750
+ #
1751
+ def parse(*argv, into: nil)
1752
+ argv = argv[0].dup if argv.size == 1 and Array === argv[0]
1753
+ parse!(argv, into: into)
1754
+ end
1755
+
1756
+ #
1757
+ # Same as #parse, but removes switches destructively.
1758
+ # Non-option arguments remain in +argv+.
1759
+ #
1760
+ def parse!(argv = default_argv, into: nil)
1761
+ if ENV.include?('POSIXLY_CORRECT')
1762
+ order!(argv, into: into)
1763
+ else
1764
+ permute!(argv, into: into)
1765
+ end
1766
+ end
1767
+
1768
+ #
1769
+ # Wrapper method for getopts.rb.
1770
+ #
1771
+ # params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option")
1772
+ # # params["a"] = true # -a
1773
+ # # params["b"] = "1" # -b1
1774
+ # # params["foo"] = "1" # --foo
1775
+ # # params["bar"] = "x" # --bar x
1776
+ # # params["zot"] = "z" # --zot Z
1777
+ #
1778
+ def getopts(*args)
1779
+ argv = Array === args.first ? args.shift : default_argv
1780
+ single_options, *long_options = *args
1781
+
1782
+ result = {}
1783
+
1784
+ single_options.scan(/(.)(:)?/) do |opt, val|
1785
+ if val
1786
+ result[opt] = nil
1787
+ define("-#{opt} VAL")
1788
+ else
1789
+ result[opt] = false
1790
+ define("-#{opt}")
1791
+ end
1792
+ end if single_options
1793
+
1794
+ long_options.each do |arg|
1795
+ arg, desc = arg.split(';', 2)
1796
+ opt, val = arg.split(':', 2)
1797
+ if val
1798
+ result[opt] = val.empty? ? nil : val
1799
+ define("--#{opt}=#{result[opt] || "VAL"}", *[desc].compact)
1800
+ else
1801
+ result[opt] = false
1802
+ define("--#{opt}", *[desc].compact)
1803
+ end
1804
+ end
1805
+
1806
+ parse_in_order(argv, result.method(:[]=))
1807
+ result
1808
+ end
1809
+
1810
+ #
1811
+ # See #getopts.
1812
+ #
1813
+ def self.getopts(*args)
1814
+ new.getopts(*args)
1815
+ end
1816
+
1817
+ #
1818
+ # Traverses @stack, sending each element method +id+ with +args+ and
1819
+ # +block+.
1820
+ #
1821
+ def visit(id, *args, &block) # :nodoc:
1822
+ @stack.reverse_each do |el|
1823
+ el.__send__(id, *args, &block)
1824
+ end
1825
+ nil
1826
+ end
1827
+ private :visit
1828
+
1829
+ #
1830
+ # Searches +key+ in @stack for +id+ hash and returns or yields the result.
1831
+ #
1832
+ def search(id, key) # :nodoc:
1833
+ block_given = block_given?
1834
+ visit(:search, id, key) do |k|
1835
+ return block_given ? yield(k) : k
1836
+ end
1837
+ end
1838
+ private :search
1839
+
1840
+ #
1841
+ # Completes shortened long style option switch and returns pair of
1842
+ # canonical switch and switch descriptor Gem::OptionParser::Switch.
1843
+ #
1844
+ # +typ+:: Searching table.
1845
+ # +opt+:: Searching key.
1846
+ # +icase+:: Search case insensitive if true.
1847
+ # +pat+:: Optional pattern for completion.
1848
+ #
1849
+ def complete(typ, opt, icase = false, *pat) # :nodoc:
1850
+ if pat.empty?
1851
+ search(typ, opt) {|sw| return [sw, opt]} # exact match or...
1852
+ end
1853
+ ambiguous = catch(:ambiguous) {
1854
+ visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
1855
+ }
1856
+ exc = ambiguous ? AmbiguousOption : InvalidOption
1857
+ raise exc.new(opt, additional: self.method(:additional_message).curry[typ])
1858
+ end
1859
+ private :complete
1860
+
1861
+ #
1862
+ # Returns additional info.
1863
+ #
1864
+ def additional_message(typ, opt)
1865
+ return unless typ and opt and defined?(DidYouMean::SpellChecker)
1866
+ all_candidates = []
1867
+ visit(:get_candidates, typ) do |candidates|
1868
+ all_candidates.concat(candidates)
1869
+ end
1870
+ all_candidates.select! {|cand| cand.is_a?(String) }
1871
+ checker = DidYouMean::SpellChecker.new(dictionary: all_candidates)
1872
+ DidYouMean.formatter.message_for(all_candidates & checker.correct(opt))
1873
+ end
1874
+
1875
+ def candidate(word)
1876
+ list = []
1877
+ case word
1878
+ when '-'
1879
+ long = short = true
1880
+ when /\A--/
1881
+ word, arg = word.split(/=/, 2)
1882
+ argpat = Completion.regexp(arg, false) if arg and !arg.empty?
1883
+ long = true
1884
+ when /\A-/
1885
+ short = true
1886
+ end
1887
+ pat = Completion.regexp(word, long)
1888
+ visit(:each_option) do |opt|
1889
+ next unless Switch === opt
1890
+ opts = (long ? opt.long : []) + (short ? opt.short : [])
1891
+ opts = Completion.candidate(word, true, pat, &opts.method(:each)).map(&:first) if pat
1892
+ if /\A=/ =~ opt.arg
1893
+ opts.map! {|sw| sw + "="}
1894
+ if arg and CompletingHash === opt.pattern
1895
+ if opts = opt.pattern.candidate(arg, false, argpat)
1896
+ opts.map!(&:last)
1897
+ end
1898
+ end
1899
+ end
1900
+ list.concat(opts)
1901
+ end
1902
+ list
1903
+ end
1904
+
1905
+ #
1906
+ # Loads options from file names as +filename+. Does nothing when the file
1907
+ # is not present. Returns whether successfully loaded.
1908
+ #
1909
+ # +filename+ defaults to basename of the program without suffix in a
1910
+ # directory ~/.options, then the basename with '.options' suffix
1911
+ # under XDG and Haiku standard places.
1912
+ #
1913
+ # The optional +into+ keyword argument works exactly like that accepted in
1914
+ # method #parse.
1915
+ #
1916
+ def load(filename = nil, into: nil)
1917
+ unless filename
1918
+ basename = File.basename($0, '.*')
1919
+ return true if load(File.expand_path(basename, '~/.options'), into: into) rescue nil
1920
+ basename << ".options"
1921
+ return [
1922
+ # XDG
1923
+ ENV['XDG_CONFIG_HOME'],
1924
+ '~/.config',
1925
+ *ENV['XDG_CONFIG_DIRS']&.split(File::PATH_SEPARATOR),
1926
+
1927
+ # Haiku
1928
+ '~/config/settings',
1929
+ ].any? {|dir|
1930
+ next if !dir or dir.empty?
1931
+ load(File.expand_path(basename, dir), into: into) rescue nil
1932
+ }
1933
+ end
1934
+ begin
1935
+ parse(*File.readlines(filename, chomp: true), into: into)
1936
+ true
1937
+ rescue Errno::ENOENT, Errno::ENOTDIR
1938
+ false
1939
+ end
1940
+ end
1941
+
1942
+ #
1943
+ # Parses environment variable +env+ or its uppercase with splitting like a
1944
+ # shell.
1945
+ #
1946
+ # +env+ defaults to the basename of the program.
1947
+ #
1948
+ def environment(env = File.basename($0, '.*'))
1949
+ env = ENV[env] || ENV[env.upcase] or return
1950
+ require 'shellwords'
1951
+ parse(*Shellwords.shellwords(env))
1952
+ end
1953
+
1954
+ #
1955
+ # Acceptable argument classes
1956
+ #
1957
+
1958
+ #
1959
+ # Any string and no conversion. This is fall-back.
1960
+ #
1961
+ accept(Object) {|s,|s or s.nil?}
1962
+
1963
+ accept(NilClass) {|s,|s}
1964
+
1965
+ #
1966
+ # Any non-empty string, and no conversion.
1967
+ #
1968
+ accept(String, /.+/m) {|s,*|s}
1969
+
1970
+ #
1971
+ # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal
1972
+ # for 0x, and decimal for others; with optional sign prefix. Converts to
1973
+ # Integer.
1974
+ #
1975
+ decimal = '\d+(?:_\d+)*'
1976
+ binary = 'b[01]+(?:_[01]+)*'
1977
+ hex = 'x[\da-f]+(?:_[\da-f]+)*'
1978
+ octal = "0(?:[0-7]+(?:_[0-7]+)*|#{binary}|#{hex})?"
1979
+ integer = "#{octal}|#{decimal}"
1980
+
1981
+ accept(Integer, %r"\A[-+]?(?:#{integer})\z"io) {|s,|
1982
+ begin
1983
+ Integer(s)
1984
+ rescue ArgumentError
1985
+ raise Gem::OptionParser::InvalidArgument, s
1986
+ end if s
1987
+ }
1988
+
1989
+ #
1990
+ # Float number format, and converts to Float.
1991
+ #
1992
+ float = "(?:#{decimal}(?=(.)?)(?:\\.(?:#{decimal})?)?|\\.#{decimal})(?:E[-+]?#{decimal})?"
1993
+ floatpat = %r"\A[-+]?#{float}\z"io
1994
+ accept(Float, floatpat) {|s,| s.to_f if s}
1995
+
1996
+ #
1997
+ # Generic numeric format, converts to Integer for integer format, Float
1998
+ # for float format, and Rational for rational format.
1999
+ #
2000
+ real = "[-+]?(?:#{octal}|#{float})"
2001
+ accept(Numeric, /\A(#{real})(?:\/(#{real}))?\z/io) {|s, d, f, n,|
2002
+ if n
2003
+ Rational(d, n)
2004
+ elsif f
2005
+ Float(s)
2006
+ else
2007
+ Integer(s)
2008
+ end
2009
+ }
2010
+
2011
+ #
2012
+ # Decimal integer format, to be converted to Integer.
2013
+ #
2014
+ DecimalInteger = /\A[-+]?#{decimal}\z/io
2015
+ accept(DecimalInteger, DecimalInteger) {|s,|
2016
+ begin
2017
+ Integer(s, 10)
2018
+ rescue ArgumentError
2019
+ raise Gem::OptionParser::InvalidArgument, s
2020
+ end if s
2021
+ }
2022
+
2023
+ #
2024
+ # Ruby/C like octal/hexadecimal/binary integer format, to be converted to
2025
+ # Integer.
2026
+ #
2027
+ OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))\z/io
2028
+ accept(OctalInteger, OctalInteger) {|s,|
2029
+ begin
2030
+ Integer(s, 8)
2031
+ rescue ArgumentError
2032
+ raise Gem::OptionParser::InvalidArgument, s
2033
+ end if s
2034
+ }
2035
+
2036
+ #
2037
+ # Decimal integer/float number format, to be converted to Integer for
2038
+ # integer format, Float for float format.
2039
+ #
2040
+ DecimalNumeric = floatpat # decimal integer is allowed as float also.
2041
+ accept(DecimalNumeric, floatpat) {|s, f|
2042
+ begin
2043
+ if f
2044
+ Float(s)
2045
+ else
2046
+ Integer(s)
2047
+ end
2048
+ rescue ArgumentError
2049
+ raise Gem::OptionParser::InvalidArgument, s
2050
+ end if s
2051
+ }
2052
+
2053
+ #
2054
+ # Boolean switch, which means whether it is present or not, whether it is
2055
+ # absent or not with prefix no-, or it takes an argument
2056
+ # yes/no/true/false/+/-.
2057
+ #
2058
+ yesno = CompletingHash.new
2059
+ %w[- no false].each {|el| yesno[el] = false}
2060
+ %w[+ yes true].each {|el| yesno[el] = true}
2061
+ yesno['nil'] = false # should be nil?
2062
+ accept(TrueClass, yesno) {|arg, val| val == nil or val}
2063
+ #
2064
+ # Similar to TrueClass, but defaults to false.
2065
+ #
2066
+ accept(FalseClass, yesno) {|arg, val| val != nil and val}
2067
+
2068
+ #
2069
+ # List of strings separated by ",".
2070
+ #
2071
+ accept(Array) do |s, |
2072
+ if s
2073
+ s = s.split(',').collect {|ss| ss unless ss.empty?}
2074
+ end
2075
+ s
2076
+ end
2077
+
2078
+ #
2079
+ # Regular expression with options.
2080
+ #
2081
+ accept(Regexp, %r"\A/((?:\\.|[^\\])*)/([[:alpha:]]+)?\z|.*") do |all, s, o|
2082
+ f = 0
2083
+ if o
2084
+ f |= Regexp::IGNORECASE if /i/ =~ o
2085
+ f |= Regexp::MULTILINE if /m/ =~ o
2086
+ f |= Regexp::EXTENDED if /x/ =~ o
2087
+ k = o.delete("imx")
2088
+ k = nil if k.empty?
2089
+ end
2090
+ Regexp.new(s || all, f, k)
2091
+ end
2092
+
2093
+ #
2094
+ # Exceptions
2095
+ #
2096
+
2097
+ #
2098
+ # Base class of exceptions from Gem::OptionParser.
2099
+ #
2100
+ class ParseError < RuntimeError
2101
+ # Reason which caused the error.
2102
+ Reason = 'parse error'
2103
+
2104
+ def initialize(*args, additional: nil)
2105
+ @additional = additional
2106
+ @arg0, = args
2107
+ @args = args
2108
+ @reason = nil
2109
+ end
2110
+
2111
+ attr_reader :args
2112
+ attr_writer :reason
2113
+ attr_accessor :additional
2114
+
2115
+ #
2116
+ # Pushes back erred argument(s) to +argv+.
2117
+ #
2118
+ def recover(argv)
2119
+ argv[0, 0] = @args
2120
+ argv
2121
+ end
2122
+
2123
+ def self.filter_backtrace(array)
2124
+ unless $DEBUG
2125
+ array.delete_if(&%r"\A#{Regexp.quote(__FILE__)}:"o.method(:=~))
2126
+ end
2127
+ array
2128
+ end
2129
+
2130
+ def set_backtrace(array)
2131
+ super(self.class.filter_backtrace(array))
2132
+ end
2133
+
2134
+ def set_option(opt, eq)
2135
+ if eq
2136
+ @args[0] = opt
2137
+ else
2138
+ @args.unshift(opt)
2139
+ end
2140
+ self
2141
+ end
2142
+
2143
+ #
2144
+ # Returns error reason. Override this for I18N.
2145
+ #
2146
+ def reason
2147
+ @reason || self.class::Reason
2148
+ end
2149
+
2150
+ def inspect
2151
+ "#<#{self.class}: #{args.join(' ')}>"
2152
+ end
2153
+
2154
+ #
2155
+ # Default stringizing method to emit standard error message.
2156
+ #
2157
+ def message
2158
+ "#{reason}: #{args.join(' ')}#{additional[@arg0] if additional}"
2159
+ end
2160
+
2161
+ alias to_s message
2162
+ end
2163
+
2164
+ #
2165
+ # Raises when ambiguously completable string is encountered.
2166
+ #
2167
+ class AmbiguousOption < ParseError
2168
+ const_set(:Reason, 'ambiguous option')
2169
+ end
2170
+
2171
+ #
2172
+ # Raises when there is an argument for a switch which takes no argument.
2173
+ #
2174
+ class NeedlessArgument < ParseError
2175
+ const_set(:Reason, 'needless argument')
2176
+ end
2177
+
2178
+ #
2179
+ # Raises when a switch with mandatory argument has no argument.
2180
+ #
2181
+ class MissingArgument < ParseError
2182
+ const_set(:Reason, 'missing argument')
2183
+ end
2184
+
2185
+ #
2186
+ # Raises when switch is undefined.
2187
+ #
2188
+ class InvalidOption < ParseError
2189
+ const_set(:Reason, 'invalid option')
2190
+ end
2191
+
2192
+ #
2193
+ # Raises when the given argument does not match required format.
2194
+ #
2195
+ class InvalidArgument < ParseError
2196
+ const_set(:Reason, 'invalid argument')
2197
+ end
2198
+
2199
+ #
2200
+ # Raises when the given argument word can't be completed uniquely.
2201
+ #
2202
+ class AmbiguousArgument < InvalidArgument
2203
+ const_set(:Reason, 'ambiguous argument')
2204
+ end
2205
+
2206
+ #
2207
+ # Miscellaneous
2208
+ #
2209
+
2210
+ #
2211
+ # Extends command line arguments array (ARGV) to parse itself.
2212
+ #
2213
+ module Arguable
2214
+
2215
+ #
2216
+ # Sets Gem::OptionParser object, when +opt+ is +false+ or +nil+, methods
2217
+ # Gem::OptionParser::Arguable#options and Gem::OptionParser::Arguable#options= are
2218
+ # undefined. Thus, there is no ways to access the Gem::OptionParser object
2219
+ # via the receiver object.
2220
+ #
2221
+ def options=(opt)
2222
+ unless @optparse = opt
2223
+ class << self
2224
+ undef_method(:options)
2225
+ undef_method(:options=)
2226
+ end
2227
+ end
2228
+ end
2229
+
2230
+ #
2231
+ # Actual Gem::OptionParser object, automatically created if nonexistent.
2232
+ #
2233
+ # If called with a block, yields the Gem::OptionParser object and returns the
2234
+ # result of the block. If an Gem::OptionParser::ParseError exception occurs
2235
+ # in the block, it is rescued, a error message printed to STDERR and
2236
+ # +nil+ returned.
2237
+ #
2238
+ def options
2239
+ @optparse ||= Gem::OptionParser.new
2240
+ @optparse.default_argv = self
2241
+ block_given? or return @optparse
2242
+ begin
2243
+ yield @optparse
2244
+ rescue ParseError
2245
+ @optparse.warn $!
2246
+ nil
2247
+ end
2248
+ end
2249
+
2250
+ #
2251
+ # Parses +self+ destructively in order and returns +self+ containing the
2252
+ # rest arguments left unparsed.
2253
+ #
2254
+ def order!(&blk) options.order!(self, &blk) end
2255
+
2256
+ #
2257
+ # Parses +self+ destructively in permutation mode and returns +self+
2258
+ # containing the rest arguments left unparsed.
2259
+ #
2260
+ def permute!() options.permute!(self) end
2261
+
2262
+ #
2263
+ # Parses +self+ destructively and returns +self+ containing the
2264
+ # rest arguments left unparsed.
2265
+ #
2266
+ def parse!() options.parse!(self) end
2267
+
2268
+ #
2269
+ # Substitution of getopts is possible as follows. Also see
2270
+ # Gem::OptionParser#getopts.
2271
+ #
2272
+ # def getopts(*args)
2273
+ # ($OPT = ARGV.getopts(*args)).each do |opt, val|
2274
+ # eval "$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val"
2275
+ # end
2276
+ # rescue Gem::OptionParser::ParseError
2277
+ # end
2278
+ #
2279
+ def getopts(*args)
2280
+ options.getopts(self, *args)
2281
+ end
2282
+
2283
+ #
2284
+ # Initializes instance variable.
2285
+ #
2286
+ def self.extend_object(obj)
2287
+ super
2288
+ obj.instance_eval {@optparse = nil}
2289
+ end
2290
+ def initialize(*args)
2291
+ super
2292
+ @optparse = nil
2293
+ end
2294
+ end
2295
+
2296
+ #
2297
+ # Acceptable argument classes. Now contains DecimalInteger, OctalInteger
2298
+ # and DecimalNumeric. See Acceptable argument classes (in source code).
2299
+ #
2300
+ module Acceptables
2301
+ const_set(:DecimalInteger, Gem::OptionParser::DecimalInteger)
2302
+ const_set(:OctalInteger, Gem::OptionParser::OctalInteger)
2303
+ const_set(:DecimalNumeric, Gem::OptionParser::DecimalNumeric)
2304
+ end
2305
+ end
2306
+
2307
+ # ARGV is arguable by Gem::OptionParser
2308
+ ARGV.extend(Gem::OptionParser::Arguable)