<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 23, 2016, at 3:03 PM, Martin Waitz via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><span style="font-family: SFUIText-Regular;" class="">The review of "SE-0145: Package Manager Version Pinning" begins again after revisions, starting now and running through November 28th. The proposal is available here:</span></div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br style="font-family: SFUIText-Regular;" class=""><span class="Apple-tab-span" style="font-family: SFUIText-Regular; white-space: pre;">        </span><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0145-package-manager-version-pinning.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0145-package-manager-version-pinning.md</a><div class=""><br style="font-family: SFUIText-Regular;" class=""></div></div></div></blockquote><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span style="font-family: SFUIText-Regular;" class="">What is your evaluation of the proposal?</span><br style="font-family: SFUIText-Regular;" class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">+1</div><div class="">I think this is an important change for the Swift package ecosystem.</div><div class="">Having reproducible builds by default is a big step forward.</div><div class="">Storing the version of all dependencies in version control and having an easy way to update them helps to reduce maintenance overhead of packages.</div><div class=""><br class=""></div><div class="">I have two comments / requests for improvement:</div><div class=""> * Having two completely separate modes (—enable-autopin vs. —disable-autopin) with a different semantic (e.g. for `swift update`) unnecessarily complicates the design. I understand that there are different use cases where packages have to be handled differently, however I think we should invest some more time on understanding these use cases (see below).</div></div></div></div></blockquote><div><br class=""></div>I agree, I am not very happy with this part.</div><div><br class=""></div><div>However, I expect that in practice what will happen is almost all projects will simply fall into one of the two camps, they either use auto pinning or not. For developers working on that package, their workflow will then end up being consistent. For developers who end up working on a bunch of projects with inconsistent choices, then I agree it might be somewhat confusing, and I hope the diagnostics will end up addressing this.</div><div><br class=""></div><div>I still think that this is a better compromise than a more complex (but consistent) mechanism like the one you propose. I think we should gain some experience with the proposed mechanism and then see if we feel it needs revision in practice.</div><div><br class=""></div><div> - Daniel</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""> * For me the term ‚pin‘ (just like ‚lock‘) implies that the version of pinned dependencies should be fixed and should therefore not be changed/updated. (But I’m not a native speaker, so you may have other associations here.) We should make clear that we *manage* dependencies and that dependencies should be easy to update even while they can be reproduced exactly.</div><div class=""><br class=""></div><div class="">Let’s look at the features of the proposal and how they can be used:</div><div class=""> * Defines two groups of dependencies (pinned vs. unpinned) where one group can be updated independently;</div><div class=""> * unpinned dependencies are automatically updated on clone, not just on update;</div><div class=""> * updates of unpinned dependencies are not considered a change in the package’s repository.</div><div class="">This can be used to easily update internal dependencies while keeping the same version of external dependencies.</div><div class="">Or to keep some difficult-to-update dependencies while constantly updating all the other dependencies.</div><div class="">Or to not create git changes for some selected dependencies.</div><div class="">You name it.</div><div class=""><br class=""></div><div class="">Basically it boils down to better control when and how dependencies are updated.</div><div class="">However, I’m not yet convinced that the proposed pinning system is the best way to do that.</div><div class="">Why only support two groups? Why these two modes of operation? Why not support a specific set of dependencies which are unmanaged while still tracking all new dependencies?</div><div class=""><br class=""></div><div class=""><div class="">When we want to create groups of dependencies and handle them differently, then we should do that explicitly, by introducing groups which can be defined by the package maintainer.</div><div class=""><br class=""></div><div class="">E.g.:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>swift package dependency <dep-name> —group <group-name></div><div class=""><br class=""></div><div class="">We could store each group in a file of its own (e.g. `Package-<group-name>.versions` or whatever) and the maintainer could put each one under version control or not as he likes.</div><div class=""><br class=""></div><div class="">A whole group could be updated in one go:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>swift package update —group internal</div><div class=""><br class=""></div><div class="">This could simulate the pinning as described in the proposal:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>swift package dependency A —group unpinned</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>swift package dependency B —group pinned</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>echo Package-unpinned.versions > .gitignore</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>git add .gitignore Package-pinned.versions</div><div class=""><br class=""></div><div class="">Each group can be updated individually and the package maintainer can put this group under version control or not.</div><div class="">One group would have to be special to automatically include all new dependencies.</div><div class="">Other than that we would not need any special handling ala —repin/—enable-autopin. Groups could be defined to make updating related packages easier.</div><div class="">When needed, we could even set some groups to update automatically on build (not only on clone/update).</div><div class="">This could be useful for closely related packages. Why should clone be special anyways?</div><div class=""><br class=""></div><div class=""><br class=""></div></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span style="font-family: SFUIText-Regular;" class=""> Is the problem being addressed significant enough to warrant a change to Swift?</span><br style="font-family: SFUIText-Regular;" class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">Yes.</div><div class="">Not managing the package dependencies would unnecessarily complicate package maintenance in the long term.</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span style="font-family: SFUIText-Regular;" class="">Does this proposal fit well with the feel and direction of Swift?</span><br style="font-family: SFUIText-Regular;" class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">Yes.</div><div class="">Reproducible builds fit well into the safe-by-default approach of Swift.<br class=""></div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span style="font-family: SFUIText-Regular;" class="">If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?</span><br style="font-family: SFUIText-Regular;" class=""></div></div></div></blockquote><div class=""><br class=""></div>I always hated `npm` and all those node packages which had overly restrictive dependency requirements.<br class="">I guess these were used in order to have more control about which version to use, but this resulted<br class="">in both packages which I could not build out of the box (because some dependencies changed),<br class="">and packages I could not update because of conflicting requirements.<br class="">Using loose version requirements + semver in `Package.swift` files together with exact versions<br class="">of all dependencies stored in the top-level package solves everything: you get reproducible builds<br class="">(based on `Package*.versions`) together with easy updates (based on all packages’ `Package.swift`).</div><div class=""><br class=""></div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span style="font-family: SFUIText-Regular;" class="">How much effort did you put into your review? A glance, a quick reading, or an in-depth study?</span><br style="font-family: SFUIText-Regular;" class=""></div></div></div></blockquote></div><div class=""><br class=""></div>Read both versions of the proposal, took part in the discussion.<div class=""><br class=""><div class="">— Martin Waitz</div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>