> The big struggle I have is that if we go the other direction, and as a result 
> people's semantic versions become poorly specified, we will never be able to 
> recover. The converse is not true, if we start with this direction and 
> realize it doesn't work, we can relax our behavior.

Forgot to touch on this. One interesting thing we can observe from the current 
npm/yarn split is that because npm has set the tone about trusting semver 
plenty of people will still follow this, but in my opinion it's mostly a matter 
of them not being burned *yet*.

Whatever you decide is the right thing to do now will probably cement in users 
minds for years to come, regardless of how easy it technically is to make a 

(Did I say yet that I'm pessimistic about these things?)

> On 14 Oct 2016, at 18:42, Daniel Dunbar <daniel_dun...@apple.com> wrote:
> Hey Eloy,
> Same question as I sent to Orta, can you detail exactly what you would prefer 
> to change?
>> On Oct 14, 2016, at 4:06 AM, Eloy Durán via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> I cannot agree more with Orta.
>> > It drives the user away from taking full advantage of semantic versioning.
>> While I ideally subscribe to this thought, the truth of the matter is that 
>> this has proven unreliable on multiple occasions. Promoting the idea that it 
>> works is going to inevitably lead users into problems when they did not take 
>> explicit user action to update dependencies.
> This makes a lot of sense to me. The open question in my mind is, given our 
> other goals, are we in a position to make this model work, or to make it "the 
> right model for us". Some of the other things I am considering (and maybe 
> should go into the proposal):
> 1. Swift is still evolving in a much greater way than other languages. That 
> means we continue to need to have a very strong push towards forward 
> versions. This is also true for the package manager features, we need the 
> ecosystem to move forward aggressively so that we can move our own features 
> forward aggressively.
> 2. We have some lofty goals around semantic versioning, like trying to have a 
> much deeper integration with the compiler, API, and ABI, and testing in order 
> to help manage this more effectively.
>> Semantic versioning is a great tool when you decide to sit down and 
>> explicitly update dependencies.
> The problem is they go hand in hand. The more people pin versus following the 
> semantic versioning, the more and more likely it is that those specifications 
> are wrong. That leads to more pinning, which leads to more wrong 
> specifications.
> My preference is that we very aggressively commit to using semantic 
> versioning, and then follow up with the entire cross functional design (an 
> index, if we ever do one, the compiler features, any IDE integration) to make 
> this work. I think we are in a better position than other tools which didn't 
> have the ability to make as many cross functional changes (e.g., integration 
> with the compiler to assist in semantic versioning).
> On the other hand, I am also very pragmatic, and I respect your experience 
> here... if this model simply isn't going to work, then we shouldn't try to go 
> that way.
> The big struggle I have is that if we go the other direction, and as a result 
> people's semantic versions become poorly specified, we will never be able to 
> recover. The converse is not true, if we start with this direction and 
> realize it doesn't work, we can relax our behavior.
>> > We think it will be good for the package ecosystem if such a restriction 
>> > is not the default behavior and that this design will lead to faster 
>> > discovery of bugs and fixes in the upstream.
>> Again, ideally I would subscribe to this, but the truth is that when people 
>> are working on their projects they *really really really* do *not* like 
>> their builds breaking, especially not when it’s seemingly caused outside of 
>> their own fault.
> One discussion we had a lot was that there are very different workflows 
> between when you are largely the consumer of packages, versus when you are 
> working on a package that is shared.
> We generally agree that when you are simply the consumer of packages, pinning 
> makes sense.
> However, when you are primarily a distributor of packages (and this is 
> expected to *most* of the momentum behind SwiftPM in the near term), I 
> believe that it is very important to the ecosystem that the semver specs be 
> correct, and so even if the team *wants* to pin, doing so would be actively 
> harmful.
>> In the end, it comes down to whether you prioritise surfacing bugs (long 
>> term happiness) over user-experience (short term happiness). As a dependency 
>> manager author, I can tell you that I agree with your ideals and would want 
>> to choose the former, but as a user of dependency managers I would choose UX 
>> and Getting (The) Things (I Really Wanted To Do) Done over surfacing bugs 
>> *any* day.
> I really appreciate the feedback. Do my arguments that we might be in a 
> position to do better here have any weight with you?
>  - Daniel
>> [A.]         Eloy Durán
>>              Artsy
>>              e...@artsy.net
>>              Twitter
>>              GitHub
>>> On 14 Oct 2016, at 09:29, orta therox via swift-build-dev 
>>> <swift-build-...@swift.org> wrote:
>>> Please don’t make this a separate command, it should ideally be created at 
>>> the end of an build (when there isn’t one already) or an update of your 
>>> dependencies - most people will be expecting to get the same set of 
>>> dependencies as the rest of their team. This pattern makes that harder.
>>> NPM shrinkwrap is an example of this, and it’s a bad one - I’ve wasted a 
>>> lot of time trying to keep that up to date for our npm projects. Facebook 
>>> made a replacement for NPM with mainly the  feature of “always locking” in 
>>> yarn and I’d expect that to take a lot of the JS mindshare on this one 
>>> feature alone.
>>> -- 
>>> [A.]            Orta Therox
>>>> w/ Artsy
>>>> CocoaPods / CocoaDocs / GIFs.app
>>>> @orta / orta.github.com
>>>> Artsy is totally hiring iOS Devs ATM
>>>> On 14 Oct 2016, at 07:01, Ankit Aggarwal via swift-build-dev 
>>>> <swift-build-...@swift.org> wrote:
>>>> Hi,
>>>> We're proposing version pinning feature in Swift Package Manager. The 
>>>> proposal is available here and also in this email:
>>>> Feedback welcomed!
>>>> Thanks,
>>>> Ankit
>>>> --------
>>>> Package Manager Version Pinning
>>>> Proposal: SE-XXXX
>>>> Author: Daniel Dunbar, Ankit Aggarwal
>>>> Review Manager: TBD
>>>> Status: Discussion
>>>> Introduction
>>>> This is a proposal for adding package manager features to "pin" or "lock" 
>>>> package dependencies to particular versions.
>>>> Motivation
>>>> As used in this proposal, version pinning refers to the practice of 
>>>> controlling exactly which specific version of a dependency is selected by 
>>>> the dependency resolution algorithm, independent from the semantic 
>>>> versioning specification. Thus, it is a way of instructing the package 
>>>> manager to select a particular version from among all of the versions of a 
>>>> package which could be chosen while honoring the dependency constraints.
>>>> Terminology
>>>> We have chosen to use "pinning" to refer to this feature, over 
>>>> "lockfiles", since the term "lock" is already overloaded between POSIX 
>>>> file locks and locks in concurrent programming.
>>>> Philosophy
>>>> Our philosophy with regard to pinning is that we actively want to 
>>>> encourage packages to develop against the latest semantically appropriate 
>>>> versions of their dependencies, in order to foster rapid development 
>>>> amongst the ecosystem and strong reliance on the semantic versioning 
>>>> concept. Our design for version pinning is thus intended to be a feature 
>>>> for package authors and users to use in crafting specific workflows, not 
>>>> be a mechanism by which most of the packages in the ecosystem pin 
>>>> themselves to specific versions of each other.
>>>> Use Cases
>>>> Our proposal is designed to satisfy several different use cases for such a 
>>>> behavior:
>>>> Standardizing team workflows
>>>> When collaborating on a package, it can be valuable for team members (and 
>>>> continuous integration) to all know they are using the same exact version 
>>>> of dependencies, to avoid "works for me" situations.
>>>> This can be particularly important for certain kinds of open source 
>>>> projects which are actively being cloned by new users, and which want to 
>>>> have some measure of control around exactly which available version of a 
>>>> dependency is selected.
>>>> Difficult to test packages or dependencies
>>>> Complex packages which have dependencies which may be hard to test, or 
>>>> hard to analyze when they break, may choose to maintain careful control 
>>>> over what versions of their upstream dependencies they recommend -- even 
>>>> if conceptually they regularly update those recommendations following the 
>>>> true semantic version specification of the dependency.
>>>> Dependency locking w.r.t. deployment
>>>> When stabilizing a release for deployment, or building a version of a 
>>>> package for deployment, it is important to be able to lock down the exact 
>>>> versions of dependencies in use, so that the resulting product can be 
>>>> exactly recreated later if necessary.
>>>> Proposed solution
>>>> We will introduce support for an optional new file Package.pins adjacent 
>>>> to the Package.swift manifest, called the "pins file". We will also 
>>>> introduce a number of new commands (see below) for maintaining the pins 
>>>> file.
>>>> This file will record the active version pin information for the package, 
>>>> including data such as the package identifier, the pinned version, and 
>>>> explicit information on the pinned version (e.g., the commit hash/SHA for 
>>>> the resolved tag).
>>>> The exact file format is unspecified/implementation defined, however, in 
>>>> practice it will be a JSON data file.
>>>> This file may be checked into SCM by the user, so that its effects apply 
>>>> to all users of the package. However, it may also be maintained only 
>>>> locally (e.g., placed in the .gitignore file). We intend to leave it to 
>>>> package authors to decide which use case is best for their project.
>>>> In the presence of a Package.pins file, the package manager will respect 
>>>> the pinned dependencies recorded in the file whenever it needs to do 
>>>> dependency resolution (e.g., on the initial checkout or when updating).
>>>> The pins file will not override Manifest specified version requirements 
>>>> and it will be an error (with proper diagnostics) if there is a conflict 
>>>> between the pins and the manifest specification.
>>>> Detailed Design
>>>> We will add a new command pin to swift package tool with following 
>>>> semantics:
>>>> $ swift package pin ( [--all] | [<package-name>] [<version>] ) [--message 
>>>> <message>]
>>>> The package-name refers to the name of the package as specified in its 
>>>> manifest.
>>>> This command pins one or all dependencies. The command which pins a single 
>>>> version can optionally take a specific version to pin to, if unspecified 
>>>> (or with --all) the behaviour is to pin to the current package version in 
>>>> use. Examples: 
>>>> $ swift package pin --all - pins all the dependencies.
>>>> $ swift package pin Foo - pins Foo at current resolved version.
>>>> $ swift package pin Foo 1.2.3 - pins Foo at 1.2.3. The specified version 
>>>> should be valid and resolvable.
>>>> The --reason option is an optional argument to document the reason for 
>>>> pinning a dependency. This could be helpful for user to later remember why 
>>>> a dependency was pinned. Example: 
>>>> $ swift package pin Foo --reason "The patch updates for Foo are really 
>>>> unstable and need screening."
>>>> Dependencies are never automatically pinned, pinning is only ever taken as 
>>>> a result of an explicit user action.
>>>> We will add a new command unpin:
>>>> $ swift package unpin ( [--all] | [<package-name>] )
>>>> This is the counterpart to the pin command, and unpins one or all packages.
>>>> We will fetch and resolve the dependencies when running the pin commands, 
>>>> in case we don't have the complete dependency graph yet.
>>>> We will extend the workflow for update to honour version pinning, that is, 
>>>> it will only update packages which are unpinned, and it will only update 
>>>> to versions which can satisfy the existing pins. The update command will, 
>>>> however, also take an optional argument --repin:
>>>> $ swift package update [--repin]
>>>> Update command errors if there are no unpinned packages which can be 
>>>> updated.
>>>> Otherwise, the behaviour is to update all unpinned packages to the latest 
>>>> possible versions which can be resolved while respecting the existing pins.
>>>> The [--repin] argument can be used to lift the version pinning 
>>>> restrictions. In this case, the behaviour is that all packages are 
>>>> updated, and packages which were previously pinned are then repinned to 
>>>> the latest resolved versions.
>>>> The update and checkout will both emit logs, notifying the user that 
>>>> pinning is in effect.
>>>> The swift package show-dependencies subcommand will be updated to indicate 
>>>> if a dependency is pinned.
>>>> As a future extension, we anticipate using the SHA information recorded in 
>>>> a pins file as a security feature, to prevent man-in-the-middle attacks on 
>>>> parts of the package graph.
>>>> Impact on existing code
>>>> There will be change in the behaviours of swift build and swift package 
>>>> update in presence of the pins file, as noted in the proposal however the 
>>>> existing package will continue to build without any modifications.
>>>> Alternative considered
>>>> We considered making the pinning behavior default on running swift build, 
>>>> however we think that pinning by default is likely to make the package 
>>>> graph more constrained than it should be. It drives the user away from 
>>>> taking full advantage of semantic versioning. We think it will be good for 
>>>> the package ecosystem if such a restriction is not the default behavior 
>>>> and that this design will lead to faster discovery of bugs and fixes in 
>>>> the upstream.
>>>> _______________________________________________
>>>> swift-build-dev mailing list
>>>> swift-build-...@swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-build-dev
>>> _______________________________________________
>>> swift-build-dev mailing list
>>> swift-build-...@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-build-dev
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
swift-evolution mailing list

Reply via email to