summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Bundler Bot <bot@bundler.io>2017-06-23 00:26:33 +0000
committerThe Bundler Bot <bot@bundler.io>2017-06-23 00:26:33 +0000
commit7a76c3555af9fb7f56327397ae2876bd684a95f0 (patch)
treed57e02cb9357a2e6e9e63fac8f131cfac5109941
parent67ff76af19e6d033d26e63ff2f064754316fee38 (diff)
parentc35495cd1738b9c867cde5198319deacb52df555 (diff)
downloadbundler-7a76c3555af9fb7f56327397ae2876bd684a95f0.tar.gz
Auto merge of #5788 - bundler:seg-allow-bundler-dep-conflicts, r=indirect
[2.0] Allow conflicts between bundler dependencies and the current bundler version ### What was the end-user problem that led to this PR? The problem will occur once 2.0 is released -- there are many gems that declare a `s.dependency "bundler", "~> 1.x"` dependency on bundler. This would essentially make them inoperable with Bundler 2. We want to make adopting 2.0 as pain-free as possible, so hard conflicts are a no-go. ### Was was your diagnosis of the problem? My diagnosis was that we need a way to allow conflicts on the bundler dependency once 2.0 comes out, so people can use 2.0. ### What is your fix for the problem, implemented in this PR? My fix introduces a feature flag for allowing these conflicts (enabled on 2.0), which when enabled will ignore bundler dependencies during resolution, and warn in the installer when a conflict would've occurred. ### Why did you choose this fix out of the possible options? I chose this fix because it has the minimal performance penalty with the feature flag enabled. This is mostly a port of https://github.com/bundler/bundler/pull/3871 to master.
-rw-r--r--lib/bundler/definition.rb5
-rw-r--r--lib/bundler/feature_flag.rb1
-rw-r--r--lib/bundler/installer.rb17
-rw-r--r--lib/bundler/resolver.rb14
-rw-r--r--lib/bundler/settings.rb1
-rw-r--r--lib/bundler/shared_helpers.rb11
-rw-r--r--man/bundle-config.ronn3
-rw-r--r--spec/install/bundler_spec.rb22
8 files changed, 64 insertions, 10 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 0e39cf710c..7157c46b98 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -567,10 +567,7 @@ module Bundler
end
def pretty_dep(dep, source = false)
- msg = String.new(dep.name)
- msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
- msg << " from the `#{dep.source}` source" if source && dep.source
- msg
+ SharedHelpers.pretty_dependency(dep, source)
end
# Check if the specs of the given source changed
diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb
index b07ea49679..0a3b010d1a 100644
--- a/lib/bundler/feature_flag.rb
+++ b/lib/bundler/feature_flag.rb
@@ -14,6 +14,7 @@ module Bundler
(1..10).each {|v| define_method("bundler_#{v}_mode?") { major_version >= v } }
+ settings_flag(:allow_bundler_dependency_conflicts) { bundler_2_mode? }
settings_flag(:allow_offline_install) { bundler_2_mode? }
settings_flag(:error_on_stderr) { bundler_2_mode? }
settings_flag(:init_gems_rb) { bundler_2_mode? }
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index 7c13c0c8a9..c47012973b 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -80,6 +80,7 @@ module Bundler
resolve_if_needed(options)
ensure_specs_are_compatible!
+ warn_on_incompatible_bundler_deps
install(options)
lock unless Bundler.settings[:frozen]
@@ -202,6 +203,22 @@ module Bundler
end
end
+ def warn_on_incompatible_bundler_deps
+ bundler_version = Gem::Version.create(Bundler::VERSION)
+ @definition.specs.each do |spec|
+ spec.dependencies.each do |dep|
+ next if dep.type == :development
+ next unless dep.name == "bundler".freeze
+ next if dep.requirement.satisfied_by?(bundler_version)
+
+ Bundler.ui.warn "#{spec.name} (#{spec.version}) has dependency" \
+ " #{SharedHelpers.pretty_dependency(dep)}" \
+ ", which is unsatisfied by the current bundler version #{VERSION}" \
+ ", so the dependency is being ignored"
+ end
+ end
+ end
+
def can_install_in_parallel?
if Bundler.rubygems.provides?(">= 2.1.0")
true
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index db2ae496a4..93c9d669c4 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -5,11 +5,7 @@ module Bundler
class Molinillo::VersionConflict
def printable_dep(dep)
- if dep.is_a?(Bundler::Dependency)
- DepProxy.new(dep, dep.platforms.join(", ")).to_s.strip
- else
- dep.to_s
- end
+ SharedHelpers.pretty_dependency(dep)
end
def message
@@ -79,6 +75,7 @@ module Bundler
include GemHelpers
attr_reader :activated
+ attr_accessor :ignores_bundler_dependencies
def initialize(a)
super
@@ -88,6 +85,7 @@ module Bundler
@specs = Hash.new do |specs, platform|
specs[platform] = select_best_platform_match(self, platform)
end
+ @ignores_bundler_dependencies = true
end
def initialize_copy(o)
@@ -151,6 +149,7 @@ module Bundler
if spec = @specs[platform]
spec.dependencies.each do |dep|
next if dep.type == :development
+ next if @ignores_bundler_dependencies && dep.name == "bundler".freeze
dependencies[platform] << DepProxy.new(dep, platform)
end
end
@@ -206,6 +205,7 @@ module Bundler
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
@platforms = platforms
@gem_version_promoter = gem_version_promoter
+ @allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
end
def start(requirements)
@@ -281,7 +281,9 @@ module Bundler
end
nested.reduce([]) do |groups, (version, specs)|
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
- groups << SpecGroup.new(specs)
+ spec_group = SpecGroup.new(specs)
+ spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
+ groups << spec_group
end
else
[]
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index e0eb660a8a..77f01774a2 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -7,6 +7,7 @@ module Bundler
autoload :Mirrors, "bundler/mirror"
BOOL_KEYS = %w[
+ allow_bundler_dependency_conflicts
allow_offline_install
auto_install
cache_all
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb
index 39f0423f7f..07880387f0 100644
--- a/lib/bundler/shared_helpers.rb
+++ b/lib/bundler/shared_helpers.rb
@@ -176,6 +176,17 @@ module Bundler
"\nEither installing with `--full-index` or running `bundle update #{spec.name}` should fix the problem."
end
+ def pretty_dependency(dep, print_source = false)
+ msg = String.new(dep.name)
+ msg << " (#{dep.requirement})" unless dep.requirement == Gem::Requirement.default
+ if dep.is_a?(Bundler::Dependency)
+ platform_string = dep.platforms.join(", ")
+ msg << " " << platform_string if !platform_string.empty? && platform_string != Gem::Platform::RUBY
+ end
+ msg << " from the `#{dep.source}` source" if print_source && dep.source
+ msg
+ end
+
private
def find_gemfile(order_matters = false)
diff --git a/man/bundle-config.ronn b/man/bundle-config.ronn
index c8a1391d3e..9fc62edae3 100644
--- a/man/bundle-config.ronn
+++ b/man/bundle-config.ronn
@@ -234,6 +234,9 @@ learn more about their operation in [bundle install(1)][bundle-install].
* `update_requires_all_flag` (`BUNDLE_UPDATE_REQUIRES_ALL_FLAG`)
Require passing `--all` to `bundle update` when everything should be updated,
and disallow passing no options to `bundle update`.
+* `allow_bundler_dependency_conflicts` (`BUNDLE_ALLOW_BUNDLER_DEPENDENCY_CONFLICTS`):
+ Allow resolving to specifications that have dependencies on `bundler` that
+ are incompatible with the running Bundler version.
In general, you should set these settings per-application by using the applicable
flag to the [bundle install(1)][bundle-install] or [bundle package(1)][bundle-package] command.
diff --git a/spec/install/bundler_spec.rb b/spec/install/bundler_spec.rb
index 5035937ea1..ca17d19abd 100644
--- a/spec/install/bundler_spec.rb
+++ b/spec/install/bundler_spec.rb
@@ -142,5 +142,27 @@ RSpec.describe "bundle install" do
bundle "check"
expect(out).to include("The Gemfile's dependencies are satisfied")
end
+
+ context "with allow_bundler_dependency_conflicts set" do
+ before { bundle! "config allow_bundler_dependency_conflicts true" }
+
+ it "are forced to the current bundler version with warnings when no compatible version is found" do
+ build_repo4 do
+ build_gem "requires_nonexistant_bundler" do |s|
+ s.add_runtime_dependency "bundler", "99.99.99.99"
+ end
+ end
+
+ install_gemfile! <<-G
+ source "file://#{gem_repo4}"
+ gem "requires_nonexistant_bundler"
+ G
+
+ expect(out).to include "requires_nonexistant_bundler (1.0) has dependency bundler (= 99.99.99.99), " \
+ "which is unsatisfied by the current bundler version #{Bundler::VERSION}, so the dependency is being ignored"
+
+ expect(the_bundle).to include_gems "bundler #{Bundler::VERSION}", "requires_nonexistant_bundler 1.0"
+ end
+ end
end
end