bundler 1.15.4 → 1.16.0.pre.1
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 +43 -0
- data/README.md +12 -7
- data/exe/bundle +1 -1
- data/exe/bundle_ruby +4 -3
- data/lib/bundler.rb +47 -37
- data/lib/bundler/build_metadata.rb +38 -0
- data/lib/bundler/capistrano.rb +5 -0
- data/lib/bundler/cli.rb +155 -67
- data/lib/bundler/cli/add.rb +0 -1
- data/lib/bundler/cli/binstubs.rb +9 -7
- data/lib/bundler/cli/cache.rb +5 -4
- data/lib/bundler/cli/check.rb +3 -5
- data/lib/bundler/cli/clean.rb +5 -6
- data/lib/bundler/cli/common.rb +11 -2
- data/lib/bundler/cli/config.rb +2 -1
- data/lib/bundler/cli/console.rb +2 -1
- data/lib/bundler/cli/doctor.rb +1 -0
- data/lib/bundler/cli/exec.rb +2 -1
- data/lib/bundler/cli/gem.rb +3 -2
- data/lib/bundler/cli/info.rb +0 -1
- data/lib/bundler/cli/init.rb +17 -6
- data/lib/bundler/cli/inject.rb +1 -0
- data/lib/bundler/cli/install.rb +61 -61
- data/lib/bundler/cli/issue.rb +1 -1
- data/lib/bundler/cli/list.rb +22 -0
- data/lib/bundler/cli/lock.rb +0 -1
- data/lib/bundler/cli/open.rb +2 -2
- data/lib/bundler/cli/outdated.rb +13 -8
- data/lib/bundler/cli/package.rb +9 -6
- data/lib/bundler/cli/platform.rb +1 -0
- data/lib/bundler/cli/plugin.rb +1 -0
- data/lib/bundler/cli/pristine.rb +9 -2
- data/lib/bundler/cli/show.rb +0 -1
- data/lib/bundler/cli/update.rb +31 -5
- data/lib/bundler/cli/viz.rb +1 -0
- data/lib/bundler/compact_index_client.rb +1 -0
- data/lib/bundler/compact_index_client/cache.rb +1 -0
- data/lib/bundler/compact_index_client/updater.rb +3 -2
- data/lib/bundler/compatibility_guard.rb +14 -0
- data/lib/bundler/constants.rb +1 -0
- data/lib/bundler/current_ruby.rb +5 -4
- data/lib/bundler/definition.rb +140 -95
- data/lib/bundler/dep_proxy.rb +2 -0
- data/lib/bundler/dependency.rb +6 -7
- data/lib/bundler/deployment.rb +1 -1
- data/lib/bundler/deprecate.rb +1 -0
- data/lib/bundler/dsl.rb +97 -62
- data/lib/bundler/endpoint_specification.rb +9 -0
- data/lib/bundler/env.rb +63 -27
- data/lib/bundler/environment_preserver.rb +26 -6
- data/lib/bundler/errors.rb +1 -0
- data/lib/bundler/feature_flag.rb +39 -4
- data/lib/bundler/fetcher.rb +15 -8
- data/lib/bundler/fetcher/base.rb +1 -0
- data/lib/bundler/fetcher/compact_index.rb +2 -11
- data/lib/bundler/fetcher/dependency.rb +1 -0
- data/lib/bundler/fetcher/downloader.rb +1 -0
- data/lib/bundler/fetcher/index.rb +1 -0
- data/lib/bundler/friendly_errors.rb +2 -1
- data/lib/bundler/gem_helper.rb +14 -9
- data/lib/bundler/gem_helpers.rb +1 -0
- data/lib/bundler/gem_remote_fetcher.rb +1 -0
- data/lib/bundler/gem_tasks.rb +1 -0
- data/lib/bundler/gem_version_promoter.rb +1 -0
- data/lib/bundler/gemdeps.rb +1 -0
- data/lib/bundler/graph.rb +1 -0
- data/lib/bundler/index.rb +15 -8
- data/lib/bundler/injector.rb +25 -22
- data/lib/bundler/inline.rb +5 -7
- data/lib/bundler/installer.rb +93 -45
- data/lib/bundler/installer/gem_installer.rb +2 -0
- data/lib/bundler/installer/parallel_installer.rb +73 -42
- data/lib/bundler/installer/standalone.rb +1 -0
- data/lib/bundler/lazy_specification.rb +2 -1
- data/lib/bundler/lockfile_generator.rb +95 -0
- data/lib/bundler/lockfile_parser.rb +10 -4
- data/lib/bundler/match_platform.rb +1 -0
- data/lib/bundler/mirror.rb +6 -3
- data/lib/bundler/plugin.rb +1 -0
- data/lib/bundler/plugin/api/source.rb +8 -0
- data/lib/bundler/plugin/installer.rb +7 -6
- data/lib/bundler/plugin/source_list.rb +7 -8
- data/lib/bundler/process_lock.rb +24 -0
- data/lib/bundler/psyched_yaml.rb +1 -0
- data/lib/bundler/remote_specification.rb +1 -0
- data/lib/bundler/resolver.rb +138 -191
- data/lib/bundler/resolver/spec_group.rb +111 -0
- data/lib/bundler/retry.rb +1 -0
- data/lib/bundler/ruby_dsl.rb +1 -0
- data/lib/bundler/ruby_version.rb +1 -0
- data/lib/bundler/rubygems_ext.rb +5 -4
- data/lib/bundler/rubygems_gem_installer.rb +23 -0
- data/lib/bundler/rubygems_integration.rb +56 -27
- data/lib/bundler/runtime.rb +3 -5
- data/lib/bundler/settings.rb +177 -76
- data/lib/bundler/settings/validator.rb +79 -0
- data/lib/bundler/setup.rb +1 -0
- data/lib/bundler/shared_helpers.rb +86 -26
- data/lib/bundler/similarity_detector.rb +1 -0
- data/lib/bundler/source.rb +32 -0
- data/lib/bundler/source/gemspec.rb +1 -0
- data/lib/bundler/source/git.rb +21 -16
- data/lib/bundler/source/git/git_proxy.rb +14 -10
- data/lib/bundler/source/metadata.rb +63 -0
- data/lib/bundler/source/path.rb +8 -8
- data/lib/bundler/source/path/installer.rb +2 -0
- data/lib/bundler/source/rubygems.rb +131 -84
- data/lib/bundler/source/rubygems/remote.rb +3 -0
- data/lib/bundler/source_list.rb +75 -15
- data/lib/bundler/spec_set.rb +2 -1
- data/lib/bundler/ssl_certs/certificate_manager.rb +2 -1
- data/lib/bundler/stub_specification.rb +1 -0
- data/lib/bundler/templates/Executable +4 -0
- data/lib/bundler/templates/Executable.bundler +105 -0
- data/lib/bundler/templates/Gemfile +1 -0
- data/lib/bundler/templates/gems.rb +8 -0
- data/lib/bundler/templates/newgem/README.md.tt +1 -1
- data/lib/bundler/templates/newgem/gitignore.tt +0 -1
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +4 -1
- data/lib/bundler/templates/newgem/rspec.tt +1 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +0 -2
- data/lib/bundler/ui.rb +1 -0
- data/lib/bundler/ui/rg_proxy.rb +1 -0
- data/lib/bundler/ui/shell.rb +15 -4
- data/lib/bundler/ui/silent.rb +1 -0
- data/lib/bundler/uri_credentials_filter.rb +1 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1638 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +2 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +7 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +3 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +3 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +69 -6
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +3 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +487 -148
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +8 -4
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
- data/lib/bundler/vendored_fileutils.rb +9 -0
- data/lib/bundler/vendored_molinillo.rb +1 -0
- data/lib/bundler/vendored_persistent.rb +34 -0
- data/lib/bundler/vendored_thor.rb +1 -0
- data/lib/bundler/version.rb +6 -2
- data/lib/bundler/version_ranges.rb +1 -0
- data/lib/bundler/vlad.rb +5 -0
- data/lib/bundler/worker.rb +1 -0
- data/lib/bundler/yaml_serializer.rb +3 -3
- data/man/bundle-add.1 +43 -0
- data/man/bundle-add.1.txt +40 -0
- data/man/bundle-binstubs.1 +40 -0
- data/man/bundle-binstubs.1.txt +48 -0
- data/man/bundle-binstubs.ronn +14 -0
- data/man/bundle-check.1 +31 -0
- data/man/bundle-check.1.txt +32 -0
- data/man/bundle-clean.1 +24 -0
- data/man/bundle-clean.1.txt +26 -0
- data/man/bundle-config.1 +455 -0
- data/man/bundle-config.1.txt +491 -0
- data/man/bundle-config.ronn +133 -79
- data/man/bundle-exec.1 +165 -0
- data/man/bundle-exec.1.txt +178 -0
- data/man/bundle-exec.ronn +7 -0
- data/man/bundle-gem.1 +80 -0
- data/man/bundle-gem.1.txt +91 -0
- data/man/bundle-gem.ronn +2 -1
- data/man/bundle-info.1 +20 -0
- data/man/bundle-info.1.txt +21 -0
- data/man/bundle-init.1 +20 -0
- data/man/bundle-init.1.txt +24 -0
- data/man/bundle-inject.1 +33 -0
- data/man/bundle-inject.1.txt +32 -0
- data/man/bundle-install.1 +305 -0
- data/man/bundle-install.1.txt +385 -0
- data/man/bundle-install.ronn +32 -32
- data/man/bundle-list.1 +20 -0
- data/man/bundle-list.1.txt +21 -0
- data/man/bundle-list.ronn +15 -0
- data/man/bundle-lock.1 +84 -0
- data/man/bundle-lock.1.txt +93 -0
- data/man/bundle-open.1 +32 -0
- data/man/bundle-open.1.txt +29 -0
- data/man/bundle-outdated.1 +151 -0
- data/man/bundle-outdated.1.txt +127 -0
- data/man/bundle-outdated.ronn +1 -1
- data/man/bundle-package.1 +55 -0
- data/man/bundle-package.1.txt +79 -0
- data/man/bundle-package.ronn +5 -0
- data/man/bundle-platform.1 +61 -0
- data/man/bundle-platform.1.txt +57 -0
- data/man/bundle-pristine.1 +34 -0
- data/man/bundle-pristine.1.txt +44 -0
- data/man/bundle-pristine.ronn +24 -3
- data/man/bundle-show.1 +23 -0
- data/man/bundle-show.1.txt +25 -0
- data/man/bundle-update.1 +390 -0
- data/man/bundle-update.1.txt +386 -0
- data/man/bundle-update.ronn +2 -2
- data/man/bundle-viz.1 +39 -0
- data/man/bundle-viz.1.txt +38 -0
- data/man/bundle-viz.ronn +5 -5
- data/man/bundle.1 +132 -0
- data/man/bundle.1.txt +113 -0
- data/man/bundle.ronn +5 -2
- data/man/gemfile.5 +679 -0
- data/man/gemfile.5.ronn +31 -0
- data/man/gemfile.5.txt +636 -0
- data/man/index.txt +23 -0
- metadata +21 -36
- data/.codeclimate.yml +0 -25
- data/.gitignore +0 -18
- data/.rspec +0 -3
- data/.rubocop.yml +0 -131
- data/.rubocop_todo.yml +0 -418
- data/.travis.yml +0 -122
- data/CODE_OF_CONDUCT.md +0 -42
- data/CONTRIBUTING.md +0 -17
- data/Rakefile +0 -338
- data/bin/rake +0 -19
- data/bin/rspec +0 -15
- data/bin/rubocop +0 -17
- data/bin/with_rubygems +0 -39
- data/bundler.gemspec +0 -48
- data/doc/README.md +0 -30
- data/doc/TROUBLESHOOTING.md +0 -64
- data/doc/contributing/BUG_TRIAGE.md +0 -36
- data/doc/contributing/COMMUNITY.md +0 -13
- data/doc/contributing/GETTING_HELP.md +0 -11
- data/doc/contributing/HOW_YOU_CAN_HELP.md +0 -27
- data/doc/contributing/ISSUES.md +0 -51
- data/doc/contributing/README.md +0 -38
- data/doc/development/NEW_FEATURES.md +0 -10
- data/doc/development/PULL_REQUESTS.md +0 -40
- data/doc/development/README.md +0 -19
- data/doc/development/RELEASING.md +0 -9
- data/doc/development/SETUP.md +0 -27
- data/doc/documentation/README.md +0 -29
- data/doc/documentation/VISION.md +0 -26
- data/doc/documentation/WRITING.md +0 -54
- data/task/release.rake +0 -116
@@ -90,7 +90,7 @@ module Bundler
|
|
90
90
|
send("parse_#{@state}", line)
|
91
91
|
end
|
92
92
|
end
|
93
|
-
@sources << @rubygems_aggregate
|
93
|
+
@sources << @rubygems_aggregate unless Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
94
94
|
@specs = @specs.values.sort_by(&:identifier)
|
95
95
|
warn_for_outdated_bundler_version
|
96
96
|
rescue ArgumentError => e
|
@@ -141,10 +141,16 @@ module Bundler
|
|
141
141
|
@sources << @current_source
|
142
142
|
end
|
143
143
|
when GEM
|
144
|
-
|
145
|
-
@
|
144
|
+
if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
145
|
+
@opts["remotes"] = @opts.delete("remote")
|
146
|
+
@current_source = TYPES[@type].from_lock(@opts)
|
147
|
+
@sources << @current_source
|
148
|
+
else
|
149
|
+
Array(@opts["remote"]).each do |url|
|
150
|
+
@rubygems_aggregate.add_remote(url)
|
151
|
+
end
|
152
|
+
@current_source = @rubygems_aggregate
|
146
153
|
end
|
147
|
-
@current_source = @rubygems_aggregate
|
148
154
|
when PLUGIN
|
149
155
|
@current_source = Plugin.source_from_lock(@opts)
|
150
156
|
@sources << @current_source
|
data/lib/bundler/mirror.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "socket"
|
3
4
|
|
4
5
|
module Bundler
|
@@ -37,7 +38,7 @@ module Bundler
|
|
37
38
|
mirror = if config.all?
|
38
39
|
@all
|
39
40
|
else
|
40
|
-
|
41
|
+
@mirrors[config.uri] ||= Mirror.new
|
41
42
|
end
|
42
43
|
config.update_mirror(mirror)
|
43
44
|
end
|
@@ -45,7 +46,9 @@ module Bundler
|
|
45
46
|
private
|
46
47
|
|
47
48
|
def fetch_valid_mirror_for(uri)
|
48
|
-
|
49
|
+
downcased = uri.to_s.downcase
|
50
|
+
mirror = @mirrors[downcased] || @mirrors[URI(downcased).host] || Mirror.new(uri)
|
51
|
+
mirror.validate!(@prober)
|
49
52
|
mirror = Mirror.new(uri) unless mirror.valid?
|
50
53
|
mirror
|
51
54
|
end
|
@@ -117,7 +120,7 @@ module Bundler
|
|
117
120
|
|
118
121
|
def initialize(config_line, value)
|
119
122
|
uri, fallback =
|
120
|
-
config_line.match(%r{
|
123
|
+
config_line.match(%r{\Amirror\.(all|.+?)(\.fallback_timeout)?\/?\z}).captures
|
121
124
|
@fallback = !fallback.nil?
|
122
125
|
@all = false
|
123
126
|
if uri == "all"
|
data/lib/bundler/plugin.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "uri"
|
3
4
|
require "digest/sha1"
|
4
5
|
|
@@ -293,6 +294,13 @@ module Bundler
|
|
293
294
|
def bundler_plugin_api_source?
|
294
295
|
true
|
295
296
|
end
|
297
|
+
|
298
|
+
# @private
|
299
|
+
# This API on source might not be stable, and for now we expect plugins
|
300
|
+
# to download all specs in `#specs`, so we implement the method for
|
301
|
+
# compatibility purposes and leave it undocumented (and don't support)
|
302
|
+
# overriding it)
|
303
|
+
def double_check_for(*); end
|
296
304
|
end
|
297
305
|
end
|
298
306
|
end
|
@@ -13,12 +13,13 @@ module Bundler
|
|
13
13
|
|
14
14
|
def install(names, options)
|
15
15
|
version = options[:version] || [">= 0"]
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
Bundler.settings.temporary(:lockfile_uses_separate_rubygems_sources => false, :disable_multisource => false) do
|
17
|
+
if options[:git]
|
18
|
+
install_git(names, version, options)
|
19
|
+
else
|
20
|
+
sources = options[:source] || Bundler.rubygems.sources
|
21
|
+
install_rubygems(names, version, sources)
|
22
|
+
end
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
@@ -5,13 +5,6 @@ module Bundler
|
|
5
5
|
# approptiate options to be used with Source classes for plugin installation
|
6
6
|
module Plugin
|
7
7
|
class SourceList < Bundler::SourceList
|
8
|
-
def initialize
|
9
|
-
@path_sources = []
|
10
|
-
@git_sources = []
|
11
|
-
@rubygems_aggregate = Plugin::Installer::Rubygems.new
|
12
|
-
@rubygems_sources = []
|
13
|
-
end
|
14
|
-
|
15
8
|
def add_git_source(options = {})
|
16
9
|
add_source_to_list Plugin::Installer::Git.new(options), git_sources
|
17
10
|
end
|
@@ -21,7 +14,13 @@ module Bundler
|
|
21
14
|
end
|
22
15
|
|
23
16
|
def all_sources
|
24
|
-
path_sources + git_sources + rubygems_sources
|
17
|
+
path_sources + git_sources + rubygems_sources + [metadata_source]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def rubygems_aggregate_class
|
23
|
+
Plugin::Installer::Rubygems
|
25
24
|
end
|
26
25
|
end
|
27
26
|
end
|
@@ -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
|
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
data/lib/bundler/resolver.rb
CHANGED
@@ -1,178 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Bundler
|
3
4
|
class Resolver
|
4
5
|
require "bundler/vendored_molinillo"
|
5
|
-
|
6
|
-
class Molinillo::VersionConflict
|
7
|
-
def printable_dep(dep)
|
8
|
-
if dep.is_a?(Bundler::Dependency)
|
9
|
-
DepProxy.new(dep, dep.platforms.join(", ")).to_s.strip
|
10
|
-
else
|
11
|
-
dep.to_s
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def message
|
16
|
-
conflicts.sort.reduce(String.new) do |o, (name, conflict)|
|
17
|
-
o << %(\nBundler could not find compatible versions for gem "#{name}":\n)
|
18
|
-
if conflict.locked_requirement
|
19
|
-
o << %( In snapshot (#{Bundler.default_lockfile.basename}):\n)
|
20
|
-
o << %( #{printable_dep(conflict.locked_requirement)}\n)
|
21
|
-
o << %(\n)
|
22
|
-
end
|
23
|
-
o << %( In Gemfile:\n)
|
24
|
-
trees = conflict.requirement_trees
|
25
|
-
|
26
|
-
maximal = 1.upto(trees.size).map do |size|
|
27
|
-
trees.map(&:last).flatten(1).combination(size).to_a
|
28
|
-
end.flatten(1).select do |deps|
|
29
|
-
Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
30
|
-
end.min_by(&:size)
|
31
|
-
trees.reject! {|t| !maximal.include?(t.last) } if maximal
|
32
|
-
|
33
|
-
o << trees.sort_by {|t| t.reverse.map(&:name) }.map do |tree|
|
34
|
-
t = String.new
|
35
|
-
depth = 2
|
36
|
-
tree.each do |req|
|
37
|
-
t << " " * depth << req.to_s
|
38
|
-
unless tree.last == req
|
39
|
-
if spec = conflict.activated_by_name[req.name]
|
40
|
-
t << %( was resolved to #{spec.version}, which)
|
41
|
-
end
|
42
|
-
t << %( depends on)
|
43
|
-
end
|
44
|
-
t << %(\n)
|
45
|
-
depth += 1
|
46
|
-
end
|
47
|
-
t
|
48
|
-
end.join("\n")
|
49
|
-
|
50
|
-
if name == "bundler"
|
51
|
-
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
52
|
-
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
|
53
|
-
end
|
54
|
-
|
55
|
-
if name == "bundler" && other_bundler_required
|
56
|
-
o << "\n"
|
57
|
-
o << "This Gemfile requires a different version of Bundler.\n"
|
58
|
-
o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
|
59
|
-
end
|
60
|
-
if conflict.locked_requirement
|
61
|
-
o << "\n"
|
62
|
-
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
63
|
-
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
64
|
-
elsif !conflict.existing
|
65
|
-
o << "\n"
|
66
|
-
if conflict.requirement_trees.first.size > 1
|
67
|
-
o << "Could not find gem '#{conflict.requirement}', which is required by "
|
68
|
-
o << "gem '#{conflict.requirement_trees.first[-2]}', in any of the sources."
|
69
|
-
else
|
70
|
-
o << "Could not find gem '#{conflict.requirement}' in any of the sources\n"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
o
|
74
|
-
end.strip
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
class SpecGroup < Array
|
79
|
-
include GemHelpers
|
80
|
-
|
81
|
-
attr_reader :activated
|
82
|
-
|
83
|
-
def initialize(a)
|
84
|
-
super
|
85
|
-
@required_by = []
|
86
|
-
@activated_platforms = []
|
87
|
-
@dependencies = nil
|
88
|
-
@specs = Hash.new do |specs, platform|
|
89
|
-
specs[platform] = select_best_platform_match(self, platform)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def initialize_copy(o)
|
94
|
-
super
|
95
|
-
@activated_platforms = o.activated.dup
|
96
|
-
end
|
97
|
-
|
98
|
-
def to_specs
|
99
|
-
@activated_platforms.map do |p|
|
100
|
-
next unless s = @specs[p]
|
101
|
-
lazy_spec = LazySpecification.new(name, version, s.platform, source)
|
102
|
-
lazy_spec.dependencies.replace s.dependencies
|
103
|
-
lazy_spec
|
104
|
-
end.compact
|
105
|
-
end
|
106
|
-
|
107
|
-
def activate_platform!(platform)
|
108
|
-
return unless for?(platform)
|
109
|
-
return if @activated_platforms.include?(platform)
|
110
|
-
@activated_platforms << platform
|
111
|
-
end
|
112
|
-
|
113
|
-
def name
|
114
|
-
@name ||= first.name
|
115
|
-
end
|
116
|
-
|
117
|
-
def version
|
118
|
-
@version ||= first.version
|
119
|
-
end
|
120
|
-
|
121
|
-
def source
|
122
|
-
@source ||= first.source
|
123
|
-
end
|
124
|
-
|
125
|
-
def for?(platform)
|
126
|
-
spec = @specs[platform]
|
127
|
-
!spec.nil?
|
128
|
-
end
|
129
|
-
|
130
|
-
def to_s
|
131
|
-
"#{name} (#{version})"
|
132
|
-
end
|
133
|
-
|
134
|
-
def dependencies_for_activated_platforms
|
135
|
-
dependencies = @activated_platforms.map {|p| __dependencies[p] }
|
136
|
-
metadata_dependencies = @activated_platforms.map do |platform|
|
137
|
-
metadata_dependencies(@specs[platform], platform)
|
138
|
-
end
|
139
|
-
dependencies.concat(metadata_dependencies).flatten
|
140
|
-
end
|
141
|
-
|
142
|
-
def platforms_for_dependency_named(dependency)
|
143
|
-
__dependencies.select {|_, deps| deps.map(&:name).include? dependency }.keys
|
144
|
-
end
|
145
|
-
|
146
|
-
private
|
147
|
-
|
148
|
-
def __dependencies
|
149
|
-
@dependencies = Hash.new do |dependencies, platform|
|
150
|
-
dependencies[platform] = []
|
151
|
-
if spec = @specs[platform]
|
152
|
-
spec.dependencies.each do |dep|
|
153
|
-
next if dep.type == :development
|
154
|
-
dependencies[platform] << DepProxy.new(dep, platform)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
dependencies[platform]
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def metadata_dependencies(spec, platform)
|
162
|
-
return [] unless spec
|
163
|
-
# Only allow endpoint specifications since they won't hit the network to
|
164
|
-
# fetch the full gemspec when calling required_ruby_version
|
165
|
-
return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
|
166
|
-
dependencies = []
|
167
|
-
if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
|
168
|
-
dependencies << DepProxy.new(Gem::Dependency.new("ruby\0", spec.required_ruby_version), platform)
|
169
|
-
end
|
170
|
-
if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
|
171
|
-
dependencies << DepProxy.new(Gem::Dependency.new("rubygems\0", spec.required_rubygems_version), platform)
|
172
|
-
end
|
173
|
-
dependencies
|
174
|
-
end
|
175
|
-
end
|
6
|
+
require "bundler/resolver/spec_group"
|
176
7
|
|
177
8
|
# Figures out the best possible configuration of gems that satisfies
|
178
9
|
# the list of passed dependencies and any child dependencies without
|
@@ -206,6 +37,7 @@ module Bundler
|
|
206
37
|
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
|
207
38
|
@platforms = platforms
|
208
39
|
@gem_version_promoter = gem_version_promoter
|
40
|
+
@allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
|
209
41
|
end
|
210
42
|
|
211
43
|
def start(requirements)
|
@@ -215,7 +47,8 @@ module Bundler
|
|
215
47
|
reject {|sg| sg.name.end_with?("\0") }.
|
216
48
|
map(&:to_specs).flatten
|
217
49
|
rescue Molinillo::VersionConflict => e
|
218
|
-
|
50
|
+
message = version_conflict_message(e)
|
51
|
+
raise VersionConflict.new(e.conflicts.keys.uniq, message)
|
219
52
|
rescue Molinillo::CircularDependencyError => e
|
220
53
|
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
|
221
54
|
raise CyclicDependencyError, "Your bundle requires gems that depend" \
|
@@ -281,7 +114,9 @@ module Bundler
|
|
281
114
|
end
|
282
115
|
nested.reduce([]) do |groups, (version, specs)|
|
283
116
|
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
|
284
|
-
|
117
|
+
spec_group = SpecGroup.new(specs)
|
118
|
+
spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
|
119
|
+
groups << spec_group
|
285
120
|
end
|
286
121
|
else
|
287
122
|
[]
|
@@ -298,7 +133,22 @@ module Bundler
|
|
298
133
|
end
|
299
134
|
|
300
135
|
def index_for(dependency)
|
301
|
-
@source_requirements[dependency.name]
|
136
|
+
source = @source_requirements[dependency.name]
|
137
|
+
if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
138
|
+
Index.build do |idx|
|
139
|
+
if source
|
140
|
+
idx.add_source source.specs
|
141
|
+
elsif dependency.all_sources
|
142
|
+
dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
|
143
|
+
else
|
144
|
+
idx.add_source @source_requirements[:default].specs
|
145
|
+
end
|
146
|
+
end
|
147
|
+
elsif source
|
148
|
+
source.specs
|
149
|
+
else
|
150
|
+
@index
|
151
|
+
end
|
302
152
|
end
|
303
153
|
|
304
154
|
def name_for(dependency)
|
@@ -319,12 +169,27 @@ module Bundler
|
|
319
169
|
|
320
170
|
def requirement_satisfied_by?(requirement, activated, spec)
|
321
171
|
return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
172
|
+
if spec.version.prerelease? && !requirement.prerelease? && search_for(requirement).any? {|sg| !sg.version.prerelease? }
|
173
|
+
vertex = activated.vertex_named(spec.name)
|
174
|
+
return false if vertex.requirements.none?(&:prerelease?)
|
175
|
+
end
|
322
176
|
spec.activate_platform!(requirement.__platform) if !@platforms || @platforms.include?(requirement.__platform)
|
323
177
|
true
|
324
178
|
end
|
325
179
|
|
180
|
+
def relevant_sources_for_vertex(vertex)
|
181
|
+
if vertex.root?
|
182
|
+
[@source_requirements[vertex.name]]
|
183
|
+
elsif Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
184
|
+
vertex.recursive_predecessors.map do |v|
|
185
|
+
@source_requirements[v.name]
|
186
|
+
end << @source_requirements[:default]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
326
190
|
def sort_dependencies(dependencies, activated, conflicts)
|
327
191
|
dependencies.sort_by do |dependency|
|
192
|
+
dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
|
328
193
|
name = name_for(dependency)
|
329
194
|
[
|
330
195
|
@base_dg.vertex_named(name) ? 0 : 1,
|
@@ -332,10 +197,23 @@ module Bundler
|
|
332
197
|
amount_constrained(dependency),
|
333
198
|
conflicts[name] ? 0 : 1,
|
334
199
|
activated.vertex_named(name).payload ? 0 : search_for(dependency).count,
|
200
|
+
self.class.platform_sort_key(dependency.__platform),
|
335
201
|
]
|
336
202
|
end
|
337
203
|
end
|
338
204
|
|
205
|
+
# Sort platforms from most general to most specific
|
206
|
+
def self.sort_platforms(platforms)
|
207
|
+
platforms.sort_by do |platform|
|
208
|
+
platform_sort_key(platform)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.platform_sort_key(platform)
|
213
|
+
return ["", "", ""] if Gem::Platform::RUBY == platform
|
214
|
+
platform.to_a.map {|part| part || "" }
|
215
|
+
end
|
216
|
+
|
339
217
|
private
|
340
218
|
|
341
219
|
# returns an integer \in (-\infty, 0]
|
@@ -364,32 +242,34 @@ module Bundler
|
|
364
242
|
|
365
243
|
def verify_gemfile_dependencies_are_found!(requirements)
|
366
244
|
requirements.each do |requirement|
|
367
|
-
|
245
|
+
name = requirement.name
|
246
|
+
next if name == "bundler"
|
368
247
|
next unless search_for(requirement).empty?
|
369
|
-
|
248
|
+
|
249
|
+
cache_message = begin
|
250
|
+
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
251
|
+
rescue GemfileNotFound
|
252
|
+
nil
|
253
|
+
end
|
254
|
+
|
255
|
+
if (base = @base[name]) && !base.empty?
|
370
256
|
version = base.first.version
|
371
257
|
message = "You have requested:\n" \
|
372
|
-
" #{
|
373
|
-
"The bundle currently has #{
|
374
|
-
"Try running `bundle update #{
|
258
|
+
" #{name} #{requirement.requirement}\n\n" \
|
259
|
+
"The bundle currently has #{name} locked at #{version}.\n" \
|
260
|
+
"Try running `bundle update #{name}`\n\n" \
|
375
261
|
"If you are updating multiple gems in your Gemfile at once,\n" \
|
376
262
|
"try passing them all to `bundle update`"
|
377
|
-
elsif
|
378
|
-
|
379
|
-
specs = @source_requirements[name][name]
|
263
|
+
elsif source = @source_requirements[name]
|
264
|
+
specs = source.specs[name]
|
380
265
|
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
|
381
|
-
message = String.new("Could not find gem '#{requirement}' in #{
|
266
|
+
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
|
382
267
|
message << if versions_with_platforms.any?
|
383
|
-
"
|
268
|
+
"The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
|
384
269
|
else
|
385
|
-
"
|
270
|
+
"The source does not contain any versions of '#{name}'"
|
386
271
|
end
|
387
272
|
else
|
388
|
-
cache_message = begin
|
389
|
-
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
390
|
-
rescue GemfileNotFound
|
391
|
-
nil
|
392
|
-
end
|
393
273
|
message = "Could not find gem '#{requirement}' in any of the gem sources " \
|
394
274
|
"listed in your Gemfile#{cache_message}."
|
395
275
|
end
|
@@ -402,9 +282,76 @@ module Bundler
|
|
402
282
|
version = vwp.first
|
403
283
|
platform = vwp.last
|
404
284
|
version_platform_str = String.new(version.to_s)
|
405
|
-
version_platform_str << " #{platform}" unless platform.nil?
|
285
|
+
version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
|
286
|
+
version_platform_str
|
406
287
|
end
|
407
288
|
version_platform_strs.join(", ")
|
408
289
|
end
|
290
|
+
|
291
|
+
def version_conflict_message(e)
|
292
|
+
e.message_with_trees(
|
293
|
+
:solver_name => "Bundler",
|
294
|
+
:possibility_type => "gem",
|
295
|
+
:reduce_trees => lambda do |trees|
|
296
|
+
maximal = 1.upto(trees.size).map do |size|
|
297
|
+
trees.map(&:last).flatten(1).combination(size).to_a
|
298
|
+
end.flatten(1).select do |deps|
|
299
|
+
Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
300
|
+
end.min_by(&:size)
|
301
|
+
trees.reject! {|t| !maximal.include?(t.last) } if maximal
|
302
|
+
|
303
|
+
trees = trees.sort_by {|t| t.flatten.map(&:to_s) }
|
304
|
+
trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
|
305
|
+
|
306
|
+
trees.sort_by {|t| t.reverse.map(&:name) }
|
307
|
+
end,
|
308
|
+
:printable_requirement => lambda {|req| SharedHelpers.pretty_dependency(req) },
|
309
|
+
:additional_message_for_conflict => lambda do |o, name, conflict|
|
310
|
+
if name == "bundler"
|
311
|
+
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
312
|
+
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
|
313
|
+
end
|
314
|
+
|
315
|
+
if name == "bundler" && other_bundler_required
|
316
|
+
o << "\n"
|
317
|
+
o << "This Gemfile requires a different version of Bundler.\n"
|
318
|
+
o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
|
319
|
+
end
|
320
|
+
if conflict.locked_requirement
|
321
|
+
o << "\n"
|
322
|
+
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
323
|
+
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
324
|
+
elsif !conflict.existing
|
325
|
+
o << "\n"
|
326
|
+
|
327
|
+
relevant_sources = if conflict.requirement.source
|
328
|
+
[conflict.requirement.source]
|
329
|
+
elsif conflict.requirement.all_sources
|
330
|
+
conflict.requirement.all_sources
|
331
|
+
elsif Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
|
332
|
+
# every conflict should have an explicit group of sources when we
|
333
|
+
# enforce strict pinning
|
334
|
+
raise "no source set for #{conflict}"
|
335
|
+
else
|
336
|
+
[]
|
337
|
+
end.compact.map(&:to_s).uniq.sort
|
338
|
+
|
339
|
+
o << "Could not find gem '#{SharedHelpers.pretty_dependency(conflict.requirement)}'"
|
340
|
+
if conflict.requirement_trees.first.size > 1
|
341
|
+
o << ", which is required by "
|
342
|
+
o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
|
343
|
+
end
|
344
|
+
o << " "
|
345
|
+
|
346
|
+
o << if relevant_sources.empty?
|
347
|
+
"in any of the sources.\n"
|
348
|
+
else
|
349
|
+
"in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end,
|
353
|
+
:version_for_spec => lambda {|spec| spec.version }
|
354
|
+
)
|
355
|
+
end
|
409
356
|
end
|
410
357
|
end
|