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
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class ProcessLock
|
5
|
+
def self.lock(bundle_path = Bundler.bundle_path)
|
6
|
+
lock_file_path = File.join(bundle_path, "bundler.lock")
|
7
|
+
has_lock = false
|
8
|
+
|
9
|
+
File.open(lock_file_path, "w") do |f|
|
10
|
+
f.flock(File::LOCK_EX)
|
11
|
+
has_lock = true
|
12
|
+
yield
|
13
|
+
f.flock(File::LOCK_UN)
|
14
|
+
end
|
15
|
+
rescue Errno::EACCES, Errno::ENOLCK, *[SharedHelpers.const_get_safely(:ENOTSUP, Errno)].compact
|
16
|
+
# In the case the user does not have access to
|
17
|
+
# create the lock file or is using NFS where
|
18
|
+
# locks are not available we skip locking.
|
19
|
+
yield
|
20
|
+
ensure
|
21
|
+
FileUtils.rm_f(lock_file_path) if has_lock
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/bundler/psyched_yaml.rb
CHANGED
@@ -1,26 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Psych could be a gem, so try to ask for it
|
2
4
|
begin
|
3
|
-
gem
|
5
|
+
gem "psych"
|
4
6
|
rescue LoadError
|
5
7
|
end if defined?(gem)
|
6
8
|
|
7
|
-
# Psych could
|
9
|
+
# Psych could be in the stdlib
|
8
10
|
# but it's too late if Syck is already loaded
|
9
11
|
begin
|
10
|
-
require
|
12
|
+
require "psych" unless defined?(Syck)
|
11
13
|
rescue LoadError
|
12
14
|
# Apparently Psych wasn't available. Oh well.
|
13
15
|
end
|
14
16
|
|
15
17
|
# At least load the YAML stdlib, whatever that may be
|
16
|
-
require
|
18
|
+
require "yaml" unless defined?(YAML.dump)
|
17
19
|
|
18
20
|
module Bundler
|
19
21
|
# On encountering invalid YAML,
|
20
22
|
# Psych raises Psych::SyntaxError
|
21
23
|
if defined?(::Psych::SyntaxError)
|
22
|
-
|
24
|
+
YamlLibrarySyntaxError = ::Psych::SyntaxError
|
23
25
|
else # Syck raises ArgumentError
|
24
|
-
|
26
|
+
YamlLibrarySyntaxError = ::ArgumentError
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
require "bundler/deprecate"
|
31
|
+
begin
|
32
|
+
Bundler::Deprecate.skip_during do
|
33
|
+
require "rubygems/safe_yaml"
|
25
34
|
end
|
35
|
+
rescue LoadError
|
36
|
+
# it's OK if the file isn't there
|
26
37
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "uri"
|
2
|
-
require "rubygems/spec_fetcher"
|
3
4
|
|
4
5
|
module Bundler
|
5
6
|
# Represents a lazily loaded gem specification, where the full specification
|
@@ -8,15 +9,18 @@ module Bundler
|
|
8
9
|
# full specification will only be fetched when necessary.
|
9
10
|
class RemoteSpecification
|
10
11
|
include MatchPlatform
|
12
|
+
include Comparable
|
11
13
|
|
12
14
|
attr_reader :name, :version, :platform
|
13
|
-
|
15
|
+
attr_writer :dependencies
|
16
|
+
attr_accessor :source, :remote
|
14
17
|
|
15
18
|
def initialize(name, version, platform, spec_fetcher)
|
16
19
|
@name = name
|
17
|
-
@version = version
|
20
|
+
@version = Gem::Version.create version
|
18
21
|
@platform = platform
|
19
22
|
@spec_fetcher = spec_fetcher
|
23
|
+
@dependencies = nil
|
20
24
|
end
|
21
25
|
|
22
26
|
# Needed before installs, since the arch matters then and quick
|
@@ -26,32 +30,85 @@ module Bundler
|
|
26
30
|
end
|
27
31
|
|
28
32
|
def full_name
|
29
|
-
if platform == Gem::Platform::RUBY
|
33
|
+
if platform == Gem::Platform::RUBY || platform.nil?
|
30
34
|
"#{@name}-#{@version}"
|
31
35
|
else
|
32
36
|
"#{@name}-#{@version}-#{platform}"
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
40
|
+
# Compare this specification against another object. Using sort_obj
|
41
|
+
# is compatible with Gem::Specification and other Bundler or RubyGems
|
42
|
+
# objects. Otherwise, use the default Object comparison.
|
43
|
+
def <=>(other)
|
44
|
+
if other.respond_to?(:sort_obj)
|
45
|
+
sort_obj <=> other.sort_obj
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
36
51
|
# Because Rubyforge cannot be trusted to provide valid specifications
|
37
52
|
# once the remote gem is downloaded, the backend specification will
|
38
53
|
# be swapped out.
|
39
54
|
def __swap__(spec)
|
40
|
-
|
55
|
+
SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies)
|
56
|
+
@_remote_specification = spec
|
57
|
+
end
|
58
|
+
|
59
|
+
# Create a delegate used for sorting. This strategy is copied from
|
60
|
+
# RubyGems 2.23 and ensures that Bundler's specifications can be
|
61
|
+
# compared and sorted with RubyGems' own specifications.
|
62
|
+
#
|
63
|
+
# @see #<=>
|
64
|
+
# @see Gem::Specification#sort_obj
|
65
|
+
#
|
66
|
+
# @return [Array] an object you can use to compare and sort this
|
67
|
+
# specification against other specifications
|
68
|
+
def sort_obj
|
69
|
+
[@name, @version, @platform == Gem::Platform::RUBY ? -1 : 1]
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_s
|
73
|
+
"#<#{self.class} name=#{name} version=#{version} platform=#{platform}>"
|
74
|
+
end
|
75
|
+
|
76
|
+
def dependencies
|
77
|
+
@dependencies ||= begin
|
78
|
+
deps = method_missing(:dependencies)
|
79
|
+
|
80
|
+
# allow us to handle when the specs dependencies are an array of array of string
|
81
|
+
# see https://github.com/bundler/bundler/issues/5797
|
82
|
+
deps = deps.map {|d| d.is_a?(Gem::Dependency) ? d : Gem::Dependency.new(*d) }
|
83
|
+
|
84
|
+
deps
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def git_version
|
89
|
+
return unless loaded_from && source.is_a?(Bundler::Source::Git)
|
90
|
+
" #{source.revision[0..6]}"
|
41
91
|
end
|
42
92
|
|
43
93
|
private
|
44
94
|
|
95
|
+
def to_ary
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
|
45
99
|
def _remote_specification
|
46
|
-
@
|
100
|
+
@_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
|
101
|
+
@_remote_specification || raise(GemspecError, "Gemspec data for #{full_name} was" \
|
102
|
+
" missing from the server! Try installing with `--full-index` as a workaround.")
|
47
103
|
end
|
48
104
|
|
49
105
|
def method_missing(method, *args, &blk)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
106
|
+
_remote_specification.send(method, *args, &blk)
|
107
|
+
end
|
108
|
+
|
109
|
+
def respond_to?(method, include_all = false)
|
110
|
+
super || _remote_specification.respond_to?(method, include_all)
|
55
111
|
end
|
112
|
+
public :respond_to?
|
56
113
|
end
|
57
114
|
end
|
data/lib/bundler/resolver.rb
CHANGED
@@ -1,170 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# This is the latest iteration of the gem dependency resolving algorithm. As of now,
|
4
|
-
# it can resolve (as a success or failure) any set of gem dependencies we throw at it
|
5
|
-
# in a reasonable amount of time. The most iterations I've seen it take is about 150.
|
6
|
-
# The actual implementation of the algorithm is not as good as it could be yet, but that
|
7
|
-
# can come later.
|
1
|
+
# frozen_string_literal: true
|
8
2
|
|
9
3
|
module Bundler
|
10
4
|
class Resolver
|
11
|
-
|
12
|
-
require
|
13
|
-
|
14
|
-
class Molinillo::VersionConflict
|
15
|
-
def clean_req(req)
|
16
|
-
if req.to_s.include?(">= 0")
|
17
|
-
req.to_s.gsub(/ \(.*?\)$/, '')
|
18
|
-
else
|
19
|
-
req.to_s.gsub(/\, (runtime|development)\)$/, ')')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def message
|
24
|
-
conflicts.values.flatten.reduce('') do |o, conflict|
|
25
|
-
o << %(Bundler could not find compatible versions for gem "#{conflict.requirement.name}":\n)
|
26
|
-
if conflict.locked_requirement
|
27
|
-
o << %( In snapshot (Gemfile.lock):\n)
|
28
|
-
o << %( #{clean_req conflict.locked_requirement}\n)
|
29
|
-
o << %(\n)
|
30
|
-
end
|
31
|
-
o << %( In Gemfile:\n)
|
32
|
-
o << conflict.requirement_trees.map do |tree|
|
33
|
-
t = ''
|
34
|
-
depth = 2
|
35
|
-
tree.each do |req|
|
36
|
-
t << ' ' * depth << %(#{clean_req req})
|
37
|
-
t << %( depends on) unless tree[-1] == req
|
38
|
-
t << %(\n)
|
39
|
-
depth += 1
|
40
|
-
end
|
41
|
-
t
|
42
|
-
end.join("\n")
|
43
|
-
|
44
|
-
if conflict.requirement.name == 'bundler'
|
45
|
-
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
46
|
-
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
|
47
|
-
end
|
48
|
-
|
49
|
-
if conflict.requirement.name == "bundler" && other_bundler_required
|
50
|
-
o << "\n"
|
51
|
-
o << "This Gemfile requires a different version of Bundler.\n"
|
52
|
-
o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
|
53
|
-
end
|
54
|
-
if conflict.locked_requirement
|
55
|
-
o << "\n"
|
56
|
-
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
57
|
-
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
58
|
-
elsif !conflict.existing
|
59
|
-
if conflict.requirement_trees.first.size > 1
|
60
|
-
o << "Could not find gem '#{clean_req(conflict.requirement)}', which is required by "
|
61
|
-
o << "gem '#{clean_req(conflict.requirement_trees.first[-2])}', in any of the sources."
|
62
|
-
else
|
63
|
-
o << "Could not find gem '#{clean_req(conflict.requirement)} in any of the sources\n"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
o
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
ALL = Bundler::Dependency::PLATFORM_MAP.values.uniq.freeze
|
72
|
-
|
73
|
-
class SpecGroup < Array
|
74
|
-
include GemHelpers
|
75
|
-
|
76
|
-
attr_reader :activated, :required_by
|
77
|
-
|
78
|
-
def initialize(a)
|
79
|
-
super
|
80
|
-
@required_by = []
|
81
|
-
@activated = []
|
82
|
-
@dependencies = nil
|
83
|
-
@specs = {}
|
84
|
-
|
85
|
-
ALL.each do |p|
|
86
|
-
@specs[p] = reverse.find { |s| s.match_platform(p) }
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def initialize_copy(o)
|
91
|
-
super
|
92
|
-
@required_by = o.required_by.dup
|
93
|
-
@activated = o.activated.dup
|
94
|
-
end
|
95
|
-
|
96
|
-
def to_specs
|
97
|
-
specs = {}
|
98
|
-
|
99
|
-
@activated.each do |p|
|
100
|
-
if s = @specs[p]
|
101
|
-
platform = generic(Gem::Platform.new(s.platform))
|
102
|
-
next if specs[platform]
|
103
|
-
|
104
|
-
lazy_spec = LazySpecification.new(name, version, platform, source)
|
105
|
-
lazy_spec.dependencies.replace s.dependencies
|
106
|
-
specs[platform] = lazy_spec
|
107
|
-
end
|
108
|
-
end
|
109
|
-
specs.values
|
110
|
-
end
|
111
|
-
|
112
|
-
def activate_platform(platform)
|
113
|
-
unless @activated.include?(platform)
|
114
|
-
if for?(platform)
|
115
|
-
@activated << platform
|
116
|
-
return __dependencies[platform] || []
|
117
|
-
end
|
118
|
-
end
|
119
|
-
[]
|
120
|
-
end
|
121
|
-
|
122
|
-
def name
|
123
|
-
@name ||= first.name
|
124
|
-
end
|
125
|
-
|
126
|
-
def version
|
127
|
-
@version ||= first.version
|
128
|
-
end
|
129
|
-
|
130
|
-
def source
|
131
|
-
@source ||= first.source
|
132
|
-
end
|
133
|
-
|
134
|
-
def for?(platform)
|
135
|
-
@specs[platform]
|
136
|
-
end
|
137
|
-
|
138
|
-
def to_s
|
139
|
-
"#{name} (#{version})"
|
140
|
-
end
|
141
|
-
|
142
|
-
def dependencies_for_activated_platforms
|
143
|
-
@activated.map { |p| __dependencies[p] }.flatten
|
144
|
-
end
|
145
|
-
|
146
|
-
def platforms_for_dependency_named(dependency)
|
147
|
-
__dependencies.select { |p, deps| deps.map(&:name).include? dependency }.keys
|
148
|
-
end
|
149
|
-
|
150
|
-
private
|
151
|
-
|
152
|
-
def __dependencies
|
153
|
-
@dependencies ||= begin
|
154
|
-
dependencies = {}
|
155
|
-
ALL.each do |p|
|
156
|
-
if spec = @specs[p]
|
157
|
-
dependencies[p] = []
|
158
|
-
spec.dependencies.each do |dep|
|
159
|
-
next if dep.type == :development
|
160
|
-
dependencies[p] << DepProxy.new(dep, p)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
dependencies
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
5
|
+
require "bundler/vendored_molinillo"
|
6
|
+
require "bundler/resolver/spec_group"
|
168
7
|
|
169
8
|
# Figures out the best possible configuration of gems that satisfies
|
170
9
|
# the list of passed dependencies and any child dependencies without
|
@@ -176,36 +15,50 @@ module Bundler
|
|
176
15
|
# ==== Returns
|
177
16
|
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
|
178
17
|
# collection of gemspecs is returned. Otherwise, nil is returned.
|
179
|
-
def self.resolve(requirements, index, source_requirements = {}, base = [])
|
18
|
+
def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
|
19
|
+
platforms = Set.new(platforms) if platforms
|
180
20
|
base = SpecSet.new(base) unless base.is_a?(SpecSet)
|
181
|
-
resolver = new(index, source_requirements, base)
|
21
|
+
resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
182
22
|
result = resolver.start(requirements)
|
183
23
|
SpecSet.new(result)
|
184
24
|
end
|
185
25
|
|
186
|
-
|
187
|
-
def initialize(index, source_requirements, base)
|
26
|
+
def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
188
27
|
@index = index
|
189
28
|
@source_requirements = source_requirements
|
190
29
|
@base = base
|
191
30
|
@resolver = Molinillo::Resolver.new(self, self)
|
192
31
|
@search_for = {}
|
193
|
-
@prereleases_cache = Hash.new { |h,k| h[k] = k.prerelease? }
|
194
32
|
@base_dg = Molinillo::DependencyGraph.new
|
195
|
-
@base.each
|
33
|
+
@base.each do |ls|
|
34
|
+
dep = Dependency.new(ls.name, ls.version)
|
35
|
+
@base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true)
|
36
|
+
end
|
37
|
+
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
|
38
|
+
@platforms = platforms
|
39
|
+
@gem_version_promoter = gem_version_promoter
|
40
|
+
@allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
|
41
|
+
@lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
42
|
+
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
|
196
43
|
end
|
197
44
|
|
198
45
|
def start(requirements)
|
46
|
+
@gem_version_promoter.prerelease_specified = @prerelease_specified = {}
|
47
|
+
requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
|
48
|
+
|
199
49
|
verify_gemfile_dependencies_are_found!(requirements)
|
200
50
|
dg = @resolver.resolve(requirements, @base_dg)
|
201
|
-
dg.map(&:payload).
|
51
|
+
dg.map(&:payload).
|
52
|
+
reject {|sg| sg.name.end_with?("\0") }.
|
53
|
+
map(&:to_specs).flatten
|
202
54
|
rescue Molinillo::VersionConflict => e
|
203
|
-
|
55
|
+
message = version_conflict_message(e)
|
56
|
+
raise VersionConflict.new(e.conflicts.keys.uniq, message)
|
204
57
|
rescue Molinillo::CircularDependencyError => e
|
205
|
-
names = e.dependencies.sort_by(&:name).map {
|
206
|
-
raise CyclicDependencyError, "Your
|
58
|
+
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
|
59
|
+
raise CyclicDependencyError, "Your bundle requires gems that depend" \
|
207
60
|
" on each other, creating an infinite loop. Please remove" \
|
208
|
-
" #{names.count > 1 ?
|
61
|
+
" #{names.count > 1 ? "either " : ""}#{names.join(" or ")}" \
|
209
62
|
" and try again."
|
210
63
|
end
|
211
64
|
|
@@ -216,31 +69,29 @@ module Bundler
|
|
216
69
|
# @param [Integer] depth the current depth of the resolution process.
|
217
70
|
# @return [void]
|
218
71
|
def debug(depth = 0)
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
end
|
72
|
+
return unless debug?
|
73
|
+
debug_info = yield
|
74
|
+
debug_info = debug_info.inspect unless debug_info.is_a?(String)
|
75
|
+
STDERR.puts debug_info.split("\n").map {|s| " " * depth + s }
|
224
76
|
end
|
225
77
|
|
226
78
|
def debug?
|
227
|
-
|
79
|
+
return @debug_mode if defined?(@debug_mode)
|
80
|
+
@debug_mode = ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"] || false
|
228
81
|
end
|
229
82
|
|
230
83
|
def before_resolution
|
231
|
-
Bundler.ui.info
|
84
|
+
Bundler.ui.info "Resolving dependencies...", debug?
|
232
85
|
end
|
233
86
|
|
234
87
|
def after_resolution
|
235
|
-
Bundler.ui.info
|
88
|
+
Bundler.ui.info ""
|
236
89
|
end
|
237
90
|
|
238
91
|
def indicate_progress
|
239
|
-
Bundler.ui.info
|
92
|
+
Bundler.ui.info ".", false unless debug?
|
240
93
|
end
|
241
94
|
|
242
|
-
private
|
243
|
-
|
244
95
|
include Molinillo::SpecificationProvider
|
245
96
|
|
246
97
|
def dependencies_for(specification)
|
@@ -251,28 +102,65 @@ module Bundler
|
|
251
102
|
platform = dependency.__platform
|
252
103
|
dependency = dependency.dep unless dependency.is_a? Gem::Dependency
|
253
104
|
search = @search_for[dependency] ||= begin
|
254
|
-
index =
|
105
|
+
index = index_for(dependency)
|
255
106
|
results = index.search(dependency, @base[dependency.name])
|
107
|
+
|
256
108
|
if vertex = @base_dg.vertex_named(dependency.name)
|
257
109
|
locked_requirement = vertex.payload.requirement
|
258
110
|
end
|
259
|
-
|
260
|
-
|
261
|
-
|
111
|
+
|
112
|
+
if !@prerelease_specified[dependency.name] && (!@use_gvp || locked_requirement.nil?)
|
113
|
+
# Move prereleases to the beginning of the list, so they're considered
|
114
|
+
# last during resolution.
|
115
|
+
pre, results = results.partition {|spec| spec.version.prerelease? }
|
116
|
+
results = pre + results
|
117
|
+
end
|
118
|
+
|
119
|
+
spec_groups = if results.any?
|
120
|
+
nested = []
|
262
121
|
results.each do |spec|
|
263
|
-
|
264
|
-
|
265
|
-
|
122
|
+
version, specs = nested.last
|
123
|
+
if version == spec.version
|
124
|
+
specs << spec
|
125
|
+
else
|
126
|
+
nested << [spec.version, [spec]]
|
266
127
|
end
|
267
|
-
nested.last << spec
|
268
128
|
end
|
269
|
-
|
270
|
-
|
129
|
+
nested.reduce([]) do |groups, (version, specs)|
|
130
|
+
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
|
131
|
+
spec_group = SpecGroup.new(specs)
|
132
|
+
spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
|
133
|
+
groups << spec_group
|
134
|
+
end
|
271
135
|
else
|
272
136
|
[]
|
273
137
|
end
|
138
|
+
# GVP handles major itself, but it's still a bit risky to trust it with it
|
139
|
+
# until we get it settled with new behavior. For 2.x it can take over all cases.
|
140
|
+
if !@use_gvp
|
141
|
+
spec_groups
|
142
|
+
else
|
143
|
+
@gem_version_promoter.sort_versions(dependency, spec_groups)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) }
|
147
|
+
end
|
148
|
+
|
149
|
+
def index_for(dependency)
|
150
|
+
source = @source_requirements[dependency.name]
|
151
|
+
if source
|
152
|
+
source.specs
|
153
|
+
elsif @lockfile_uses_separate_rubygems_sources
|
154
|
+
Index.build do |idx|
|
155
|
+
if dependency.all_sources
|
156
|
+
dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
|
157
|
+
else
|
158
|
+
idx.add_source @source_requirements[:default].specs
|
159
|
+
end
|
160
|
+
end
|
161
|
+
else
|
162
|
+
@index
|
274
163
|
end
|
275
|
-
search.select { |sg| sg.for?(platform) }.each { |sg| sg.activate_platform(platform) }
|
276
164
|
end
|
277
165
|
|
278
166
|
def name_for(dependency)
|
@@ -280,60 +168,206 @@ module Bundler
|
|
280
168
|
end
|
281
169
|
|
282
170
|
def name_for_explicit_dependency_source
|
283
|
-
|
171
|
+
Bundler.default_gemfile.basename.to_s
|
172
|
+
rescue
|
173
|
+
"Gemfile"
|
284
174
|
end
|
285
175
|
|
286
176
|
def name_for_locking_dependency_source
|
287
|
-
|
177
|
+
Bundler.default_lockfile.basename.to_s
|
178
|
+
rescue
|
179
|
+
"Gemfile.lock"
|
288
180
|
end
|
289
181
|
|
290
182
|
def requirement_satisfied_by?(requirement, activated, spec)
|
291
|
-
requirement.matches_spec?(spec)
|
183
|
+
return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
184
|
+
spec.activate_platform!(requirement.__platform) if !@platforms || @platforms.include?(requirement.__platform)
|
185
|
+
true
|
186
|
+
end
|
187
|
+
|
188
|
+
def relevant_sources_for_vertex(vertex)
|
189
|
+
if vertex.root?
|
190
|
+
[@source_requirements[vertex.name]]
|
191
|
+
elsif @lockfile_uses_separate_rubygems_sources
|
192
|
+
vertex.recursive_predecessors.map do |v|
|
193
|
+
@source_requirements[v.name]
|
194
|
+
end << @source_requirements[:default]
|
195
|
+
end
|
292
196
|
end
|
293
197
|
|
294
198
|
def sort_dependencies(dependencies, activated, conflicts)
|
295
199
|
dependencies.sort_by do |dependency|
|
200
|
+
dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
|
296
201
|
name = name_for(dependency)
|
202
|
+
vertex = activated.vertex_named(name)
|
297
203
|
[
|
298
|
-
|
299
|
-
|
204
|
+
@base_dg.vertex_named(name) ? 0 : 1,
|
205
|
+
vertex.payload ? 0 : 1,
|
206
|
+
vertex.root? ? 0 : 1,
|
207
|
+
amount_constrained(dependency),
|
300
208
|
conflicts[name] ? 0 : 1,
|
301
|
-
|
209
|
+
vertex.payload ? 0 : search_for(dependency).count,
|
210
|
+
self.class.platform_sort_key(dependency.__platform),
|
302
211
|
]
|
303
212
|
end
|
304
213
|
end
|
305
214
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
215
|
+
# Sort platforms from most general to most specific
|
216
|
+
def self.sort_platforms(platforms)
|
217
|
+
platforms.sort_by do |platform|
|
218
|
+
platform_sort_key(platform)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def self.platform_sort_key(platform)
|
223
|
+
return ["", "", ""] if Gem::Platform::RUBY == platform
|
224
|
+
platform.to_a.map {|part| part || "" }
|
225
|
+
end
|
226
|
+
|
227
|
+
private
|
228
|
+
|
229
|
+
# returns an integer \in (-\infty, 0]
|
230
|
+
# a number closer to 0 means the dependency is less constraining
|
231
|
+
#
|
232
|
+
# dependencies w/ 0 or 1 possibilities (ignoring version requirements)
|
233
|
+
# are given very negative values, so they _always_ sort first,
|
234
|
+
# before dependencies that are unconstrained
|
235
|
+
def amount_constrained(dependency)
|
236
|
+
@amount_constrained ||= {}
|
237
|
+
@amount_constrained[dependency.name] ||= begin
|
238
|
+
if (base = @base[dependency.name]) && !base.empty?
|
239
|
+
dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
|
240
|
+
else
|
241
|
+
all = index_for(dependency).search(dependency.name).size
|
242
|
+
|
243
|
+
if all <= 1
|
244
|
+
all - 1_000_000
|
325
245
|
else
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
else
|
330
|
-
message << "in the gems available on this machine."
|
331
|
-
end
|
246
|
+
search = search_for(dependency)
|
247
|
+
search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
|
248
|
+
search - all
|
332
249
|
end
|
333
|
-
raise GemNotFound, message
|
334
250
|
end
|
335
251
|
end
|
336
252
|
end
|
337
253
|
|
254
|
+
def verify_gemfile_dependencies_are_found!(requirements)
|
255
|
+
requirements.each do |requirement|
|
256
|
+
name = requirement.name
|
257
|
+
next if name == "bundler"
|
258
|
+
next unless search_for(requirement).empty?
|
259
|
+
|
260
|
+
cache_message = begin
|
261
|
+
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
262
|
+
rescue GemfileNotFound
|
263
|
+
nil
|
264
|
+
end
|
265
|
+
|
266
|
+
if (base = @base[name]) && !base.empty?
|
267
|
+
version = base.first.version
|
268
|
+
message = "You have requested:\n" \
|
269
|
+
" #{name} #{requirement.requirement}\n\n" \
|
270
|
+
"The bundle currently has #{name} locked at #{version}.\n" \
|
271
|
+
"Try running `bundle update #{name}`\n\n" \
|
272
|
+
"If you are updating multiple gems in your Gemfile at once,\n" \
|
273
|
+
"try passing them all to `bundle update`"
|
274
|
+
elsif source = @source_requirements[name]
|
275
|
+
specs = source.specs[name]
|
276
|
+
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
|
277
|
+
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
|
278
|
+
message << if versions_with_platforms.any?
|
279
|
+
"The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
|
280
|
+
else
|
281
|
+
"The source does not contain any versions of '#{name}'"
|
282
|
+
end
|
283
|
+
else
|
284
|
+
message = "Could not find gem '#{requirement}' in any of the gem sources " \
|
285
|
+
"listed in your Gemfile#{cache_message}."
|
286
|
+
end
|
287
|
+
raise GemNotFound, message
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def formatted_versions_with_platforms(versions_with_platforms)
|
292
|
+
version_platform_strs = versions_with_platforms.map do |vwp|
|
293
|
+
version = vwp.first
|
294
|
+
platform = vwp.last
|
295
|
+
version_platform_str = String.new(version.to_s)
|
296
|
+
version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
|
297
|
+
version_platform_str
|
298
|
+
end
|
299
|
+
version_platform_strs.join(", ")
|
300
|
+
end
|
301
|
+
|
302
|
+
def version_conflict_message(e)
|
303
|
+
e.message_with_trees(
|
304
|
+
:solver_name => "Bundler",
|
305
|
+
:possibility_type => "gem",
|
306
|
+
:reduce_trees => lambda do |trees|
|
307
|
+
# called first, because we want to reduce the amount of work required to find maximal empty sets
|
308
|
+
trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
|
309
|
+
|
310
|
+
# bail out if tree size is too big for Array#combination to make any sense
|
311
|
+
return trees if trees.size > 15
|
312
|
+
maximal = 1.upto(trees.size).map do |size|
|
313
|
+
trees.map(&:last).flatten(1).combination(size).to_a
|
314
|
+
end.flatten(1).select do |deps|
|
315
|
+
Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
316
|
+
end.min_by(&:size)
|
317
|
+
trees.reject! {|t| !maximal.include?(t.last) } if maximal
|
318
|
+
|
319
|
+
trees = trees.sort_by {|t| t.flatten.map(&:to_s) }
|
320
|
+
trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
|
321
|
+
|
322
|
+
trees.sort_by {|t| t.reverse.map(&:name) }
|
323
|
+
end,
|
324
|
+
:printable_requirement => lambda {|req| SharedHelpers.pretty_dependency(req) },
|
325
|
+
:additional_message_for_conflict => lambda do |o, name, conflict|
|
326
|
+
if name == "bundler"
|
327
|
+
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
328
|
+
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
|
329
|
+
end
|
330
|
+
|
331
|
+
if name == "bundler" && other_bundler_required
|
332
|
+
o << "\n"
|
333
|
+
o << "This Gemfile requires a different version of Bundler.\n"
|
334
|
+
o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
|
335
|
+
end
|
336
|
+
if conflict.locked_requirement
|
337
|
+
o << "\n"
|
338
|
+
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
339
|
+
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
340
|
+
elsif !conflict.existing
|
341
|
+
o << "\n"
|
342
|
+
|
343
|
+
relevant_sources = if conflict.requirement.source
|
344
|
+
[conflict.requirement.source]
|
345
|
+
elsif conflict.requirement.all_sources
|
346
|
+
conflict.requirement.all_sources
|
347
|
+
elsif @lockfile_uses_separate_rubygems_sources
|
348
|
+
# every conflict should have an explicit group of sources when we
|
349
|
+
# enforce strict pinning
|
350
|
+
raise "no source set for #{conflict}"
|
351
|
+
else
|
352
|
+
[]
|
353
|
+
end.compact.map(&:to_s).uniq.sort
|
354
|
+
|
355
|
+
o << "Could not find gem '#{SharedHelpers.pretty_dependency(conflict.requirement)}'"
|
356
|
+
if conflict.requirement_trees.first.size > 1
|
357
|
+
o << ", which is required by "
|
358
|
+
o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
|
359
|
+
end
|
360
|
+
o << " "
|
361
|
+
|
362
|
+
o << if relevant_sources.empty?
|
363
|
+
"in any of the sources.\n"
|
364
|
+
else
|
365
|
+
"in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end,
|
369
|
+
:version_for_spec => lambda {|spec| spec.version }
|
370
|
+
)
|
371
|
+
end
|
338
372
|
end
|
339
373
|
end
|