[swift-build-dev] [swift-evolution] Proposal: Package Manager Version Pinning

Huon Wilson huon_wilson at apple.com
Fri Oct 14 12:37:35 CDT 2016

> On Oct 14, 2016, at 09:43, Alexis via swift-evolution <swift-evolution at swift.org> wrote:
> A library shouldn’t pin its dependencies, while an application should.

Not only “shouldn’t” but can’t: Rust’s cargo (I don’t know for sure about Bundler and Yarn, but they’re all in the same vein, and pretty much from the same person) will just ignore any non-top-level lock files, i.e. the package that user is working on has a record of the exact versions of everything in their dependency graph, and the user can update all or just parts of that graph fairly precisely, as desired.

My impression is that other ecosystems without pinning-by-default have seriously suffered from the lack of reliable reproducible builds. For instance, a major complaint I have seen about "go get” is that one can come back to some code after a few months to fix a minor bug and have no chance of getting the code to compile, basically just requiring a full rewrite, because dependencies' code has changed (or disappeared entirely) and there’s no record of what the original was, despite your code being completely untouched in all that time. Of course, a hard push towards API-level semantic versioning may allay the worst of the code-changing problems, but unless there’s going to be some seriously fancy static analysis (something something halting problem), there will be a lot of breaking changes that can’t be picked up.


To reframe the discussion slightly, not pinning dependencies effectively means that the tools are making “random" changes to your code outside your control. Sure, those changes were transitively made by possibly-computer-assisted humans and may fix bugs, but those pesky meat-bags can still make mistakes, and, they don’t see the interactions between all the different packages in your specific application.

IME having the predictability of “never changing code under my feet” combined with pervasive semantic versioning hits an empowering middle ground of being able to depend on many & varied packages and update them to the latest versions without fear (for one, it’s easy to revert the lock file if something breaks during an update). Feedback from others about cargo is the same, often along the lines of “it’s the best package manager I’ve ever used”.

Also, more on the side of implementation details, having a lock file by default probably mean one can (get closer to) never hitting the network unless the user asks for it, making working offline or on a low-speed/high-latency connection easier, i.e. no need to check for new versions of the whole dependency graph on O(every) build, which aggressively keeping everything up to date would seemingly have to do? (I don’t know swift-pm’s current behavior here, so maybe there’s some tricks that avoid it.)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-build-dev/attachments/20161014/6aa6fb77/attachment.html>

More information about the swift-build-dev mailing list