-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Bundler 1.10.1 breaks Rails 2.3.x plugin-loading #3762
Comments
@tony-spataro-rs do you have a project I can investigate this on? |
I'm unable to reproduce outside of my closed-source project, even after duplicating Gemfile and Gemfile.lock exactly in freshly-created Rails 2.3.18 scaffold app. This indicates that something within my project might be at fault; will update as I investigate. |
Still unclear as to why this is happening only in my project, but after researching #3278 and #3279, I've made StubSpecification comparable to Gem::Specification by adding a flying-saucer instance method. I don't understand the problem domain well enough to advocate this as a viable fix -- but if the purpose of a module Bundler
class StubSpecification
def <=>(other)
p0 = name <=> other.name
p1 = version <=> other.version
p2 = platform <=> other.platform
(p0 != 0 && p0) || (p1 != 0 && p1) || (p2 != 0 && p2) || 0
end
end
end |
Can you check if this patch also fixes the issue? diff --git a/lib/bundler/stub_specification.rb b/lib/bundler/stub_specification.rb
index be73c90..1562612 100644
--- a/lib/bundler/stub_specification.rb
+++ b/lib/bundler/stub_specification.rb
@@ -14,10 +14,22 @@ module Bundler
_remote_specification.to_yaml
end
+ def respond_to_missing?(name, *args)
+ Gem::Specification.instance_methods.include?(name) || super
+ end
+
+ def method_missing(name, *args, &blk)
+ if respond_to_missing?(name)
+ stub.to_spec.send(name, *args, &blk)
+ else
+ super
+ end
+ end
+
private
def _remote_specification
stub.to_spec
end
end
-end
\ No newline at end of file
+end |
Interestingly, it does not. It seems that
|
Indulging myself in a bit of shotgun debugging ... getting rid of the metaprogramming in your patch, we seem to make some progress. diff --git a/lib/bundler/stub_specification.rb b/lib/bundler/stub_specification.rb
index be73c90..0fbde3e 100644
--- a/lib/bundler/stub_specification.rb
+++ b/lib/bundler/stub_specification.rb
@@ -14,10 +14,19 @@ module Bundler
_remote_specification.to_yaml
end
+ def <=>(other)
+ case other
+ when Gem::Specification
+ self.to_spec <=> other
+ else
+ super
+ end
+ end
+
private
def _remote_specification
stub.to_spec
end
end
-end
\ No newline at end of file
+end This results in a failure to compare StubSpecification with itself -- better than comparing two dislike classes!
It seems that neither
|
That observation about comparability led me to try the following solution, which does fix the issue in my Rails app (and is a bit cleaner than my first attempt at comparability). diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb
index c80eaa4..c2c29bd 100644
--- a/lib/bundler/remote_specification.rb
+++ b/lib/bundler/remote_specification.rb
@@ -8,6 +8,7 @@ module Bundler
# full specification will only be fetched when necessary.
class RemoteSpecification
include MatchPlatform
+ include Comparable
attr_reader :name, :version, :platform
attr_accessor :source, :remote
@@ -33,6 +34,14 @@ module Bundler
end
end
+ def <=>(other)
+ if other.respond_to?(:full_name)
+ full_name <=> other.full_name
+ else
+ super
+ end
+ end
+
# Because Rubyforge cannot be trusted to provide valid specifications
# once the remote gem is downloaded, the backend specification will
# be swapped out. |
sounds good to me 👍 |
@indirect and @segiddins, thank you both for your input. I've skimmed Note that I pursued a slightly different fix than my last proposal; I reviewed the source of Gem::Specification and realized that it was best to exactly duplicate its comparison semantics (including the use of #sort_obj). Verified that this still fixed my issue. |
The RemoteSpecification#sort_obj method was added in e5d936e (which was cherry-picked from #3767) to fix #3762, but it still fails when comparing two instances of RemoteSpecification. As #sort_obj is private, the check for other.respond_to?(:sort_obj) returns false, which means the <=> check falls back to the default (from Object) which returns nil if the objects being compared don't match. This then results in an ArgumentError when (e.g.) sorting an array containing multiple instances of RemoteSpecification. The fix is simple: make RemoteSpecification#sort_obj public.
I'm seeing a similar message on a rails 2.3 application with bundler 1.10.5:
|
My fix had an issue (comparison isn't symmetrical); see #3815 which is pending release. |
Thanks @tony-spataro-rs! |
I appreciate that this might not be a bug in Bundler per se, but it's exasperating for those of us who still maintain Rails 2 apps, so I thought I'd report it and see if there's any advice on a workaround.
It seems that Rails 2 calls
Gem::DependencyList#dependency_order
while locating gems that host a plugin. This method does not appear to be deprecated, or at least the stdlib docs for Ruby 2.1.6 don't mention it. However, it results in an exception (see backtrace below).Any advice on how to overcome this would be greatly appreciated; I'd hate to be locked into using an older Bundler version. If there's a more modern, supported way to sort specs in dependency order, then I'll be happy to monkey-patch that into my app.
The text was updated successfully, but these errors were encountered: