bundler 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3111 -0
- data/LICENSE.md +23 -0
- data/README.md +63 -0
- data/bundler.gemspec +65 -0
- data/exe/bundle +31 -0
- data/exe/bundle_ruby +60 -0
- data/exe/bundler +4 -0
- data/lib/bundler.rb +567 -0
- data/lib/bundler/build_metadata.rb +53 -0
- data/lib/bundler/capistrano.rb +22 -0
- data/lib/bundler/cli.rb +792 -0
- data/lib/bundler/cli/add.rb +35 -0
- data/lib/bundler/cli/binstubs.rb +49 -0
- data/lib/bundler/cli/cache.rb +36 -0
- data/lib/bundler/cli/check.rb +38 -0
- data/lib/bundler/cli/clean.rb +25 -0
- data/lib/bundler/cli/common.rb +102 -0
- data/lib/bundler/cli/config.rb +119 -0
- data/lib/bundler/cli/console.rb +43 -0
- data/lib/bundler/cli/doctor.rb +140 -0
- data/lib/bundler/cli/exec.rb +105 -0
- data/lib/bundler/cli/gem.rb +252 -0
- data/lib/bundler/cli/info.rb +50 -0
- data/lib/bundler/cli/init.rb +47 -0
- data/lib/bundler/cli/inject.rb +60 -0
- data/lib/bundler/cli/install.rb +218 -0
- 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 +26 -0
- data/lib/bundler/cli/outdated.rb +266 -0
- data/lib/bundler/cli/package.rb +49 -0
- data/lib/bundler/cli/platform.rb +46 -0
- 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 +75 -0
- data/lib/bundler/cli/update.rb +91 -0
- data/lib/bundler/cli/viz.rb +31 -0
- 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 +13 -0
- data/lib/bundler/constants.rb +7 -0
- data/lib/bundler/current_ruby.rb +94 -0
- data/lib/bundler/definition.rb +995 -0
- data/lib/bundler/dep_proxy.rb +48 -0
- data/lib/bundler/dependency.rb +139 -0
- data/lib/bundler/deployment.rb +69 -0
- data/lib/bundler/deprecate.rb +44 -0
- data/lib/bundler/dsl.rb +615 -0
- data/lib/bundler/endpoint_specification.rb +141 -0
- data/lib/bundler/env.rb +149 -0
- data/lib/bundler/environment_preserver.rb +59 -0
- data/lib/bundler/errors.rb +158 -0
- data/lib/bundler/feature_flag.rb +75 -0
- data/lib/bundler/fetcher.rb +312 -0
- 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 +131 -0
- data/lib/bundler/gem_helper.rb +217 -0
- data/lib/bundler/gem_helpers.rb +101 -0
- data/lib/bundler/gem_remote_fetcher.rb +43 -0
- data/lib/bundler/gem_tasks.rb +7 -0
- data/lib/bundler/gem_version_promoter.rb +190 -0
- data/lib/bundler/gemdeps.rb +29 -0
- data/lib/bundler/graph.rb +152 -0
- data/lib/bundler/index.rb +213 -0
- data/lib/bundler/injector.rb +253 -0
- data/lib/bundler/inline.rb +74 -0
- data/lib/bundler/installer.rb +318 -0
- data/lib/bundler/installer/gem_installer.rb +85 -0
- data/lib/bundler/installer/parallel_installer.rb +229 -0
- data/lib/bundler/installer/standalone.rb +53 -0
- data/lib/bundler/lazy_specification.rb +123 -0
- data/lib/bundler/lockfile_generator.rb +95 -0
- data/lib/bundler/lockfile_parser.rb +256 -0
- data/lib/bundler/match_platform.rb +24 -0
- data/lib/bundler/mirror.rb +223 -0
- data/lib/bundler/plugin.rb +294 -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 +165 -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 +37 -0
- data/lib/bundler/remote_specification.rb +114 -0
- data/lib/bundler/resolver.rb +373 -0
- data/lib/bundler/resolver/spec_group.rb +106 -0
- data/lib/bundler/retry.rb +66 -0
- data/lib/bundler/ruby_dsl.rb +18 -0
- data/lib/bundler/ruby_version.rb +152 -0
- data/lib/bundler/rubygems_ext.rb +209 -0
- data/lib/bundler/rubygems_gem_installer.rb +99 -0
- data/lib/bundler/rubygems_integration.rb +915 -0
- data/lib/bundler/runtime.rb +322 -0
- data/lib/bundler/settings.rb +464 -0
- data/lib/bundler/settings/validator.rb +102 -0
- data/lib/bundler/setup.rb +28 -0
- data/lib/bundler/shared_helpers.rb +386 -0
- data/lib/bundler/similarity_detector.rb +63 -0
- data/lib/bundler/source.rb +94 -0
- data/lib/bundler/source/gemspec.rb +18 -0
- data/lib/bundler/source/git.rb +329 -0
- data/lib/bundler/source/git/git_proxy.rb +262 -0
- data/lib/bundler/source/metadata.rb +62 -0
- data/lib/bundler/source/path.rb +249 -0
- data/lib/bundler/source/path/installer.rb +74 -0
- data/lib/bundler/source/rubygems.rb +539 -0
- data/lib/bundler/source/rubygems/remote.rb +69 -0
- data/lib/bundler/source_list.rb +186 -0
- data/lib/bundler/spec_set.rb +208 -0
- data/lib/bundler/ssl_certs/.document +1 -0
- data/lib/bundler/ssl_certs/certificate_manager.rb +66 -0
- data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
- data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +23 -0
- data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +25 -0
- data/lib/bundler/stub_specification.rb +108 -0
- data/lib/bundler/templates/.document +1 -0
- data/lib/bundler/templates/Executable +29 -0
- data/lib/bundler/templates/Executable.bundler +105 -0
- data/lib/bundler/templates/Executable.standalone +14 -0
- data/lib/bundler/templates/Gemfile +7 -0
- data/lib/bundler/templates/gems.rb +8 -0
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +74 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
- data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
- data/lib/bundler/templates/newgem/README.md.tt +47 -0
- data/lib/bundler/templates/newgem/Rakefile.tt +29 -0
- data/lib/bundler/templates/newgem/bin/console.tt +14 -0
- data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
- data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
- data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +3 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
- data/lib/bundler/templates/newgem/gitignore.tt +20 -0
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +13 -0
- data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +50 -0
- data/lib/bundler/templates/newgem/rspec.tt +3 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +9 -0
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +14 -0
- data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +11 -0
- data/lib/bundler/templates/newgem/test/test_helper.rb.tt +8 -0
- data/lib/bundler/templates/newgem/travis.yml.tt +7 -0
- data/lib/bundler/ui.rb +9 -0
- data/lib/bundler/ui/rg_proxy.rb +19 -0
- data/lib/bundler/ui/shell.rb +146 -0
- data/lib/bundler/ui/silent.rb +69 -0
- data/lib/bundler/uri_credentials_filter.rb +37 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1741 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -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/lib/molinillo/modules/specification_provider.rb +101 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +67 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +837 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +46 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +58 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +27 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1233 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +129 -0
- data/lib/bundler/vendor/thor/lib/thor.rb +509 -0
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +331 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +104 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +60 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +118 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +143 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +373 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +109 -0
- data/lib/bundler/vendor/thor/lib/thor/base.rb +678 -0
- data/lib/bundler/vendor/thor/lib/thor/command.rb +135 -0
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +97 -0
- 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/lib/thor/error.rb +114 -0
- data/lib/bundler/vendor/thor/lib/thor/group.rb +281 -0
- data/lib/bundler/vendor/thor/lib/thor/invocation.rb +177 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +37 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +70 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +175 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +146 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +226 -0
- data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +71 -0
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +324 -0
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +482 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +149 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +126 -0
- data/lib/bundler/vendor/thor/lib/thor/util.rb +268 -0
- data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
- data/lib/bundler/vendored_fileutils.rb +9 -0
- data/lib/bundler/vendored_molinillo.rb +4 -0
- data/lib/bundler/vendored_persistent.rb +52 -0
- data/lib/bundler/vendored_thor.rb +8 -0
- data/lib/bundler/version.rb +28 -0
- data/lib/bundler/version_ranges.rb +76 -0
- data/lib/bundler/vlad.rb +17 -0
- data/lib/bundler/worker.rb +106 -0
- 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 +397 -0
- 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 +152 -0
- 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 +378 -0
- 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 +72 -0
- data/man/bundle-platform.1 +61 -0
- data/man/bundle-platform.1.txt +57 -0
- data/man/bundle-platform.ronn +42 -0
- data/man/bundle-pristine.1 +34 -0
- data/man/bundle-pristine.1.txt +44 -0
- data/man/bundle-pristine.ronn +34 -0
- data/man/bundle-remove.1 +31 -0
- data/man/bundle-remove.1.txt +34 -0
- data/man/bundle-remove.ronn +23 -0
- data/man/bundle-show.1 +23 -0
- data/man/bundle-show.1.txt +27 -0
- data/man/bundle-show.ronn +21 -0
- data/man/bundle-update.1 +394 -0
- data/man/bundle-update.1.txt +391 -0
- data/man/bundle-update.ronn +350 -0
- 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 +111 -0
- data/man/gemfile.5 +689 -0
- data/man/gemfile.5.ronn +521 -0
- data/man/gemfile.5.txt +653 -0
- data/man/index.txt +25 -0
- metadata +463 -0
@@ -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
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Psych could be a gem, so try to ask for it
|
4
|
+
begin
|
5
|
+
gem "psych"
|
6
|
+
rescue LoadError
|
7
|
+
end if defined?(gem)
|
8
|
+
|
9
|
+
# Psych could be in the stdlib
|
10
|
+
# but it's too late if Syck is already loaded
|
11
|
+
begin
|
12
|
+
require "psych" unless defined?(Syck)
|
13
|
+
rescue LoadError
|
14
|
+
# Apparently Psych wasn't available. Oh well.
|
15
|
+
end
|
16
|
+
|
17
|
+
# At least load the YAML stdlib, whatever that may be
|
18
|
+
require "yaml" unless defined?(YAML.dump)
|
19
|
+
|
20
|
+
module Bundler
|
21
|
+
# On encountering invalid YAML,
|
22
|
+
# Psych raises Psych::SyntaxError
|
23
|
+
if defined?(::Psych::SyntaxError)
|
24
|
+
YamlLibrarySyntaxError = ::Psych::SyntaxError
|
25
|
+
else # Syck raises ArgumentError
|
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"
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
# it's OK if the file isn't there
|
37
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
|
5
|
+
module Bundler
|
6
|
+
# Represents a lazily loaded gem specification, where the full specification
|
7
|
+
# is on the source server in rubygems' "quick" index. The proxy object is to
|
8
|
+
# be seeded with what we're given from the source's abbreviated index - the
|
9
|
+
# full specification will only be fetched when necessary.
|
10
|
+
class RemoteSpecification
|
11
|
+
include MatchPlatform
|
12
|
+
include Comparable
|
13
|
+
|
14
|
+
attr_reader :name, :version, :platform
|
15
|
+
attr_writer :dependencies
|
16
|
+
attr_accessor :source, :remote
|
17
|
+
|
18
|
+
def initialize(name, version, platform, spec_fetcher)
|
19
|
+
@name = name
|
20
|
+
@version = Gem::Version.create version
|
21
|
+
@platform = platform
|
22
|
+
@spec_fetcher = spec_fetcher
|
23
|
+
@dependencies = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
# Needed before installs, since the arch matters then and quick
|
27
|
+
# specs don't bother to include the arch in the platform string
|
28
|
+
def fetch_platform
|
29
|
+
@platform = _remote_specification.platform
|
30
|
+
end
|
31
|
+
|
32
|
+
def full_name
|
33
|
+
if platform == Gem::Platform::RUBY || platform.nil?
|
34
|
+
"#{@name}-#{@version}"
|
35
|
+
else
|
36
|
+
"#{@name}-#{@version}-#{platform}"
|
37
|
+
end
|
38
|
+
end
|
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
|
+
|
51
|
+
# Because Rubyforge cannot be trusted to provide valid specifications
|
52
|
+
# once the remote gem is downloaded, the backend specification will
|
53
|
+
# be swapped out.
|
54
|
+
def __swap__(spec)
|
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]}"
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def to_ary
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
|
99
|
+
def _remote_specification
|
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.")
|
103
|
+
end
|
104
|
+
|
105
|
+
def method_missing(method, *args, &blk)
|
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)
|
111
|
+
end
|
112
|
+
public :respond_to?
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,373 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class Resolver
|
5
|
+
require "bundler/vendored_molinillo"
|
6
|
+
require "bundler/resolver/spec_group"
|
7
|
+
|
8
|
+
# Figures out the best possible configuration of gems that satisfies
|
9
|
+
# the list of passed dependencies and any child dependencies without
|
10
|
+
# causing any gem activation errors.
|
11
|
+
#
|
12
|
+
# ==== Parameters
|
13
|
+
# *dependencies<Gem::Dependency>:: The list of dependencies to resolve
|
14
|
+
#
|
15
|
+
# ==== Returns
|
16
|
+
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
|
17
|
+
# collection of gemspecs is returned. Otherwise, nil is returned.
|
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
|
20
|
+
base = SpecSet.new(base) unless base.is_a?(SpecSet)
|
21
|
+
resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
22
|
+
result = resolver.start(requirements)
|
23
|
+
SpecSet.new(result)
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
27
|
+
@index = index
|
28
|
+
@source_requirements = source_requirements
|
29
|
+
@base = base
|
30
|
+
@resolver = Molinillo::Resolver.new(self, self)
|
31
|
+
@search_for = {}
|
32
|
+
@base_dg = Molinillo::DependencyGraph.new
|
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?
|
43
|
+
end
|
44
|
+
|
45
|
+
def start(requirements)
|
46
|
+
@gem_version_promoter.prerelease_specified = @prerelease_specified = {}
|
47
|
+
requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
|
48
|
+
|
49
|
+
verify_gemfile_dependencies_are_found!(requirements)
|
50
|
+
dg = @resolver.resolve(requirements, @base_dg)
|
51
|
+
dg.map(&:payload).
|
52
|
+
reject {|sg| sg.name.end_with?("\0") }.
|
53
|
+
map(&:to_specs).flatten
|
54
|
+
rescue Molinillo::VersionConflict => e
|
55
|
+
message = version_conflict_message(e)
|
56
|
+
raise VersionConflict.new(e.conflicts.keys.uniq, message)
|
57
|
+
rescue Molinillo::CircularDependencyError => e
|
58
|
+
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
|
59
|
+
raise CyclicDependencyError, "Your bundle requires gems that depend" \
|
60
|
+
" on each other, creating an infinite loop. Please remove" \
|
61
|
+
" #{names.count > 1 ? "either " : ""}#{names.join(" or ")}" \
|
62
|
+
" and try again."
|
63
|
+
end
|
64
|
+
|
65
|
+
include Molinillo::UI
|
66
|
+
|
67
|
+
# Conveys debug information to the user.
|
68
|
+
#
|
69
|
+
# @param [Integer] depth the current depth of the resolution process.
|
70
|
+
# @return [void]
|
71
|
+
def debug(depth = 0)
|
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 }
|
76
|
+
end
|
77
|
+
|
78
|
+
def debug?
|
79
|
+
return @debug_mode if defined?(@debug_mode)
|
80
|
+
@debug_mode = ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"] || false
|
81
|
+
end
|
82
|
+
|
83
|
+
def before_resolution
|
84
|
+
Bundler.ui.info "Resolving dependencies...", debug?
|
85
|
+
end
|
86
|
+
|
87
|
+
def after_resolution
|
88
|
+
Bundler.ui.info ""
|
89
|
+
end
|
90
|
+
|
91
|
+
def indicate_progress
|
92
|
+
Bundler.ui.info ".", false unless debug?
|
93
|
+
end
|
94
|
+
|
95
|
+
include Molinillo::SpecificationProvider
|
96
|
+
|
97
|
+
def dependencies_for(specification)
|
98
|
+
specification.dependencies_for_activated_platforms
|
99
|
+
end
|
100
|
+
|
101
|
+
def search_for(dependency)
|
102
|
+
platform = dependency.__platform
|
103
|
+
dependency = dependency.dep unless dependency.is_a? Gem::Dependency
|
104
|
+
search = @search_for[dependency] ||= begin
|
105
|
+
index = index_for(dependency)
|
106
|
+
results = index.search(dependency, @base[dependency.name])
|
107
|
+
|
108
|
+
if vertex = @base_dg.vertex_named(dependency.name)
|
109
|
+
locked_requirement = vertex.payload.requirement
|
110
|
+
end
|
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 = []
|
121
|
+
results.each do |spec|
|
122
|
+
version, specs = nested.last
|
123
|
+
if version == spec.version
|
124
|
+
specs << spec
|
125
|
+
else
|
126
|
+
nested << [spec.version, [spec]]
|
127
|
+
end
|
128
|
+
end
|
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
|
135
|
+
else
|
136
|
+
[]
|
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
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def name_for(dependency)
|
167
|
+
dependency.name
|
168
|
+
end
|
169
|
+
|
170
|
+
def name_for_explicit_dependency_source
|
171
|
+
Bundler.default_gemfile.basename.to_s
|
172
|
+
rescue
|
173
|
+
"Gemfile"
|
174
|
+
end
|
175
|
+
|
176
|
+
def name_for_locking_dependency_source
|
177
|
+
Bundler.default_lockfile.basename.to_s
|
178
|
+
rescue
|
179
|
+
"Gemfile.lock"
|
180
|
+
end
|
181
|
+
|
182
|
+
def requirement_satisfied_by?(requirement, activated, 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
|
196
|
+
end
|
197
|
+
|
198
|
+
def sort_dependencies(dependencies, activated, conflicts)
|
199
|
+
dependencies.sort_by do |dependency|
|
200
|
+
dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
|
201
|
+
name = name_for(dependency)
|
202
|
+
vertex = activated.vertex_named(name)
|
203
|
+
[
|
204
|
+
@base_dg.vertex_named(name) ? 0 : 1,
|
205
|
+
vertex.payload ? 0 : 1,
|
206
|
+
vertex.root? ? 0 : 1,
|
207
|
+
amount_constrained(dependency),
|
208
|
+
conflicts[name] ? 0 : 1,
|
209
|
+
vertex.payload ? 0 : search_for(dependency).count,
|
210
|
+
self.class.platform_sort_key(dependency.__platform),
|
211
|
+
]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
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
|
245
|
+
else
|
246
|
+
search = search_for(dependency)
|
247
|
+
search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
|
248
|
+
search - all
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
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
|
372
|
+
end
|
373
|
+
end
|