bundler 1.15.2 → 1.17.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 (286) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +302 -0
  3. data/README.md +17 -8
  4. data/bundler.gemspec +25 -9
  5. data/exe/bundle +1 -1
  6. data/exe/bundle_ruby +4 -3
  7. data/lib/bundler/build_metadata.rb +53 -0
  8. data/lib/bundler/capistrano.rb +5 -0
  9. data/lib/bundler/cli/add.rb +15 -6
  10. data/lib/bundler/cli/binstubs.rb +17 -9
  11. data/lib/bundler/cli/cache.rb +5 -4
  12. data/lib/bundler/cli/check.rb +3 -5
  13. data/lib/bundler/cli/clean.rb +5 -6
  14. data/lib/bundler/cli/common.rb +11 -2
  15. data/lib/bundler/cli/config.rb +2 -1
  16. data/lib/bundler/cli/console.rb +2 -1
  17. data/lib/bundler/cli/doctor.rb +48 -1
  18. data/lib/bundler/cli/exec.rb +6 -5
  19. data/lib/bundler/cli/gem.rb +13 -8
  20. data/lib/bundler/cli/info.rb +0 -1
  21. data/lib/bundler/cli/init.rb +18 -6
  22. data/lib/bundler/cli/inject.rb +1 -0
  23. data/lib/bundler/cli/install.rb +64 -61
  24. data/lib/bundler/cli/issue.rb +1 -1
  25. data/lib/bundler/cli/list.rb +58 -0
  26. data/lib/bundler/cli/lock.rb +0 -1
  27. data/lib/bundler/cli/open.rb +2 -2
  28. data/lib/bundler/cli/outdated.rb +20 -9
  29. data/lib/bundler/cli/package.rb +9 -6
  30. data/lib/bundler/cli/platform.rb +1 -0
  31. data/lib/bundler/cli/plugin.rb +1 -0
  32. data/lib/bundler/cli/pristine.rb +20 -6
  33. data/lib/bundler/cli/remove.rb +18 -0
  34. data/lib/bundler/cli/show.rb +0 -1
  35. data/lib/bundler/cli/update.rb +35 -7
  36. data/lib/bundler/cli/viz.rb +1 -0
  37. data/lib/bundler/cli.rb +227 -89
  38. data/lib/bundler/compact_index_client/cache.rb +1 -2
  39. data/lib/bundler/compact_index_client/updater.rb +14 -4
  40. data/lib/bundler/compact_index_client.rb +1 -0
  41. data/lib/bundler/compatibility_guard.rb +14 -0
  42. data/lib/bundler/constants.rb +1 -0
  43. data/lib/bundler/current_ruby.rb +13 -5
  44. data/lib/bundler/definition.rb +192 -139
  45. data/lib/bundler/dep_proxy.rb +3 -1
  46. data/lib/bundler/dependency.rb +9 -9
  47. data/lib/bundler/deployment.rb +1 -1
  48. data/lib/bundler/deprecate.rb +15 -3
  49. data/lib/bundler/dsl.rb +115 -64
  50. data/lib/bundler/endpoint_specification.rb +10 -1
  51. data/lib/bundler/env.rb +90 -29
  52. data/lib/bundler/environment_preserver.rb +27 -6
  53. data/lib/bundler/errors.rb +1 -0
  54. data/lib/bundler/feature_flag.rb +46 -4
  55. data/lib/bundler/fetcher/base.rb +1 -0
  56. data/lib/bundler/fetcher/compact_index.rb +2 -11
  57. data/lib/bundler/fetcher/dependency.rb +2 -1
  58. data/lib/bundler/fetcher/downloader.rb +11 -5
  59. data/lib/bundler/fetcher/index.rb +3 -2
  60. data/lib/bundler/fetcher.rb +18 -11
  61. data/lib/bundler/friendly_errors.rb +6 -1
  62. data/lib/bundler/gem_helper.rb +19 -10
  63. data/lib/bundler/gem_helpers.rb +1 -0
  64. data/lib/bundler/gem_remote_fetcher.rb +1 -0
  65. data/lib/bundler/gem_tasks.rb +1 -0
  66. data/lib/bundler/gem_version_promoter.rb +17 -2
  67. data/lib/bundler/gemdeps.rb +1 -0
  68. data/lib/bundler/graph.rb +1 -0
  69. data/lib/bundler/index.rb +8 -8
  70. data/lib/bundler/injector.rb +192 -30
  71. data/lib/bundler/inline.rb +5 -7
  72. data/lib/bundler/installer/gem_installer.rb +11 -2
  73. data/lib/bundler/installer/parallel_installer.rb +78 -42
  74. data/lib/bundler/installer/standalone.rb +1 -0
  75. data/lib/bundler/installer.rb +138 -53
  76. data/lib/bundler/lazy_specification.rb +3 -2
  77. data/lib/bundler/lockfile_generator.rb +95 -0
  78. data/lib/bundler/lockfile_parser.rb +10 -4
  79. data/lib/bundler/match_platform.rb +1 -0
  80. data/lib/bundler/mirror.rb +8 -5
  81. data/lib/bundler/plugin/api/source.rb +9 -2
  82. data/lib/bundler/plugin/events.rb +61 -0
  83. data/lib/bundler/plugin/index.rb +7 -2
  84. data/lib/bundler/plugin/installer.rb +7 -6
  85. data/lib/bundler/plugin/source_list.rb +7 -8
  86. data/lib/bundler/plugin.rb +13 -5
  87. data/lib/bundler/process_lock.rb +24 -0
  88. data/lib/bundler/psyched_yaml.rb +10 -0
  89. data/lib/bundler/remote_specification.rb +1 -0
  90. data/lib/bundler/resolver/spec_group.rb +106 -0
  91. data/lib/bundler/resolver.rb +158 -195
  92. data/lib/bundler/retry.rb +1 -0
  93. data/lib/bundler/ruby_dsl.rb +1 -0
  94. data/lib/bundler/ruby_version.rb +2 -1
  95. data/lib/bundler/rubygems_ext.rb +5 -4
  96. data/lib/bundler/rubygems_gem_installer.rb +31 -1
  97. data/lib/bundler/rubygems_integration.rb +71 -32
  98. data/lib/bundler/runtime.rb +11 -9
  99. data/lib/bundler/settings/validator.rb +102 -0
  100. data/lib/bundler/settings.rb +200 -77
  101. data/lib/bundler/setup.rb +1 -0
  102. data/lib/bundler/shared_helpers.rb +131 -26
  103. data/lib/bundler/similarity_detector.rb +1 -0
  104. data/lib/bundler/source/gemspec.rb +1 -0
  105. data/lib/bundler/source/git/git_proxy.rb +21 -11
  106. data/lib/bundler/source/git.rb +24 -19
  107. data/lib/bundler/source/metadata.rb +62 -0
  108. data/lib/bundler/source/path/installer.rb +2 -0
  109. data/lib/bundler/source/path.rb +8 -8
  110. data/lib/bundler/source/rubygems/remote.rb +8 -2
  111. data/lib/bundler/source/rubygems.rb +161 -84
  112. data/lib/bundler/source.rb +36 -0
  113. data/lib/bundler/source_list.rb +75 -15
  114. data/lib/bundler/spec_set.rb +10 -5
  115. data/lib/bundler/ssl_certs/certificate_manager.rb +2 -1
  116. data/lib/bundler/stub_specification.rb +1 -0
  117. data/lib/bundler/templates/.document +1 -0
  118. data/lib/bundler/templates/Executable +12 -0
  119. data/lib/bundler/templates/Executable.bundler +105 -0
  120. data/lib/bundler/templates/Gemfile +1 -0
  121. data/lib/bundler/templates/gems.rb +8 -0
  122. data/lib/bundler/templates/newgem/README.md.tt +1 -1
  123. data/lib/bundler/templates/newgem/gitignore.tt +0 -1
  124. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +1 -0
  125. data/lib/bundler/templates/newgem/newgem.gemspec.tt +12 -3
  126. data/lib/bundler/templates/newgem/rspec.tt +1 -0
  127. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +0 -2
  128. data/lib/bundler/templates/newgem/{.travis.yml.tt → travis.yml.tt} +2 -0
  129. data/lib/bundler/ui/rg_proxy.rb +1 -0
  130. data/lib/bundler/ui/shell.rb +17 -4
  131. data/lib/bundler/ui/silent.rb +1 -0
  132. data/lib/bundler/ui.rb +1 -0
  133. data/lib/bundler/uri_credentials_filter.rb +1 -0
  134. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1638 -0
  135. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
  136. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +7 -0
  137. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +1 -0
  138. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +1 -0
  139. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -0
  140. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -0
  141. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -0
  142. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -0
  143. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +1 -0
  144. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -0
  145. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -0
  146. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +15 -4
  147. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +3 -2
  148. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +75 -7
  149. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +2 -1
  150. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -0
  151. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +3 -1
  152. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +491 -148
  153. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +1 -0
  154. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +8 -4
  155. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +2 -0
  156. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
  157. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -0
  158. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -0
  159. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +9 -1
  160. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +45 -8
  161. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +9 -3
  162. data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -3
  163. data/lib/bundler/vendor/thor/lib/thor/base.rb +27 -4
  164. data/lib/bundler/vendor/thor/lib/thor/command.rb +9 -7
  165. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +12 -0
  166. data/lib/bundler/vendor/thor/lib/thor/group.rb +1 -1
  167. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +2 -0
  168. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +5 -5
  169. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +6 -5
  170. data/lib/bundler/vendor/thor/lib/thor/runner.rb +6 -4
  171. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +10 -9
  172. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  173. data/lib/bundler/vendor/thor/lib/thor.rb +25 -8
  174. data/lib/bundler/vendored_fileutils.rb +9 -0
  175. data/lib/bundler/vendored_molinillo.rb +1 -0
  176. data/lib/bundler/vendored_persistent.rb +35 -0
  177. data/lib/bundler/vendored_thor.rb +1 -0
  178. data/lib/bundler/version.rb +6 -2
  179. data/lib/bundler/version_ranges.rb +1 -0
  180. data/lib/bundler/vlad.rb +5 -0
  181. data/lib/bundler/worker.rb +1 -0
  182. data/lib/bundler/yaml_serializer.rb +3 -3
  183. data/lib/bundler.rb +86 -52
  184. data/man/bundle-add.1 +18 -3
  185. data/man/bundle-add.1.txt +26 -14
  186. data/man/bundle-add.ronn +13 -2
  187. data/man/bundle-binstubs.1 +11 -1
  188. data/man/bundle-binstubs.1.txt +33 -18
  189. data/man/bundle-binstubs.ronn +15 -1
  190. data/man/bundle-check.1 +4 -4
  191. data/man/bundle-check.1.txt +15 -14
  192. data/man/bundle-check.ronn +3 -3
  193. data/man/bundle-clean.1 +1 -1
  194. data/man/bundle-clean.1.txt +10 -10
  195. data/man/bundle-config.1 +129 -29
  196. data/man/bundle-config.1.txt +285 -174
  197. data/man/bundle-config.ronn +167 -88
  198. data/man/bundle-doctor.1 +44 -0
  199. data/man/bundle-doctor.1.txt +44 -0
  200. data/man/bundle-doctor.ronn +33 -0
  201. data/man/bundle-exec.1 +6 -3
  202. data/man/bundle-exec.1.txt +78 -71
  203. data/man/bundle-exec.ronn +10 -3
  204. data/man/bundle-gem.1 +3 -3
  205. data/man/bundle-gem.1.txt +40 -39
  206. data/man/bundle-gem.ronn +2 -1
  207. data/man/bundle-info.1 +1 -1
  208. data/man/bundle-info.1.txt +8 -8
  209. data/man/bundle-init.1 +9 -4
  210. data/man/bundle-init.1.txt +23 -13
  211. data/man/bundle-init.ronn +15 -4
  212. data/man/bundle-inject.1 +4 -4
  213. data/man/bundle-inject.1.txt +10 -10
  214. data/man/bundle-inject.ronn +3 -3
  215. data/man/bundle-install.1 +31 -28
  216. data/man/bundle-install.1.txt +205 -194
  217. data/man/bundle-install.ronn +44 -35
  218. data/man/bundle-list.1 +50 -0
  219. data/man/bundle-list.1.txt +43 -0
  220. data/man/bundle-list.ronn +33 -0
  221. data/man/bundle-lock.1 +1 -1
  222. data/man/bundle-lock.1.txt +47 -47
  223. data/man/bundle-lock.ronn +1 -1
  224. data/man/bundle-open.1 +1 -1
  225. data/man/bundle-open.1.txt +7 -7
  226. data/man/bundle-outdated.1 +7 -3
  227. data/man/bundle-outdated.1.txt +40 -36
  228. data/man/bundle-outdated.ronn +6 -2
  229. data/man/bundle-package.1 +6 -3
  230. data/man/bundle-package.1.txt +44 -39
  231. data/man/bundle-package.ronn +7 -2
  232. data/man/bundle-platform.1 +1 -1
  233. data/man/bundle-platform.1.txt +13 -13
  234. data/man/bundle-pristine.1 +21 -3
  235. data/man/bundle-pristine.1.txt +33 -10
  236. data/man/bundle-pristine.ronn +24 -3
  237. data/man/bundle-remove.1 +31 -0
  238. data/man/bundle-remove.1.txt +34 -0
  239. data/man/bundle-remove.ronn +23 -0
  240. data/man/bundle-show.1 +3 -3
  241. data/man/bundle-show.1.txt +14 -12
  242. data/man/bundle-show.ronn +3 -2
  243. data/man/bundle-update.1 +13 -9
  244. data/man/bundle-update.1.txt +133 -130
  245. data/man/bundle-update.ronn +21 -17
  246. data/man/bundle-viz.1 +7 -7
  247. data/man/bundle-viz.1.txt +17 -15
  248. data/man/bundle-viz.ronn +6 -6
  249. data/man/bundle.1 +31 -23
  250. data/man/bundle.1.txt +63 -57
  251. data/man/bundle.ronn +35 -29
  252. data/man/gemfile.5 +44 -8
  253. data/man/gemfile.5.ronn +54 -8
  254. data/man/gemfile.5.txt +218 -165
  255. data/man/index.txt +25 -15
  256. metadata +36 -36
  257. data/.codeclimate.yml +0 -25
  258. data/.gitignore +0 -18
  259. data/.rspec +0 -3
  260. data/.rubocop.yml +0 -131
  261. data/.rubocop_todo.yml +0 -418
  262. data/.travis.yml +0 -122
  263. data/CODE_OF_CONDUCT.md +0 -42
  264. data/CONTRIBUTING.md +0 -17
  265. data/Rakefile +0 -338
  266. data/bin/rake +0 -19
  267. data/bin/rspec +0 -15
  268. data/bin/rubocop +0 -17
  269. data/bin/with_rubygems +0 -39
  270. data/doc/README.md +0 -30
  271. data/doc/TROUBLESHOOTING.md +0 -64
  272. data/doc/contributing/BUG_TRIAGE.md +0 -36
  273. data/doc/contributing/COMMUNITY.md +0 -13
  274. data/doc/contributing/GETTING_HELP.md +0 -11
  275. data/doc/contributing/HOW_YOU_CAN_HELP.md +0 -27
  276. data/doc/contributing/ISSUES.md +0 -51
  277. data/doc/contributing/README.md +0 -38
  278. data/doc/development/NEW_FEATURES.md +0 -10
  279. data/doc/development/PULL_REQUESTS.md +0 -40
  280. data/doc/development/README.md +0 -19
  281. data/doc/development/RELEASING.md +0 -9
  282. data/doc/development/SETUP.md +0 -27
  283. data/doc/documentation/README.md +0 -29
  284. data/doc/documentation/VISION.md +0 -26
  285. data/doc/documentation/WRITING.md +0 -54
  286. data/task/release.rake +0 -116
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph'
3
4
 
4
5
  module Bundler::Molinillo
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bundler::Molinillo
3
4
  # A state that a {Resolution} can be in
4
5
  # @attr [String] name the name of the current requirement
@@ -7,7 +8,8 @@ module Bundler::Molinillo
7
8
  # @attr [Object] requirement the current requirement
8
9
  # @attr [Object] possibilities the possibilities to satisfy the current requirement
9
10
  # @attr [Integer] depth the depth of the resolution
10
- # @attr [Set<Object>] conflicts unresolved conflicts
11
+ # @attr [Hash] conflicts unresolved conflicts, indexed by dependency name
12
+ # @attr [Array<UnwindDetails>] unused_unwind_options unwinds for previous conflicts that weren't explored
11
13
  ResolutionState = Struct.new(
12
14
  :name,
13
15
  :requirements,
@@ -15,14 +17,15 @@ module Bundler::Molinillo
15
17
  :requirement,
16
18
  :possibilities,
17
19
  :depth,
18
- :conflicts
20
+ :conflicts,
21
+ :unused_unwind_options
19
22
  )
20
23
 
21
24
  class ResolutionState
22
25
  # Returns an empty resolution state
23
26
  # @return [ResolutionState] an empty state
24
27
  def self.empty
25
- new(nil, [], DependencyGraph.new, nil, nil, 0, Set.new)
28
+ new(nil, [], DependencyGraph.new, nil, nil, 0, {}, [])
26
29
  end
27
30
  end
28
31
 
@@ -40,7 +43,8 @@ module Bundler::Molinillo
40
43
  requirement,
41
44
  [possibilities.pop],
42
45
  depth + 1,
43
- conflicts.dup
46
+ conflicts.dup,
47
+ unused_unwind_options.dup
44
48
  ).tap do |state|
45
49
  state.activated.tag(state)
46
50
  end
@@ -1,4 +1,6 @@
1
1
  # frozen_string_literal: true
2
+
3
+ require 'bundler/vendor/molinillo/lib/molinillo/compatibility'
2
4
  require 'bundler/vendor/molinillo/lib/molinillo/gem_metadata'
3
5
  require 'bundler/vendor/molinillo/lib/molinillo/errors'
4
6
  require 'bundler/vendor/molinillo/lib/molinillo/resolver'
@@ -814,7 +814,7 @@ class Bundler::Persistent::Net::HTTP::Persistent
814
814
 
815
815
  ##
816
816
  # Pipelines +requests+ to the HTTP server at +uri+ yielding responses if a
817
- # block is given. Returns all responses recieved.
817
+ # block is given. Returns all responses received.
818
818
  #
819
819
  # See
820
820
  # Net::HTTP::Pipeline[http://docs.seattlerb.org/net-http-pipeline/Net/HTTP/Pipeline.html]
@@ -58,6 +58,7 @@ class Bundler::Thor
58
58
 
59
59
  def invoke!
60
60
  invoke_with_conflict_check do
61
+ require "fileutils"
61
62
  FileUtils.mkdir_p(File.dirname(destination))
62
63
  File.open(destination, "wb") { |f| f.write render }
63
64
  end
@@ -38,6 +38,7 @@ class Bundler::Thor
38
38
 
39
39
  def invoke!
40
40
  invoke_with_conflict_check do
41
+ require "fileutils"
41
42
  FileUtils.mkdir_p(File.dirname(destination))
42
43
  # Create a symlink by default
43
44
  config[:symbolic] = true if config[:symbolic].nil?
@@ -48,12 +48,14 @@ class Bundler::Thor
48
48
 
49
49
  def invoke!
50
50
  invoke_with_conflict_check do
51
+ require "fileutils"
51
52
  ::FileUtils.mkdir_p(destination)
52
53
  end
53
54
  end
54
55
 
55
56
  def revoke!
56
57
  say_status :remove, :red
58
+ require "fileutils"
57
59
  ::FileUtils.rm_rf(destination) if !pretend? && exists?
58
60
  given_destination
59
61
  end
@@ -112,11 +114,17 @@ class Bundler::Thor
112
114
  if exists?
113
115
  on_conflict_behavior(&block)
114
116
  else
115
- say_status :create, :green
116
117
  yield unless pretend?
118
+ say_status :create, :green
117
119
  end
118
120
 
119
121
  destination
122
+ rescue Errno::EISDIR, Errno::EEXIST
123
+ on_file_clash_behavior
124
+ end
125
+
126
+ def on_file_clash_behavior
127
+ say_status :file_clash, :red
120
128
  end
121
129
 
122
130
  # What to do when the destination file already exists.
@@ -1,5 +1,4 @@
1
1
  require "erb"
2
- require "open-uri"
3
2
 
4
3
  class Bundler::Thor
5
4
  module Actions
@@ -78,7 +77,12 @@ class Bundler::Thor
78
77
  config = args.last.is_a?(Hash) ? args.pop : {}
79
78
  destination = args.first
80
79
 
81
- source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ %r{^https?\://}
80
+ if source =~ %r{^https?\://}
81
+ require "open-uri"
82
+ else
83
+ source = File.expand_path(find_in_source_paths(source.to_s))
84
+ end
85
+
82
86
  render = open(source) { |input| input.binmode.read }
83
87
 
84
88
  destination ||= if block_given?
@@ -113,7 +117,9 @@ class Bundler::Thor
113
117
  context = config.delete(:context) || instance_eval("binding")
114
118
 
115
119
  create_file destination, nil, config do
116
- content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
120
+ content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").tap do |erb|
121
+ erb.filename = source
122
+ end.result(context)
117
123
  content = yield(content) if block
118
124
  content
119
125
  end
@@ -134,7 +140,10 @@ class Bundler::Thor
134
140
  return unless behavior == :invoke
135
141
  path = File.expand_path(path, destination_root)
136
142
  say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
137
- FileUtils.chmod_R(mode, path) unless options[:pretend]
143
+ unless options[:pretend]
144
+ require "fileutils"
145
+ FileUtils.chmod_R(mode, path)
146
+ end
138
147
  end
139
148
 
140
149
  # Prepend text to a file. Since it depends on insert_into_file, it's reversible.
@@ -204,6 +213,29 @@ class Bundler::Thor
204
213
  insert_into_file(path, *(args << config), &block)
205
214
  end
206
215
 
216
+ # Injects text right after the module definition. Since it depends on
217
+ # insert_into_file, it's reversible.
218
+ #
219
+ # ==== Parameters
220
+ # path<String>:: path of the file to be changed
221
+ # module_name<String|Class>:: the module to be manipulated
222
+ # data<String>:: the data to append to the class, can be also given as a block.
223
+ # config<Hash>:: give :verbose => false to not log the status.
224
+ #
225
+ # ==== Examples
226
+ #
227
+ # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper, " def help; 'help'; end\n"
228
+ #
229
+ # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper do
230
+ # " def help; 'help'; end\n"
231
+ # end
232
+ #
233
+ def inject_into_module(path, module_name, *args, &block)
234
+ config = args.last.is_a?(Hash) ? args.pop : {}
235
+ config[:after] = /module #{module_name}\n|module #{module_name} .*\n/
236
+ insert_into_file(path, *(args << config), &block)
237
+ end
238
+
207
239
  # Run a regular expression replacement on a file.
208
240
  #
209
241
  # ==== Parameters
@@ -288,7 +320,10 @@ class Bundler::Thor
288
320
  path = File.expand_path(path, destination_root)
289
321
 
290
322
  say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
291
- ::FileUtils.rm_rf(path) if !options[:pretend] && File.exist?(path)
323
+ if !options[:pretend] && File.exist?(path)
324
+ require "fileutils"
325
+ ::FileUtils.rm_rf(path)
326
+ end
292
327
  end
293
328
  alias_method :remove_dir, :remove_file
294
329
 
@@ -305,8 +340,10 @@ class Bundler::Thor
305
340
  with_output_buffer { yield(*args) }
306
341
  end
307
342
 
308
- def with_output_buffer(buf = "") #:nodoc:
309
- self.output_buffer, old_buffer = buf, output_buffer
343
+ def with_output_buffer(buf = "".dup) #:nodoc:
344
+ raise ArgumentError, "Buffer can not be a frozen object" if buf.frozen?
345
+ old_buffer = output_buffer
346
+ self.output_buffer = buf
310
347
  yield
311
348
  output_buffer
312
349
  ensure
@@ -319,7 +356,7 @@ class Bundler::Thor
319
356
  def set_eoutvar(compiler, eoutvar = "_erbout")
320
357
  compiler.put_cmd = "#{eoutvar}.concat"
321
358
  compiler.insert_cmd = "#{eoutvar}.concat"
322
- compiler.pre_cmd = ["#{eoutvar} = ''"]
359
+ compiler.pre_cmd = ["#{eoutvar} = ''.dup"]
323
360
  compiler.post_cmd = [eoutvar]
324
361
  end
325
362
  end
@@ -53,7 +53,13 @@ class Bundler::Thor
53
53
  replacement + '\0'
54
54
  end
55
55
 
56
- replace!(/#{flag}/, content, config[:force])
56
+ if exists?
57
+ replace!(/#{flag}/, content, config[:force])
58
+ else
59
+ unless pretend?
60
+ raise Bundler::Thor::Error, "The file #{ destination } does not appear to exist"
61
+ end
62
+ end
57
63
  end
58
64
 
59
65
  def revoke!
@@ -91,8 +97,8 @@ class Bundler::Thor
91
97
  # Adds the content to the file.
92
98
  #
93
99
  def replace!(regexp, string, force)
94
- return if base.options[:pretend]
95
- content = File.binread(destination)
100
+ return if pretend?
101
+ content = File.read(destination)
96
102
  if force || !content.include?(replacement)
97
103
  content.gsub!(regexp, string)
98
104
  File.open(destination, "wb") { |file| file.write(content) }
@@ -1,4 +1,3 @@
1
- require "fileutils"
2
1
  require "uri"
3
2
  require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read"
4
3
  require "bundler/vendor/thor/lib/thor/actions/create_file"
@@ -141,7 +140,7 @@ class Bundler::Thor
141
140
  end
142
141
  end
143
142
 
144
- message = "Could not find #{file.inspect} in any of your source paths. "
143
+ message = "Could not find #{file.inspect} in any of your source paths. ".dup
145
144
 
146
145
  unless self.class.source_root
147
146
  message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. "
@@ -175,6 +174,7 @@ class Bundler::Thor
175
174
 
176
175
  # If the directory doesnt exist and we're not pretending
177
176
  if !File.exist?(destination_root) && !pretend
177
+ require "fileutils"
178
178
  FileUtils.mkdir_p(destination_root)
179
179
  end
180
180
 
@@ -182,6 +182,7 @@ class Bundler::Thor
182
182
  # In pretend mode, just yield down to the block
183
183
  block.arity == 1 ? yield(destination_root) : yield
184
184
  else
185
+ require "fileutils"
185
186
  FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield }
186
187
  end
187
188
 
@@ -251,7 +252,9 @@ class Bundler::Thor
251
252
 
252
253
  say_status :run, desc, config.fetch(:verbose, true)
253
254
 
254
- !options[:pretend] && config[:capture] ? `#{command}` : system(command.to_s)
255
+ unless options[:pretend]
256
+ config[:capture] ? `#{command}` : system(command.to_s)
257
+ end
255
258
  end
256
259
 
257
260
  # Executes a ruby script (taking into account WIN32 platform quirks).
@@ -42,7 +42,7 @@ class Bundler::Thor
42
42
  # config<Hash>:: Configuration for this Bundler::Thor class.
43
43
  #
44
44
  def initialize(args = [], local_options = {}, config = {})
45
- parse_options = config[:current_command] && config[:current_command].disable_class_options ? {} : self.class.class_options
45
+ parse_options = self.class.class_options
46
46
 
47
47
  # The start method splits inbound arguments at the first argument
48
48
  # that looks like an option (starts with - or --). It then calls
@@ -65,7 +65,8 @@ class Bundler::Thor
65
65
  # declared options from the array. This will leave us with
66
66
  # a list of arguments that weren't declared.
67
67
  stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
68
- opts = Bundler::Thor::Options.new(parse_options, hash_options, stop_on_unknown)
68
+ disable_required_check = self.class.disable_required_check? config[:current_command]
69
+ opts = Bundler::Thor::Options.new(parse_options, hash_options, stop_on_unknown, disable_required_check)
69
70
  self.options = opts.parse(array_options)
70
71
  self.options = config[:class_options].merge(options) if config[:class_options]
71
72
 
@@ -150,6 +151,21 @@ class Bundler::Thor
150
151
  !!check_unknown_options
151
152
  end
152
153
 
154
+ # If you want to raise an error when the default value of an option does not match
155
+ # the type call check_default_type!
156
+ # This is disabled by default for compatibility.
157
+ def check_default_type!
158
+ @check_default_type = true
159
+ end
160
+
161
+ def check_default_type #:nodoc:
162
+ @check_default_type ||= from_superclass(:check_default_type, false)
163
+ end
164
+
165
+ def check_default_type? #:nodoc:
166
+ !!check_default_type
167
+ end
168
+
153
169
  # If true, option parsing is suspended as soon as an unknown option or a
154
170
  # regular argument is encountered. All remaining arguments are passed to
155
171
  # the command as regular arguments.
@@ -157,6 +173,12 @@ class Bundler::Thor
157
173
  false
158
174
  end
159
175
 
176
+ # If true, option set will not suspend the execution of the command when
177
+ # a required option is not provided.
178
+ def disable_required_check?(command_name) #:nodoc:
179
+ false
180
+ end
181
+
160
182
  # If you want only strict string args (useful when cascading thor classes),
161
183
  # call strict_args_position! This is disabled by default to allow dynamic
162
184
  # invocations.
@@ -477,7 +499,8 @@ class Bundler::Thor
477
499
  alias_method :handle_no_task_error, :handle_no_command_error
478
500
 
479
501
  def handle_argument_error(command, error, args, arity) #:nodoc:
480
- msg = "ERROR: \"#{basename} #{command.name}\" was called with "
502
+ name = [command.ancestor_name, command.name].compact.join(" ")
503
+ msg = "ERROR: \"#{basename} #{name}\" was called with ".dup
481
504
  msg << "no arguments" if args.empty?
482
505
  msg << "arguments " << args.inspect unless args.empty?
483
506
  msg << "\nUsage: #{banner(command).inspect}"
@@ -541,7 +564,7 @@ class Bundler::Thor
541
564
  # options<Hash>:: Described in both class_option and method_option.
542
565
  # scope<Hash>:: Options hash that is being built up
543
566
  def build_option(name, options, scope) #:nodoc:
544
- scope[name] = Bundler::Thor::Option.new(name, options)
567
+ scope[name] = Bundler::Thor::Option.new(name, options.merge(:check_default_type => check_default_type?))
545
568
  end
546
569
 
547
570
  # Receives a hash of options, parse them and add to the scope. This is a
@@ -1,9 +1,9 @@
1
1
  class Bundler::Thor
2
- class Command < Struct.new(:name, :description, :long_description, :usage, :options, :disable_class_options)
2
+ class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
3
3
  FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
4
4
 
5
- def initialize(name, description, long_description, usage, options = nil, disable_class_options = false)
6
- super(name.to_s, description, long_description, usage, options || {}, disable_class_options)
5
+ def initialize(name, description, long_description, usage, options = nil)
6
+ super(name.to_s, description, long_description, usage, options || {})
7
7
  end
8
8
 
9
9
  def initialize_copy(other) #:nodoc:
@@ -39,13 +39,15 @@ class Bundler::Thor
39
39
  # Returns the formatted usage by injecting given required arguments
40
40
  # and required options into the given usage.
41
41
  def formatted_usage(klass, namespace = true, subcommand = false)
42
- if namespace
42
+ if ancestor_name
43
+ formatted = "#{ancestor_name} ".dup # add space
44
+ elsif namespace
43
45
  namespace = klass.namespace
44
- formatted = "#{namespace.gsub(/^(default)/, '')}:"
46
+ formatted = "#{namespace.gsub(/^(default)/, '')}:".dup
45
47
  end
46
- formatted = "#{klass.namespace.split(':').last} " if subcommand
48
+ formatted ||= "#{klass.namespace.split(':').last} ".dup if subcommand
47
49
 
48
- formatted ||= ""
50
+ formatted ||= "".dup
49
51
 
50
52
  # Add usage with required arguments
51
53
  formatted << if klass && !klass.arguments.empty?
@@ -51,6 +51,18 @@ class Bundler::Thor
51
51
  self
52
52
  end
53
53
 
54
+ def reverse_merge(other)
55
+ self.class.new(other).merge(self)
56
+ end
57
+
58
+ def reverse_merge!(other_hash)
59
+ replace(reverse_merge(other_hash))
60
+ end
61
+
62
+ def replace(other_hash)
63
+ super(other_hash)
64
+ end
65
+
54
66
  # Convert to a Hash with String keys.
55
67
  def to_hash
56
68
  Hash.new(default).merge!(self)
@@ -205,7 +205,7 @@ class Bundler::Thor::Group
205
205
  alias_method :printable_tasks, :printable_commands
206
206
 
207
207
  def handle_argument_error(command, error, _args, arity) #:nodoc:
208
- msg = "#{basename} #{command.name} takes #{arity} argument"
208
+ msg = "#{basename} #{command.name} takes #{arity} argument".dup
209
209
  msg << "s" if arity > 1
210
210
  msg << ", but it should not."
211
211
  raise error, msg
@@ -23,6 +23,8 @@ class Bundler::Thor
23
23
  if echo?
24
24
  $stdin.gets
25
25
  else
26
+ # Lazy-load io/console since it is gem-ified as of 2.3
27
+ require "io/console" if RUBY_VERSION > "1.9.2"
26
28
  $stdin.noecho(&:gets)
27
29
  end
28
30
  end
@@ -5,6 +5,7 @@ class Bundler::Thor
5
5
  VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
6
6
 
7
7
  def initialize(name, options = {})
8
+ @check_default_type = options[:check_default_type]
8
9
  options[:required] = false unless options.key?(:required)
9
10
  super
10
11
  @lazy_default = options[:lazy_default]
@@ -80,12 +81,12 @@ class Bundler::Thor
80
81
 
81
82
  def usage(padding = 0)
82
83
  sample = if banner && !banner.to_s.empty?
83
- "#{switch_name}=#{banner}"
84
+ "#{switch_name}=#{banner}".dup
84
85
  else
85
86
  switch_name
86
87
  end
87
88
 
88
- sample = "[#{sample}]" unless required?
89
+ sample = "[#{sample}]".dup unless required?
89
90
 
90
91
  if boolean?
91
92
  sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-")
@@ -110,7 +111,7 @@ class Bundler::Thor
110
111
 
111
112
  def validate!
112
113
  raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
113
- validate_default_type!
114
+ validate_default_type! if @check_default_type
114
115
  end
115
116
 
116
117
  def validate_default_type!
@@ -127,8 +128,7 @@ class Bundler::Thor
127
128
  @default.class.name.downcase.to_sym
128
129
  end
129
130
 
130
- # TODO: This should raise an ArgumentError in a future version of Bundler::Thor
131
- warn "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
131
+ raise ArgumentError, "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
132
132
  end
133
133
 
134
134
  def dasherized?
@@ -18,19 +18,20 @@ class Bundler::Thor
18
18
  when Hash
19
19
  "--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}"
20
20
  when nil, false
21
- ""
21
+ nil
22
22
  else
23
23
  "--#{key} #{value.inspect}"
24
24
  end
25
- end.join(" ")
25
+ end.compact.join(" ")
26
26
  end
27
27
 
28
28
  # Takes a hash of Bundler::Thor::Option and a hash with defaults.
29
29
  #
30
30
  # If +stop_on_unknown+ is true, #parse will stop as soon as it encounters
31
31
  # an unknown option or a regular argument.
32
- def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false)
32
+ def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false)
33
33
  @stop_on_unknown = stop_on_unknown
34
+ @disable_required_check = disable_required_check
34
35
  options = hash_options.values
35
36
  super(options)
36
37
 
@@ -111,7 +112,7 @@ class Bundler::Thor
111
112
  end
112
113
  end
113
114
 
114
- check_requirement!
115
+ check_requirement! unless @disable_required_check
115
116
 
116
117
  assigns = Bundler::Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
117
118
  assigns.freeze
@@ -188,7 +189,7 @@ class Bundler::Thor
188
189
  shift
189
190
  false
190
191
  else
191
- true
192
+ !no_or_skip?(switch)
192
193
  end
193
194
  else
194
195
  @switches.key?(switch) || !no_or_skip?(switch)
@@ -2,10 +2,8 @@ require "bundler/vendor/thor/lib/thor"
2
2
  require "bundler/vendor/thor/lib/thor/group"
3
3
  require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read"
4
4
 
5
- require "fileutils"
6
- require "open-uri"
7
5
  require "yaml"
8
- require "digest/md5"
6
+ require "digest"
9
7
  require "pathname"
10
8
 
11
9
  class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLength
@@ -92,7 +90,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
92
90
  end
93
91
 
94
92
  thor_yaml[as] = {
95
- :filename => Digest::MD5.hexdigest(name + as),
93
+ :filename => Digest(:MD5).hexdigest(name + as),
96
94
  :location => location,
97
95
  :namespaces => Bundler::Thor::Util.namespaces_in_content(contents, base)
98
96
  }
@@ -104,6 +102,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
104
102
  if package == :file
105
103
  File.open(destination, "w") { |f| f.puts contents }
106
104
  else
105
+ require "fileutils"
107
106
  FileUtils.cp_r(name, destination)
108
107
  end
109
108
 
@@ -120,6 +119,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
120
119
  def uninstall(name)
121
120
  raise Error, "Can't find module '#{name}'" unless thor_yaml[name]
122
121
  say "Uninstalling #{name}."
122
+ require "fileutils"
123
123
  FileUtils.rm_rf(File.join(thor_root, (thor_yaml[name][:filename]).to_s))
124
124
 
125
125
  thor_yaml.delete(name)
@@ -138,6 +138,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
138
138
  self.options = options.merge("as" => name)
139
139
 
140
140
  if File.directory? File.expand_path(name)
141
+ require "fileutils"
141
142
  FileUtils.rm_rf(File.join(thor_root, old_filename))
142
143
 
143
144
  thor_yaml.delete(old_filename)
@@ -194,6 +195,7 @@ private
194
195
  yaml_file = File.join(thor_root, "thor.yml")
195
196
 
196
197
  unless File.exist?(yaml_file)
198
+ require "fileutils"
197
199
  FileUtils.mkdir_p(thor_root)
198
200
  yaml_file = File.join(thor_root, "thor.yml")
199
201
  FileUtils.touch(yaml_file)
@@ -1,6 +1,3 @@
1
- require "tempfile"
2
- require "io/console" if RUBY_VERSION > "1.9.2"
3
-
4
1
  class Bundler::Thor
5
2
  module Shell
6
3
  class Basic
@@ -110,7 +107,7 @@ class Bundler::Thor
110
107
  status = set_color status, color, true if color
111
108
 
112
109
  buffer = "#{status}#{spaces}#{message}"
113
- buffer << "\n" unless buffer.end_with?("\n")
110
+ buffer = "#{buffer}\n" unless buffer.end_with?("\n")
114
111
 
115
112
  stdout.print(buffer)
116
113
  stdout.flush
@@ -165,7 +162,7 @@ class Bundler::Thor
165
162
  colwidth = options[:colwidth]
166
163
  options[:truncate] = terminal_width if options[:truncate] == true
167
164
 
168
- formats << "%-#{colwidth + 2}s" if colwidth
165
+ formats << "%-#{colwidth + 2}s".dup if colwidth
169
166
  start = colwidth ? 1 : 0
170
167
 
171
168
  colcount = array.max { |a, b| a.size <=> b.size }.size
@@ -177,9 +174,9 @@ class Bundler::Thor
177
174
  maximas << maxima
178
175
  formats << if index == colcount - 1
179
176
  # Don't output 2 trailing spaces when printing the last column
180
- "%-s"
177
+ "%-s".dup
181
178
  else
182
- "%-#{maxima + 2}s"
179
+ "%-#{maxima + 2}s".dup
183
180
  end
184
181
  end
185
182
 
@@ -187,7 +184,7 @@ class Bundler::Thor
187
184
  formats << "%s"
188
185
 
189
186
  array.each do |row|
190
- sentence = ""
187
+ sentence = "".dup
191
188
 
192
189
  row.each_with_index do |column, index|
193
190
  maxima = maximas[index]
@@ -255,6 +252,9 @@ class Bundler::Thor
255
252
  )
256
253
 
257
254
  case answer
255
+ when nil
256
+ say ""
257
+ return true
258
258
  when is?(:yes), is?(:force), ""
259
259
  return true
260
260
  when is?(:no), is?(:skip)
@@ -350,6 +350,7 @@ class Bundler::Thor
350
350
  def show_diff(destination, content) #:nodoc:
351
351
  diff_cmd = ENV["THOR_DIFF"] || ENV["RAILS_DIFF"] || "diff -u"
352
352
 
353
+ require "tempfile"
353
354
  Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp|
354
355
  temp.write content
355
356
  temp.rewind
@@ -411,7 +412,7 @@ class Bundler::Thor
411
412
 
412
413
  return unless result
413
414
 
414
- result.strip!
415
+ result = result.strip
415
416
 
416
417
  if default && result == ""
417
418
  default
@@ -1,3 +1,3 @@
1
1
  class Bundler::Thor
2
- VERSION = "0.19.4"
2
+ VERSION = "0.20.0"
3
3
  end