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,49 +1,77 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bundler
3
4
  class Injector
5
+ INJECTED_GEMS = "injected gems".freeze
6
+
4
7
  def self.inject(new_deps, options = {})
5
8
  injector = new(new_deps, options)
6
9
  injector.inject(Bundler.default_gemfile, Bundler.default_lockfile)
7
10
  end
8
11
 
9
- def initialize(new_deps, options = {})
10
- @new_deps = new_deps
12
+ def self.remove(gems, options = {})
13
+ injector = new(gems, options)
14
+ injector.remove(Bundler.default_gemfile, Bundler.default_lockfile)
15
+ end
16
+
17
+ def initialize(deps, options = {})
18
+ @deps = deps
11
19
  @options = options
12
20
  end
13
21
 
22
+ # @param [Pathname] gemfile_path The Gemfile in which to inject the new dependency.
23
+ # @param [Pathname] lockfile_path The lockfile in which to inject the new dependency.
24
+ # @return [Array]
14
25
  def inject(gemfile_path, lockfile_path)
15
- if Bundler.settings[:frozen]
26
+ if Bundler.frozen_bundle?
16
27
  # ensure the lock and Gemfile are synced
17
28
  Bundler.definition.ensure_equivalent_gemfile_and_lockfile(true)
18
- # temporarily remove frozen while we inject
19
- frozen = Bundler.settings.delete(:frozen)
20
29
  end
21
30
 
22
- # evaluate the Gemfile we have now
23
- builder = Dsl.new
24
- builder.eval_gemfile(gemfile_path)
31
+ # temporarily unfreeze
32
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
33
+ # evaluate the Gemfile we have now
34
+ builder = Dsl.new
35
+ builder.eval_gemfile(gemfile_path)
36
+
37
+ # don't inject any gems that are already in the Gemfile
38
+ @deps -= builder.dependencies
25
39
 
26
- # don't inject any gems that are already in the Gemfile
27
- @new_deps -= builder.dependencies
40
+ # add new deps to the end of the in-memory Gemfile
41
+ # Set conservative versioning to false because
42
+ # we want to let the resolver resolve the version first
43
+ builder.eval_gemfile(INJECTED_GEMS, build_gem_lines(false)) if @deps.any?
28
44
 
29
- # add new deps to the end of the in-memory Gemfile
30
- # Set conservative versioining to false because we want to let the resolver resolve the version first
31
- builder.eval_gemfile("injected gems", build_gem_lines(false)) if @new_deps.any?
45
+ # resolve to see if the new deps broke anything
46
+ @definition = builder.to_definition(lockfile_path, {})
47
+ @definition.resolve_remotely!
32
48
 
33
- # resolve to see if the new deps broke anything
34
- @definition = builder.to_definition(lockfile_path, {})
35
- @definition.resolve_remotely!
49
+ # since nothing broke, we can add those gems to the gemfile
50
+ append_to(gemfile_path, build_gem_lines(@options[:conservative_versioning])) if @deps.any?
36
51
 
37
- # since nothing broke, we can add those gems to the gemfile
38
- append_to(gemfile_path, build_gem_lines(@options[:conservative_versioning])) if @new_deps.any?
52
+ # since we resolved successfully, write out the lockfile
53
+ @definition.lock(Bundler.default_lockfile)
39
54
 
40
- # since we resolved successfully, write out the lockfile
41
- @definition.lock(Bundler.default_lockfile)
55
+ # invalidate the cached Bundler.definition
56
+ Bundler.reset_paths!
42
57
 
43
- # return an array of the deps that we added
44
- return @new_deps
45
- ensure
46
- Bundler.settings[:frozen] = "1" if frozen
58
+ # return an array of the deps that we added
59
+ @deps
60
+ end
61
+ end
62
+
63
+ # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
64
+ # @param [Pathname] lockfile_path The lockfile from which to remove dependencies.
65
+ # @return [Array]
66
+ def remove(gemfile_path, lockfile_path)
67
+ # remove gems from each gemfiles we have
68
+ Bundler.definition.gemfiles.each do |path|
69
+ deps = remove_deps(path)
70
+
71
+ show_warning("No gems were removed from the gemfile.") if deps.empty?
72
+
73
+ deps.each {|dep| Bundler.ui.confirm "#{SharedHelpers.pretty_dependency(dep, false)} was removed." }
74
+ end
47
75
  end
48
76
 
49
77
  private
@@ -55,11 +83,21 @@ module Bundler
55
83
  seg_end_index = version >= Gem::Version.new("1.0") ? 1 : 2
56
84
 
57
85
  prerelease_suffix = version.to_s.gsub(version.release.to_s, "") if version.prerelease?
58
- "~> #{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
86
+ "#{version_prefix}#{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
87
+ end
88
+
89
+ def version_prefix
90
+ if @options[:strict]
91
+ "= "
92
+ elsif @options[:optimistic]
93
+ ">= "
94
+ else
95
+ "~> "
96
+ end
59
97
  end
60
98
 
61
99
  def build_gem_lines(conservative_versioning)
62
- @new_deps.map do |d|
100
+ @deps.map do |d|
63
101
  name = d.name.dump
64
102
 
65
103
  requirement = if conservative_versioning
@@ -69,7 +107,7 @@ module Bundler
69
107
  end
70
108
 
71
109
  if d.groups != Array(:default)
72
- group = d.groups.size == 1 ? ", :group => #{d.groups.inspect}" : ", :groups => #{d.groups.inspect}"
110
+ group = d.groups.size == 1 ? ", :group => #{d.groups.first.inspect}" : ", :groups => #{d.groups.inspect}"
73
111
  end
74
112
 
75
113
  source = ", :source => \"#{d.source}\"" unless d.source.nil?
@@ -81,11 +119,135 @@ module Bundler
81
119
  def append_to(gemfile_path, new_gem_lines)
82
120
  gemfile_path.open("a") do |f|
83
121
  f.puts
84
- if @options["timestamp"] || @options["timestamp"].nil?
85
- f.puts "# Added at #{Time.now} by #{`whoami`.chomp}:"
86
- end
87
122
  f.puts new_gem_lines
88
123
  end
89
124
  end
125
+
126
+ # evalutes a gemfile to remove the specified gem
127
+ # from it.
128
+ def remove_deps(gemfile_path)
129
+ initial_gemfile = IO.readlines(gemfile_path)
130
+
131
+ Bundler.ui.info "Removing gems from #{gemfile_path}"
132
+
133
+ # evaluate the Gemfile we have
134
+ builder = Dsl.new
135
+ builder.eval_gemfile(gemfile_path)
136
+
137
+ removed_deps = remove_gems_from_dependencies(builder, @deps, gemfile_path)
138
+
139
+ # abort the opertion if no gems were removed
140
+ # no need to operate on gemfile furthur
141
+ return [] if removed_deps.empty?
142
+
143
+ cleaned_gemfile = remove_gems_from_gemfile(@deps, gemfile_path)
144
+
145
+ SharedHelpers.write_to_gemfile(gemfile_path, cleaned_gemfile)
146
+
147
+ # check for errors
148
+ # including extra gems being removed
149
+ # or some gems not being removed
150
+ # and return the actual removed deps
151
+ cross_check_for_errors(gemfile_path, builder.dependencies, removed_deps, initial_gemfile)
152
+ end
153
+
154
+ # @param [Dsl] builder Dsl object of current Gemfile.
155
+ # @param [Array] gems Array of names of gems to be removed.
156
+ # @param [Pathname] path of the Gemfile
157
+ # @return [Array] removed_deps Array of removed dependencies.
158
+ def remove_gems_from_dependencies(builder, gems, gemfile_path)
159
+ removed_deps = []
160
+
161
+ gems.each do |gem_name|
162
+ deleted_dep = builder.dependencies.find {|d| d.name == gem_name }
163
+
164
+ if deleted_dep.nil?
165
+ raise GemfileError, "`#{gem_name}` is not specified in #{gemfile_path} so it could not be removed."
166
+ end
167
+
168
+ builder.dependencies.delete(deleted_dep)
169
+
170
+ removed_deps << deleted_dep
171
+ end
172
+
173
+ removed_deps
174
+ end
175
+
176
+ # @param [Array] gems Array of names of gems to be removed.
177
+ # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
178
+ def remove_gems_from_gemfile(gems, gemfile_path)
179
+ patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/
180
+
181
+ # remove lines which match the regex
182
+ new_gemfile = IO.readlines(gemfile_path).reject {|line| line.match(patterns) }
183
+
184
+ # remove lone \n and append them with other strings
185
+ new_gemfile.each_with_index do |_line, index|
186
+ if new_gemfile[index + 1] == "\n"
187
+ new_gemfile[index] += new_gemfile[index + 1]
188
+ new_gemfile.delete_at(index + 1)
189
+ end
190
+ end
191
+
192
+ %w[group source env install_if].each {|block| remove_nested_blocks(new_gemfile, block) }
193
+
194
+ new_gemfile.join.chomp
195
+ end
196
+
197
+ # @param [Array] gemfile Array of gemfile contents.
198
+ # @param [String] block_name Name of block name to look for.
199
+ def remove_nested_blocks(gemfile, block_name)
200
+ nested_blocks = 0
201
+
202
+ # count number of nested blocks
203
+ gemfile.each_with_index {|line, index| nested_blocks += 1 if !gemfile[index + 1].nil? && gemfile[index + 1].include?(block_name) && line.include?(block_name) }
204
+
205
+ while nested_blocks >= 0
206
+ nested_blocks -= 1
207
+
208
+ gemfile.each_with_index do |line, index|
209
+ next unless !line.nil? && line.include?(block_name)
210
+ if gemfile[index + 1] =~ /^\s*end\s*$/
211
+ gemfile[index] = nil
212
+ gemfile[index + 1] = nil
213
+ end
214
+ end
215
+
216
+ gemfile.compact!
217
+ end
218
+ end
219
+
220
+ # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
221
+ # @param [Array] original_deps Array of original dependencies.
222
+ # @param [Array] removed_deps Array of removed dependencies.
223
+ # @param [Array] initial_gemfile Contents of original Gemfile before any operation.
224
+ def cross_check_for_errors(gemfile_path, original_deps, removed_deps, initial_gemfile)
225
+ # evalute the new gemfile to look for any failure cases
226
+ builder = Dsl.new
227
+ builder.eval_gemfile(gemfile_path)
228
+
229
+ # record gems which were removed but not requested
230
+ extra_removed_gems = original_deps - builder.dependencies
231
+
232
+ # if some extra gems were removed then raise error
233
+ # and revert Gemfile to original
234
+ unless extra_removed_gems.empty?
235
+ SharedHelpers.write_to_gemfile(gemfile_path, initial_gemfile.join)
236
+
237
+ raise InvalidOption, "Gems could not be removed. #{extra_removed_gems.join(", ")} would also have been removed. Bundler cannot continue."
238
+ end
239
+
240
+ # record gems which could not be removed due to some reasons
241
+ errored_deps = builder.dependencies.select {|d| d.gemfile == gemfile_path } & removed_deps.select {|d| d.gemfile == gemfile_path }
242
+
243
+ show_warning "#{errored_deps.map(&:name).join(", ")} could not be removed." unless errored_deps.empty?
244
+
245
+ # return actual removed dependencies
246
+ removed_deps - errored_deps
247
+ end
248
+
249
+ def show_warning(message)
250
+ Bundler.ui.info Bundler.ui.add_color(message, :yellow)
251
+ end
90
252
  end
91
253
  end
@@ -1,4 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
3
+ require "bundler/compatibility_guard"
4
+
2
5
  # Allows for declaring a Gemfile inline in a ruby script, optionally installing
3
6
  # any gems that aren't already installed on the user's system.
4
7
  #
@@ -39,7 +42,7 @@ def gemfile(install = false, options = {}, &gemfile)
39
42
  def Bundler.root
40
43
  Bundler::SharedHelpers.pwd.expand_path
41
44
  end
42
- ENV["BUNDLE_GEMFILE"] = "Gemfile"
45
+ Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile"
43
46
 
44
47
  Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins?
45
48
  builder = Bundler::Dsl.new
@@ -50,12 +53,7 @@ def gemfile(install = false, options = {}, &gemfile)
50
53
  definition.validate_runtime!
51
54
 
52
55
  missing_specs = proc do
53
- begin
54
- !definition.missing_specs.empty?
55
- rescue Bundler::GemNotFound, Bundler::GitError
56
- definition.instance_variable_set(:@index, nil)
57
- true
58
- end
56
+ definition.missing_specs?
59
57
  end
60
58
 
61
59
  Bundler.ui = ui if install
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bundler
3
4
  class GemInstaller
4
5
  attr_reader :spec, :standalone, :worker, :force, :installer
@@ -20,7 +21,7 @@ module Bundler
20
21
  raise
21
22
  rescue Errno::ENOSPC
22
23
  return false, out_of_space_message
23
- rescue => e
24
+ rescue StandardError => e
24
25
  return false, specific_failure_message(e)
25
26
  end
26
27
 
@@ -43,7 +44,14 @@ module Bundler
43
44
  end
44
45
 
45
46
  def gem_install_message
46
- "Make sure that `gem install #{spec.name} -v '#{spec.version}'` succeeds before bundling."
47
+ source = spec.source
48
+ return unless source.respond_to?(:remotes)
49
+
50
+ if source.remotes.size == 1
51
+ "Make sure that `gem install #{spec.name} -v '#{spec.version}' --source '#{source.remotes.first}'` succeeds before bundling."
52
+ else
53
+ "Make sure that `gem install #{spec.name} -v '#{spec.version}'` succeeds before bundling."
54
+ end
47
55
  end
48
56
 
49
57
  def spec_settings
@@ -65,6 +73,7 @@ module Bundler
65
73
  end
66
74
 
67
75
  def generate_executable_stubs
76
+ return if Bundler.feature_flag.forget_cli_options?
68
77
  return if Bundler.settings[:inline]
69
78
  if Bundler.settings[:bin] && standalone
70
79
  installer.generate_standalone_bundler_executable_stubs(spec)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "bundler/worker"
3
4
  require "bundler/installer/gem_installer"
4
5
 
@@ -77,11 +78,6 @@ module Bundler
77
78
  new(*args).call
78
79
  end
79
80
 
80
- # Returns max number of threads machine can handle with a min of 1
81
- def self.max_threads
82
- [Bundler.settings[:jobs].to_i - 1, 1].max
83
- end
84
-
85
81
  attr_reader :size
86
82
 
87
83
  def initialize(installer, all_specs, size, standalone, force)
@@ -91,6 +87,7 @@ module Bundler
91
87
  @force = force
92
88
  @specs = all_specs.map {|s| SpecInstallation.new(s) }
93
89
  @spec_set = all_specs
90
+ @rake = @specs.find {|s| s.name == "rake" }
94
91
  end
95
92
 
96
93
  def call
@@ -99,49 +96,19 @@ module Bundler
99
96
  require "bundler/gem_remote_fetcher" if RUBY_VERSION < "1.9"
100
97
 
101
98
  check_for_corrupt_lockfile
102
- enqueue_specs
103
- process_specs until @specs.all?(&:installed?) || @specs.any?(&:failed?)
99
+
100
+ if @size > 1
101
+ install_with_worker
102
+ else
103
+ install_serially
104
+ end
105
+
104
106
  handle_error if @specs.any?(&:failed?)
105
107
  @specs
106
108
  ensure
107
109
  worker_pool && worker_pool.stop
108
110
  end
109
111
 
110
- def worker_pool
111
- @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda { |spec_install, worker_num|
112
- gem_installer = Bundler::GemInstaller.new(
113
- spec_install.spec, @installer, @standalone, worker_num, @force
114
- )
115
- success, message = gem_installer.install_from_spec
116
- if success && !message.nil?
117
- spec_install.post_install_message = message
118
- elsif !success
119
- spec_install.state = :failed
120
- spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
121
- end
122
- spec_install
123
- }
124
- end
125
-
126
- # Dequeue a spec and save its post-install message and then enqueue the
127
- # remaining specs.
128
- # Some specs might've had to wait til this spec was installed to be
129
- # processed so the call to `enqueue_specs` is important after every
130
- # dequeue.
131
- def process_specs
132
- spec = worker_pool.deq
133
- spec.state = :installed unless spec.failed?
134
- enqueue_specs
135
- end
136
-
137
- def handle_error
138
- errors = @specs.select(&:failed?).map(&:error)
139
- if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) }
140
- raise exception
141
- end
142
- raise Bundler::InstallError, errors.map(&:to_s).join("\n\n")
143
- end
144
-
145
112
  def check_for_corrupt_lockfile
146
113
  missing_dependencies = @specs.map do |s|
147
114
  [
@@ -167,6 +134,73 @@ module Bundler
167
134
  Bundler.ui.warn(warning.join("\n"))
168
135
  end
169
136
 
137
+ private
138
+
139
+ def install_with_worker
140
+ enqueue_specs
141
+ process_specs until finished_installing?
142
+ end
143
+
144
+ def install_serially
145
+ until finished_installing?
146
+ raise "failed to find a spec to enqueue while installing serially" unless spec_install = @specs.find(&:ready_to_enqueue?)
147
+ spec_install.state = :enqueued
148
+ do_install(spec_install, 0)
149
+ end
150
+ end
151
+
152
+ def worker_pool
153
+ @worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda { |spec_install, worker_num|
154
+ do_install(spec_install, worker_num)
155
+ }
156
+ end
157
+
158
+ def do_install(spec_install, worker_num)
159
+ Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL, spec_install)
160
+ gem_installer = Bundler::GemInstaller.new(
161
+ spec_install.spec, @installer, @standalone, worker_num, @force
162
+ )
163
+ success, message = begin
164
+ gem_installer.install_from_spec
165
+ rescue RuntimeError => e
166
+ raise e, "#{e}\n\n#{require_tree_for_spec(spec_install.spec)}"
167
+ end
168
+ if success
169
+ spec_install.state = :installed
170
+ spec_install.post_install_message = message unless message.nil?
171
+ else
172
+ spec_install.state = :failed
173
+ spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
174
+ end
175
+ Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL, spec_install)
176
+ spec_install
177
+ end
178
+
179
+ # Dequeue a spec and save its post-install message and then enqueue the
180
+ # remaining specs.
181
+ # Some specs might've had to wait til this spec was installed to be
182
+ # processed so the call to `enqueue_specs` is important after every
183
+ # dequeue.
184
+ def process_specs
185
+ worker_pool.deq
186
+ enqueue_specs
187
+ end
188
+
189
+ def finished_installing?
190
+ @specs.all? do |spec|
191
+ return true if spec.failed?
192
+ spec.installed?
193
+ end
194
+ end
195
+
196
+ def handle_error
197
+ errors = @specs.select(&:failed?).map(&:error)
198
+ if exception = errors.find {|e| e.is_a?(Bundler::BundlerError) }
199
+ raise exception
200
+ end
201
+ raise Bundler::InstallError, errors.map(&:to_s).join("\n\n")
202
+ end
203
+
170
204
  def require_tree_for_spec(spec)
171
205
  tree = @spec_set.what_required(spec)
172
206
  t = String.new("In #{File.basename(SharedHelpers.default_gemfile)}:\n")
@@ -187,6 +221,8 @@ module Bundler
187
221
  # are installed.
188
222
  def enqueue_specs
189
223
  @specs.select(&:ready_to_enqueue?).each do |spec|
224
+ next if @rake && !@rake.installed? && spec.name != @rake.name
225
+
190
226
  if spec.dependencies_installed? @specs
191
227
  spec.state = :enqueued
192
228
  worker_pool.enq spec
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bundler
3
4
  class Standalone
4
5
  def initialize(groups, definition)