bundler 1.13.6 → 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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +554 -9
- data/README.md +28 -5
- data/bundler.gemspec +40 -11
- data/exe/bundle +4 -8
- data/exe/bundle_ruby +4 -3
- data/lib/bundler.rb +162 -68
- data/lib/bundler/build_metadata.rb +53 -0
- data/lib/bundler/capistrano.rb +5 -0
- data/lib/bundler/cli.rb +360 -118
- data/lib/bundler/cli/add.rb +35 -0
- data/lib/bundler/cli/binstubs.rb +18 -10
- data/lib/bundler/cli/cache.rb +6 -5
- data/lib/bundler/cli/check.rb +4 -6
- data/lib/bundler/cli/clean.rb +6 -7
- data/lib/bundler/cli/common.rb +47 -1
- data/lib/bundler/cli/config.rb +26 -7
- data/lib/bundler/cli/console.rb +2 -1
- data/lib/bundler/cli/doctor.rb +63 -18
- data/lib/bundler/cli/exec.rb +12 -5
- data/lib/bundler/cli/gem.rb +59 -21
- data/lib/bundler/cli/info.rb +50 -0
- data/lib/bundler/cli/init.rb +21 -7
- data/lib/bundler/cli/inject.rb +13 -4
- data/lib/bundler/cli/install.rb +72 -101
- data/lib/bundler/cli/issue.rb +40 -0
- data/lib/bundler/cli/list.rb +58 -0
- data/lib/bundler/cli/lock.rb +9 -6
- data/lib/bundler/cli/open.rb +4 -3
- data/lib/bundler/cli/outdated.rb +175 -60
- data/lib/bundler/cli/package.rb +9 -6
- data/lib/bundler/cli/platform.rb +2 -1
- data/lib/bundler/cli/plugin.rb +1 -0
- data/lib/bundler/cli/pristine.rb +47 -0
- data/lib/bundler/cli/remove.rb +18 -0
- data/lib/bundler/cli/show.rb +2 -2
- data/lib/bundler/cli/update.rb +44 -34
- data/lib/bundler/cli/viz.rb +5 -1
- data/lib/bundler/compact_index_client.rb +109 -0
- data/lib/bundler/compact_index_client/cache.rb +118 -0
- data/lib/bundler/compact_index_client/updater.rb +116 -0
- data/lib/bundler/compatibility_guard.rb +14 -0
- data/lib/bundler/constants.rb +1 -0
- data/lib/bundler/current_ruby.rb +17 -8
- data/lib/bundler/definition.rb +353 -182
- data/lib/bundler/dep_proxy.rb +3 -1
- data/lib/bundler/dependency.rb +22 -10
- data/lib/bundler/deployment.rb +1 -1
- data/lib/bundler/deprecate.rb +15 -3
- data/lib/bundler/dsl.rb +122 -64
- data/lib/bundler/endpoint_specification.rb +13 -3
- data/lib/bundler/env.rb +110 -38
- data/lib/bundler/environment_preserver.rb +27 -6
- data/lib/bundler/errors.rb +24 -0
- data/lib/bundler/feature_flag.rb +74 -0
- data/lib/bundler/fetcher.rb +18 -11
- data/lib/bundler/fetcher/base.rb +1 -0
- data/lib/bundler/fetcher/compact_index.rb +7 -5
- data/lib/bundler/fetcher/dependency.rb +3 -2
- data/lib/bundler/fetcher/downloader.rb +25 -7
- data/lib/bundler/fetcher/index.rb +3 -2
- data/lib/bundler/friendly_errors.rb +33 -7
- data/lib/bundler/gem_helper.rb +25 -11
- data/lib/bundler/gem_helpers.rb +70 -1
- data/lib/bundler/gem_remote_fetcher.rb +1 -0
- data/lib/bundler/gem_tasks.rb +1 -0
- data/lib/bundler/gem_version_promoter.rb +17 -2
- data/lib/bundler/gemdeps.rb +29 -0
- data/lib/bundler/graph.rb +1 -0
- data/lib/bundler/index.rb +28 -15
- data/lib/bundler/injector.rb +216 -33
- data/lib/bundler/inline.rb +12 -12
- data/lib/bundler/installer.rb +139 -53
- data/lib/bundler/installer/gem_installer.rb +15 -5
- data/lib/bundler/installer/parallel_installer.rb +113 -28
- data/lib/bundler/installer/standalone.rb +1 -0
- data/lib/bundler/lazy_specification.rb +31 -3
- data/lib/bundler/lockfile_generator.rb +95 -0
- data/lib/bundler/lockfile_parser.rb +50 -37
- data/lib/bundler/match_platform.rb +13 -3
- data/lib/bundler/mirror.rb +10 -5
- data/lib/bundler/plugin.rb +22 -8
- data/lib/bundler/plugin/api.rb +2 -1
- data/lib/bundler/plugin/api/source.rb +17 -4
- data/lib/bundler/plugin/events.rb +61 -0
- data/lib/bundler/plugin/index.rb +9 -2
- data/lib/bundler/plugin/installer.rb +7 -6
- data/lib/bundler/plugin/source_list.rb +7 -8
- data/lib/bundler/process_lock.rb +24 -0
- data/lib/bundler/psyched_yaml.rb +10 -0
- data/lib/bundler/remote_specification.rb +30 -1
- data/lib/bundler/resolver.rb +187 -194
- data/lib/bundler/resolver/spec_group.rb +106 -0
- data/lib/bundler/retry.rb +5 -1
- data/lib/bundler/ruby_dsl.rb +1 -0
- data/lib/bundler/ruby_version.rb +12 -2
- data/lib/bundler/rubygems_ext.rb +23 -8
- data/lib/bundler/rubygems_gem_installer.rb +90 -0
- data/lib/bundler/rubygems_integration.rb +193 -70
- data/lib/bundler/runtime.rb +39 -22
- data/lib/bundler/settings.rb +245 -85
- data/lib/bundler/settings/validator.rb +102 -0
- data/lib/bundler/setup.rb +4 -7
- data/lib/bundler/shared_helpers.rb +183 -40
- data/lib/bundler/similarity_detector.rb +1 -0
- data/lib/bundler/source.rb +58 -1
- data/lib/bundler/source/gemspec.rb +1 -0
- data/lib/bundler/source/git.rb +52 -23
- data/lib/bundler/source/git/git_proxy.rb +30 -14
- data/lib/bundler/source/metadata.rb +62 -0
- data/lib/bundler/source/path.rb +42 -16
- data/lib/bundler/source/path/installer.rb +4 -2
- data/lib/bundler/source/rubygems.rb +171 -82
- data/lib/bundler/source/rubygems/remote.rb +12 -2
- data/lib/bundler/source_list.rb +75 -15
- data/lib/bundler/spec_set.rb +67 -32
- data/lib/bundler/ssl_certs/certificate_manager.rb +2 -1
- data/lib/bundler/stub_specification.rb +86 -2
- data/lib/bundler/templates/.document +1 -0
- data/lib/bundler/templates/Executable +13 -1
- data/lib/bundler/templates/Executable.bundler +105 -0
- data/lib/bundler/templates/Executable.standalone +5 -5
- data/lib/bundler/templates/Gemfile +3 -0
- data/lib/bundler/templates/gems.rb +8 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +4 -2
- data/lib/bundler/templates/newgem/LICENSE.txt.tt +1 -1
- data/lib/bundler/templates/newgem/README.md.tt +14 -8
- data/lib/bundler/templates/newgem/Rakefile.tt +5 -5
- data/lib/bundler/templates/newgem/bin/console.tt +1 -1
- data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +4 -4
- data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +3 -3
- data/lib/bundler/templates/newgem/gitignore.tt +5 -1
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +7 -6
- data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +4 -4
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +21 -12
- data/lib/bundler/templates/newgem/rspec.tt +1 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -3
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +13 -1
- data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +1 -1
- data/lib/bundler/templates/newgem/test/test_helper.rb.tt +3 -3
- data/lib/bundler/templates/newgem/{.travis.yml.tt → travis.yml.tt} +2 -0
- data/lib/bundler/ui.rb +1 -0
- data/lib/bundler/ui/rg_proxy.rb +1 -0
- data/lib/bundler/ui/shell.rb +30 -10
- data/lib/bundler/ui/silent.rb +21 -1
- data/lib/bundler/uri_credentials_filter.rb +1 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1638 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +2 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +7 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +26 -6
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +12 -4
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +3 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +11 -3
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +13 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +3 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +3 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +18 -5
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +75 -7
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +3 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +499 -128
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +8 -4
- data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/faster.rb +1 -0
- data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent.rb +27 -24
- data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent/ssl_reuse.rb +2 -1
- data/lib/bundler/vendor/thor/lib/thor.rb +46 -21
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +24 -22
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +2 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +2 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +16 -8
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +66 -18
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +17 -15
- data/lib/bundler/vendor/thor/lib/thor/base.rb +55 -32
- data/lib/bundler/vendor/thor/lib/thor/command.rb +13 -11
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +21 -1
- data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +7 -5
- data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +94 -63
- data/lib/bundler/vendor/thor/lib/thor/error.rb +3 -3
- data/lib/bundler/vendor/thor/lib/thor/group.rb +13 -13
- data/lib/bundler/vendor/thor/lib/thor/invocation.rb +4 -5
- data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +2 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +4 -7
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +16 -16
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +42 -21
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +13 -10
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +31 -29
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +49 -33
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/util.rb +8 -7
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendored_fileutils.rb +9 -0
- data/lib/bundler/vendored_molinillo.rb +1 -0
- data/lib/bundler/vendored_persistent.rb +43 -3
- data/lib/bundler/vendored_thor.rb +6 -2
- data/lib/bundler/version.rb +19 -2
- data/lib/bundler/version_ranges.rb +76 -0
- data/lib/bundler/vlad.rb +5 -0
- data/lib/bundler/worker.rb +30 -6
- data/lib/bundler/yaml_serializer.rb +4 -4
- data/man/bundle-add.1 +58 -0
- data/man/bundle-add.1.txt +52 -0
- data/man/bundle-add.ronn +40 -0
- data/{lib/bundler/man/bundle-binstubs → man/bundle-binstubs.1} +11 -1
- data/man/bundle-binstubs.1.txt +48 -0
- data/man/bundle-binstubs.ronn +15 -1
- data/man/bundle-check.1 +31 -0
- data/man/bundle-check.1.txt +33 -0
- data/man/bundle-check.ronn +26 -0
- data/man/bundle-clean.1 +24 -0
- data/man/bundle-clean.1.txt +26 -0
- data/man/bundle-clean.ronn +18 -0
- data/man/bundle-config.1 +497 -0
- data/man/bundle-config.1.txt +529 -0
- data/man/bundle-config.ronn +233 -61
- data/man/bundle-doctor.1 +44 -0
- data/man/bundle-doctor.1.txt +44 -0
- data/man/bundle-doctor.ronn +33 -0
- data/{lib/bundler/man/bundle-exec → man/bundle-exec.1} +6 -3
- data/man/bundle-exec.1.txt +178 -0
- data/man/bundle-exec.ronn +10 -3
- data/{lib/bundler/man/bundle-gem → man/bundle-gem.1} +4 -4
- data/man/bundle-gem.1.txt +91 -0
- data/man/bundle-gem.ronn +3 -2
- data/man/bundle-info.1 +20 -0
- data/man/bundle-info.1.txt +21 -0
- data/man/bundle-info.ronn +17 -0
- data/man/bundle-init.1 +25 -0
- data/man/bundle-init.1.txt +34 -0
- data/man/bundle-init.ronn +29 -0
- data/man/bundle-inject.1 +33 -0
- data/man/bundle-inject.1.txt +32 -0
- data/man/bundle-inject.ronn +22 -0
- data/{lib/bundler/man/bundle-install → man/bundle-install.1} +32 -29
- data/man/bundle-install.1.txt +396 -0
- data/man/bundle-install.ronn +45 -36
- data/man/bundle-list.1 +50 -0
- data/man/bundle-list.1.txt +43 -0
- data/man/bundle-list.ronn +33 -0
- data/{lib/bundler/man/bundle-lock → man/bundle-lock.1} +43 -2
- data/man/bundle-lock.1.txt +93 -0
- data/man/bundle-lock.ronn +47 -0
- data/man/bundle-open.1 +32 -0
- data/man/bundle-open.1.txt +29 -0
- data/man/bundle-open.ronn +19 -0
- data/man/bundle-outdated.1 +155 -0
- data/man/bundle-outdated.1.txt +131 -0
- data/man/bundle-outdated.ronn +111 -0
- data/{lib/bundler/man/bundle-package → man/bundle-package.1} +6 -3
- data/man/bundle-package.1.txt +79 -0
- data/man/bundle-package.ronn +7 -2
- data/{lib/bundler/man/bundle-platform → man/bundle-platform.1} +1 -1
- data/man/bundle-platform.1.txt +57 -0
- data/man/bundle-pristine.1 +34 -0
- data/man/bundle-pristine.1.txt +44 -0
- data/man/bundle-pristine.ronn +34 -0
- data/man/bundle-remove.1 +31 -0
- data/man/bundle-remove.1.txt +34 -0
- data/man/bundle-remove.ronn +23 -0
- data/man/bundle-show.1 +23 -0
- data/man/bundle-show.1.txt +27 -0
- data/man/bundle-show.ronn +21 -0
- data/man/bundle-update.1 +394 -0
- data/man/bundle-update.1.txt +391 -0
- data/man/bundle-update.ronn +172 -16
- data/man/bundle-viz.1 +39 -0
- data/man/bundle-viz.1.txt +39 -0
- data/man/bundle-viz.ronn +30 -0
- data/{lib/bundler/man/bundle → man/bundle.1} +44 -28
- data/man/bundle.1.txt +116 -0
- data/man/bundle.ronn +39 -27
- data/{lib/bundler/man → man}/gemfile.5 +67 -84
- data/man/gemfile.5.ronn +77 -55
- data/man/gemfile.5.txt +653 -0
- data/man/index.txt +25 -8
- metadata +118 -58
- data/.codeclimate.yml +0 -25
- data/.gitignore +0 -16
- data/.rspec +0 -3
- data/.rubocop.yml +0 -128
- data/.rubocop_todo.yml +0 -248
- data/.travis.yml +0 -108
- data/CODE_OF_CONDUCT.md +0 -42
- data/CONTRIBUTING.md +0 -36
- data/DEVELOPMENT.md +0 -148
- data/ISSUES.md +0 -100
- data/Rakefile +0 -333
- data/bin/rake +0 -19
- data/bin/rspec +0 -15
- data/bin/rubocop +0 -17
- data/bin/with_rubygems +0 -39
- data/lib/bundler/man/bundle-binstubs.txt +0 -33
- data/lib/bundler/man/bundle-config +0 -254
- data/lib/bundler/man/bundle-config.txt +0 -282
- data/lib/bundler/man/bundle-exec.txt +0 -171
- data/lib/bundler/man/bundle-gem.txt +0 -90
- data/lib/bundler/man/bundle-install.txt +0 -385
- data/lib/bundler/man/bundle-lock.txt +0 -52
- data/lib/bundler/man/bundle-package.txt +0 -74
- data/lib/bundler/man/bundle-platform.txt +0 -57
- data/lib/bundler/man/bundle-update +0 -221
- data/lib/bundler/man/bundle-update.txt +0 -227
- data/lib/bundler/man/bundle.txt +0 -104
- data/lib/bundler/man/gemfile.5.txt +0 -636
- data/lib/bundler/postit_trampoline.rb +0 -68
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb +0 -79
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/cache.rb +0 -112
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb +0 -80
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/version.rb +0 -4
- data/lib/bundler/vendor/postit/lib/postit.rb +0 -15
- data/lib/bundler/vendor/postit/lib/postit/environment.rb +0 -44
- data/lib/bundler/vendor/postit/lib/postit/installer.rb +0 -28
- data/lib/bundler/vendor/postit/lib/postit/parser.rb +0 -21
- data/lib/bundler/vendor/postit/lib/postit/setup.rb +0 -12
- data/lib/bundler/vendor/postit/lib/postit/version.rb +0 -3
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/vendored_fileutils"
|
4
|
+
require "stringio"
|
5
|
+
require "zlib"
|
6
|
+
|
7
|
+
module Bundler
|
8
|
+
class CompactIndexClient
|
9
|
+
class Updater
|
10
|
+
class MisMatchedChecksumError < Error
|
11
|
+
def initialize(path, server_checksum, local_checksum)
|
12
|
+
@path = path
|
13
|
+
@server_checksum = server_checksum
|
14
|
+
@local_checksum = local_checksum
|
15
|
+
end
|
16
|
+
|
17
|
+
def message
|
18
|
+
"The checksum of /#{@path} does not match the checksum provided by the server! Something is wrong " \
|
19
|
+
"(local checksum is #{@local_checksum.inspect}, was expecting #{@server_checksum.inspect})."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(fetcher)
|
24
|
+
@fetcher = fetcher
|
25
|
+
require "tmpdir"
|
26
|
+
end
|
27
|
+
|
28
|
+
def update(local_path, remote_path, retrying = nil)
|
29
|
+
headers = {}
|
30
|
+
|
31
|
+
Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir|
|
32
|
+
local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename)
|
33
|
+
|
34
|
+
# first try to fetch any new bytes on the existing file
|
35
|
+
if retrying.nil? && local_path.file?
|
36
|
+
SharedHelpers.filesystem_access(local_temp_path) do
|
37
|
+
FileUtils.cp local_path, local_temp_path
|
38
|
+
end
|
39
|
+
headers["If-None-Match"] = etag_for(local_temp_path)
|
40
|
+
headers["Range"] =
|
41
|
+
if local_temp_path.size.nonzero?
|
42
|
+
# Subtract a byte to ensure the range won't be empty.
|
43
|
+
# Avoids 416 (Range Not Satisfiable) responses.
|
44
|
+
"bytes=#{local_temp_path.size - 1}-"
|
45
|
+
else
|
46
|
+
"bytes=#{local_temp_path.size}-"
|
47
|
+
end
|
48
|
+
else
|
49
|
+
# Fastly ignores Range when Accept-Encoding: gzip is set
|
50
|
+
headers["Accept-Encoding"] = "gzip"
|
51
|
+
end
|
52
|
+
|
53
|
+
response = @fetcher.call(remote_path, headers)
|
54
|
+
return nil if response.is_a?(Net::HTTPNotModified)
|
55
|
+
|
56
|
+
content = response.body
|
57
|
+
if response["Content-Encoding"] == "gzip"
|
58
|
+
content = Zlib::GzipReader.new(StringIO.new(content)).read
|
59
|
+
end
|
60
|
+
|
61
|
+
SharedHelpers.filesystem_access(local_temp_path) do
|
62
|
+
if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero?
|
63
|
+
local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) }
|
64
|
+
else
|
65
|
+
local_temp_path.open("w") {|f| f << content }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
response_etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
|
70
|
+
if etag_for(local_temp_path) == response_etag
|
71
|
+
SharedHelpers.filesystem_access(local_path) do
|
72
|
+
FileUtils.mv(local_temp_path, local_path)
|
73
|
+
end
|
74
|
+
return nil
|
75
|
+
end
|
76
|
+
|
77
|
+
if retrying
|
78
|
+
raise MisMatchedChecksumError.new(remote_path, response_etag, etag_for(local_temp_path))
|
79
|
+
end
|
80
|
+
|
81
|
+
update(local_path, remote_path, :retrying)
|
82
|
+
end
|
83
|
+
rescue Errno::EACCES
|
84
|
+
raise Bundler::PermissionError,
|
85
|
+
"Bundler does not have write access to create a temp directory " \
|
86
|
+
"within #{Dir.tmpdir}. Bundler must have write access to your " \
|
87
|
+
"systems temp directory to function properly. "
|
88
|
+
rescue Zlib::GzipFile::Error
|
89
|
+
raise Bundler::HTTPError
|
90
|
+
end
|
91
|
+
|
92
|
+
def etag_for(path)
|
93
|
+
sum = checksum_for_file(path)
|
94
|
+
sum ? %("#{sum}") : nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def slice_body(body, range)
|
98
|
+
if body.respond_to?(:byteslice)
|
99
|
+
body.byteslice(range)
|
100
|
+
else # pre-1.9.3
|
101
|
+
body.unpack("@#{range.first}a#{range.end + 1}").first
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def checksum_for_file(path)
|
106
|
+
return nil unless path.file?
|
107
|
+
# This must use IO.read instead of Digest.file().hexdigest
|
108
|
+
# because we need to preserve \n line endings on windows when calculating
|
109
|
+
# the checksum
|
110
|
+
SharedHelpers.filesystem_access(path, :read) do
|
111
|
+
SharedHelpers.digest(:MD5).hexdigest(IO.read(path))
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "bundler/version"
|
5
|
+
|
6
|
+
if Bundler::VERSION.split(".").first.to_i >= 2
|
7
|
+
if Gem::Version.new(Object::RUBY_VERSION.dup) < Gem::Version.new("2.3")
|
8
|
+
abort "Bundler 2 requires Ruby 2.3 or later. Either install bundler 1 or update to a supported Ruby version."
|
9
|
+
end
|
10
|
+
|
11
|
+
if Gem::Version.new(Gem::VERSION.dup) < Gem::Version.new("2.5")
|
12
|
+
abort "Bundler 2 requires RubyGems 2.5 or later. Either install bundler 1 or update to a supported RubyGems version."
|
13
|
+
end
|
14
|
+
end
|
data/lib/bundler/constants.rb
CHANGED
data/lib/bundler/current_ruby.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Bundler
|
3
4
|
# Returns current version of Ruby
|
4
5
|
#
|
@@ -8,7 +9,7 @@ module Bundler
|
|
8
9
|
end
|
9
10
|
|
10
11
|
class CurrentRuby
|
11
|
-
KNOWN_MINOR_VERSIONS = %w
|
12
|
+
KNOWN_MINOR_VERSIONS = %w[
|
12
13
|
1.8
|
13
14
|
1.9
|
14
15
|
2.0
|
@@ -16,11 +17,13 @@ module Bundler
|
|
16
17
|
2.2
|
17
18
|
2.3
|
18
19
|
2.4
|
19
|
-
|
20
|
+
2.5
|
21
|
+
2.6
|
22
|
+
].freeze
|
20
23
|
|
21
24
|
KNOWN_MAJOR_VERSIONS = KNOWN_MINOR_VERSIONS.map {|v| v.split(".", 2).first }.uniq.freeze
|
22
25
|
|
23
|
-
KNOWN_PLATFORMS = %w
|
26
|
+
KNOWN_PLATFORMS = %w[
|
24
27
|
jruby
|
25
28
|
maglev
|
26
29
|
mingw
|
@@ -29,11 +32,13 @@ module Bundler
|
|
29
32
|
mswin64
|
30
33
|
rbx
|
31
34
|
ruby
|
35
|
+
truffleruby
|
32
36
|
x64_mingw
|
33
|
-
|
37
|
+
].freeze
|
34
38
|
|
35
39
|
def ruby?
|
36
|
-
!mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" ||
|
40
|
+
!mswin? && (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" ||
|
41
|
+
RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev" || RUBY_ENGINE == "truffleruby")
|
37
42
|
end
|
38
43
|
|
39
44
|
def mri?
|
@@ -52,20 +57,24 @@ module Bundler
|
|
52
57
|
defined?(RUBY_ENGINE) && RUBY_ENGINE == "maglev"
|
53
58
|
end
|
54
59
|
|
60
|
+
def truffleruby?
|
61
|
+
defined?(RUBY_ENGINE) && RUBY_ENGINE == "truffleruby"
|
62
|
+
end
|
63
|
+
|
55
64
|
def mswin?
|
56
65
|
Bundler::WINDOWS
|
57
66
|
end
|
58
67
|
|
59
68
|
def mswin64?
|
60
|
-
Bundler::WINDOWS && Gem::Platform.
|
69
|
+
Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
|
61
70
|
end
|
62
71
|
|
63
72
|
def mingw?
|
64
|
-
Bundler::WINDOWS && Gem::Platform.
|
73
|
+
Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
|
65
74
|
end
|
66
75
|
|
67
76
|
def x64_mingw?
|
68
|
-
Bundler::WINDOWS && Gem::Platform.
|
77
|
+
Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64"
|
69
78
|
end
|
70
79
|
|
71
80
|
(KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
|
data/lib/bundler/definition.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "bundler/lockfile_parser"
|
3
|
-
require "digest/sha1"
|
4
4
|
require "set"
|
5
5
|
|
6
6
|
module Bundler
|
@@ -9,12 +9,13 @@ module Bundler
|
|
9
9
|
|
10
10
|
attr_reader(
|
11
11
|
:dependencies,
|
12
|
-
:gem_version_promoter,
|
13
12
|
:locked_deps,
|
14
13
|
:locked_gems,
|
15
14
|
:platforms,
|
16
15
|
:requires,
|
17
|
-
:ruby_version
|
16
|
+
:ruby_version,
|
17
|
+
:lockfile,
|
18
|
+
:gemfiles
|
18
19
|
)
|
19
20
|
|
20
21
|
# Given a gemfile and lockfile creates a Bundler definition
|
@@ -51,8 +52,16 @@ module Bundler
|
|
51
52
|
# to be updated or true if all gems should be updated
|
52
53
|
# @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version
|
53
54
|
# @param optional_groups [Array(String)] A list of optional groups
|
54
|
-
def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [])
|
55
|
-
|
55
|
+
def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [], gemfiles = [])
|
56
|
+
if [true, false].include?(unlock)
|
57
|
+
@unlocking_bundler = false
|
58
|
+
@unlocking = unlock
|
59
|
+
else
|
60
|
+
unlock = unlock.dup
|
61
|
+
@unlocking_bundler = unlock.delete(:bundler)
|
62
|
+
unlock.delete_if {|_k, v| Array(v).empty? }
|
63
|
+
@unlocking = !unlock.empty?
|
64
|
+
end
|
56
65
|
|
57
66
|
@dependencies = dependencies
|
58
67
|
@sources = sources
|
@@ -61,15 +70,19 @@ module Bundler
|
|
61
70
|
@remote = false
|
62
71
|
@specs = nil
|
63
72
|
@ruby_version = ruby_version
|
73
|
+
@gemfiles = gemfiles
|
64
74
|
|
75
|
+
@lockfile = lockfile
|
65
76
|
@lockfile_contents = String.new
|
66
77
|
@locked_bundler_version = nil
|
67
78
|
@locked_ruby_version = nil
|
79
|
+
@locked_specs_incomplete_for_platform = false
|
68
80
|
|
69
81
|
if lockfile && File.exist?(lockfile)
|
70
82
|
@lockfile_contents = Bundler.read_file(lockfile)
|
71
83
|
@locked_gems = LockfileParser.new(@lockfile_contents)
|
72
|
-
@
|
84
|
+
@locked_platforms = @locked_gems.platforms
|
85
|
+
@platforms = @locked_platforms.dup
|
73
86
|
@locked_bundler_version = @locked_gems.bundler_version
|
74
87
|
@locked_ruby_version = @locked_gems.ruby_version
|
75
88
|
|
@@ -79,7 +92,7 @@ module Bundler
|
|
79
92
|
@locked_sources = @locked_gems.sources
|
80
93
|
else
|
81
94
|
@unlock = {}
|
82
|
-
@locked_deps =
|
95
|
+
@locked_deps = {}
|
83
96
|
@locked_specs = SpecSet.new([])
|
84
97
|
@locked_sources = []
|
85
98
|
end
|
@@ -87,68 +100,51 @@ module Bundler
|
|
87
100
|
@unlock = {}
|
88
101
|
@platforms = []
|
89
102
|
@locked_gems = nil
|
90
|
-
@locked_deps =
|
103
|
+
@locked_deps = {}
|
91
104
|
@locked_specs = SpecSet.new([])
|
92
105
|
@locked_sources = []
|
106
|
+
@locked_platforms = []
|
93
107
|
end
|
94
108
|
|
95
109
|
@unlock[:gems] ||= []
|
96
110
|
@unlock[:sources] ||= []
|
97
|
-
@unlock[:ruby] ||= if @ruby_version &&
|
98
|
-
unless locked_ruby_version_object = RubyVersion.from_string(@locked_ruby_version)
|
99
|
-
raise LockfileError, "Failed to create a `RubyVersion` object from " \
|
100
|
-
"`#{@locked_ruby_version}` found in #{lockfile} -- try running `bundle update --ruby`."
|
101
|
-
end
|
111
|
+
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
|
102
112
|
@ruby_version.diff(locked_ruby_version_object)
|
103
113
|
end
|
104
114
|
@unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
|
105
115
|
|
106
|
-
|
107
|
-
add_platform(current_platform)
|
116
|
+
add_current_platform unless Bundler.frozen_bundle?
|
108
117
|
|
118
|
+
converge_path_sources_to_gemspec_sources
|
109
119
|
@path_changes = converge_paths
|
110
|
-
|
111
|
-
@unlock[:gems] = @locked_specs.for(eager_unlock).map(&:name)
|
120
|
+
@source_changes = converge_sources
|
112
121
|
|
113
|
-
@
|
122
|
+
unless @unlock[:lock_shared_dependencies]
|
123
|
+
eager_unlock = expand_dependencies(@unlock[:gems], true)
|
124
|
+
@unlock[:gems] = @locked_specs.for(eager_unlock, [], false, false, false).map(&:name)
|
125
|
+
end
|
114
126
|
|
115
|
-
@source_changes = converge_sources
|
116
127
|
@dependency_changes = converge_dependencies
|
117
128
|
@local_changes = converge_locals
|
118
129
|
|
119
130
|
@requires = compute_requires
|
120
|
-
|
121
|
-
fixup_dependency_types!
|
122
131
|
end
|
123
132
|
|
124
|
-
def
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
133
|
+
def gem_version_promoter
|
134
|
+
@gem_version_promoter ||= begin
|
135
|
+
locked_specs =
|
136
|
+
if unlocking? && @locked_specs.empty? && !@lockfile_contents.empty?
|
137
|
+
# Definition uses an empty set of locked_specs to indicate all gems
|
138
|
+
# are unlocked, but GemVersionPromoter needs the locked_specs
|
139
|
+
# for conservative comparison.
|
140
|
+
Bundler::SpecSet.new(@locked_gems.specs)
|
141
|
+
else
|
142
|
+
@locked_specs
|
143
|
+
end
|
144
|
+
GemVersionPromoter.new(locked_specs, @unlock[:gems])
|
136
145
|
end
|
137
146
|
end
|
138
147
|
|
139
|
-
def create_gem_version_promoter
|
140
|
-
locked_specs =
|
141
|
-
if @unlocking && @locked_specs.empty? && !@lockfile_contents.empty?
|
142
|
-
# Definition uses an empty set of locked_specs to indicate all gems
|
143
|
-
# are unlocked, but GemVersionPromoter needs the locked_specs
|
144
|
-
# for conservative comparison.
|
145
|
-
Bundler::SpecSet.new(@locked_gems.specs)
|
146
|
-
else
|
147
|
-
@locked_specs
|
148
|
-
end
|
149
|
-
GemVersionPromoter.new(locked_specs, @unlock[:gems])
|
150
|
-
end
|
151
|
-
|
152
148
|
def resolve_with_cache!
|
153
149
|
raise "Specs already loaded" if @specs
|
154
150
|
sources.cached!
|
@@ -175,16 +171,15 @@ module Bundler
|
|
175
171
|
rescue GemNotFound => e # Handle yanked gem
|
176
172
|
gem_name, gem_version = extract_gem_info(e)
|
177
173
|
locked_gem = @locked_specs[gem_name].last
|
178
|
-
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version
|
174
|
+
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
|
179
175
|
raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
|
180
176
|
"be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
|
181
177
|
"that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
|
182
|
-
"to a
|
178
|
+
"to a version other than #{locked_gem} that hasn't been removed in order to install."
|
183
179
|
end
|
184
180
|
unless specs["bundler"].any?
|
185
|
-
|
186
|
-
bundler =
|
187
|
-
specs["bundler"] = bundler if bundler
|
181
|
+
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
|
182
|
+
specs["bundler"] = bundler
|
188
183
|
end
|
189
184
|
|
190
185
|
specs
|
@@ -209,10 +204,19 @@ module Bundler
|
|
209
204
|
missing
|
210
205
|
end
|
211
206
|
|
212
|
-
def
|
213
|
-
missing =
|
214
|
-
|
215
|
-
missing
|
207
|
+
def missing_specs?
|
208
|
+
missing = missing_specs
|
209
|
+
return false if missing.empty?
|
210
|
+
Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
|
211
|
+
true
|
212
|
+
rescue BundlerError => e
|
213
|
+
@index = nil
|
214
|
+
@resolve = nil
|
215
|
+
@specs = nil
|
216
|
+
@gem_version_promoter = nil
|
217
|
+
|
218
|
+
Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
|
219
|
+
true
|
216
220
|
end
|
217
221
|
|
218
222
|
def requested_specs
|
@@ -241,14 +245,22 @@ module Bundler
|
|
241
245
|
def resolve
|
242
246
|
@resolve ||= begin
|
243
247
|
last_resolve = converge_locked_specs
|
244
|
-
|
245
|
-
Bundler.
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
248
|
+
resolve =
|
249
|
+
if Bundler.frozen_bundle?
|
250
|
+
Bundler.ui.debug "Frozen, using resolution from the lockfile"
|
251
|
+
last_resolve
|
252
|
+
elsif !unlocking? && nothing_changed?
|
253
|
+
Bundler.ui.debug("Found no changes, using resolution from the lockfile")
|
254
|
+
last_resolve
|
255
|
+
else
|
256
|
+
# Run a resolve against the locally available gems
|
257
|
+
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
|
258
|
+
last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
|
259
|
+
end
|
260
|
+
|
261
|
+
# filter out gems that _can_ be installed on multiple platforms, but don't need
|
262
|
+
# to be
|
263
|
+
resolve.for(expand_dependencies(dependencies, true), [], false, false, false)
|
252
264
|
end
|
253
265
|
end
|
254
266
|
|
@@ -257,23 +269,44 @@ module Bundler
|
|
257
269
|
dependency_names = @dependencies.map(&:name)
|
258
270
|
|
259
271
|
sources.all_sources.each do |source|
|
260
|
-
source.dependency_names = dependency_names
|
272
|
+
source.dependency_names = dependency_names - pinned_spec_names(source)
|
261
273
|
idx.add_source source.specs
|
262
|
-
dependency_names -= pinned_spec_names(source.specs)
|
263
274
|
dependency_names.concat(source.unmet_deps).uniq!
|
264
275
|
end
|
265
|
-
end
|
266
|
-
end
|
267
276
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
277
|
+
double_check_for_index(idx, dependency_names)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
|
282
|
+
# sources A and B. At this point, the API request will have found all the versions of Bar in source A,
|
283
|
+
# but will not have found any versions of Bar from source B, which is a problem if the requested version
|
284
|
+
# of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
|
285
|
+
# each spec we found, we add all possible versions from all sources to the index.
|
286
|
+
def double_check_for_index(idx, dependency_names)
|
287
|
+
pinned_names = pinned_spec_names
|
288
|
+
loop do
|
289
|
+
idxcount = idx.size
|
290
|
+
|
291
|
+
names = :names # do this so we only have to traverse to get dependency_names from the index once
|
292
|
+
unmet_dependency_names = lambda do
|
293
|
+
return names unless names == :names
|
294
|
+
new_names = sources.all_sources.map(&:dependency_names_to_double_check)
|
295
|
+
return names = nil if new_names.compact!
|
296
|
+
names = new_names.flatten(1).concat(dependency_names)
|
297
|
+
names.uniq!
|
298
|
+
names -= pinned_names
|
299
|
+
names
|
274
300
|
end
|
301
|
+
|
302
|
+
sources.all_sources.each do |source|
|
303
|
+
source.double_check_for(unmet_dependency_names)
|
304
|
+
end
|
305
|
+
|
306
|
+
break if idxcount == idx.size
|
275
307
|
end
|
276
308
|
end
|
309
|
+
private :double_check_for_index
|
277
310
|
|
278
311
|
def has_rubygems_remotes?
|
279
312
|
sources.rubygems_sources.any? {|s| s.remotes.any? }
|
@@ -308,10 +341,11 @@ module Bundler
|
|
308
341
|
end
|
309
342
|
end
|
310
343
|
|
311
|
-
preserve_unknown_sections ||= !updating_major && (Bundler.
|
312
|
-
return if lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
|
344
|
+
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
313
345
|
|
314
|
-
if
|
346
|
+
return if file && File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
|
347
|
+
|
348
|
+
if Bundler.frozen_bundle?
|
315
349
|
Bundler.ui.error "Cannot write a changed lockfile while frozen."
|
316
350
|
return
|
317
351
|
end
|
@@ -338,52 +372,21 @@ module Bundler
|
|
338
372
|
end
|
339
373
|
end
|
340
374
|
|
341
|
-
def
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
# This needs to be sorted by full name so that
|
351
|
-
# gems with the same name, but different platform
|
352
|
-
# are ordered consistently
|
353
|
-
sort_by(&:full_name).
|
354
|
-
each do |spec|
|
355
|
-
next if spec.name == "bundler"
|
356
|
-
out << spec.to_lock
|
357
|
-
end
|
358
|
-
out << "\n"
|
359
|
-
end
|
360
|
-
|
361
|
-
out << "PLATFORMS\n"
|
362
|
-
|
363
|
-
platforms.map(&:to_s).sort.each do |p|
|
364
|
-
out << " #{p}\n"
|
365
|
-
end
|
366
|
-
|
367
|
-
out << "\n"
|
368
|
-
out << "DEPENDENCIES\n"
|
369
|
-
|
370
|
-
handled = []
|
371
|
-
dependencies.sort_by(&:to_s).each do |dep|
|
372
|
-
next if handled.include?(dep.name)
|
373
|
-
out << dep.to_lock
|
374
|
-
handled << dep.name
|
375
|
-
end
|
376
|
-
|
377
|
-
if locked_ruby_version
|
378
|
-
out << "\nRUBY VERSION\n"
|
379
|
-
out << " #{locked_ruby_version}\n"
|
375
|
+
def locked_ruby_version_object
|
376
|
+
return unless @locked_ruby_version
|
377
|
+
@locked_ruby_version_object ||= begin
|
378
|
+
unless version = RubyVersion.from_string(@locked_ruby_version)
|
379
|
+
raise LockfileError, "The Ruby version #{@locked_ruby_version} from " \
|
380
|
+
"#{@lockfile} could not be parsed. " \
|
381
|
+
"Try running bundle update --ruby to resolve this."
|
382
|
+
end
|
383
|
+
version
|
380
384
|
end
|
385
|
+
end
|
381
386
|
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
out
|
387
|
+
def to_lock
|
388
|
+
require "bundler/lockfile_generator"
|
389
|
+
LockfileGenerator.generate(self)
|
387
390
|
end
|
388
391
|
|
389
392
|
def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
|
@@ -393,26 +396,38 @@ module Bundler
|
|
393
396
|
"updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control."
|
394
397
|
|
395
398
|
unless explicit_flag
|
399
|
+
suggested_command = if Bundler.settings.locations("frozen")[:global]
|
400
|
+
"bundle config --delete frozen"
|
401
|
+
elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
|
402
|
+
"bundle config --delete deployment"
|
403
|
+
else
|
404
|
+
"bundle install --no-deployment"
|
405
|
+
end
|
396
406
|
msg << "\n\nIf this is a development machine, remove the #{Bundler.default_gemfile} " \
|
397
|
-
"freeze \nby running
|
407
|
+
"freeze \nby running `#{suggested_command}`."
|
398
408
|
end
|
399
409
|
|
400
410
|
added = []
|
401
411
|
deleted = []
|
402
412
|
changed = []
|
403
413
|
|
414
|
+
new_platforms = @platforms - @locked_platforms
|
415
|
+
deleted_platforms = @locked_platforms - @platforms
|
416
|
+
added.concat new_platforms.map {|p| "* platform: #{p}" }
|
417
|
+
deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
|
418
|
+
|
404
419
|
gemfile_sources = sources.lock_sources
|
405
420
|
|
406
421
|
new_sources = gemfile_sources - @locked_sources
|
407
422
|
deleted_sources = @locked_sources - gemfile_sources
|
408
423
|
|
409
|
-
new_deps = @dependencies - @locked_deps
|
410
|
-
deleted_deps = @locked_deps - @dependencies
|
424
|
+
new_deps = @dependencies - @locked_deps.values
|
425
|
+
deleted_deps = @locked_deps.values - @dependencies
|
411
426
|
|
412
427
|
# Check if it is possible that the source is only changed thing
|
413
428
|
if (new_deps.empty? && deleted_deps.empty?) && (!new_sources.empty? && !deleted_sources.empty?)
|
414
|
-
new_sources.reject! {|source| source.
|
415
|
-
deleted_sources.reject! {|source| source.
|
429
|
+
new_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
430
|
+
deleted_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
416
431
|
end
|
417
432
|
|
418
433
|
if @locked_sources != gemfile_sources
|
@@ -432,7 +447,7 @@ module Bundler
|
|
432
447
|
|
433
448
|
both_sources = Hash.new {|h, k| h[k] = [] }
|
434
449
|
@dependencies.each {|d| both_sources[d.name][0] = d }
|
435
|
-
@locked_deps.each {|d| both_sources[
|
450
|
+
@locked_deps.each {|name, d| both_sources[name][1] = d.source }
|
436
451
|
|
437
452
|
both_sources.each do |name, (dep, lock_source)|
|
438
453
|
next unless (dep.nil? && !lock_source.nil?) || (!dep.nil? && !lock_source.nil? && !lock_source.can_lock?(dep))
|
@@ -441,12 +456,19 @@ module Bundler
|
|
441
456
|
changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
|
442
457
|
end
|
443
458
|
|
459
|
+
reason = change_reason
|
460
|
+
msg << "\n\n#{reason.split(", ").map(&:capitalize).join("\n")}" unless reason.strip.empty?
|
444
461
|
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
|
445
462
|
msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
|
446
463
|
msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
|
447
464
|
msg << "\n"
|
448
465
|
|
449
|
-
raise ProductionError, msg if added.any? || deleted.any? || changed.any?
|
466
|
+
raise ProductionError, msg if added.any? || deleted.any? || changed.any? || !nothing_changed?
|
467
|
+
end
|
468
|
+
|
469
|
+
def validate_runtime!
|
470
|
+
validate_ruby!
|
471
|
+
validate_platforms!
|
450
472
|
end
|
451
473
|
|
452
474
|
def validate_ruby!
|
@@ -474,6 +496,18 @@ module Bundler
|
|
474
496
|
end
|
475
497
|
end
|
476
498
|
|
499
|
+
def validate_platforms!
|
500
|
+
return if @platforms.any? do |bundle_platform|
|
501
|
+
Bundler.rubygems.platforms.any? do |local_platform|
|
502
|
+
MatchPlatform.platforms_match?(bundle_platform, local_platform)
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
|
507
|
+
"but your local platforms are #{Bundler.rubygems.platforms.map(&:to_s)}, and " \
|
508
|
+
"there's no compatible match between those two lists."
|
509
|
+
end
|
510
|
+
|
477
511
|
def add_platform(platform)
|
478
512
|
@new_platform ||= !@platforms.include?(platform)
|
479
513
|
@platforms |= [platform]
|
@@ -484,17 +518,35 @@ module Bundler
|
|
484
518
|
raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
|
485
519
|
end
|
486
520
|
|
521
|
+
def add_current_platform
|
522
|
+
current_platform = Bundler.local_platform
|
523
|
+
add_platform(current_platform) if Bundler.feature_flag.specific_platform?
|
524
|
+
add_platform(generic(current_platform))
|
525
|
+
end
|
526
|
+
|
527
|
+
def find_resolved_spec(current_spec)
|
528
|
+
specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
|
529
|
+
end
|
530
|
+
|
531
|
+
def find_indexed_specs(current_spec)
|
532
|
+
index[current_spec.name].select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
|
533
|
+
end
|
534
|
+
|
487
535
|
attr_reader :sources
|
488
536
|
private :sources
|
489
537
|
|
490
|
-
private
|
491
|
-
|
492
538
|
def nothing_changed?
|
493
|
-
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes
|
539
|
+
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
|
540
|
+
end
|
541
|
+
|
542
|
+
def unlocking?
|
543
|
+
@unlocking
|
494
544
|
end
|
495
545
|
|
546
|
+
private
|
547
|
+
|
496
548
|
def change_reason
|
497
|
-
if
|
549
|
+
if unlocking?
|
498
550
|
unlock_reason = @unlock.reject {|_k, v| Array(v).empty? }.map do |k, v|
|
499
551
|
if v == true
|
500
552
|
k.to_s
|
@@ -511,14 +563,12 @@ module Bundler
|
|
511
563
|
[@new_platform, "you added a new platform to your gemfile"],
|
512
564
|
[@path_changes, "the gemspecs for path gems changed"],
|
513
565
|
[@local_changes, "the gemspecs for git local gems changed"],
|
566
|
+
[@locked_specs_incomplete_for_platform, "the lockfile does not have all gems needed for the current platform"],
|
514
567
|
].select(&:first).map(&:last).join(", ")
|
515
568
|
end
|
516
569
|
|
517
570
|
def pretty_dep(dep, source = false)
|
518
|
-
|
519
|
-
msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
|
520
|
-
msg << " from the `#{dep.source}` source" if source && dep.source
|
521
|
-
msg
|
571
|
+
SharedHelpers.pretty_dependency(dep, source)
|
522
572
|
end
|
523
573
|
|
524
574
|
# Check if the specs of the given source changed
|
@@ -531,7 +581,7 @@ module Bundler
|
|
531
581
|
|
532
582
|
def dependencies_for_source_changed?(source, locked_source = source)
|
533
583
|
deps_for_source = @dependencies.select {|s| s.source == source }
|
534
|
-
locked_deps_for_source = @locked_deps.select {|
|
584
|
+
locked_deps_for_source = @locked_deps.values.select {|dep| dep.source == locked_source }
|
535
585
|
|
536
586
|
Set.new(deps_for_source) != Set.new(locked_deps_for_source)
|
537
587
|
end
|
@@ -540,7 +590,11 @@ module Bundler
|
|
540
590
|
locked_index = Index.new
|
541
591
|
locked_index.use(@locked_specs.select {|s| source.can_lock?(s) })
|
542
592
|
|
543
|
-
source.specs
|
593
|
+
# order here matters, since Index#== is checking source.specs.include?(locked_index)
|
594
|
+
locked_index != source.specs
|
595
|
+
rescue PathError, GitError => e
|
596
|
+
Bundler.ui.debug "Assuming that #{source} has not changed since fetching its specs errored (#{e})"
|
597
|
+
false
|
544
598
|
end
|
545
599
|
|
546
600
|
# Get all locals and override their matching sources.
|
@@ -576,29 +630,44 @@ module Bundler
|
|
576
630
|
gemspec_source || source
|
577
631
|
end
|
578
632
|
|
579
|
-
def
|
580
|
-
changes = false
|
581
|
-
|
633
|
+
def converge_path_sources_to_gemspec_sources
|
582
634
|
@locked_sources.map! do |source|
|
583
635
|
converge_path_source_to_gemspec_source(source)
|
584
636
|
end
|
585
637
|
@locked_specs.each do |spec|
|
586
638
|
spec.source &&= converge_path_source_to_gemspec_source(spec.source)
|
587
639
|
end
|
640
|
+
@locked_deps.each do |_, dep|
|
641
|
+
dep.source &&= converge_path_source_to_gemspec_source(dep.source)
|
642
|
+
end
|
643
|
+
end
|
588
644
|
|
589
|
-
|
645
|
+
def converge_rubygems_sources
|
646
|
+
return false if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
647
|
+
|
648
|
+
changes = false
|
649
|
+
|
650
|
+
# Get the RubyGems sources from the Gemfile.lock
|
590
651
|
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
591
|
-
# Get the
|
652
|
+
# Get the RubyGems remotes from the Gemfile
|
592
653
|
actual_remotes = sources.rubygems_remotes
|
593
654
|
|
594
|
-
# If there is a
|
655
|
+
# If there is a RubyGems source in both
|
595
656
|
if !locked_gem_sources.empty? && !actual_remotes.empty?
|
596
657
|
locked_gem_sources.each do |locked_gem|
|
597
658
|
# Merge the remotes from the Gemfile into the Gemfile.lock
|
598
|
-
changes |= locked_gem.replace_remotes(actual_remotes)
|
659
|
+
changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
|
599
660
|
end
|
600
661
|
end
|
601
662
|
|
663
|
+
changes
|
664
|
+
end
|
665
|
+
|
666
|
+
def converge_sources
|
667
|
+
changes = false
|
668
|
+
|
669
|
+
changes |= converge_rubygems_sources
|
670
|
+
|
602
671
|
# Replace the sources from the Gemfile with the sources from the Gemfile.lock,
|
603
672
|
# if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
|
604
673
|
# source in the Gemfile.lock, use the one from the Gemfile.
|
@@ -620,11 +689,12 @@ module Bundler
|
|
620
689
|
end
|
621
690
|
|
622
691
|
def converge_dependencies
|
623
|
-
|
624
|
-
|
692
|
+
frozen = Bundler.frozen_bundle?
|
693
|
+
(@dependencies + @locked_deps.values).each do |dep|
|
694
|
+
locked_source = @locked_deps[dep.name]
|
625
695
|
# This is to make sure that if bundler is installing in deployment mode and
|
626
696
|
# after locked_source and sources don't match, we still use locked_source.
|
627
|
-
if
|
697
|
+
if frozen && !locked_source.nil? &&
|
628
698
|
locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
|
629
699
|
dep.source = locked_source.source
|
630
700
|
elsif dep.source
|
@@ -634,7 +704,31 @@ module Bundler
|
|
634
704
|
dep.platforms.concat(@platforms.map {|p| Dependency::REVERSE_PLATFORM_MAP[p] }.flatten(1)).uniq!
|
635
705
|
end
|
636
706
|
end
|
637
|
-
|
707
|
+
|
708
|
+
changes = false
|
709
|
+
# We want to know if all match, but don't want to check all entries
|
710
|
+
# This means we need to return false if any dependency doesn't match
|
711
|
+
# the lock or doesn't exist in the lock.
|
712
|
+
@dependencies.each do |dependency|
|
713
|
+
unless locked_dep = @locked_deps[dependency.name]
|
714
|
+
changes = true
|
715
|
+
next
|
716
|
+
end
|
717
|
+
|
718
|
+
# Gem::Dependency#== matches Gem::Dependency#type. As the lockfile
|
719
|
+
# doesn't carry a notion of the dependency type, if you use
|
720
|
+
# add_development_dependency in a gemspec that's loaded with the gemspec
|
721
|
+
# directive, the lockfile dependencies and resolved dependencies end up
|
722
|
+
# with a mismatch on #type. Work around that by setting the type on the
|
723
|
+
# dep from the lockfile.
|
724
|
+
locked_dep.instance_variable_set(:@type, dependency.type)
|
725
|
+
|
726
|
+
# We already know the name matches from the hash lookup
|
727
|
+
# so we only need to check the requirement now
|
728
|
+
changes ||= dependency.requirement != locked_dep.requirement
|
729
|
+
end
|
730
|
+
|
731
|
+
changes
|
638
732
|
end
|
639
733
|
|
640
734
|
# Remove elements from the locked specs that are expired. This will most
|
@@ -647,12 +741,11 @@ module Bundler
|
|
647
741
|
# and Gemfile.lock. If the Gemfile modified a dependency, but
|
648
742
|
# the gem in the Gemfile.lock still satisfies it, this is fine
|
649
743
|
# too.
|
650
|
-
locked_deps_hash = @locked_deps.inject({}) do |hsh, dep|
|
651
|
-
hsh[dep] = dep
|
652
|
-
hsh
|
653
|
-
end
|
654
744
|
@dependencies.each do |dep|
|
655
|
-
locked_dep =
|
745
|
+
locked_dep = @locked_deps[dep.name]
|
746
|
+
|
747
|
+
# If the locked_dep doesn't match the dependency we're looking for then we ignore the locked_dep
|
748
|
+
locked_dep = nil unless locked_dep == dep
|
656
749
|
|
657
750
|
if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
|
658
751
|
deps << dep
|
@@ -666,6 +759,8 @@ module Bundler
|
|
666
759
|
end
|
667
760
|
end
|
668
761
|
|
762
|
+
unlock_source_unlocks_spec = Bundler.feature_flag.unlock_source_unlocks_spec?
|
763
|
+
|
669
764
|
converged = []
|
670
765
|
@locked_specs.each do |s|
|
671
766
|
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
@@ -673,42 +768,60 @@ module Bundler
|
|
673
768
|
s.source = (dep && dep.source) || sources.get(s.source)
|
674
769
|
|
675
770
|
# Don't add a spec to the list if its source is expired. For example,
|
676
|
-
# if you change a Git gem to
|
677
|
-
next if s.source.nil?
|
771
|
+
# if you change a Git gem to RubyGems.
|
772
|
+
next if s.source.nil?
|
773
|
+
next if @unlock[:sources].include?(s.source.name)
|
678
774
|
|
679
775
|
# XXX This is a backwards-compatibility fix to preserve the ability to
|
680
776
|
# unlock a single gem by passing its name via `--source`. See issue #3759
|
681
|
-
|
777
|
+
# TODO: delete in Bundler 2
|
778
|
+
next if unlock_source_unlocks_spec && @unlock[:sources].include?(s.name)
|
682
779
|
|
683
780
|
# If the spec is from a path source and it doesn't exist anymore
|
684
781
|
# then we unlock it.
|
685
782
|
|
686
783
|
# Path sources have special logic
|
687
784
|
if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec)
|
688
|
-
|
785
|
+
other_sources_specs = begin
|
786
|
+
s.source.specs
|
787
|
+
rescue PathError, GitError
|
788
|
+
# if we won't need the source (according to the lockfile),
|
789
|
+
# don't error if the path/git source isn't available
|
790
|
+
next if @locked_specs.
|
791
|
+
for(requested_dependencies, [], false, true, false).
|
792
|
+
none? {|locked_spec| locked_spec.source == s.source }
|
793
|
+
|
794
|
+
raise
|
795
|
+
end
|
796
|
+
|
797
|
+
other = other_sources_specs[s].first
|
689
798
|
|
690
799
|
# If the spec is no longer in the path source, unlock it. This
|
691
800
|
# commonly happens if the version changed in the gemspec
|
692
801
|
next unless other
|
693
802
|
|
694
803
|
deps2 = other.dependencies.select {|d| d.type != :development }
|
804
|
+
runtime_dependencies = s.dependencies.select {|d| d.type != :development }
|
695
805
|
# If the dependencies of the path source have changed, unlock it
|
696
|
-
next unless
|
806
|
+
next unless runtime_dependencies.sort == deps2.sort
|
697
807
|
end
|
698
808
|
|
699
809
|
converged << s
|
700
810
|
end
|
701
811
|
|
702
812
|
resolve = SpecSet.new(converged)
|
703
|
-
|
704
|
-
|
813
|
+
expanded_deps = expand_dependencies(deps, true)
|
814
|
+
@locked_specs_incomplete_for_platform = !resolve.for(expanded_deps, @unlock[:gems], true, true)
|
815
|
+
resolve = resolve.for(expanded_deps, @unlock[:gems], false, false, false)
|
816
|
+
diff = nil
|
705
817
|
|
706
818
|
# Now, we unlock any sources that do not have anymore gems pinned to it
|
707
819
|
sources.all_sources.each do |source|
|
708
820
|
next unless source.respond_to?(:unlock!)
|
709
821
|
|
710
822
|
unless resolve.any? {|s| s.source == source }
|
711
|
-
|
823
|
+
diff ||= @locked_specs.to_a - resolve.to_a
|
824
|
+
source.unlock! if diff.any? {|s| s.source == source }
|
712
825
|
end
|
713
826
|
end
|
714
827
|
|
@@ -723,19 +836,64 @@ module Bundler
|
|
723
836
|
end
|
724
837
|
|
725
838
|
def satisfies_locked_spec?(dep)
|
726
|
-
@locked_specs.any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
|
839
|
+
@locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
|
727
840
|
end
|
728
841
|
|
842
|
+
# This list of dependencies is only used in #resolve, so it's OK to add
|
843
|
+
# the metadata dependencies here
|
729
844
|
def expanded_dependencies
|
730
|
-
@expanded_dependencies ||=
|
845
|
+
@expanded_dependencies ||= begin
|
846
|
+
expand_dependencies(dependencies + metadata_dependencies, @remote)
|
847
|
+
end
|
848
|
+
end
|
849
|
+
|
850
|
+
def metadata_dependencies
|
851
|
+
@metadata_dependencies ||= begin
|
852
|
+
ruby_versions = concat_ruby_version_requirements(@ruby_version)
|
853
|
+
if ruby_versions.empty? || !@ruby_version.exact?
|
854
|
+
concat_ruby_version_requirements(RubyVersion.system)
|
855
|
+
concat_ruby_version_requirements(locked_ruby_version_object) unless @unlock[:ruby]
|
856
|
+
end
|
857
|
+
[
|
858
|
+
Dependency.new("ruby\0", ruby_versions),
|
859
|
+
Dependency.new("rubygems\0", Gem::VERSION),
|
860
|
+
]
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
def concat_ruby_version_requirements(ruby_version, ruby_versions = [])
|
865
|
+
return ruby_versions unless ruby_version
|
866
|
+
if ruby_version.patchlevel
|
867
|
+
ruby_versions << ruby_version.to_gem_version_with_patchlevel
|
868
|
+
else
|
869
|
+
ruby_versions.concat(ruby_version.versions.map do |version|
|
870
|
+
requirement = Gem::Requirement.new(version)
|
871
|
+
if requirement.exact?
|
872
|
+
"~> #{version}.0"
|
873
|
+
else
|
874
|
+
requirement
|
875
|
+
end
|
876
|
+
end)
|
877
|
+
end
|
731
878
|
end
|
732
879
|
|
733
880
|
def expand_dependencies(dependencies, remote = false)
|
881
|
+
sorted_platforms = Resolver.sort_platforms(@platforms)
|
734
882
|
deps = []
|
735
883
|
dependencies.each do |dep|
|
736
884
|
dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
|
737
|
-
next
|
738
|
-
dep.gem_platforms(
|
885
|
+
next if !remote && !dep.current_platform?
|
886
|
+
platforms = dep.gem_platforms(sorted_platforms)
|
887
|
+
if platforms.empty? && !Bundler.settings[:disable_platform_warnings]
|
888
|
+
mapped_platforms = dep.platforms.map {|p| Dependency::PLATFORM_MAP[p] }
|
889
|
+
Bundler.ui.warn \
|
890
|
+
"The dependency #{dep} will be unused by any of the platforms Bundler is installing for. " \
|
891
|
+
"Bundler is installing for #{@platforms.join ", "} but the dependency " \
|
892
|
+
"is only for #{mapped_platforms.join ", "}. " \
|
893
|
+
"To add those platforms to the bundle, " \
|
894
|
+
"run `bundle lock --add-platform #{mapped_platforms.join " "}`."
|
895
|
+
end
|
896
|
+
platforms.each do |p|
|
739
897
|
deps << DepProxy.new(dep, p) if remote || p == generic_local_platform
|
740
898
|
end
|
741
899
|
end
|
@@ -755,30 +913,33 @@ module Bundler
|
|
755
913
|
# Record the specs available in each gem's source, so that those
|
756
914
|
# specs will be available later when the resolver knows where to
|
757
915
|
# look for that gemspec (or its dependencies)
|
758
|
-
|
916
|
+
default = sources.default_source
|
917
|
+
source_requirements = { :default => default }
|
918
|
+
default = nil unless Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
759
919
|
dependencies.each do |dep|
|
760
|
-
next unless dep.source
|
761
|
-
source_requirements[dep.name] =
|
920
|
+
next unless source = dep.source || default
|
921
|
+
source_requirements[dep.name] = source
|
922
|
+
end
|
923
|
+
metadata_dependencies.each do |dep|
|
924
|
+
source_requirements[dep.name] = sources.metadata_source
|
762
925
|
end
|
926
|
+
source_requirements["bundler"] = sources.metadata_source # needs to come last to override
|
763
927
|
source_requirements
|
764
928
|
end
|
765
929
|
|
766
|
-
def pinned_spec_names(
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
names << s.name
|
774
|
-
end
|
930
|
+
def pinned_spec_names(skip = nil)
|
931
|
+
pinned_names = []
|
932
|
+
default = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? && sources.default_source
|
933
|
+
@dependencies.each do |dep|
|
934
|
+
next unless dep_source = dep.source || default
|
935
|
+
next if dep_source == skip
|
936
|
+
pinned_names << dep.name
|
775
937
|
end
|
776
|
-
|
777
|
-
names
|
938
|
+
pinned_names
|
778
939
|
end
|
779
940
|
|
780
941
|
def requested_groups
|
781
|
-
groups - Bundler.settings
|
942
|
+
groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
|
782
943
|
end
|
783
944
|
|
784
945
|
def lockfiles_equal?(current, proposed, preserve_unknown_sections)
|
@@ -812,11 +973,21 @@ module Bundler
|
|
812
973
|
end
|
813
974
|
|
814
975
|
def additional_base_requirements_for_resolve
|
815
|
-
return [] unless @locked_gems && Bundler.
|
976
|
+
return [] unless @locked_gems && Bundler.feature_flag.only_update_to_newer_versions?
|
977
|
+
dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
|
816
978
|
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
|
817
|
-
|
979
|
+
name = locked_spec.name
|
980
|
+
next requirements if @locked_gems.dependencies[name] != dependencies_by_name[name]
|
981
|
+
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
|
982
|
+
requirements[name] = DepProxy.new(dep, locked_spec.platform)
|
818
983
|
requirements
|
819
984
|
end.values
|
820
985
|
end
|
986
|
+
|
987
|
+
def equivalent_rubygems_remotes?(source)
|
988
|
+
return false unless source.is_a?(Source::Rubygems)
|
989
|
+
|
990
|
+
Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
|
991
|
+
end
|
821
992
|
end
|
822
993
|
end
|