bundler 2.0.0.pre.1 → 2.1.0.pre.3

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

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (230) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +774 -574
  3. data/LICENSE.md +18 -19
  4. data/README.md +9 -8
  5. data/bundler.gemspec +12 -23
  6. data/exe/bundle +19 -3
  7. data/lib/bundler.rb +203 -87
  8. data/lib/bundler/build_metadata.rb +14 -7
  9. data/lib/bundler/capistrano.rb +5 -5
  10. data/lib/bundler/cli.rb +181 -143
  11. data/lib/bundler/cli/add.rb +28 -16
  12. data/lib/bundler/cli/cache.rb +25 -13
  13. data/lib/bundler/cli/common.rb +11 -12
  14. data/lib/bundler/cli/config.rb +161 -86
  15. data/lib/bundler/cli/console.rb +2 -2
  16. data/lib/bundler/cli/doctor.rb +4 -4
  17. data/lib/bundler/cli/exec.rb +4 -16
  18. data/lib/bundler/cli/gem.rb +5 -5
  19. data/lib/bundler/cli/info.rb +17 -5
  20. data/lib/bundler/cli/init.rb +1 -1
  21. data/lib/bundler/cli/install.rb +12 -11
  22. data/lib/bundler/cli/issue.rb +3 -3
  23. data/lib/bundler/cli/open.rb +10 -6
  24. data/lib/bundler/cli/outdated.rb +85 -81
  25. data/lib/bundler/cli/plugin.rb +9 -2
  26. data/lib/bundler/cli/pristine.rb +1 -1
  27. data/lib/bundler/cli/show.rb +1 -1
  28. data/lib/bundler/cli/update.rb +32 -12
  29. data/lib/bundler/compact_index_client.rb +25 -9
  30. data/lib/bundler/compact_index_client/updater.rb +2 -6
  31. data/lib/bundler/current_ruby.rb +9 -7
  32. data/lib/bundler/definition.rb +36 -27
  33. data/lib/bundler/dependency.rb +16 -4
  34. data/lib/bundler/deployment.rb +2 -2
  35. data/lib/bundler/dsl.rb +18 -42
  36. data/lib/bundler/env.rb +8 -13
  37. data/lib/bundler/environment_preserver.rb +0 -1
  38. data/lib/bundler/feature_flag.rb +1 -11
  39. data/lib/bundler/fetcher.rb +14 -11
  40. data/lib/bundler/fetcher/compact_index.rb +26 -12
  41. data/lib/bundler/fetcher/dependency.rb +1 -1
  42. data/lib/bundler/fetcher/downloader.rb +4 -1
  43. data/lib/bundler/fetcher/index.rb +4 -2
  44. data/lib/bundler/friendly_errors.rb +5 -6
  45. data/lib/bundler/gem_helper.rb +38 -25
  46. data/lib/bundler/gem_helpers.rb +2 -4
  47. data/lib/bundler/gem_tasks.rb +1 -1
  48. data/lib/bundler/gem_version_promoter.rb +3 -3
  49. data/lib/bundler/graph.rb +2 -2
  50. data/lib/bundler/injector.rb +10 -8
  51. data/lib/bundler/inline.rb +25 -20
  52. data/lib/bundler/installer.rb +7 -14
  53. data/lib/bundler/installer/gem_installer.rb +5 -1
  54. data/lib/bundler/installer/parallel_installer.rb +4 -8
  55. data/lib/bundler/installer/standalone.rb +1 -2
  56. data/lib/bundler/lazy_specification.rb +2 -2
  57. data/lib/bundler/lockfile_parser.rb +14 -21
  58. data/lib/bundler/match_platform.rb +1 -1
  59. data/lib/bundler/plugin.rb +42 -29
  60. data/lib/bundler/plugin/api.rb +1 -1
  61. data/lib/bundler/plugin/api/source.rb +2 -2
  62. data/lib/bundler/plugin/index.rb +14 -3
  63. data/lib/bundler/plugin/installer.rb +28 -15
  64. data/lib/bundler/psyched_yaml.rb +1 -1
  65. data/lib/bundler/resolver.rb +72 -24
  66. data/lib/bundler/resolver/spec_group.rb +3 -2
  67. data/lib/bundler/retry.rb +2 -2
  68. data/lib/bundler/ruby_version.rb +4 -19
  69. data/lib/bundler/rubygems_ext.rb +11 -67
  70. data/lib/bundler/rubygems_gem_installer.rb +1 -1
  71. data/lib/bundler/rubygems_integration.rb +143 -395
  72. data/lib/bundler/runtime.rb +2 -9
  73. data/lib/bundler/settings.rb +15 -48
  74. data/lib/bundler/setup.rb +7 -13
  75. data/lib/bundler/shared_helpers.rb +57 -73
  76. data/lib/bundler/similarity_detector.rb +2 -2
  77. data/lib/bundler/source.rb +5 -5
  78. data/lib/bundler/source/git.rb +19 -12
  79. data/lib/bundler/source/git/git_proxy.rb +36 -40
  80. data/lib/bundler/source/metadata.rb +9 -5
  81. data/lib/bundler/source/path.rb +13 -8
  82. data/lib/bundler/source/rubygems.rb +11 -5
  83. data/lib/bundler/source/rubygems/remote.rb +1 -2
  84. data/lib/bundler/source_list.rb +9 -12
  85. data/lib/bundler/spec_set.rb +23 -12
  86. data/lib/bundler/stub_specification.rb +18 -30
  87. data/lib/bundler/templates/Executable.bundler +23 -14
  88. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +3 -3
  89. data/lib/bundler/templates/newgem/Gemfile.tt +8 -2
  90. data/lib/bundler/templates/newgem/README.md.tt +4 -3
  91. data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -27
  92. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +1 -1
  93. data/lib/bundler/templates/newgem/travis.yml.tt +0 -1
  94. data/lib/bundler/ui.rb +3 -3
  95. data/lib/bundler/ui/rg_proxy.rb +1 -1
  96. data/lib/bundler/ui/shell.rb +4 -8
  97. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +161 -0
  98. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +66 -0
  99. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +176 -0
  100. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  101. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +273 -147
  102. data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -0
  103. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +6 -6
  104. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  105. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
  106. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
  107. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
  108. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
  109. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +6 -6
  110. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
  111. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
  112. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +30 -8
  113. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
  114. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +4 -4
  115. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -2
  116. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +248 -279
  117. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
  118. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
  119. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
  120. data/lib/bundler/vendor/thor/lib/thor.rb +12 -4
  121. data/lib/bundler/vendor/thor/lib/thor/actions.rb +22 -11
  122. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
  123. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -1
  124. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +7 -17
  125. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +16 -7
  126. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +19 -8
  127. data/lib/bundler/vendor/thor/lib/thor/base.rb +25 -24
  128. data/lib/bundler/vendor/thor/lib/thor/command.rb +21 -14
  129. data/lib/bundler/vendor/thor/lib/thor/error.rb +78 -0
  130. data/lib/bundler/vendor/thor/lib/thor/group.rb +3 -3
  131. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -0
  132. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
  133. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +1 -1
  134. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +6 -6
  135. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
  136. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +1 -1
  137. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +8 -6
  138. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +20 -5
  139. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +1 -0
  140. data/lib/bundler/vendor/thor/lib/thor/runner.rb +8 -6
  141. data/lib/bundler/vendor/thor/lib/thor/shell.rb +4 -4
  142. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +52 -7
  143. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +6 -2
  144. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
  145. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  146. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  147. data/lib/bundler/vendored_fileutils.rb +1 -6
  148. data/lib/bundler/vendored_molinillo.rb +1 -1
  149. data/lib/bundler/vendored_persistent.rb +7 -5
  150. data/lib/bundler/vendored_thor.rb +2 -2
  151. data/lib/bundler/version.rb +1 -20
  152. data/lib/bundler/version_ranges.rb +51 -5
  153. data/lib/bundler/vlad.rb +3 -3
  154. data/lib/bundler/worker.rb +1 -3
  155. data/lib/bundler/yaml_serializer.rb +2 -3
  156. data/man/bundle-add.1 +10 -2
  157. data/man/bundle-add.1.txt +11 -5
  158. data/man/bundle-add.ronn +7 -1
  159. data/man/bundle-binstubs.1 +2 -2
  160. data/man/bundle-binstubs.1.txt +2 -2
  161. data/man/bundle-binstubs.ronn +1 -1
  162. data/man/bundle-cache.1 +55 -0
  163. data/man/bundle-cache.1.txt +78 -0
  164. data/man/{bundle-package.ronn → bundle-cache.ronn} +15 -15
  165. data/man/bundle-check.1 +1 -1
  166. data/man/bundle-check.1.txt +6 -6
  167. data/man/bundle-clean.1 +1 -1
  168. data/man/bundle-clean.1.txt +1 -1
  169. data/man/bundle-config.1 +36 -36
  170. data/man/bundle-config.1.txt +66 -67
  171. data/man/bundle-config.ronn +42 -40
  172. data/man/bundle-doctor.1 +1 -1
  173. data/man/bundle-doctor.1.txt +1 -1
  174. data/man/bundle-exec.1 +2 -2
  175. data/man/bundle-exec.1.txt +2 -2
  176. data/man/bundle-exec.ronn +1 -1
  177. data/man/bundle-gem.1 +1 -1
  178. data/man/bundle-gem.1.txt +3 -3
  179. data/man/bundle-info.1 +1 -1
  180. data/man/bundle-info.1.txt +1 -1
  181. data/man/bundle-init.1 +2 -2
  182. data/man/bundle-init.1.txt +2 -2
  183. data/man/bundle-init.ronn +1 -1
  184. data/man/bundle-inject.1 +1 -1
  185. data/man/bundle-inject.1.txt +1 -1
  186. data/man/bundle-install.1 +8 -5
  187. data/man/bundle-install.1.txt +56 -51
  188. data/man/bundle-install.ronn +9 -4
  189. data/man/bundle-list.1 +1 -1
  190. data/man/bundle-list.1.txt +1 -1
  191. data/man/bundle-lock.1 +1 -1
  192. data/man/bundle-lock.1.txt +16 -16
  193. data/man/bundle-open.1 +1 -1
  194. data/man/bundle-open.1.txt +1 -1
  195. data/man/bundle-outdated.1 +1 -1
  196. data/man/bundle-outdated.1.txt +1 -1
  197. data/man/bundle-platform.1 +1 -1
  198. data/man/bundle-platform.1.txt +1 -1
  199. data/man/bundle-pristine.1 +1 -1
  200. data/man/bundle-pristine.1.txt +1 -1
  201. data/man/bundle-remove.1 +1 -1
  202. data/man/bundle-remove.1.txt +1 -1
  203. data/man/bundle-show.1 +1 -1
  204. data/man/bundle-show.1.txt +1 -1
  205. data/man/bundle-update.1 +4 -4
  206. data/man/bundle-update.1.txt +64 -65
  207. data/man/bundle-update.ronn +3 -3
  208. data/man/bundle-viz.1 +1 -1
  209. data/man/bundle-viz.1.txt +1 -1
  210. data/man/bundle.1 +7 -3
  211. data/man/bundle.1.txt +11 -8
  212. data/man/bundle.ronn +5 -2
  213. data/man/gemfile.5 +17 -20
  214. data/man/gemfile.5.ronn +14 -18
  215. data/man/gemfile.5.txt +108 -112
  216. data/man/index.txt +1 -1
  217. metadata +19 -107
  218. data/exe/bundle_ruby +0 -60
  219. data/lib/bundler/cli/package.rb +0 -49
  220. data/lib/bundler/compatibility_guard.rb +0 -14
  221. data/lib/bundler/ssl_certs/.document +0 -1
  222. data/lib/bundler/ssl_certs/certificate_manager.rb +0 -66
  223. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +0 -21
  224. data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
  225. data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
  226. data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +0 -27
  227. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +0 -129
  228. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -129
  229. data/man/bundle-package.1 +0 -55
  230. data/man/bundle-package.1.txt +0 -79
@@ -1,17 +1,16 @@
1
- require "bundler/vendor/thor/lib/thor/command"
2
- require "bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access"
3
- require "bundler/vendor/thor/lib/thor/core_ext/ordered_hash"
4
- require "bundler/vendor/thor/lib/thor/error"
5
- require "bundler/vendor/thor/lib/thor/invocation"
6
- require "bundler/vendor/thor/lib/thor/parser"
7
- require "bundler/vendor/thor/lib/thor/shell"
8
- require "bundler/vendor/thor/lib/thor/line_editor"
9
- require "bundler/vendor/thor/lib/thor/util"
1
+ require_relative "command"
2
+ require_relative "core_ext/hash_with_indifferent_access"
3
+ require_relative "error"
4
+ require_relative "invocation"
5
+ require_relative "parser"
6
+ require_relative "shell"
7
+ require_relative "line_editor"
8
+ require_relative "util"
10
9
 
11
10
  class Bundler::Thor
12
- autoload :Actions, "bundler/vendor/thor/lib/thor/actions"
13
- autoload :RakeCompat, "bundler/vendor/thor/lib/thor/rake_compat"
14
- autoload :Group, "bundler/vendor/thor/lib/thor/group"
11
+ autoload :Actions, File.expand_path("actions", __dir__)
12
+ autoload :RakeCompat, File.expand_path("rake_compat", __dir__)
13
+ autoload :Group, File.expand_path("group", __dir__)
15
14
 
16
15
  # Shortcuts for help.
17
16
  HELP_MAPPINGS = %w(-h -? --help -D)
@@ -89,6 +88,7 @@ class Bundler::Thor
89
88
 
90
89
  class << self
91
90
  def included(base) #:nodoc:
91
+ super(base)
92
92
  base.extend ClassMethods
93
93
  base.send :include, Invocation
94
94
  base.send :include, Shell
@@ -113,7 +113,7 @@ class Bundler::Thor
113
113
  end
114
114
 
115
115
  # Whenever a class inherits from Bundler::Thor or Bundler::Thor::Group, we should track the
116
- # class and the file on Bundler::Thor::Base. This is the method responsable for it.
116
+ # class and the file on Bundler::Thor::Base. This is the method responsible for it.
117
117
  #
118
118
  def register_klass_file(klass) #:nodoc:
119
119
  file = caller[1].match(/(.*):\d+/)[1]
@@ -353,22 +353,22 @@ class Bundler::Thor
353
353
  # Returns the commands for this Bundler::Thor class.
354
354
  #
355
355
  # ==== Returns
356
- # OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command
357
- # objects as values.
356
+ # Hash:: An ordered hash with commands names as keys and Bundler::Thor::Command
357
+ # objects as values.
358
358
  #
359
359
  def commands
360
- @commands ||= Bundler::Thor::CoreExt::OrderedHash.new
360
+ @commands ||= Hash.new
361
361
  end
362
362
  alias_method :tasks, :commands
363
363
 
364
364
  # Returns the commands for this Bundler::Thor class and all subclasses.
365
365
  #
366
366
  # ==== Returns
367
- # OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command
368
- # objects as values.
367
+ # Hash:: An ordered hash with commands names as keys and Bundler::Thor::Command
368
+ # objects as values.
369
369
  #
370
370
  def all_commands
371
- @all_commands ||= from_superclass(:all_commands, Bundler::Thor::CoreExt::OrderedHash.new)
371
+ @all_commands ||= from_superclass(:all_commands, Hash.new)
372
372
  @all_commands.merge!(commands)
373
373
  end
374
374
  alias_method :all_tasks, :all_commands
@@ -466,13 +466,13 @@ class Bundler::Thor
466
466
  dispatch(nil, given_args.dup, nil, config)
467
467
  rescue Bundler::Thor::Error => e
468
468
  config[:debug] || ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
469
- exit(1) if exit_on_failure?
469
+ exit(false) if exit_on_failure?
470
470
  rescue Errno::EPIPE
471
471
  # This happens if a thor command is piped to something like `head`,
472
472
  # which closes the pipe when it's done reading. This will also
473
473
  # mean that if the pipe is closed, further unnecessary
474
474
  # computation will not occur.
475
- exit(0)
475
+ exit(true)
476
476
  end
477
477
 
478
478
  # Allows to use private methods from parent in child classes as commands.
@@ -493,8 +493,7 @@ class Bundler::Thor
493
493
  alias_method :public_task, :public_command
494
494
 
495
495
  def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
496
- raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace." if has_namespace
497
- raise UndefinedCommandError, "Could not find command #{command.inspect}."
496
+ raise UndefinedCommandError.new(command, all_commands.keys, (namespace if has_namespace))
498
497
  end
499
498
  alias_method :handle_no_task_error, :handle_no_command_error
500
499
 
@@ -503,7 +502,7 @@ class Bundler::Thor
503
502
  msg = "ERROR: \"#{basename} #{name}\" was called with ".dup
504
503
  msg << "no arguments" if args.empty?
505
504
  msg << "arguments " << args.inspect unless args.empty?
506
- msg << "\nUsage: #{banner(command).inspect}"
505
+ msg << "\nUsage: \"#{banner(command).split("\n").join("\"\n \"")}\""
507
506
  raise InvocationError, msg
508
507
  end
509
508
 
@@ -597,6 +596,7 @@ class Bundler::Thor
597
596
  # Everytime someone inherits from a Bundler::Thor class, register the klass
598
597
  # and file into baseclass.
599
598
  def inherited(klass)
599
+ super(klass)
600
600
  Bundler::Thor::Base.register_klass_file(klass)
601
601
  klass.instance_variable_set(:@no_commands, false)
602
602
  end
@@ -604,6 +604,7 @@ class Bundler::Thor
604
604
  # Fire this callback whenever a method is added. Added methods are
605
605
  # tracked as commands by invoking the create_command method.
606
606
  def method_added(meth)
607
+ super(meth)
607
608
  meth = meth.to_s
608
609
 
609
610
  if meth == "initialize"
@@ -49,24 +49,32 @@ class Bundler::Thor
49
49
 
50
50
  formatted ||= "".dup
51
51
 
52
- # Add usage with required arguments
53
- formatted << if klass && !klass.arguments.empty?
54
- usage.to_s.gsub(/^#{name}/) do |match|
55
- match << " " << klass.arguments.map(&:usage).compact.join(" ")
56
- end
57
- else
58
- usage.to_s
59
- end
52
+ Array(usage).map do |specific_usage|
53
+ formatted_specific_usage = formatted
60
54
 
61
- # Add required options
62
- formatted << " #{required_options}"
55
+ formatted_specific_usage += required_arguments_for(klass, specific_usage)
63
56
 
64
- # Strip and go!
65
- formatted.strip
57
+ # Add required options
58
+ formatted_specific_usage += " #{required_options}"
59
+
60
+ # Strip and go!
61
+ formatted_specific_usage.strip
62
+ end.join("\n")
66
63
  end
67
64
 
68
65
  protected
69
66
 
67
+ # Add usage with required arguments
68
+ def required_arguments_for(klass, usage)
69
+ if klass && !klass.arguments.empty?
70
+ usage.to_s.gsub(/^#{name}/) do |match|
71
+ match << " " << klass.arguments.map(&:usage).compact.join(" ")
72
+ end
73
+ else
74
+ usage.to_s
75
+ end
76
+ end
77
+
70
78
  def not_debugging?(instance)
71
79
  !(instance.class.respond_to?(:debugging) && instance.class.debugging)
72
80
  end
@@ -97,8 +105,7 @@ class Bundler::Thor
97
105
  def handle_argument_error?(instance, error, caller)
98
106
  not_debugging?(instance) && (error.message =~ /wrong number of arguments/ || error.message =~ /given \d*, expected \d*/) && begin
99
107
  saned = sans_backtrace(error.backtrace, caller)
100
- # Ruby 1.9 always include the called method in the backtrace
101
- saned.empty? || (saned.size == 1 && RUBY_VERSION >= "1.9")
108
+ saned.empty? || saned.size == 1
102
109
  end
103
110
  end
104
111
 
@@ -1,4 +1,19 @@
1
1
  class Bundler::Thor
2
+ Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable)
3
+ # In order to support versions of Ruby that don't have keyword
4
+ # arguments, we need our own spell checker class that doesn't take key
5
+ # words. Even though this code wouldn't be hit because of the check
6
+ # above, it's still necessary because the interpreter would otherwise be
7
+ # unable to parse the file.
8
+ class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc:
9
+ def initialize(dictionary)
10
+ @dictionary = dictionary
11
+ end
12
+ end
13
+
14
+ DidYouMean::Correctable
15
+ end
16
+
2
17
  # Bundler::Thor::Error is raised when it's caused by wrong usage of thor classes. Those
3
18
  # errors have their backtrace suppressed and are nicely shown to the user.
4
19
  #
@@ -10,6 +25,35 @@ class Bundler::Thor
10
25
 
11
26
  # Raised when a command was not found.
12
27
  class UndefinedCommandError < Error
28
+ class SpellChecker
29
+ attr_reader :error
30
+
31
+ def initialize(error)
32
+ @error = error
33
+ end
34
+
35
+ def corrections
36
+ @corrections ||= spell_checker.correct(error.command).map(&:inspect)
37
+ end
38
+
39
+ def spell_checker
40
+ NoKwargSpellChecker.new(error.all_commands)
41
+ end
42
+ end
43
+
44
+ attr_reader :command, :all_commands
45
+
46
+ def initialize(command, all_commands, namespace)
47
+ @command = command
48
+ @all_commands = all_commands
49
+
50
+ message = "Could not find command #{command.inspect}"
51
+ message = namespace ? "#{message} in #{namespace.inspect} namespace." : "#{message}."
52
+
53
+ super(message)
54
+ end
55
+
56
+ prepend Correctable if Correctable
13
57
  end
14
58
  UndefinedTaskError = UndefinedCommandError
15
59
 
@@ -22,6 +66,33 @@ class Bundler::Thor
22
66
  end
23
67
 
24
68
  class UnknownArgumentError < Error
69
+ class SpellChecker
70
+ attr_reader :error
71
+
72
+ def initialize(error)
73
+ @error = error
74
+ end
75
+
76
+ def corrections
77
+ @corrections ||=
78
+ error.unknown.flat_map { |unknown| spell_checker.correct(unknown) }.uniq.map(&:inspect)
79
+ end
80
+
81
+ def spell_checker
82
+ @spell_checker ||= NoKwargSpellChecker.new(error.switches)
83
+ end
84
+ end
85
+
86
+ attr_reader :switches, :unknown
87
+
88
+ def initialize(switches, unknown)
89
+ @switches = switches
90
+ @unknown = unknown
91
+
92
+ super("Unknown switches #{unknown.map(&:inspect).join(', ')}")
93
+ end
94
+
95
+ prepend Correctable if Correctable
25
96
  end
26
97
 
27
98
  class RequiredArgumentMissingError < InvocationError
@@ -29,4 +100,11 @@ class Bundler::Thor
29
100
 
30
101
  class MalformattedArgumentError < InvocationError
31
102
  end
103
+
104
+ if Correctable
105
+ DidYouMean::SPELL_CHECKERS.merge!(
106
+ 'Bundler::Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker,
107
+ 'Bundler::Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker
108
+ )
109
+ end
32
110
  end
@@ -1,4 +1,4 @@
1
- require "bundler/vendor/thor/lib/thor/base"
1
+ require_relative "base"
2
2
 
3
3
  # Bundler::Thor has a special class called Bundler::Thor::Group. The main difference to Bundler::Thor class
4
4
  # is that it invokes all commands at once. It also include some methods that allows
@@ -61,7 +61,7 @@ class Bundler::Thor::Group
61
61
  invocations[name] = false
62
62
  invocation_blocks[name] = block if block_given?
63
63
 
64
- class_eval <<-METHOD, __FILE__, __LINE__
64
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
65
65
  def _invoke_#{name.to_s.gsub(/\W/, '_')}
66
66
  klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
67
67
 
@@ -120,7 +120,7 @@ class Bundler::Thor::Group
120
120
  invocations[name] = true
121
121
  invocation_blocks[name] = block if block_given?
122
122
 
123
- class_eval <<-METHOD, __FILE__, __LINE__
123
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
124
124
  def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
125
125
  return unless options[#{name.inspect}]
126
126
 
@@ -1,6 +1,7 @@
1
1
  class Bundler::Thor
2
2
  module Invocation
3
3
  def self.included(base) #:nodoc:
4
+ super(base)
4
5
  base.extend ClassMethods
5
6
  end
6
7
 
@@ -1,5 +1,5 @@
1
- require "bundler/vendor/thor/lib/thor/line_editor/basic"
2
- require "bundler/vendor/thor/lib/thor/line_editor/readline"
1
+ require_relative "line_editor/basic"
2
+ require_relative "line_editor/readline"
3
3
 
4
4
  class Bundler::Thor
5
5
  module LineEditor
@@ -24,7 +24,7 @@ class Bundler::Thor
24
24
  $stdin.gets
25
25
  else
26
26
  # Lazy-load io/console since it is gem-ified as of 2.3
27
- require "io/console" if RUBY_VERSION > "1.9.2"
27
+ require "io/console"
28
28
  $stdin.noecho(&:gets)
29
29
  end
30
30
  end
@@ -1,19 +1,19 @@
1
- begin
2
- require "readline"
3
- rescue LoadError
4
- end
5
-
6
1
  class Bundler::Thor
7
2
  module LineEditor
8
3
  class Readline < Basic
9
4
  def self.available?
5
+ begin
6
+ require "readline"
7
+ rescue LoadError
8
+ end
9
+
10
10
  Object.const_defined?(:Readline)
11
11
  end
12
12
 
13
13
  def readline
14
14
  if echo?
15
15
  ::Readline.completion_append_character = nil
16
- # Ruby 1.8.7 does not allow Readline.completion_proc= to receive nil.
16
+ # rb-readline does not allow Readline.completion_proc= to receive nil.
17
17
  if complete = completion_proc
18
18
  ::Readline.completion_proc = complete
19
19
  end
@@ -1,4 +1,4 @@
1
- require "bundler/vendor/thor/lib/thor/parser/argument"
2
- require "bundler/vendor/thor/lib/thor/parser/arguments"
3
- require "bundler/vendor/thor/lib/thor/parser/option"
4
- require "bundler/vendor/thor/lib/thor/parser/options"
1
+ require_relative "parser/argument"
2
+ require_relative "parser/arguments"
3
+ require_relative "parser/option"
4
+ require_relative "parser/options"
@@ -9,7 +9,7 @@ class Bundler::Thor
9
9
  arguments = []
10
10
 
11
11
  args.each do |item|
12
- break if item =~ /^-/
12
+ break if item.is_a?(String) && item =~ /^-/
13
13
  arguments << item
14
14
  end
15
15
 
@@ -1,17 +1,18 @@
1
1
  class Bundler::Thor
2
2
  class Option < Argument #:nodoc:
3
- attr_reader :aliases, :group, :lazy_default, :hide
3
+ attr_reader :aliases, :group, :lazy_default, :hide, :repeatable
4
4
 
5
5
  VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
6
6
 
7
7
  def initialize(name, options = {})
8
8
  @check_default_type = options[:check_default_type]
9
9
  options[:required] = false unless options.key?(:required)
10
+ @repeatable = options.fetch(:repeatable, false)
10
11
  super
11
- @lazy_default = options[:lazy_default]
12
- @group = options[:group].to_s.capitalize if options[:group]
13
- @aliases = Array(options[:aliases])
14
- @hide = options[:hide]
12
+ @lazy_default = options[:lazy_default]
13
+ @group = options[:group].to_s.capitalize if options[:group]
14
+ @aliases = Array(options[:aliases])
15
+ @hide = options[:hide]
15
16
  end
16
17
 
17
18
  # This parse quick options given as method_options. It makes several
@@ -128,7 +129,8 @@ class Bundler::Thor
128
129
  @default.class.name.downcase.to_sym
129
130
  end
130
131
 
131
- raise ArgumentError, "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
132
+ expected_type = (@repeatable && @type != :hash) ? :array : @type
133
+ raise ArgumentError, "Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == expected_type
132
134
  end
133
135
 
134
136
  def dasherized?
@@ -44,6 +44,7 @@ class Bundler::Thor
44
44
  @shorts = {}
45
45
  @switches = {}
46
46
  @extra = []
47
+ @stopped_parsing_after_extra_index = nil
47
48
 
48
49
  options.each do |option|
49
50
  @switches[option.switch_name] = option
@@ -66,6 +67,7 @@ class Bundler::Thor
66
67
  if result == OPTS_END
67
68
  shift
68
69
  @parsing_options = false
70
+ @stopped_parsing_after_extra_index ||= @extra.size
69
71
  super
70
72
  else
71
73
  result
@@ -95,10 +97,12 @@ class Bundler::Thor
95
97
 
96
98
  switch = normalize_switch(switch)
97
99
  option = switch_option(switch)
98
- @assigns[option.human_name] = parse_peek(switch, option)
100
+ result = parse_peek(switch, option)
101
+ assign_result!(option, result)
99
102
  elsif @stop_on_unknown
100
103
  @parsing_options = false
101
104
  @extra << shifted
105
+ @stopped_parsing_after_extra_index ||= @extra.size
102
106
  @extra << shift while peek
103
107
  break
104
108
  elsif match
@@ -120,13 +124,24 @@ class Bundler::Thor
120
124
  end
121
125
 
122
126
  def check_unknown!
127
+ to_check = @stopped_parsing_after_extra_index ? @extra[0...@stopped_parsing_after_extra_index] : @extra
128
+
123
129
  # an unknown option starts with - or -- and has no more --'s afterward.
124
- unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
125
- raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
130
+ unknown = to_check.select { |str| str =~ /^--?(?:(?!--).)*$/ }
131
+ raise UnknownArgumentError.new(@switches.keys, unknown) unless unknown.empty?
126
132
  end
127
133
 
128
134
  protected
129
135
 
136
+ def assign_result!(option, result)
137
+ if option.repeatable && option.type == :hash
138
+ (@assigns[option.human_name] ||= {}).merge!(result)
139
+ elsif option.repeatable
140
+ (@assigns[option.human_name] ||= []) << result
141
+ else
142
+ @assigns[option.human_name] = result
143
+ end
144
+ end
130
145
  # Check if the current value in peek is a registered switch.
131
146
  #
132
147
  # Two booleans are returned. The first is true if the current value
@@ -156,7 +171,7 @@ class Bundler::Thor
156
171
  end
157
172
 
158
173
  def switch?(arg)
159
- switch_option(normalize_switch(arg))
174
+ !switch_option(normalize_switch(arg)).nil?
160
175
  end
161
176
 
162
177
  def switch_option(arg)
@@ -189,7 +204,7 @@ class Bundler::Thor
189
204
  shift
190
205
  false
191
206
  else
192
- !no_or_skip?(switch)
207
+ @switches.key?(switch) || !no_or_skip?(switch)
193
208
  end
194
209
  else
195
210
  @switches.key?(switch) || !no_or_skip?(switch)