[Specification] `wants_head` attribute. #432

Closed
wants to merge 1 commit into
from

4 participants

@fabiopelosin
CocoaPods member
Description

An attribute that allows a podspec to declare that it wants to use the head version.

This attribute should be set to true only in the last version of a podspec. If a version of a pod wants head and a change in the interface of the library is introduced a new version should be created and the previous version should point to the last valid/compatible reference (commit) of the library.

To persevere the idempotence of pod install in a team, the Podfile.lock should keep track of the information necessary to retrieve the library from the reference of the first install.

As usual with my experimental proposals this is a proof of concept, missing tests.

Rationale

I think that the ruby approach of versioning every release is not the best balance for CocoaPods. Objective-C is a statically compiled and heavily influenced by very stable frameworks. This is usually reflected by the community by rarely releasing breaking changes in libraries.

This approach would allow us to support with ease libraries that are in maintenance mode and unversioned libraries where the head of the repo is intended as being always backwards compatible by the author. Also it would reduce the need to ask authors to change their behavior by starting tagging.

@travisbot

This pull request passes (merged 0b1a329 into 6654114).

@alloy
CocoaPods member

@irrationalfab So if I understand it correctly, this attribute indicates that instead of a tag, the HEAD version should be used instead?

While I understand the motivation, I worry about the case where incompatibilities are actually introduced. How would the user opt-out from HEAD? Another Podfile#pod option?

Also, can you explain why specifying the :head option to Podfile#pod (i.e. whitelist vs blacklist) is more cumbersome?

@fabiopelosin
CocoaPods member

So if I understand it correctly, this attribute indicates that instead of a tag, the HEAD version should be used instead?

Yes

While I understand the motivation, I worry about the case where incompatibilities are actually introduced. How would the user opt-out from HEAD? Another Podfile#pod option?

That is good issue that I was considering as well. The alternatives that I see are:

  • add a global option in the podfile like platform
  • if the version is specified opt-out from the head version like GData, 1.9.1
  • allow to specify the download options (new attribute but best solution). It would also work to point a podspec to your fork.

I think that this feature is more important that the :podspec and :git options of the podfile.

Also, can you explain why specifying the :head option to Podfile#pod (i.e. whitelist vs blacklist) is more cumbersome?

Specifying the option in to podspec is done once for everybody. The GData example is very suitable as the podspec is in maintenance mode and unversioned by choice of the author; in this case CocoaPods would do the right thing.

There are many library where newer is always better, which almost often the case for unversioned ones. Moreover, as many pods are unversioned or not up to date I always need to check if a podspec is pointing to a recent commit or if I need to use the :head option.

I think that the fact that CocoaPods doesn't serves the latest and the greatest version of a library is one of the last big missing pieces (the other one is pod update).


To be clear I think that this option should be used only when the author makes clear that it will just refine or expand a library maintaing backward compatibility. This appears to be the case for most of the pods that I have seen... It is a cultural factor of the objective-c community. There are some cases where this might be dangerous because it leads to a change of behavior like a shadow added to a custom view, but this is mitigated by the fact that you have to call pod update manually.

@fabiopelosin
CocoaPods member

SocketRocket is another example of a library that would benefit from this. It is updated constantly (4 days ago) but with the status quo the podspec returns a commit of 2 months ago and I don't really like the idea of the community versioning. It is even worse because the podspec has been created a lot earlier, I didn't specified a commit, so it would have pointed to a commit of 5 months ago.

It is important to notice that the wants_head option would kick in for dependencies as well, which otherwise would have no way of using up to date code for unversioned libraries.

@alloy
CocoaPods member

You have convinced me :)

Regarding how to opt-out, let’s just use an option like the :head option for now. I.e. :no_head.

@MonsieurDart

@irrationalfab I tried to use the new :head version tag for GData pod, but I got the following error:

No such file or directory - /Users/mathieu/Dropbox/Latmob/Projets/Moet Rose/Code - moetrose2013/Rose 2013/Pods/GData/COPYING.txt

After some investigation, it seems that CocoaPods does not check out the …/svn/trunk of the GData SVN repo, but checks out the …/svn/ directory with all the branches, tags, trunk… But if I change the s.source from this:

:svn => 'http://gdata-objectivec-client.googlecode.com/svn', :tag => 'gdata-objectivec-client-1.9.1'

… to this:

:svn => 'http://gdata-objectivec-client.googlecode.com/svn/tags/gdata-objectivec-client-1.9.1'

And it works fine. I cannot really go further in the investigation (and maybe I'm not posting this at the wrong place, feel free to tell me), but if I can help, let me know.

@fabiopelosin
CocoaPods member

@MonsieurDart Actually I've never used svn so I'm not very familiar with it. I remember that I've tested the GData podspec with the :head version and that it was working.

Anyway, the as the code is very simple even for non rubists, can you check that I'm resolving the correct urls.

@MonsieurDart

@irrationalfab With the :head set (I'm sure of that because the log says Installing GData (1.9.1) [HEAD]), when using:

:svn => 'http://gdata-objectivec-client.googlecode.com/svn', :tag => 'gdata-objectivec-client-1.9.1'

the #{url}/#{options[:folder]} is:

http://gdata-objectivec-client.googlecode.com/svn/

But when using:

:svn => 'http://gdata-objectivec-client.googlecode.com/svn/tags/gdata-objectivec-client-1.9.1'

the #{url}/#{options[:folder]} is:

http://gdata-objectivec-client.googlecode.com/svn/tags/gdata-objectivec-client-1.9.1/

Actually, in those two cases, it is wrong. The bleeding edge path should be:

http://gdata-objectivec-client.googlecode.com/svn/trunk

I will continue investigating.

@fabiopelosin
CocoaPods member

What about the following url for the head version?:

  svn %|checkout "#{url}/#{options[:folder]}/trunk" "#{target_path}"|

Would this work for all svn repositories? In other words. Give the address of a repo, how can I build the url for the head version?

@MonsieurDart

Argh! I lost my message… Damn GitHub! ;-)

Sounds OK for the trunk addition (that was the object of my lost message: I also came to this conclusion and it worked here locally with GData). But I don't know what the :folder options are used for…

@fabiopelosin
CocoaPods member

But I don't know what the :folder options are used for…

Some pods just clone a specific folder of a svn repo.

@MonsieurDart

Ok, so it sounds good to me. The common use of SVN is:

server/path/to/a/module/trunk/
server/path/to/a/module/tags/
server/path/to/a/module/branches/
@MonsieurDart

And here is why it's cool to use the bleeding edge mode: ;-)

@fabiopelosin
CocoaPods member

@MonsieurDart

What do you think of this version?

Should I rename folder to module?

And here is why it's cool to use the bleeding edge mode: ;-)

Indeed :-).
Did Google stop versioning their iOS libraries? GData 1.9.1 is from revision 389 of Nov 2, 2009 and today we are at revision 729.

@MonsieurDart

@irrationalfab Your new version seems fine to me. I don't think module is a really official or even vastly used name, so I think it is better to stick with folder.

About Google, what they told me is that they will not tag GData anymore. This library is no longer considered in development, only maintenance is on. They seem to have a new lib to access their data, I haven't had time to look at it yet. BTW, this is why, in this case, the head version of this pod is vital! ;-)

@fabiopelosin
CocoaPods member

@MonsieurDart Thanks!

@fabiopelosin fabiopelosin was assigned Sep 24, 2012
@fabiopelosin
CocoaPods member

I'm closing this one as the recommended way is to create versioned forks.

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