bundler 2.0.2

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 (303) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3111 -0
  3. data/LICENSE.md +23 -0
  4. data/README.md +63 -0
  5. data/bundler.gemspec +65 -0
  6. data/exe/bundle +31 -0
  7. data/exe/bundle_ruby +60 -0
  8. data/exe/bundler +4 -0
  9. data/lib/bundler.rb +567 -0
  10. data/lib/bundler/build_metadata.rb +53 -0
  11. data/lib/bundler/capistrano.rb +22 -0
  12. data/lib/bundler/cli.rb +792 -0
  13. data/lib/bundler/cli/add.rb +35 -0
  14. data/lib/bundler/cli/binstubs.rb +49 -0
  15. data/lib/bundler/cli/cache.rb +36 -0
  16. data/lib/bundler/cli/check.rb +38 -0
  17. data/lib/bundler/cli/clean.rb +25 -0
  18. data/lib/bundler/cli/common.rb +102 -0
  19. data/lib/bundler/cli/config.rb +119 -0
  20. data/lib/bundler/cli/console.rb +43 -0
  21. data/lib/bundler/cli/doctor.rb +140 -0
  22. data/lib/bundler/cli/exec.rb +105 -0
  23. data/lib/bundler/cli/gem.rb +252 -0
  24. data/lib/bundler/cli/info.rb +50 -0
  25. data/lib/bundler/cli/init.rb +47 -0
  26. data/lib/bundler/cli/inject.rb +60 -0
  27. data/lib/bundler/cli/install.rb +218 -0
  28. data/lib/bundler/cli/issue.rb +40 -0
  29. data/lib/bundler/cli/list.rb +58 -0
  30. data/lib/bundler/cli/lock.rb +63 -0
  31. data/lib/bundler/cli/open.rb +26 -0
  32. data/lib/bundler/cli/outdated.rb +266 -0
  33. data/lib/bundler/cli/package.rb +49 -0
  34. data/lib/bundler/cli/platform.rb +46 -0
  35. data/lib/bundler/cli/plugin.rb +24 -0
  36. data/lib/bundler/cli/pristine.rb +47 -0
  37. data/lib/bundler/cli/remove.rb +18 -0
  38. data/lib/bundler/cli/show.rb +75 -0
  39. data/lib/bundler/cli/update.rb +91 -0
  40. data/lib/bundler/cli/viz.rb +31 -0
  41. data/lib/bundler/compact_index_client.rb +109 -0
  42. data/lib/bundler/compact_index_client/cache.rb +118 -0
  43. data/lib/bundler/compact_index_client/updater.rb +116 -0
  44. data/lib/bundler/compatibility_guard.rb +13 -0
  45. data/lib/bundler/constants.rb +7 -0
  46. data/lib/bundler/current_ruby.rb +94 -0
  47. data/lib/bundler/definition.rb +995 -0
  48. data/lib/bundler/dep_proxy.rb +48 -0
  49. data/lib/bundler/dependency.rb +139 -0
  50. data/lib/bundler/deployment.rb +69 -0
  51. data/lib/bundler/deprecate.rb +44 -0
  52. data/lib/bundler/dsl.rb +615 -0
  53. data/lib/bundler/endpoint_specification.rb +141 -0
  54. data/lib/bundler/env.rb +149 -0
  55. data/lib/bundler/environment_preserver.rb +59 -0
  56. data/lib/bundler/errors.rb +158 -0
  57. data/lib/bundler/feature_flag.rb +75 -0
  58. data/lib/bundler/fetcher.rb +312 -0
  59. data/lib/bundler/fetcher/base.rb +52 -0
  60. data/lib/bundler/fetcher/compact_index.rb +126 -0
  61. data/lib/bundler/fetcher/dependency.rb +82 -0
  62. data/lib/bundler/fetcher/downloader.rb +84 -0
  63. data/lib/bundler/fetcher/index.rb +52 -0
  64. data/lib/bundler/friendly_errors.rb +131 -0
  65. data/lib/bundler/gem_helper.rb +217 -0
  66. data/lib/bundler/gem_helpers.rb +101 -0
  67. data/lib/bundler/gem_remote_fetcher.rb +43 -0
  68. data/lib/bundler/gem_tasks.rb +7 -0
  69. data/lib/bundler/gem_version_promoter.rb +190 -0
  70. data/lib/bundler/gemdeps.rb +29 -0
  71. data/lib/bundler/graph.rb +152 -0
  72. data/lib/bundler/index.rb +213 -0
  73. data/lib/bundler/injector.rb +253 -0
  74. data/lib/bundler/inline.rb +74 -0
  75. data/lib/bundler/installer.rb +318 -0
  76. data/lib/bundler/installer/gem_installer.rb +85 -0
  77. data/lib/bundler/installer/parallel_installer.rb +229 -0
  78. data/lib/bundler/installer/standalone.rb +53 -0
  79. data/lib/bundler/lazy_specification.rb +123 -0
  80. data/lib/bundler/lockfile_generator.rb +95 -0
  81. data/lib/bundler/lockfile_parser.rb +256 -0
  82. data/lib/bundler/match_platform.rb +24 -0
  83. data/lib/bundler/mirror.rb +223 -0
  84. data/lib/bundler/plugin.rb +294 -0
  85. data/lib/bundler/plugin/api.rb +81 -0
  86. data/lib/bundler/plugin/api/source.rb +306 -0
  87. data/lib/bundler/plugin/dsl.rb +53 -0
  88. data/lib/bundler/plugin/events.rb +61 -0
  89. data/lib/bundler/plugin/index.rb +165 -0
  90. data/lib/bundler/plugin/installer.rb +96 -0
  91. data/lib/bundler/plugin/installer/git.rb +38 -0
  92. data/lib/bundler/plugin/installer/rubygems.rb +27 -0
  93. data/lib/bundler/plugin/source_list.rb +27 -0
  94. data/lib/bundler/process_lock.rb +24 -0
  95. data/lib/bundler/psyched_yaml.rb +37 -0
  96. data/lib/bundler/remote_specification.rb +114 -0
  97. data/lib/bundler/resolver.rb +373 -0
  98. data/lib/bundler/resolver/spec_group.rb +106 -0
  99. data/lib/bundler/retry.rb +66 -0
  100. data/lib/bundler/ruby_dsl.rb +18 -0
  101. data/lib/bundler/ruby_version.rb +152 -0
  102. data/lib/bundler/rubygems_ext.rb +209 -0
  103. data/lib/bundler/rubygems_gem_installer.rb +99 -0
  104. data/lib/bundler/rubygems_integration.rb +915 -0
  105. data/lib/bundler/runtime.rb +322 -0
  106. data/lib/bundler/settings.rb +464 -0
  107. data/lib/bundler/settings/validator.rb +102 -0
  108. data/lib/bundler/setup.rb +28 -0
  109. data/lib/bundler/shared_helpers.rb +386 -0
  110. data/lib/bundler/similarity_detector.rb +63 -0
  111. data/lib/bundler/source.rb +94 -0
  112. data/lib/bundler/source/gemspec.rb +18 -0
  113. data/lib/bundler/source/git.rb +329 -0
  114. data/lib/bundler/source/git/git_proxy.rb +262 -0
  115. data/lib/bundler/source/metadata.rb +62 -0
  116. data/lib/bundler/source/path.rb +249 -0
  117. data/lib/bundler/source/path/installer.rb +74 -0
  118. data/lib/bundler/source/rubygems.rb +539 -0
  119. data/lib/bundler/source/rubygems/remote.rb +69 -0
  120. data/lib/bundler/source_list.rb +186 -0
  121. data/lib/bundler/spec_set.rb +208 -0
  122. data/lib/bundler/ssl_certs/.document +1 -0
  123. data/lib/bundler/ssl_certs/certificate_manager.rb +66 -0
  124. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
  125. data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +23 -0
  126. data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +25 -0
  127. data/lib/bundler/stub_specification.rb +108 -0
  128. data/lib/bundler/templates/.document +1 -0
  129. data/lib/bundler/templates/Executable +29 -0
  130. data/lib/bundler/templates/Executable.bundler +105 -0
  131. data/lib/bundler/templates/Executable.standalone +14 -0
  132. data/lib/bundler/templates/Gemfile +7 -0
  133. data/lib/bundler/templates/gems.rb +8 -0
  134. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +74 -0
  135. data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
  136. data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
  137. data/lib/bundler/templates/newgem/README.md.tt +47 -0
  138. data/lib/bundler/templates/newgem/Rakefile.tt +29 -0
  139. data/lib/bundler/templates/newgem/bin/console.tt +14 -0
  140. data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
  141. data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
  142. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +3 -0
  143. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
  144. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
  145. data/lib/bundler/templates/newgem/gitignore.tt +20 -0
  146. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +13 -0
  147. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
  148. data/lib/bundler/templates/newgem/newgem.gemspec.tt +50 -0
  149. data/lib/bundler/templates/newgem/rspec.tt +3 -0
  150. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +9 -0
  151. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +14 -0
  152. data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +11 -0
  153. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +8 -0
  154. data/lib/bundler/templates/newgem/travis.yml.tt +7 -0
  155. data/lib/bundler/ui.rb +9 -0
  156. data/lib/bundler/ui/rg_proxy.rb +19 -0
  157. data/lib/bundler/ui/shell.rb +146 -0
  158. data/lib/bundler/ui/silent.rb +69 -0
  159. data/lib/bundler/uri_credentials_filter.rb +37 -0
  160. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1741 -0
  161. data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -0
  162. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +12 -0
  163. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
  164. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
  165. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
  166. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +223 -0
  167. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
  168. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
  169. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
  170. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
  171. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
  172. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
  174. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +136 -0
  176. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +143 -0
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
  178. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +101 -0
  179. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +67 -0
  180. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +837 -0
  181. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +46 -0
  182. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +58 -0
  183. data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +27 -0
  184. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1233 -0
  185. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +129 -0
  186. data/lib/bundler/vendor/thor/lib/thor.rb +509 -0
  187. data/lib/bundler/vendor/thor/lib/thor/actions.rb +331 -0
  188. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +104 -0
  189. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +60 -0
  190. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +118 -0
  191. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +143 -0
  192. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +373 -0
  193. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +109 -0
  194. data/lib/bundler/vendor/thor/lib/thor/base.rb +678 -0
  195. data/lib/bundler/vendor/thor/lib/thor/command.rb +135 -0
  196. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +97 -0
  197. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +12 -0
  198. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +129 -0
  199. data/lib/bundler/vendor/thor/lib/thor/error.rb +114 -0
  200. data/lib/bundler/vendor/thor/lib/thor/group.rb +281 -0
  201. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +177 -0
  202. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
  203. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +37 -0
  204. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
  205. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
  206. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +70 -0
  207. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +175 -0
  208. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +146 -0
  209. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +226 -0
  210. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +71 -0
  211. data/lib/bundler/vendor/thor/lib/thor/runner.rb +324 -0
  212. data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
  213. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +482 -0
  214. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +149 -0
  215. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +126 -0
  216. data/lib/bundler/vendor/thor/lib/thor/util.rb +268 -0
  217. data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
  218. data/lib/bundler/vendored_fileutils.rb +9 -0
  219. data/lib/bundler/vendored_molinillo.rb +4 -0
  220. data/lib/bundler/vendored_persistent.rb +52 -0
  221. data/lib/bundler/vendored_thor.rb +8 -0
  222. data/lib/bundler/version.rb +28 -0
  223. data/lib/bundler/version_ranges.rb +76 -0
  224. data/lib/bundler/vlad.rb +17 -0
  225. data/lib/bundler/worker.rb +106 -0
  226. data/lib/bundler/yaml_serializer.rb +90 -0
  227. data/man/bundle-add.1 +58 -0
  228. data/man/bundle-add.1.txt +52 -0
  229. data/man/bundle-add.ronn +40 -0
  230. data/man/bundle-binstubs.1 +40 -0
  231. data/man/bundle-binstubs.1.txt +48 -0
  232. data/man/bundle-binstubs.ronn +43 -0
  233. data/man/bundle-check.1 +31 -0
  234. data/man/bundle-check.1.txt +33 -0
  235. data/man/bundle-check.ronn +26 -0
  236. data/man/bundle-clean.1 +24 -0
  237. data/man/bundle-clean.1.txt +26 -0
  238. data/man/bundle-clean.ronn +18 -0
  239. data/man/bundle-config.1 +497 -0
  240. data/man/bundle-config.1.txt +529 -0
  241. data/man/bundle-config.ronn +397 -0
  242. data/man/bundle-doctor.1 +44 -0
  243. data/man/bundle-doctor.1.txt +44 -0
  244. data/man/bundle-doctor.ronn +33 -0
  245. data/man/bundle-exec.1 +165 -0
  246. data/man/bundle-exec.1.txt +178 -0
  247. data/man/bundle-exec.ronn +152 -0
  248. data/man/bundle-gem.1 +80 -0
  249. data/man/bundle-gem.1.txt +91 -0
  250. data/man/bundle-gem.ronn +78 -0
  251. data/man/bundle-info.1 +20 -0
  252. data/man/bundle-info.1.txt +21 -0
  253. data/man/bundle-info.ronn +17 -0
  254. data/man/bundle-init.1 +25 -0
  255. data/man/bundle-init.1.txt +34 -0
  256. data/man/bundle-init.ronn +29 -0
  257. data/man/bundle-inject.1 +33 -0
  258. data/man/bundle-inject.1.txt +32 -0
  259. data/man/bundle-inject.ronn +22 -0
  260. data/man/bundle-install.1 +308 -0
  261. data/man/bundle-install.1.txt +396 -0
  262. data/man/bundle-install.ronn +378 -0
  263. data/man/bundle-list.1 +50 -0
  264. data/man/bundle-list.1.txt +43 -0
  265. data/man/bundle-list.ronn +33 -0
  266. data/man/bundle-lock.1 +84 -0
  267. data/man/bundle-lock.1.txt +93 -0
  268. data/man/bundle-lock.ronn +94 -0
  269. data/man/bundle-open.1 +32 -0
  270. data/man/bundle-open.1.txt +29 -0
  271. data/man/bundle-open.ronn +19 -0
  272. data/man/bundle-outdated.1 +155 -0
  273. data/man/bundle-outdated.1.txt +131 -0
  274. data/man/bundle-outdated.ronn +111 -0
  275. data/man/bundle-package.1 +55 -0
  276. data/man/bundle-package.1.txt +79 -0
  277. data/man/bundle-package.ronn +72 -0
  278. data/man/bundle-platform.1 +61 -0
  279. data/man/bundle-platform.1.txt +57 -0
  280. data/man/bundle-platform.ronn +42 -0
  281. data/man/bundle-pristine.1 +34 -0
  282. data/man/bundle-pristine.1.txt +44 -0
  283. data/man/bundle-pristine.ronn +34 -0
  284. data/man/bundle-remove.1 +31 -0
  285. data/man/bundle-remove.1.txt +34 -0
  286. data/man/bundle-remove.ronn +23 -0
  287. data/man/bundle-show.1 +23 -0
  288. data/man/bundle-show.1.txt +27 -0
  289. data/man/bundle-show.ronn +21 -0
  290. data/man/bundle-update.1 +394 -0
  291. data/man/bundle-update.1.txt +391 -0
  292. data/man/bundle-update.ronn +350 -0
  293. data/man/bundle-viz.1 +39 -0
  294. data/man/bundle-viz.1.txt +39 -0
  295. data/man/bundle-viz.ronn +30 -0
  296. data/man/bundle.1 +136 -0
  297. data/man/bundle.1.txt +116 -0
  298. data/man/bundle.ronn +111 -0
  299. data/man/gemfile.5 +689 -0
  300. data/man/gemfile.5.ronn +521 -0
  301. data/man/gemfile.5.txt +653 -0
  302. data/man/index.txt +25 -0
  303. metadata +463 -0
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class Source
5
+ class Path
6
+ class Installer < Bundler::RubyGemsGemInstaller
7
+ attr_reader :spec
8
+
9
+ def initialize(spec, options = {})
10
+ @options = options
11
+ @spec = spec
12
+ @gem_dir = Bundler.rubygems.path(spec.full_gem_path)
13
+ @wrappers = true
14
+ @env_shebang = true
15
+ @format_executable = options[:format_executable] || false
16
+ @build_args = options[:build_args] || Bundler.rubygems.build_args
17
+ @gem_bin_dir = "#{Bundler.rubygems.gem_dir}/bin"
18
+ @disable_extensions = options[:disable_extensions]
19
+
20
+ if Bundler.requires_sudo?
21
+ @tmp_dir = Bundler.tmp(spec.full_name).to_s
22
+ @bin_dir = "#{@tmp_dir}/bin"
23
+ else
24
+ @bin_dir = @gem_bin_dir
25
+ end
26
+ end
27
+
28
+ def post_install
29
+ SharedHelpers.chdir(@gem_dir) do
30
+ run_hooks(:pre_install)
31
+
32
+ unless @disable_extensions
33
+ build_extensions
34
+ run_hooks(:post_build)
35
+ end
36
+
37
+ generate_bin unless spec.executables.nil? || spec.executables.empty?
38
+
39
+ run_hooks(:post_install)
40
+ end
41
+ ensure
42
+ Bundler.rm_rf(@tmp_dir) if Bundler.requires_sudo?
43
+ end
44
+
45
+ private
46
+
47
+ def generate_bin
48
+ super
49
+
50
+ if Bundler.requires_sudo?
51
+ SharedHelpers.filesystem_access(@gem_bin_dir) do |p|
52
+ Bundler.mkdir_p(p)
53
+ end
54
+ spec.executables.each do |exe|
55
+ Bundler.sudo "cp -R #{@bin_dir}/#{exe} #{@gem_bin_dir}"
56
+ end
57
+ end
58
+ end
59
+
60
+ def run_hooks(type)
61
+ hooks_meth = "#{type}_hooks"
62
+ return unless Gem.respond_to?(hooks_meth)
63
+ Gem.send(hooks_meth).each do |hook|
64
+ result = hook.call(self)
65
+ next unless result == false
66
+ location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
67
+ message = "#{type} hook#{location} failed for #{spec.full_name}"
68
+ raise InstallHookError, message
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,539 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+ require "rubygems/user_interaction"
5
+
6
+ module Bundler
7
+ class Source
8
+ class Rubygems < Source
9
+ autoload :Remote, "bundler/source/rubygems/remote"
10
+
11
+ # Use the API when installing less than X gems
12
+ API_REQUEST_LIMIT = 500
13
+ # Ask for X gems per API request
14
+ API_REQUEST_SIZE = 50
15
+
16
+ attr_reader :remotes, :caches
17
+
18
+ def initialize(options = {})
19
+ @options = options
20
+ @remotes = []
21
+ @dependency_names = []
22
+ @allow_remote = false
23
+ @allow_cached = false
24
+ @caches = [cache_path, *Bundler.rubygems.gem_cache]
25
+
26
+ Array(options["remotes"] || []).reverse_each {|r| add_remote(r) }
27
+ end
28
+
29
+ def remote!
30
+ @specs = nil
31
+ @allow_remote = true
32
+ end
33
+
34
+ def cached!
35
+ @specs = nil
36
+ @allow_cached = true
37
+ end
38
+
39
+ def hash
40
+ @remotes.hash
41
+ end
42
+
43
+ def eql?(other)
44
+ other.is_a?(Rubygems) && other.credless_remotes == credless_remotes
45
+ end
46
+
47
+ alias_method :==, :eql?
48
+
49
+ def include?(o)
50
+ o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
51
+ end
52
+
53
+ def can_lock?(spec)
54
+ return super if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
55
+ spec.source.is_a?(Rubygems)
56
+ end
57
+
58
+ def options
59
+ { "remotes" => @remotes.map(&:to_s) }
60
+ end
61
+
62
+ def self.from_lock(options)
63
+ new(options)
64
+ end
65
+
66
+ def to_lock
67
+ out = String.new("GEM\n")
68
+ remotes.reverse_each do |remote|
69
+ out << " remote: #{suppress_configured_credentials remote}\n"
70
+ end
71
+ out << " specs:\n"
72
+ end
73
+
74
+ def to_s
75
+ if remotes.empty?
76
+ "locally installed gems"
77
+ else
78
+ remote_names = remotes.map(&:to_s).join(", ")
79
+ "rubygems repository #{remote_names} or installed locally"
80
+ end
81
+ end
82
+ alias_method :name, :to_s
83
+
84
+ def specs
85
+ @specs ||= begin
86
+ # remote_specs usually generates a way larger Index than the other
87
+ # sources, and large_idx.use small_idx is way faster than
88
+ # small_idx.use large_idx.
89
+ idx = @allow_remote ? remote_specs.dup : Index.new
90
+ idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
91
+ idx.use(installed_specs, :override_dupes)
92
+ idx
93
+ end
94
+ end
95
+
96
+ def install(spec, opts = {})
97
+ force = opts[:force]
98
+ ensure_builtin_gems_cached = opts[:ensure_builtin_gems_cached]
99
+
100
+ if ensure_builtin_gems_cached && builtin_gem?(spec)
101
+ if !cached_path(spec)
102
+ cached_built_in_gem(spec) unless spec.remote
103
+ force = true
104
+ else
105
+ spec.loaded_from = loaded_from(spec)
106
+ end
107
+ end
108
+
109
+ if installed?(spec) && !force
110
+ print_using_message "Using #{version_message(spec)}"
111
+ return nil # no post-install message
112
+ end
113
+
114
+ # Download the gem to get the spec, because some specs that are returned
115
+ # by rubygems.org are broken and wrong.
116
+ if spec.remote
117
+ # Check for this spec from other sources
118
+ uris = [spec.remote.anonymized_uri]
119
+ uris += remotes_for_spec(spec).map(&:anonymized_uri)
120
+ uris.uniq!
121
+ Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
122
+
123
+ s = Bundler.rubygems.spec_from_gem(fetch_gem(spec), Bundler.settings["trust-policy"])
124
+ spec.__swap__(s)
125
+ end
126
+
127
+ unless Bundler.settings[:no_install]
128
+ message = "Installing #{version_message(spec)}"
129
+ message += " with native extensions" if spec.extensions.any?
130
+ Bundler.ui.confirm message
131
+
132
+ path = cached_gem(spec)
133
+ if requires_sudo?
134
+ install_path = Bundler.tmp(spec.full_name)
135
+ bin_path = install_path.join("bin")
136
+ else
137
+ install_path = rubygems_dir
138
+ bin_path = Bundler.system_bindir
139
+ end
140
+
141
+ Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
142
+
143
+ installed_spec = nil
144
+ Bundler.rubygems.preserve_paths do
145
+ installed_spec = Bundler::RubyGemsGemInstaller.at(
146
+ path,
147
+ :install_dir => install_path.to_s,
148
+ :bin_dir => bin_path.to_s,
149
+ :ignore_dependencies => true,
150
+ :wrappers => true,
151
+ :env_shebang => true,
152
+ :build_args => opts[:build_args],
153
+ :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum,
154
+ :bundler_extension_cache_path => extension_cache_path(spec)
155
+ ).install
156
+ end
157
+ spec.full_gem_path = installed_spec.full_gem_path
158
+
159
+ # SUDO HAX
160
+ if requires_sudo?
161
+ Bundler.rubygems.repository_subdirectories.each do |name|
162
+ src = File.join(install_path, name, "*")
163
+ dst = File.join(rubygems_dir, name)
164
+ if name == "extensions" && Dir.glob(src).any?
165
+ src = File.join(src, "*/*")
166
+ ext_src = Dir.glob(src).first
167
+ ext_src.gsub!(src[0..-6], "")
168
+ dst = File.dirname(File.join(dst, ext_src))
169
+ end
170
+ SharedHelpers.filesystem_access(dst) do |p|
171
+ Bundler.mkdir_p(p)
172
+ end
173
+ Bundler.sudo "cp -R #{src} #{dst}" if Dir[src].any?
174
+ end
175
+
176
+ spec.executables.each do |exe|
177
+ SharedHelpers.filesystem_access(Bundler.system_bindir) do |p|
178
+ Bundler.mkdir_p(p)
179
+ end
180
+ Bundler.sudo "cp -R #{install_path}/bin/#{exe} #{Bundler.system_bindir}/"
181
+ end
182
+ end
183
+ installed_spec.loaded_from = loaded_from(spec)
184
+ end
185
+ spec.loaded_from = loaded_from(spec)
186
+
187
+ spec.post_install_message
188
+ ensure
189
+ Bundler.rm_rf(install_path) if requires_sudo?
190
+ end
191
+
192
+ def cache(spec, custom_path = nil)
193
+ if builtin_gem?(spec)
194
+ cached_path = cached_built_in_gem(spec)
195
+ else
196
+ cached_path = cached_gem(spec)
197
+ end
198
+ raise GemNotFound, "Missing gem file '#{spec.full_name}.gem'." unless cached_path
199
+ return if File.dirname(cached_path) == Bundler.app_cache.to_s
200
+ Bundler.ui.info " * #{File.basename(cached_path)}"
201
+ FileUtils.cp(cached_path, Bundler.app_cache(custom_path))
202
+ rescue Errno::EACCES => e
203
+ Bundler.ui.debug(e)
204
+ raise InstallError, e.message
205
+ end
206
+
207
+ def cached_built_in_gem(spec)
208
+ cached_path = cached_path(spec)
209
+ if cached_path.nil?
210
+ remote_spec = remote_specs.search(spec).first
211
+ if remote_spec
212
+ cached_path = fetch_gem(remote_spec)
213
+ else
214
+ Bundler.ui.warn "#{spec.full_name} is built in to Ruby, and can't be cached because your Gemfile doesn't have any sources that contain it."
215
+ end
216
+ end
217
+ cached_path
218
+ end
219
+
220
+ def add_remote(source)
221
+ uri = normalize_uri(source)
222
+ @remotes.unshift(uri) unless @remotes.include?(uri)
223
+ end
224
+
225
+ def equivalent_remotes?(other_remotes)
226
+ other_remotes.map(&method(:remove_auth)) == @remotes.map(&method(:remove_auth))
227
+ end
228
+
229
+ def replace_remotes(other_remotes, allow_equivalent = false)
230
+ return false if other_remotes == @remotes
231
+
232
+ equivalent = allow_equivalent && equivalent_remotes?(other_remotes)
233
+
234
+ @remotes = []
235
+ other_remotes.reverse_each do |r|
236
+ add_remote r.to_s
237
+ end
238
+
239
+ !equivalent
240
+ end
241
+
242
+ def unmet_deps
243
+ if @allow_remote && api_fetchers.any?
244
+ remote_specs.unmet_dependency_names
245
+ else
246
+ []
247
+ end
248
+ end
249
+
250
+ def fetchers
251
+ @fetchers ||= remotes.map do |uri|
252
+ remote = Source::Rubygems::Remote.new(uri)
253
+ Bundler::Fetcher.new(remote)
254
+ end
255
+ end
256
+
257
+ def double_check_for(unmet_dependency_names)
258
+ return unless @allow_remote
259
+ return unless api_fetchers.any?
260
+
261
+ unmet_dependency_names = unmet_dependency_names.call
262
+ unless unmet_dependency_names.nil?
263
+ if api_fetchers.size <= 1
264
+ # can't do this when there are multiple fetchers because then we might not fetch from _all_
265
+ # of them
266
+ unmet_dependency_names -= remote_specs.spec_names # avoid re-fetching things we've already gotten
267
+ end
268
+ return if unmet_dependency_names.empty?
269
+ end
270
+
271
+ Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}"
272
+
273
+ fetch_names(api_fetchers, unmet_dependency_names, specs, false)
274
+ end
275
+
276
+ def dependency_names_to_double_check
277
+ names = []
278
+ remote_specs.each do |spec|
279
+ case spec
280
+ when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
281
+ names.concat(spec.runtime_dependencies)
282
+ when RemoteSpecification # from the full index
283
+ return nil
284
+ else
285
+ raise "unhandled spec type (#{spec.inspect})"
286
+ end
287
+ end
288
+ names.map!(&:name) if names
289
+ names
290
+ end
291
+
292
+ protected
293
+
294
+ def credless_remotes
295
+ remotes.map(&method(:suppress_configured_credentials))
296
+ end
297
+
298
+ def remotes_for_spec(spec)
299
+ specs.search_all(spec.name).inject([]) do |uris, s|
300
+ uris << s.remote if s.remote
301
+ uris
302
+ end
303
+ end
304
+
305
+ def loaded_from(spec)
306
+ "#{rubygems_dir}/specifications/#{spec.full_name}.gemspec"
307
+ end
308
+
309
+ def cached_gem(spec)
310
+ cached_gem = cached_path(spec)
311
+ unless cached_gem
312
+ raise Bundler::GemNotFound, "Could not find #{spec.file_name} for installation"
313
+ end
314
+ cached_gem
315
+ end
316
+
317
+ def cached_path(spec)
318
+ possibilities = @caches.map {|p| "#{p}/#{spec.file_name}" }
319
+ possibilities.find {|p| File.exist?(p) }
320
+ end
321
+
322
+ def normalize_uri(uri)
323
+ uri = uri.to_s
324
+ uri = "#{uri}/" unless uri =~ %r{/$}
325
+ uri = URI(uri)
326
+ raise ArgumentError, "The source must be an absolute URI. For example:\n" \
327
+ "source 'https://rubygems.org'" if !uri.absolute? || (uri.is_a?(URI::HTTP) && uri.host.nil?)
328
+ uri
329
+ end
330
+
331
+ def suppress_configured_credentials(remote)
332
+ remote_nouser = remove_auth(remote)
333
+ if remote.userinfo && remote.userinfo == Bundler.settings[remote_nouser]
334
+ remote_nouser
335
+ else
336
+ remote
337
+ end
338
+ end
339
+
340
+ def remove_auth(remote)
341
+ if remote.user || remote.password
342
+ remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s
343
+ else
344
+ remote.to_s
345
+ end
346
+ end
347
+
348
+ def installed_specs
349
+ @installed_specs ||= Index.build do |idx|
350
+ Bundler.rubygems.all_specs.reverse_each do |spec|
351
+ next if spec.name == "bundler"
352
+ spec.source = self
353
+ if Bundler.rubygems.spec_missing_extensions?(spec, false)
354
+ Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
355
+ next
356
+ end
357
+ idx << spec
358
+ end
359
+ end
360
+ end
361
+
362
+ def cached_specs
363
+ @cached_specs ||= begin
364
+ idx = installed_specs.dup
365
+
366
+ Dir["#{cache_path}/*.gem"].each do |gemfile|
367
+ next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
368
+ s ||= Bundler.rubygems.spec_from_gem(gemfile)
369
+ s.source = self
370
+ if Bundler.rubygems.spec_missing_extensions?(s, false)
371
+ Bundler.ui.debug "Source #{self} is ignoring #{s} because it is missing extensions"
372
+ next
373
+ end
374
+ idx << s
375
+ end
376
+
377
+ idx
378
+ end
379
+ end
380
+
381
+ def api_fetchers
382
+ fetchers.select {|f| f.use_api && f.fetchers.first.api_fetcher? }
383
+ end
384
+
385
+ def remote_specs
386
+ @remote_specs ||= Index.build do |idx|
387
+ index_fetchers = fetchers - api_fetchers
388
+
389
+ # gather lists from non-api sites
390
+ fetch_names(index_fetchers, nil, idx, false)
391
+
392
+ # because ensuring we have all the gems we need involves downloading
393
+ # the gemspecs of those gems, if the non-api sites contain more than
394
+ # about 500 gems, we treat all sites as non-api for speed.
395
+ allow_api = idx.size < API_REQUEST_LIMIT && dependency_names.size < API_REQUEST_LIMIT
396
+ Bundler.ui.debug "Need to query more than #{API_REQUEST_LIMIT} gems." \
397
+ " Downloading full index instead..." unless allow_api
398
+
399
+ fetch_names(api_fetchers, allow_api && dependency_names, idx, false)
400
+ end
401
+ end
402
+
403
+ def fetch_names(fetchers, dependency_names, index, override_dupes)
404
+ fetchers.each do |f|
405
+ if dependency_names
406
+ Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
407
+ index.use f.specs_with_retry(dependency_names, self), override_dupes
408
+ Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
409
+ else
410
+ Bundler.ui.info "Fetching source index from #{f.uri}"
411
+ index.use f.specs_with_retry(nil, self), override_dupes
412
+ end
413
+ end
414
+ end
415
+
416
+ def fetch_gem(spec)
417
+ return false unless spec.remote
418
+
419
+ spec.fetch_platform
420
+
421
+ download_path = requires_sudo? ? Bundler.tmp(spec.full_name) : rubygems_dir
422
+ gem_path = "#{rubygems_dir}/cache/#{spec.full_name}.gem"
423
+
424
+ SharedHelpers.filesystem_access("#{download_path}/cache") do |p|
425
+ FileUtils.mkdir_p(p)
426
+ end
427
+ download_gem(spec, download_path)
428
+
429
+ if requires_sudo?
430
+ SharedHelpers.filesystem_access("#{rubygems_dir}/cache") do |p|
431
+ Bundler.mkdir_p(p)
432
+ end
433
+ Bundler.sudo "mv #{download_path}/cache/#{spec.full_name}.gem #{gem_path}"
434
+ end
435
+
436
+ gem_path
437
+ ensure
438
+ Bundler.rm_rf(download_path) if requires_sudo?
439
+ end
440
+
441
+ def builtin_gem?(spec)
442
+ # Ruby 2.1, where all included gems have this summary
443
+ return true if spec.summary =~ /is bundled with Ruby/
444
+
445
+ # Ruby 2.0, where gemspecs are stored in specifications/default/
446
+ spec.loaded_from && spec.loaded_from.include?("specifications/default/")
447
+ end
448
+
449
+ def installed?(spec)
450
+ installed_specs[spec].any?
451
+ end
452
+
453
+ def requires_sudo?
454
+ Bundler.requires_sudo?
455
+ end
456
+
457
+ def rubygems_dir
458
+ Bundler.rubygems.gem_dir
459
+ end
460
+
461
+ def cache_path
462
+ Bundler.app_cache
463
+ end
464
+
465
+ private
466
+
467
+ # Checks if the requested spec exists in the global cache. If it does,
468
+ # we copy it to the download path, and if it does not, we download it.
469
+ #
470
+ # @param [Specification] spec
471
+ # the spec we want to download or retrieve from the cache.
472
+ #
473
+ # @param [String] download_path
474
+ # the local directory the .gem will end up in.
475
+ #
476
+ def download_gem(spec, download_path)
477
+ local_path = File.join(download_path, "cache/#{spec.full_name}.gem")
478
+
479
+ if (cache_path = download_cache_path(spec)) && cache_path.file?
480
+ SharedHelpers.filesystem_access(local_path) do
481
+ FileUtils.cp(cache_path, local_path)
482
+ end
483
+ else
484
+ uri = spec.remote.uri
485
+ Bundler.ui.confirm("Fetching #{version_message(spec)}")
486
+ rubygems_local_path = Bundler.rubygems.download_gem(spec, uri, download_path)
487
+ if rubygems_local_path != local_path
488
+ FileUtils.mv(rubygems_local_path, local_path)
489
+ end
490
+ cache_globally(spec, local_path)
491
+ end
492
+ end
493
+
494
+ # Checks if the requested spec exists in the global cache. If it does
495
+ # not, we create the relevant global cache subdirectory if it does not
496
+ # exist and copy the spec from the local cache to the global cache.
497
+ #
498
+ # @param [Specification] spec
499
+ # the spec we want to copy to the global cache.
500
+ #
501
+ # @param [String] local_cache_path
502
+ # the local directory from which we want to copy the .gem.
503
+ #
504
+ def cache_globally(spec, local_cache_path)
505
+ return unless cache_path = download_cache_path(spec)
506
+ return if cache_path.exist?
507
+
508
+ SharedHelpers.filesystem_access(cache_path.dirname, &:mkpath)
509
+ SharedHelpers.filesystem_access(cache_path) do
510
+ FileUtils.cp(local_cache_path, cache_path)
511
+ end
512
+ end
513
+
514
+ # Returns the global cache path of the calling Rubygems::Source object.
515
+ #
516
+ # Note that the Source determines the path's subdirectory. We use this
517
+ # subdirectory in the global cache path so that gems with the same name
518
+ # -- and possibly different versions -- from different sources are saved
519
+ # to their respective subdirectories and do not override one another.
520
+ #
521
+ # @param [Gem::Specification] specification
522
+ #
523
+ # @return [Pathname] The global cache path.
524
+ #
525
+ def download_cache_path(spec)
526
+ return unless Bundler.feature_flag.global_gem_cache?
527
+ return unless remote = spec.remote
528
+ return unless cache_slug = remote.cache_slug
529
+
530
+ Bundler.user_cache.join("gems", cache_slug, spec.file_name)
531
+ end
532
+
533
+ def extension_cache_slug(spec)
534
+ return unless remote = spec.remote
535
+ remote.cache_slug
536
+ end
537
+ end
538
+ end
539
+ end