Dependency resolution does not choose best-fit #1093

Closed
dlvenable opened this Issue Jun 3, 2013 · 16 comments

Projects

None yet

4 participants

@dlvenable
Contributor

We have a project that depends on RESTKit 0.20.1 and WTURLImageView 1.0.0 (among many other pods).

On two different machines, running pod install --no-integrate on CocoaPods 0.20.2 returns different results. On machine A, the logs indicate that RESTKit's dependencies are resolved before WTURLImageView. On machine B, the logs indicate that WTURLImageView's dependencies are resolved before RESTKit.

On machine A, CocoaPods will install successfully using AFNetworking 1.2.1, which is determined by RESTKit (which was resolved first).

On machine B, CocoaPods will fail with the error:
RestKit/Network (0.20.1) tries to activateAFNetworking (~> 1.2.0)', but already activated version 1.3.0' by WTURLImageView (1.0.0).

For convenience, RestKit 0.20.1 has the following dependency:
'AFNetworking', '~> 1.2.0'
WTURLImageView 1.0.0 has the following dependency:
'AFNetworking', '~>1.0'

It appears that CocoaPods resolves AFNetworking on machine B according to WTURLImageView, which will permit getting the latest minor version (1.3.0). It does not pay any attention to RESTKit until it fails.

To me, it seems that CocoaPods should attempt to get a best-fit of all its dependencies. It can both respect RestKit's request for a 1.2.x version and WTURLImageView's request for a 1.x version.

@fabiopelosin
Member

The main issue of this ticket is described in #978.

The ordering issue instead is considered a bug. Are those machines running the CocoaPods with the same Ruby version? Could you provide a reduced test case or further information to isolate the cause of this behavior?

@dlvenable
Contributor

Thanks for pointing me to #978.

Both are Mac machines with the same version of Ruby.
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]
I'm not sure how to make an isolated test, but I will take a look.

@dlvenable
Contributor

After taking another look, I see that on both machines, the order of top-level dependencies matches that of the Podfile. Both RestKit and AFNetworking are dependencies of a common dependency (one of our own pods). The order of dependencies for that common dependency are different on both machines.

myapp
  - mymodule
    -- RestKit
         --- AFNetworking
    -- WTURLImageView
         --- AFNetworking

I also noticed a different dependency which had different sub-dependency orders.

@fabiopelosin
Member

Bingo! Thanks for the great investigative work. The Specification class is storing dependencies in a hash (which is unsorted in Ruby 1.8.7), hence the random order. As the order of the dependencies of a Specification should not be relevant for the Podfile (where the order is relevant until #978 is implemented) I plan just to sort them in the resolver.

/c @alloy

@alloy
Member
alloy commented Jun 4, 2013

The problem with that is that you can no longer influence the resolve order, no?

Maybe we should just use ActiveSupport's OrderedHash, as we already depend on AS?

On 4 jun. 2013, at 02:08, Fabio Pelosin notifications@github.com wrote:

Bingo! Thanks for the great investigative work. The Specification class is storing dependencies in a hash (which is unsorted in Ruby 1.8.7), hence the random order. As the order of the dependencies of a Specification should not be relevant for the Podfile (where the order is relevant until #978 is implemented) I plan just to sort them in the resolver.

/c @alloy


Reply to this email directly or view it on GitHub.

@fabiopelosin
Member

To be clear I want to sort only the dependencies of specifications, which I think shouldn't influence the resolver order.

​I plan to keep the support for respecting the order of the dependencies of the Podfile. 


Sent from my iPhone

On Tue, Jun 4, 2013 at 9:29 AM, Eloy Durán notifications@github.com
wrote:

The problem with that is that you can no longer influence the resolve order, no?
Maybe we should just use ActiveSupport's OrderedHash, as we already depend on AS?
On 4 jun. 2013, at 02:08, Fabio Pelosin notifications@github.com wrote:

Bingo! Thanks for the great investigative work. The Specification class is storing dependencies in a hash (which is unsorted in Ruby 1.8.7), hence the random order. As the order of the dependencies of a Specification should not be relevant for the Podfile (where the order is relevant until #978 is implemented) I plan just to sort them in the resolver.

/c @alloy

Reply to this email directly or view it on GitHub.

Reply to this email directly or view it on GitHub:
#1093 (comment)

@alloy
Member
alloy commented Jun 4, 2013

I’m afraid it will influence it. If there is no other reason to sort them, I would prefer to allow the user to influence the process as much as possible (until we have a automatic conflict resolver).

@fabiopelosin
Member

My point is that specs influence the resolution order in a hard to predict way. So lets say that the original issue would lead to the resolver error with sorting. In this case users can still add the dep to AFNetwirking 1.2 at the top of the Podfile.

Sent from my iPhone

On Tue, Jun 4, 2013 at 11:30 AM, Eloy Durán notifications@github.com
wrote:

I’m afraid it will influence it. If there is no other reason to sort them, I would prefer to allow the user to influence the process as much as possible (until we have a automatic conflict resolver).

Reply to this email directly or view it on GitHub:
#1093 (comment)

@alloy
Member
alloy commented Jun 4, 2013

Right, I get that, but more often than not, even Ruby 1.8.x will maintain hash order (it's just not guaranteed), so I worry that adding sorting might ‘break’ working setups for current users. As always, it’s very likely that I’m too worried, though ;)

But to be clear, are there any other reasons for sorting?

@fabiopelosin
Member

In my experience Ruby 1.8.x changes the order of the hash in a considerable amount of cases (I would have estimated it at 50%). I don't think that it will break working setups as I don't think that anybody did take in account the order of the declaration of the deps in the specs. Moreover a considerable chunk of our users (the majority?) uses 1.8.7 and so gets the undefined order and this is the first report that I hear about this issue.

The only reason is that, for my sanity :smile, I prefer to keep the output of CP deterministic and consistent, regardless of the Ruby implementation.

Anyway I consider this a gray area (this is the reason why I mentioned you).

@alloy
Member
alloy commented Jun 4, 2013

@irrationalfab Fair enough. Ok, we’ll have to do some proper testing on large projects, though :)

@dlvenable
Contributor

I like consistency, and think that would be the most helpful part.

I'm not sure what you are suggesting with resolver order. Do you mean sort by the Podspec, or sort consistently by some other mechanism (e.g. alphanumeric)?

We fixed our current issue by putting AFNetworking at the top of our app's Podfile. I think it would be useful to use the order of dependencies in the Podspec when resolving dependencies (useful until #978 is completed anyway). In this scenario, our module can order the Pods in the order which works best for the module itself. This way, any other app or module which uses the module already has the correct resolution order. They won't have to hit the same issue and solve it again.

@fabiopelosin
Member

The proposal is to sort alphanumerically. Whit this solution depending on the order of the dependencies it might be necessary to add the AFNetworking dep at the top. At least until the resolver doesn't become smart enough to figure it out by itself. 

Sent from my iPhone

On Tue, Jun 4, 2013 at 2:34 PM, David Venable notifications@github.com
wrote:

I like consistency, and think that would be the most helpful part.
I'm not sure what you are suggesting with resolver order. Do you mean sort by the Podspec, or sort consistently by some other mechanism (e.g. alphanumeric)?

We fixed our current issue by putting AFNetworking at the top of our app's Podfile. I think it would be useful to use the order of dependencies in the Podspec when resolving dependencies (useful until #978 is completed anyway). In this scenario, our module can order the Pods in the order which works best for the module itself. This way, any other app or module which uses the module already has the correct resolution order. They won't have to hit the same issue and solve it again.

Reply to this email directly or view it on GitHub:
#1093 (comment)

@zquintana

Did anyone fix this? I'm experiencing the same issue.

@alloy
Member
alloy commented Jul 30, 2013

Not yet. A patch that uses ActiveSupport’s OrderedHash would be much appreciated.

@fabiopelosin
Member

At this point I'm moving this to #978

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment