bundler 1.9.0 → 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 +1157 -6
- data/README.md +33 -6
- data/bundler.gemspec +51 -18
- data/exe/bundle +31 -0
- data/{bin → exe}/bundle_ruby +10 -6
- data/exe/bundler +4 -0
- data/lib/bundler.rb +326 -207
- data/lib/bundler/build_metadata.rb +53 -0
- data/lib/bundler/capistrano.rb +9 -3
- data/lib/bundler/cli.rb +522 -141
- data/lib/bundler/cli/add.rb +35 -0
- data/lib/bundler/cli/binstubs.rb +22 -11
- data/lib/bundler/cli/cache.rb +7 -6
- data/lib/bundler/cli/check.rb +11 -8
- data/lib/bundler/cli/clean.rb +7 -8
- data/lib/bundler/cli/common.rb +53 -7
- data/lib/bundler/cli/config.rb +84 -49
- data/lib/bundler/cli/console.rb +13 -8
- data/lib/bundler/cli/doctor.rb +140 -0
- data/lib/bundler/cli/exec.rb +77 -16
- data/lib/bundler/cli/gem.rb +120 -52
- data/lib/bundler/cli/info.rb +50 -0
- data/lib/bundler/cli/init.rb +21 -7
- data/lib/bundler/cli/inject.rb +37 -10
- data/lib/bundler/cli/install.rb +139 -78
- data/lib/bundler/cli/issue.rb +40 -0
- data/lib/bundler/cli/list.rb +58 -0
- data/lib/bundler/cli/lock.rb +63 -0
- data/lib/bundler/cli/open.rb +9 -6
- data/lib/bundler/cli/outdated.rb +221 -35
- data/lib/bundler/cli/package.rb +11 -7
- data/lib/bundler/cli/platform.rb +7 -4
- data/lib/bundler/cli/plugin.rb +24 -0
- data/lib/bundler/cli/pristine.rb +47 -0
- data/lib/bundler/cli/remove.rb +18 -0
- data/lib/bundler/cli/show.rb +11 -10
- data/lib/bundler/cli/update.rb +47 -29
- data/lib/bundler/cli/viz.rb +12 -8
- 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 +3 -1
- data/lib/bundler/current_ruby.rb +47 -137
- data/lib/bundler/definition.rb +599 -230
- data/lib/bundler/dep_proxy.rb +15 -10
- data/lib/bundler/dependency.rb +54 -25
- data/lib/bundler/deployment.rb +12 -2
- data/lib/bundler/deprecate.rb +33 -4
- data/lib/bundler/dsl.rb +383 -99
- data/lib/bundler/endpoint_specification.rb +72 -7
- data/lib/bundler/env.rb +121 -41
- data/lib/bundler/environment_preserver.rb +59 -0
- data/lib/bundler/errors.rb +158 -0
- data/lib/bundler/feature_flag.rb +74 -0
- data/lib/bundler/fetcher.rb +171 -280
- data/lib/bundler/fetcher/base.rb +52 -0
- data/lib/bundler/fetcher/compact_index.rb +126 -0
- data/lib/bundler/fetcher/dependency.rb +82 -0
- data/lib/bundler/fetcher/downloader.rb +84 -0
- data/lib/bundler/fetcher/index.rb +52 -0
- data/lib/bundler/friendly_errors.rb +113 -58
- data/lib/bundler/gem_helper.rb +73 -46
- data/lib/bundler/gem_helpers.rb +85 -9
- data/lib/bundler/gem_remote_fetcher.rb +43 -0
- data/lib/bundler/gem_tasks.rb +6 -1
- data/lib/bundler/gem_version_promoter.rb +190 -0
- data/lib/bundler/gemdeps.rb +29 -0
- data/lib/bundler/graph.rb +32 -49
- data/lib/bundler/index.rb +79 -67
- data/lib/bundler/injector.rb +219 -30
- data/lib/bundler/inline.rb +74 -0
- data/lib/bundler/installer.rb +191 -206
- data/lib/bundler/installer/gem_installer.rb +85 -0
- data/lib/bundler/installer/parallel_installer.rb +233 -0
- data/lib/bundler/installer/standalone.rb +53 -0
- data/lib/bundler/lazy_specification.rb +53 -13
- data/lib/bundler/lockfile_generator.rb +95 -0
- data/lib/bundler/lockfile_parser.rb +157 -62
- data/lib/bundler/match_platform.rb +15 -4
- data/lib/bundler/mirror.rb +223 -0
- data/lib/bundler/plugin.rb +292 -0
- data/lib/bundler/plugin/api.rb +81 -0
- data/lib/bundler/plugin/api/source.rb +306 -0
- data/lib/bundler/plugin/dsl.rb +53 -0
- data/lib/bundler/plugin/events.rb +61 -0
- data/lib/bundler/plugin/index.rb +162 -0
- data/lib/bundler/plugin/installer.rb +96 -0
- data/lib/bundler/plugin/installer/git.rb +38 -0
- data/lib/bundler/plugin/installer/rubygems.rb +27 -0
- data/lib/bundler/plugin/source_list.rb +27 -0
- data/lib/bundler/process_lock.rb +24 -0
- data/lib/bundler/psyched_yaml.rb +17 -6
- data/lib/bundler/remote_specification.rb +68 -11
- data/lib/bundler/resolver.rb +263 -229
- data/lib/bundler/resolver/spec_group.rb +106 -0
- data/lib/bundler/retry.rb +25 -19
- data/lib/bundler/ruby_dsl.rb +9 -2
- data/lib/bundler/ruby_version.rb +101 -66
- data/lib/bundler/rubygems_ext.rb +77 -37
- data/lib/bundler/rubygems_gem_installer.rb +106 -0
- data/lib/bundler/rubygems_integration.rb +450 -163
- data/lib/bundler/runtime.rb +133 -103
- data/lib/bundler/settings.rb +344 -83
- data/lib/bundler/settings/validator.rb +102 -0
- data/lib/bundler/setup.rb +7 -3
- data/lib/bundler/shared_helpers.rb +284 -54
- data/lib/bundler/similarity_detector.rb +21 -21
- data/lib/bundler/source.rb +68 -15
- data/lib/bundler/source/gemspec.rb +18 -0
- data/lib/bundler/source/git.rb +90 -55
- data/lib/bundler/source/git/git_proxy.rb +135 -35
- data/lib/bundler/source/metadata.rb +62 -0
- data/lib/bundler/source/path.rb +84 -61
- data/lib/bundler/source/path/installer.rb +53 -17
- data/lib/bundler/source/rubygems.rb +282 -122
- data/lib/bundler/source/rubygems/remote.rb +69 -0
- data/lib/bundler/source_list.rb +107 -22
- data/lib/bundler/spec_set.rb +83 -45
- data/lib/bundler/ssl_certs/certificate_manager.rb +8 -7
- data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
- data/lib/bundler/ssl_certs/{DigiCertHighAssuranceEVRootCA.pem → rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem} +0 -0
- data/lib/bundler/ssl_certs/{AddTrustExternalCARoot-2048.pem → rubygems.org/AddTrustExternalCARoot.pem} +0 -0
- data/lib/bundler/stub_specification.rb +108 -0
- data/lib/bundler/templates/.document +1 -0
- data/lib/bundler/templates/Executable +19 -6
- data/lib/bundler/templates/Executable.bundler +105 -0
- data/lib/bundler/templates/Executable.standalone +6 -4
- data/lib/bundler/templates/Gemfile +4 -1
- data/lib/bundler/templates/gems.rb +8 -0
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +68 -7
- 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 +19 -11
- data/lib/bundler/templates/newgem/Rakefile.tt +10 -6
- data/lib/bundler/templates/newgem/bin/console.tt +1 -1
- data/lib/bundler/templates/newgem/bin/setup.tt +2 -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 +31 -15
- data/lib/bundler/templates/newgem/rspec.tt +1 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +3 -5
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +14 -2
- data/lib/bundler/templates/newgem/test/{test_newgem.rb.tt → newgem_test.rb.tt} +2 -2
- data/lib/bundler/templates/newgem/test/test_helper.rb.tt +4 -0
- data/lib/bundler/templates/newgem/travis.yml.tt +7 -0
- data/lib/bundler/ui.rb +5 -3
- data/lib/bundler/ui/rg_proxy.rb +5 -7
- data/lib/bundler/ui/shell.rb +69 -18
- data/lib/bundler/ui/silent.rb +26 -1
- data/lib/bundler/uri_credentials_filter.rb +37 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1638 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +12 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +223 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
- 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 +61 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +136 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +143 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
- data/lib/bundler/vendor/{Molinillo-0.2.1 → molinillo}/lib/molinillo/modules/specification_provider.rb +11 -0
- data/lib/bundler/vendor/{Molinillo-0.2.1 → molinillo}/lib/molinillo/modules/ui.rb +6 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +837 -0
- data/lib/bundler/vendor/{Molinillo-0.2.1 → molinillo}/lib/molinillo/resolver.rb +6 -3
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +58 -0
- 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-0.19.1 → thor}/lib/thor.rb +47 -22
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions.rb +31 -29
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/create_file.rb +3 -2
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/create_link.rb +3 -2
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/directory.rb +3 -3
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/empty_directory.rb +16 -8
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/file_manipulation.rb +66 -18
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/inject_into_file.rb +18 -16
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/base.rb +67 -44
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/command.rb +13 -11
- data/lib/bundler/vendor/{thor-0.19.1 → 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 +12 -0
- data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +129 -0
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/error.rb +3 -3
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/group.rb +14 -14
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/invocation.rb +4 -5
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/line_editor.rb +2 -2
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/line_editor/basic.rb +2 -0
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/line_editor/readline.rb +0 -0
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/argument.rb +4 -7
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/arguments.rb +16 -16
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/option.rb +42 -21
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/options.rb +13 -10
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/rake_compat.rb +1 -1
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/runner.rb +35 -33
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell.rb +4 -4
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell/basic.rb +49 -33
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell/color.rb +2 -2
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell/html.rb +5 -5
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/util.rb +8 -7
- data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/version.rb +1 -1
- data/lib/bundler/vendored_fileutils.rb +9 -0
- data/lib/bundler/vendored_molinillo.rb +4 -5
- data/lib/bundler/vendored_persistent.rb +45 -4
- data/lib/bundler/vendored_thor.rb +8 -5
- data/lib/bundler/version.rb +23 -1
- data/lib/bundler/version_ranges.rb +76 -0
- data/lib/bundler/vlad.rb +8 -2
- data/lib/bundler/worker.rb +39 -6
- data/lib/bundler/yaml_serializer.rb +90 -0
- data/man/bundle-add.1 +58 -0
- data/man/bundle-add.1.txt +52 -0
- data/man/bundle-add.ronn +40 -0
- data/man/bundle-binstubs.1 +40 -0
- data/man/bundle-binstubs.1.txt +48 -0
- data/man/bundle-binstubs.ronn +43 -0
- 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 +256 -31
- data/man/bundle-doctor.1 +44 -0
- data/man/bundle-doctor.1.txt +44 -0
- data/man/bundle-doctor.ronn +33 -0
- data/man/bundle-exec.1 +165 -0
- data/man/bundle-exec.1.txt +178 -0
- data/man/bundle-exec.ronn +19 -3
- data/man/bundle-gem.1 +80 -0
- data/man/bundle-gem.1.txt +91 -0
- data/man/bundle-gem.ronn +78 -0
- 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/man/bundle-install.1 +308 -0
- data/man/bundle-install.1.txt +396 -0
- data/man/bundle-install.ronn +64 -67
- data/man/bundle-list.1 +50 -0
- data/man/bundle-list.1.txt +43 -0
- data/man/bundle-list.ronn +33 -0
- data/man/bundle-lock.1 +84 -0
- data/man/bundle-lock.1.txt +93 -0
- data/man/bundle-lock.ronn +94 -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/man/bundle-package.1 +55 -0
- data/man/bundle-package.1.txt +79 -0
- data/man/bundle-package.ronn +14 -8
- data/man/bundle-platform.1 +61 -0
- data/man/bundle-platform.1.txt +57 -0
- data/man/bundle-platform.ronn +1 -1
- 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 +180 -18
- data/man/bundle-viz.1 +39 -0
- data/man/bundle-viz.1.txt +39 -0
- data/man/bundle-viz.ronn +30 -0
- data/man/bundle.1 +136 -0
- data/man/bundle.1.txt +116 -0
- data/man/bundle.ronn +46 -33
- data/man/gemfile.5 +689 -0
- data/man/gemfile.5.ronn +127 -79
- data/man/gemfile.5.txt +653 -0
- data/man/index.txt +25 -7
- metadata +242 -95
- data/.gitignore +0 -16
- data/.rspec +0 -3
- data/.travis.yml +0 -110
- data/CODE_OF_CONDUCT.md +0 -40
- data/CONTRIBUTING.md +0 -32
- data/DEVELOPMENT.md +0 -119
- data/ISSUES.md +0 -96
- data/Rakefile +0 -302
- data/UPGRADING.md +0 -103
- data/bin/bundle +0 -21
- data/bin/bundler +0 -21
- data/lib/bundler/anonymizable_uri.rb +0 -32
- data/lib/bundler/environment.rb +0 -42
- data/lib/bundler/gem_installer.rb +0 -9
- data/lib/bundler/gem_path_manipulation.rb +0 -8
- data/lib/bundler/ssl_certs/AddTrustExternalCARoot.pem +0 -32
- data/lib/bundler/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
- data/lib/bundler/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
- data/lib/bundler/ssl_certs/GeoTrustGlobalCA.pem +0 -20
- data/lib/bundler/templates/newgem/.travis.yml.tt +0 -3
- data/lib/bundler/templates/newgem/test/minitest_helper.rb.tt +0 -4
- data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo.rb +0 -5
- data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/dependency_graph.rb +0 -266
- data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/errors.rb +0 -69
- data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/gem_metadata.rb +0 -3
- data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/resolution.rb +0 -412
- data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/state.rb +0 -43
- data/lib/bundler/vendor/thor-0.19.1/lib/thor/core_ext/io_binary_read.rb +0 -10
- data/lib/bundler/vendor/thor-0.19.1/lib/thor/core_ext/ordered_hash.rb +0 -98
- data/lib/bundler/vendor/thor-0.19.1/lib/thor/parser.rb +0 -4
data/lib/bundler/definition.rb
CHANGED
@@ -1,11 +1,22 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/lockfile_parser"
|
2
4
|
require "set"
|
3
5
|
|
4
6
|
module Bundler
|
5
7
|
class Definition
|
6
8
|
include GemHelpers
|
7
9
|
|
8
|
-
attr_reader
|
10
|
+
attr_reader(
|
11
|
+
:dependencies,
|
12
|
+
:locked_deps,
|
13
|
+
:locked_gems,
|
14
|
+
:platforms,
|
15
|
+
:requires,
|
16
|
+
:ruby_version,
|
17
|
+
:lockfile,
|
18
|
+
:gemfiles
|
19
|
+
)
|
9
20
|
|
10
21
|
# Given a gemfile and lockfile creates a Bundler definition
|
11
22
|
#
|
@@ -18,14 +29,11 @@ module Bundler
|
|
18
29
|
unlock ||= {}
|
19
30
|
gemfile = Pathname.new(gemfile).expand_path
|
20
31
|
|
21
|
-
unless gemfile.file?
|
22
|
-
raise GemfileNotFound, "#{gemfile} not found"
|
23
|
-
end
|
32
|
+
raise GemfileNotFound, "#{gemfile} not found" unless gemfile.file?
|
24
33
|
|
25
34
|
Dsl.evaluate(gemfile, lockfile, unlock)
|
26
35
|
end
|
27
36
|
|
28
|
-
|
29
37
|
#
|
30
38
|
# How does the new system work?
|
31
39
|
#
|
@@ -43,68 +51,97 @@ module Bundler
|
|
43
51
|
# @param unlock [Hash, Boolean, nil] Gems that have been requested
|
44
52
|
# to be updated or true if all gems should be updated
|
45
53
|
# @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version
|
46
|
-
|
47
|
-
|
54
|
+
# @param optional_groups [Array(String)] A list of optional groups
|
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
|
48
65
|
|
49
|
-
@dependencies
|
50
|
-
@
|
51
|
-
@
|
52
|
-
@
|
53
|
-
@
|
66
|
+
@dependencies = dependencies
|
67
|
+
@sources = sources
|
68
|
+
@unlock = unlock
|
69
|
+
@optional_groups = optional_groups
|
70
|
+
@remote = false
|
71
|
+
@specs = nil
|
72
|
+
@ruby_version = ruby_version
|
73
|
+
@gemfiles = gemfiles
|
74
|
+
|
75
|
+
@lockfile = lockfile
|
76
|
+
@lockfile_contents = String.new
|
77
|
+
@locked_bundler_version = nil
|
78
|
+
@locked_ruby_version = nil
|
79
|
+
@locked_specs_incomplete_for_platform = false
|
54
80
|
|
55
81
|
if lockfile && File.exist?(lockfile)
|
56
82
|
@lockfile_contents = Bundler.read_file(lockfile)
|
57
|
-
|
58
|
-
@
|
83
|
+
@locked_gems = LockfileParser.new(@lockfile_contents)
|
84
|
+
@locked_platforms = @locked_gems.platforms
|
85
|
+
@platforms = @locked_platforms.dup
|
86
|
+
@locked_bundler_version = @locked_gems.bundler_version
|
87
|
+
@locked_ruby_version = @locked_gems.ruby_version
|
59
88
|
|
60
89
|
if unlock != true
|
61
|
-
@locked_deps =
|
62
|
-
@locked_specs = SpecSet.new(
|
63
|
-
@locked_sources =
|
90
|
+
@locked_deps = @locked_gems.dependencies
|
91
|
+
@locked_specs = SpecSet.new(@locked_gems.specs)
|
92
|
+
@locked_sources = @locked_gems.sources
|
64
93
|
else
|
65
94
|
@unlock = {}
|
66
|
-
@locked_deps =
|
95
|
+
@locked_deps = {}
|
67
96
|
@locked_specs = SpecSet.new([])
|
68
97
|
@locked_sources = []
|
69
98
|
end
|
70
99
|
else
|
71
100
|
@unlock = {}
|
72
101
|
@platforms = []
|
73
|
-
@
|
102
|
+
@locked_gems = nil
|
103
|
+
@locked_deps = {}
|
74
104
|
@locked_specs = SpecSet.new([])
|
75
105
|
@locked_sources = []
|
106
|
+
@locked_platforms = []
|
76
107
|
end
|
77
108
|
|
78
109
|
@unlock[:gems] ||= []
|
79
110
|
@unlock[:sources] ||= []
|
111
|
+
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
|
112
|
+
@ruby_version.diff(locked_ruby_version_object)
|
113
|
+
end
|
114
|
+
@unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
|
80
115
|
|
81
|
-
|
82
|
-
@new_platform = !@platforms.include?(current_platform)
|
83
|
-
@platforms |= [current_platform]
|
116
|
+
add_current_platform unless Bundler.frozen_bundle?
|
84
117
|
|
118
|
+
converge_path_sources_to_gemspec_sources
|
85
119
|
@path_changes = converge_paths
|
86
|
-
eager_unlock = expand_dependencies(@unlock[:gems])
|
87
|
-
@unlock[:gems] = @locked_specs.for(eager_unlock).map { |s| s.name }
|
88
|
-
|
89
120
|
@source_changes = converge_sources
|
121
|
+
|
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
|
126
|
+
|
90
127
|
@dependency_changes = converge_dependencies
|
91
128
|
@local_changes = converge_locals
|
92
129
|
|
93
|
-
|
130
|
+
@requires = compute_requires
|
94
131
|
end
|
95
132
|
|
96
|
-
def
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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])
|
108
145
|
end
|
109
146
|
end
|
110
147
|
|
@@ -129,12 +166,20 @@ module Bundler
|
|
129
166
|
# @return [Bundler::SpecSet]
|
130
167
|
def specs
|
131
168
|
@specs ||= begin
|
132
|
-
|
133
|
-
|
169
|
+
begin
|
170
|
+
specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies)
|
171
|
+
rescue GemNotFound => e # Handle yanked gem
|
172
|
+
gem_name, gem_version = extract_gem_info(e)
|
173
|
+
locked_gem = @locked_specs[gem_name].last
|
174
|
+
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
|
175
|
+
raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
|
176
|
+
"be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
|
177
|
+
"that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
|
178
|
+
"to a version other than #{locked_gem} that hasn't been removed in order to install."
|
179
|
+
end
|
134
180
|
unless specs["bundler"].any?
|
135
|
-
|
136
|
-
bundler =
|
137
|
-
specs["bundler"] = bundler if bundler
|
181
|
+
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
|
182
|
+
specs["bundler"] = bundler
|
138
183
|
end
|
139
184
|
|
140
185
|
specs
|
@@ -159,21 +204,36 @@ module Bundler
|
|
159
204
|
missing
|
160
205
|
end
|
161
206
|
|
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
|
220
|
+
end
|
221
|
+
|
162
222
|
def requested_specs
|
163
223
|
@requested_specs ||= begin
|
164
|
-
groups =
|
165
|
-
groups.map!
|
224
|
+
groups = requested_groups
|
225
|
+
groups.map!(&:to_sym)
|
166
226
|
specs_for(groups)
|
167
227
|
end
|
168
228
|
end
|
169
229
|
|
170
230
|
def current_dependencies
|
171
|
-
dependencies.
|
231
|
+
dependencies.select(&:should_include?)
|
172
232
|
end
|
173
233
|
|
174
234
|
def specs_for(groups)
|
175
|
-
deps = dependencies.select {
|
176
|
-
deps.delete_if {
|
235
|
+
deps = dependencies.select {|d| (d.groups & groups).any? }
|
236
|
+
deps.delete_if {|d| !d.should_include? }
|
177
237
|
specs.for(expand_dependencies(deps))
|
178
238
|
end
|
179
239
|
|
@@ -184,39 +244,69 @@ module Bundler
|
|
184
244
|
# @return [SpecSet] resolved dependencies
|
185
245
|
def resolve
|
186
246
|
@resolve ||= begin
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
247
|
+
last_resolve = converge_locked_specs
|
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
|
191
260
|
|
192
|
-
|
193
|
-
|
194
|
-
|
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)
|
195
264
|
end
|
196
265
|
end
|
197
266
|
|
198
267
|
def index
|
199
268
|
@index ||= Index.build do |idx|
|
200
|
-
dependency_names = @dependencies.map
|
269
|
+
dependency_names = @dependencies.map(&:name)
|
201
270
|
|
202
271
|
sources.all_sources.each do |source|
|
203
|
-
source.dependency_names = dependency_names
|
272
|
+
source.dependency_names = dependency_names - pinned_spec_names(source)
|
204
273
|
idx.add_source source.specs
|
205
|
-
dependency_names
|
206
|
-
dependency_names.push(*source.unmet_deps).uniq!
|
274
|
+
dependency_names.concat(source.unmet_deps).uniq!
|
207
275
|
end
|
276
|
+
|
277
|
+
double_check_for_index(idx, dependency_names)
|
208
278
|
end
|
209
279
|
end
|
210
280
|
|
211
|
-
#
|
212
|
-
#
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
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
|
300
|
+
end
|
301
|
+
|
302
|
+
sources.all_sources.each do |source|
|
303
|
+
source.double_check_for(unmet_dependency_names)
|
217
304
|
end
|
305
|
+
|
306
|
+
break if idxcount == idx.size
|
218
307
|
end
|
219
308
|
end
|
309
|
+
private :double_check_for_index
|
220
310
|
|
221
311
|
def has_rubygems_remotes?
|
222
312
|
sources.rubygems_sources.any? {|s| s.remotes.any? }
|
@@ -231,193 +321,280 @@ module Bundler
|
|
231
321
|
end
|
232
322
|
|
233
323
|
def groups
|
234
|
-
dependencies.map
|
324
|
+
dependencies.map(&:groups).flatten.uniq
|
235
325
|
end
|
236
326
|
|
237
|
-
def lock(file)
|
327
|
+
def lock(file, preserve_unknown_sections = false)
|
238
328
|
contents = to_lock
|
239
329
|
|
240
330
|
# Convert to \r\n if the existing lock has them
|
241
331
|
# i.e., Windows with `git config core.autocrlf=true`
|
242
332
|
contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n")
|
243
333
|
|
244
|
-
|
334
|
+
if @locked_bundler_version
|
335
|
+
locked_major = @locked_bundler_version.segments.first
|
336
|
+
current_major = Gem::Version.create(Bundler::VERSION).segments.first
|
245
337
|
|
246
|
-
|
338
|
+
if updating_major = locked_major < current_major
|
339
|
+
Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, " \
|
340
|
+
"after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
345
|
+
|
346
|
+
return if file && File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
|
347
|
+
|
348
|
+
if Bundler.frozen_bundle?
|
247
349
|
Bundler.ui.error "Cannot write a changed lockfile while frozen."
|
248
350
|
return
|
249
351
|
end
|
250
352
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
"There was an error while trying to write to Gemfile.lock. It is likely that \n" \
|
255
|
-
"you need to allow write permissions for the file at path: \n" \
|
256
|
-
"#{File.expand_path(file)}"
|
353
|
+
SharedHelpers.filesystem_access(file) do |p|
|
354
|
+
File.open(p, "wb") {|f| f.puts(contents) }
|
355
|
+
end
|
257
356
|
end
|
258
357
|
|
259
|
-
def
|
260
|
-
|
261
|
-
|
262
|
-
sources.lock_sources.each do |source|
|
263
|
-
# Add the source header
|
264
|
-
out << source.to_lock
|
265
|
-
# Find all specs for this source
|
266
|
-
resolve.
|
267
|
-
select { |s| source.can_lock?(s) }.
|
268
|
-
# This needs to be sorted by full name so that
|
269
|
-
# gems with the same name, but different platform
|
270
|
-
# are ordered consistently
|
271
|
-
sort_by { |s| s.full_name }.
|
272
|
-
each do |spec|
|
273
|
-
next if spec.name == 'bundler'
|
274
|
-
out << spec.to_lock
|
275
|
-
end
|
276
|
-
out << "\n"
|
358
|
+
def locked_bundler_version
|
359
|
+
if @locked_bundler_version && @locked_bundler_version < Gem::Version.new(Bundler::VERSION)
|
360
|
+
new_version = Bundler::VERSION
|
277
361
|
end
|
278
362
|
|
279
|
-
|
363
|
+
new_version || @locked_bundler_version || Bundler::VERSION
|
364
|
+
end
|
280
365
|
|
281
|
-
|
282
|
-
|
366
|
+
def locked_ruby_version
|
367
|
+
return unless ruby_version
|
368
|
+
if @unlock[:ruby] || !@locked_ruby_version
|
369
|
+
Bundler::RubyVersion.system
|
370
|
+
else
|
371
|
+
@locked_ruby_version
|
283
372
|
end
|
373
|
+
end
|
284
374
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
handled << dep.name
|
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
|
295
384
|
end
|
385
|
+
end
|
296
386
|
|
297
|
-
|
387
|
+
def to_lock
|
388
|
+
require "bundler/lockfile_generator"
|
389
|
+
LockfileGenerator.generate(self)
|
298
390
|
end
|
299
391
|
|
300
392
|
def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
|
301
|
-
msg =
|
302
|
-
|
303
|
-
|
393
|
+
msg = String.new
|
394
|
+
msg << "You are trying to install in deployment mode after changing\n" \
|
395
|
+
"your Gemfile. Run `bundle install` elsewhere and add the\n" \
|
396
|
+
"updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control."
|
304
397
|
|
305
398
|
unless explicit_flag
|
306
|
-
|
307
|
-
|
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
|
406
|
+
msg << "\n\nIf this is a development machine, remove the #{Bundler.default_gemfile} " \
|
407
|
+
"freeze \nby running `#{suggested_command}`."
|
308
408
|
end
|
309
409
|
|
310
410
|
added = []
|
311
411
|
deleted = []
|
312
412
|
changed = []
|
313
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
|
+
|
314
419
|
gemfile_sources = sources.lock_sources
|
315
|
-
if @locked_sources != gemfile_sources
|
316
|
-
new_sources = gemfile_sources - @locked_sources
|
317
|
-
deleted_sources = @locked_sources - gemfile_sources
|
318
420
|
|
421
|
+
new_sources = gemfile_sources - @locked_sources
|
422
|
+
deleted_sources = @locked_sources - gemfile_sources
|
423
|
+
|
424
|
+
new_deps = @dependencies - @locked_deps.values
|
425
|
+
deleted_deps = @locked_deps.values - @dependencies
|
426
|
+
|
427
|
+
# Check if it is possible that the source is only changed thing
|
428
|
+
if (new_deps.empty? && deleted_deps.empty?) && (!new_sources.empty? && !deleted_sources.empty?)
|
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) }
|
431
|
+
end
|
432
|
+
|
433
|
+
if @locked_sources != gemfile_sources
|
319
434
|
if new_sources.any?
|
320
|
-
added.concat new_sources.map {
|
435
|
+
added.concat new_sources.map {|source| "* source: #{source}" }
|
321
436
|
end
|
322
437
|
|
323
438
|
if deleted_sources.any?
|
324
|
-
deleted.concat deleted_sources.map {
|
439
|
+
deleted.concat deleted_sources.map {|source| "* source: #{source}" }
|
325
440
|
end
|
326
441
|
end
|
327
442
|
|
328
|
-
new_deps
|
329
|
-
deleted_deps = @locked_deps - @dependencies
|
330
|
-
|
331
|
-
if new_deps.any?
|
332
|
-
added.concat new_deps.map { |d| "* #{pretty_dep(d)}" }
|
333
|
-
end
|
334
|
-
|
443
|
+
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
|
335
444
|
if deleted_deps.any?
|
336
|
-
deleted.concat deleted_deps.map {
|
445
|
+
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
|
337
446
|
end
|
338
447
|
|
339
|
-
both_sources = Hash.new {
|
340
|
-
@dependencies.each {
|
341
|
-
@locked_deps.each {
|
448
|
+
both_sources = Hash.new {|h, k| h[k] = [] }
|
449
|
+
@dependencies.each {|d| both_sources[d.name][0] = d }
|
450
|
+
@locked_deps.each {|name, d| both_sources[name][1] = d.source }
|
342
451
|
|
343
452
|
both_sources.each do |name, (dep, lock_source)|
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
end
|
453
|
+
next unless (dep.nil? && !lock_source.nil?) || (!dep.nil? && !lock_source.nil? && !lock_source.can_lock?(dep))
|
454
|
+
gemfile_source_name = (dep && dep.source) || "no specified source"
|
455
|
+
lockfile_source_name = lock_source || "no specified source"
|
456
|
+
changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
|
349
457
|
end
|
350
458
|
|
351
|
-
|
459
|
+
reason = change_reason
|
460
|
+
msg << "\n\n#{reason.split(", ").map(&:capitalize).join("\n")}" unless reason.strip.empty?
|
461
|
+
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
|
352
462
|
msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
|
353
|
-
msg << "\n\nYou have changed in the Gemfile:\n"
|
463
|
+
msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
|
354
464
|
msg << "\n"
|
355
465
|
|
356
|
-
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!
|
357
472
|
end
|
358
473
|
|
359
474
|
def validate_ruby!
|
360
475
|
return unless ruby_version
|
361
476
|
|
362
|
-
if diff = ruby_version.diff(Bundler.
|
477
|
+
if diff = ruby_version.diff(Bundler::RubyVersion.system)
|
363
478
|
problem, expected, actual = diff
|
364
479
|
|
365
480
|
msg = case problem
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
481
|
+
when :engine
|
482
|
+
"Your Ruby engine is #{actual}, but your Gemfile specified #{expected}"
|
483
|
+
when :version
|
484
|
+
"Your Ruby version is #{actual}, but your Gemfile specified #{expected}"
|
485
|
+
when :engine_version
|
486
|
+
"Your #{Bundler::RubyVersion.system.engine} version is #{actual}, but your Gemfile specified #{ruby_version.engine} #{expected}"
|
487
|
+
when :patchlevel
|
488
|
+
if !expected.is_a?(String)
|
489
|
+
"The Ruby patchlevel in your Gemfile must be a string"
|
490
|
+
else
|
491
|
+
"Your Ruby patchlevel is #{actual}, but your Gemfile specified #{expected}"
|
492
|
+
end
|
378
493
|
end
|
379
494
|
|
380
495
|
raise RubyVersionMismatch, msg
|
381
496
|
end
|
382
497
|
end
|
383
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
|
+
|
511
|
+
def add_platform(platform)
|
512
|
+
@new_platform ||= !@platforms.include?(platform)
|
513
|
+
@platforms |= [platform]
|
514
|
+
end
|
515
|
+
|
516
|
+
def remove_platform(platform)
|
517
|
+
return if @platforms.delete(Gem::Platform.new(platform))
|
518
|
+
raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
|
519
|
+
end
|
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
|
+
|
384
535
|
attr_reader :sources
|
385
|
-
private
|
536
|
+
private :sources
|
537
|
+
|
538
|
+
def nothing_changed?
|
539
|
+
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
|
540
|
+
end
|
541
|
+
|
542
|
+
def unlocking?
|
543
|
+
@unlocking
|
544
|
+
end
|
386
545
|
|
387
546
|
private
|
388
547
|
|
389
|
-
def
|
390
|
-
|
548
|
+
def change_reason
|
549
|
+
if unlocking?
|
550
|
+
unlock_reason = @unlock.reject {|_k, v| Array(v).empty? }.map do |k, v|
|
551
|
+
if v == true
|
552
|
+
k.to_s
|
553
|
+
else
|
554
|
+
v = Array(v)
|
555
|
+
"#{k}: (#{v.join(", ")})"
|
556
|
+
end
|
557
|
+
end.join(", ")
|
558
|
+
return "bundler is unlocking #{unlock_reason}"
|
559
|
+
end
|
560
|
+
[
|
561
|
+
[@source_changes, "the list of sources changed"],
|
562
|
+
[@dependency_changes, "the dependencies in your gemfile changed"],
|
563
|
+
[@new_platform, "you added a new platform to your gemfile"],
|
564
|
+
[@path_changes, "the gemspecs for path gems changed"],
|
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"],
|
567
|
+
].select(&:first).map(&:last).join(", ")
|
391
568
|
end
|
392
569
|
|
393
570
|
def pretty_dep(dep, source = false)
|
394
|
-
|
395
|
-
msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
|
396
|
-
msg << " from the `#{dep.source}` source" if source && dep.source
|
397
|
-
msg
|
571
|
+
SharedHelpers.pretty_dependency(dep, source)
|
398
572
|
end
|
399
573
|
|
400
574
|
# Check if the specs of the given source changed
|
401
|
-
# according to the locked source.
|
402
|
-
|
403
|
-
|
404
|
-
def specs_changed?(source, &block)
|
405
|
-
locked = @locked_sources.find(&block)
|
406
|
-
|
407
|
-
if locked
|
408
|
-
unlocking = @locked_specs.any? do |locked_spec|
|
409
|
-
locked_spec.source.class == locked.class && locked_spec.source != locked
|
410
|
-
end
|
411
|
-
end
|
575
|
+
# according to the locked source.
|
576
|
+
def specs_changed?(source)
|
577
|
+
locked = @locked_sources.find {|s| s == source }
|
412
578
|
|
413
|
-
!locked ||
|
579
|
+
!locked || dependencies_for_source_changed?(source, locked) || specs_for_source_changed?(source)
|
414
580
|
end
|
415
581
|
|
416
|
-
def dependencies_for_source_changed?(source)
|
417
|
-
deps_for_source = @dependencies.select {
|
418
|
-
locked_deps_for_source = @locked_deps.select {
|
582
|
+
def dependencies_for_source_changed?(source, locked_source = source)
|
583
|
+
deps_for_source = @dependencies.select {|s| s.source == source }
|
584
|
+
locked_deps_for_source = @locked_deps.values.select {|dep| dep.source == locked_source }
|
419
585
|
|
420
|
-
deps_for_source != locked_deps_for_source
|
586
|
+
Set.new(deps_for_source) != Set.new(locked_deps_for_source)
|
587
|
+
end
|
588
|
+
|
589
|
+
def specs_for_source_changed?(source)
|
590
|
+
locked_index = Index.new
|
591
|
+
locked_index.use(@locked_specs.select {|s| source.can_lock?(s) })
|
592
|
+
|
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
|
421
598
|
end
|
422
599
|
|
423
600
|
# Get all locals and override their matching sources.
|
@@ -426,48 +603,75 @@ module Bundler
|
|
426
603
|
def converge_locals
|
427
604
|
locals = []
|
428
605
|
|
429
|
-
Bundler.settings.local_overrides.map do |k,v|
|
430
|
-
spec = @dependencies.find {
|
606
|
+
Bundler.settings.local_overrides.map do |k, v|
|
607
|
+
spec = @dependencies.find {|s| s.name == k }
|
431
608
|
source = spec && spec.source
|
432
609
|
if source && source.respond_to?(:local_override!)
|
433
610
|
source.unlock! if @unlock[:gems].include?(spec.name)
|
434
|
-
locals << [
|
611
|
+
locals << [source, source.local_override!(v)]
|
435
612
|
end
|
436
613
|
end
|
437
614
|
|
438
|
-
locals.
|
439
|
-
changed || specs_changed?(source)
|
440
|
-
end
|
615
|
+
sources_with_changes = locals.select do |source, changed|
|
616
|
+
changed || specs_changed?(source)
|
617
|
+
end.map(&:first)
|
618
|
+
!sources_with_changes.each {|source| @unlock[:sources] << source.name }.empty?
|
441
619
|
end
|
442
620
|
|
443
621
|
def converge_paths
|
444
622
|
sources.path_sources.any? do |source|
|
445
|
-
specs_changed?(source)
|
446
|
-
ls.class == source.class && ls.path == source.path
|
447
|
-
end
|
623
|
+
specs_changed?(source)
|
448
624
|
end
|
449
625
|
end
|
450
626
|
|
451
|
-
def
|
627
|
+
def converge_path_source_to_gemspec_source(source)
|
628
|
+
return source unless source.instance_of?(Source::Path)
|
629
|
+
gemspec_source = sources.path_sources.find {|s| s.is_a?(Source::Gemspec) && s.as_path_source == source }
|
630
|
+
gemspec_source || source
|
631
|
+
end
|
632
|
+
|
633
|
+
def converge_path_sources_to_gemspec_sources
|
634
|
+
@locked_sources.map! do |source|
|
635
|
+
converge_path_source_to_gemspec_source(source)
|
636
|
+
end
|
637
|
+
@locked_specs.each do |spec|
|
638
|
+
spec.source &&= converge_path_source_to_gemspec_source(spec.source)
|
639
|
+
end
|
640
|
+
@locked_deps.each do |_, dep|
|
641
|
+
dep.source &&= converge_path_source_to_gemspec_source(dep.source)
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
def converge_rubygems_sources
|
646
|
+
return false if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
647
|
+
|
452
648
|
changes = false
|
453
649
|
|
454
|
-
# Get the
|
455
|
-
locked_gem_sources = @locked_sources.select {
|
456
|
-
# Get the
|
650
|
+
# Get the RubyGems sources from the Gemfile.lock
|
651
|
+
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
652
|
+
# Get the RubyGems remotes from the Gemfile
|
457
653
|
actual_remotes = sources.rubygems_remotes
|
458
654
|
|
459
|
-
# If there is a
|
655
|
+
# If there is a RubyGems source in both
|
460
656
|
if !locked_gem_sources.empty? && !actual_remotes.empty?
|
461
657
|
locked_gem_sources.each do |locked_gem|
|
462
658
|
# Merge the remotes from the Gemfile into the Gemfile.lock
|
463
|
-
changes
|
659
|
+
changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
|
464
660
|
end
|
465
661
|
end
|
466
662
|
|
663
|
+
changes
|
664
|
+
end
|
665
|
+
|
666
|
+
def converge_sources
|
667
|
+
changes = false
|
668
|
+
|
669
|
+
changes |= converge_rubygems_sources
|
670
|
+
|
467
671
|
# Replace the sources from the Gemfile with the sources from the Gemfile.lock,
|
468
672
|
# if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
|
469
673
|
# source in the Gemfile.lock, use the one from the Gemfile.
|
470
|
-
changes
|
674
|
+
changes |= sources.replace_sources!(@locked_sources)
|
471
675
|
|
472
676
|
sources.all_sources.each do |source|
|
473
677
|
# If the source is unlockable and the current command allows an unlock of
|
@@ -485,12 +689,46 @@ module Bundler
|
|
485
689
|
end
|
486
690
|
|
487
691
|
def converge_dependencies
|
488
|
-
|
489
|
-
|
692
|
+
frozen = Bundler.frozen_bundle?
|
693
|
+
(@dependencies + @locked_deps.values).each do |dep|
|
694
|
+
locked_source = @locked_deps[dep.name]
|
695
|
+
# This is to make sure that if bundler is installing in deployment mode and
|
696
|
+
# after locked_source and sources don't match, we still use locked_source.
|
697
|
+
if frozen && !locked_source.nil? &&
|
698
|
+
locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
|
699
|
+
dep.source = locked_source.source
|
700
|
+
elsif dep.source
|
490
701
|
dep.source = sources.get(dep.source)
|
491
702
|
end
|
703
|
+
if dep.source.is_a?(Source::Gemspec)
|
704
|
+
dep.platforms.concat(@platforms.map {|p| Dependency::REVERSE_PLATFORM_MAP[p] }.flatten(1)).uniq!
|
705
|
+
end
|
492
706
|
end
|
493
|
-
|
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
|
494
732
|
end
|
495
733
|
|
496
734
|
# Remove elements from the locked specs that are expired. This will most
|
@@ -503,9 +741,11 @@ module Bundler
|
|
503
741
|
# and Gemfile.lock. If the Gemfile modified a dependency, but
|
504
742
|
# the gem in the Gemfile.lock still satisfies it, this is fine
|
505
743
|
# too.
|
506
|
-
locked_deps_hash = @locked_deps.inject({}) { |hsh, dep| hsh[dep] = dep; hsh }
|
507
744
|
@dependencies.each do |dep|
|
508
|
-
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
|
509
749
|
|
510
750
|
if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
|
511
751
|
deps << dep
|
@@ -515,80 +755,155 @@ module Bundler
|
|
515
755
|
end
|
516
756
|
|
517
757
|
dep.source.unlock! if dep.source.respond_to?(:unlock!)
|
518
|
-
dep.source.specs.each {
|
758
|
+
dep.source.specs.each {|s| @unlock[:gems] << s.name }
|
519
759
|
end
|
520
760
|
end
|
521
761
|
|
762
|
+
unlock_source_unlocks_spec = Bundler.feature_flag.unlock_source_unlocks_spec?
|
763
|
+
|
522
764
|
converged = []
|
523
765
|
@locked_specs.each do |s|
|
524
|
-
s
|
766
|
+
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
767
|
+
dep = @dependencies.find {|d| s.satisfies?(d) }
|
768
|
+
s.source = (dep && dep.source) || sources.get(s.source)
|
525
769
|
|
526
770
|
# Don't add a spec to the list if its source is expired. For example,
|
527
|
-
# if you change a Git gem to
|
528
|
-
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)
|
774
|
+
|
775
|
+
# XXX This is a backwards-compatibility fix to preserve the ability to
|
776
|
+
# unlock a single gem by passing its name via `--source`. See issue #3759
|
777
|
+
# TODO: delete in Bundler 2
|
778
|
+
next if unlock_source_unlocks_spec && @unlock[:sources].include?(s.name)
|
779
|
+
|
529
780
|
# If the spec is from a path source and it doesn't exist anymore
|
530
|
-
# then we
|
781
|
+
# then we unlock it.
|
531
782
|
|
532
783
|
# Path sources have special logic
|
533
|
-
if s.source.instance_of?(Source::Path)
|
534
|
-
|
784
|
+
if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec)
|
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
|
535
798
|
|
536
799
|
# If the spec is no longer in the path source, unlock it. This
|
537
800
|
# commonly happens if the version changed in the gemspec
|
538
801
|
next unless other
|
539
802
|
|
540
|
-
deps2 = other.dependencies.select {
|
803
|
+
deps2 = other.dependencies.select {|d| d.type != :development }
|
804
|
+
runtime_dependencies = s.dependencies.select {|d| d.type != :development }
|
541
805
|
# If the dependencies of the path source have changed, unlock it
|
542
|
-
next unless
|
806
|
+
next unless runtime_dependencies.sort == deps2.sort
|
543
807
|
end
|
544
808
|
|
545
809
|
converged << s
|
546
810
|
end
|
547
811
|
|
548
812
|
resolve = SpecSet.new(converged)
|
549
|
-
|
550
|
-
|
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
|
551
817
|
|
552
818
|
# Now, we unlock any sources that do not have anymore gems pinned to it
|
553
819
|
sources.all_sources.each do |source|
|
554
820
|
next unless source.respond_to?(:unlock!)
|
555
821
|
|
556
|
-
unless resolve.any? {
|
557
|
-
|
822
|
+
unless resolve.any? {|s| s.source == source }
|
823
|
+
diff ||= @locked_specs.to_a - resolve.to_a
|
824
|
+
source.unlock! if diff.any? {|s| s.source == source }
|
558
825
|
end
|
559
826
|
end
|
560
827
|
|
561
828
|
resolve
|
562
829
|
end
|
563
830
|
|
564
|
-
def in_locked_deps?(dep,
|
565
|
-
|
831
|
+
def in_locked_deps?(dep, locked_dep)
|
832
|
+
# Because the lockfile can't link a dep to a specific remote, we need to
|
833
|
+
# treat sources as equivalent anytime the locked dep has all the remotes
|
834
|
+
# that the Gemfile dep does.
|
835
|
+
locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
|
566
836
|
end
|
567
837
|
|
568
838
|
def satisfies_locked_spec?(dep)
|
569
|
-
@locked_specs.any? {
|
839
|
+
@locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
|
570
840
|
end
|
571
841
|
|
842
|
+
# This list of dependencies is only used in #resolve, so it's OK to add
|
843
|
+
# the metadata dependencies here
|
572
844
|
def expanded_dependencies
|
573
|
-
@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
|
574
878
|
end
|
575
879
|
|
576
880
|
def expand_dependencies(dependencies, remote = false)
|
881
|
+
sorted_platforms = Resolver.sort_platforms(@platforms)
|
577
882
|
deps = []
|
578
883
|
dependencies.each do |dep|
|
579
884
|
dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
|
580
|
-
next
|
581
|
-
dep.gem_platforms(
|
582
|
-
|
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|
|
897
|
+
deps << DepProxy.new(dep, p) if remote || p == generic_local_platform
|
583
898
|
end
|
584
899
|
end
|
585
900
|
deps
|
586
901
|
end
|
587
902
|
|
588
903
|
def requested_dependencies
|
589
|
-
groups =
|
590
|
-
groups.map!
|
591
|
-
dependencies.reject {
|
904
|
+
groups = requested_groups
|
905
|
+
groups.map!(&:to_sym)
|
906
|
+
dependencies.reject {|d| !d.should_include? || (d.groups & groups).empty? }
|
592
907
|
end
|
593
908
|
|
594
909
|
def source_requirements
|
@@ -598,27 +913,81 @@ module Bundler
|
|
598
913
|
# Record the specs available in each gem's source, so that those
|
599
914
|
# specs will be available later when the resolver knows where to
|
600
915
|
# look for that gemspec (or its dependencies)
|
601
|
-
|
916
|
+
default = sources.default_source
|
917
|
+
source_requirements = { :default => default }
|
918
|
+
default = nil unless Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
602
919
|
dependencies.each do |dep|
|
603
|
-
next unless dep.source
|
604
|
-
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
|
605
925
|
end
|
926
|
+
source_requirements["bundler"] = sources.metadata_source # needs to come last to override
|
606
927
|
source_requirements
|
607
928
|
end
|
608
929
|
|
609
|
-
def pinned_spec_names(
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
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
|
937
|
+
end
|
938
|
+
pinned_names
|
939
|
+
end
|
940
|
+
|
941
|
+
def requested_groups
|
942
|
+
groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
|
943
|
+
end
|
944
|
+
|
945
|
+
def lockfiles_equal?(current, proposed, preserve_unknown_sections)
|
946
|
+
if preserve_unknown_sections
|
947
|
+
sections_to_ignore = LockfileParser.sections_to_ignore(@locked_bundler_version)
|
948
|
+
sections_to_ignore += LockfileParser.unknown_sections_in_lockfile(current)
|
949
|
+
sections_to_ignore += LockfileParser::ENVIRONMENT_VERSION_SECTIONS
|
950
|
+
pattern = /#{Regexp.union(sections_to_ignore)}\n(\s{2,}.*\n)+/
|
951
|
+
whitespace_cleanup = /\n{2,}/
|
952
|
+
current = current.gsub(pattern, "\n").gsub(whitespace_cleanup, "\n\n").strip
|
953
|
+
proposed = proposed.gsub(pattern, "\n").gsub(whitespace_cleanup, "\n\n").strip
|
954
|
+
end
|
955
|
+
current == proposed
|
956
|
+
end
|
957
|
+
|
958
|
+
def extract_gem_info(error)
|
959
|
+
# This method will extract the error message like "Could not find foo-1.2.3 in any of the sources"
|
960
|
+
# to an array. The first element will be the gem name (e.g. foo), the second will be the version number.
|
961
|
+
error.message.scan(/Could not find (\w+)-(\d+(?:\.\d+)+)/).flatten
|
962
|
+
end
|
963
|
+
|
964
|
+
def compute_requires
|
965
|
+
dependencies.reduce({}) do |requires, dep|
|
966
|
+
next requires unless dep.should_include?
|
967
|
+
requires[dep.name] = Array(dep.autorequire || dep.name).map do |file|
|
968
|
+
# Allow `require: true` as an alias for `require: <name>`
|
969
|
+
file == true ? dep.name : file
|
617
970
|
end
|
971
|
+
requires
|
618
972
|
end
|
619
|
-
names.uniq!
|
620
|
-
names
|
621
973
|
end
|
622
974
|
|
975
|
+
def additional_base_requirements_for_resolve
|
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) }
|
978
|
+
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
|
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)
|
983
|
+
requirements
|
984
|
+
end.values
|
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
|
623
992
|
end
|
624
993
|
end
|