How to use the Package.pins file


(Steven Clukey) #1

Perhaps the pinning feature and how to use it together with the version specification in the manifest could be documented somewhere? I am sorting through how to use the Package.pins file on my own projects and I am coming up a bit confused, and I assume that I am just missing the point of this somewhat intrusive change.

If it is of any interest, my initial impressions of using this behavior are these:

Currently in my package manifests I have been specifying my dependencies with exact versions (e.g. `.Package(url: "URL.git", Version(0,1,2))`), so the pins file seems entirely redundant. The statement in SE-0145 that "there has heretofore been no way to share that pinning information with other team members" seems wrong. Hasn't my package manifest with dependency versions been being shared?

I see that the pins file is supposed to disambiguate the dependency version "independent from the semantic versioning specification". Does that mean that I could have a completely different version in the pins file than the manifest and the pins file would override the manifest? Can the "version" field in the pins file accept commit hashes or branch names or other things not supported by semantic version tags? Currently, neither of these are possible (in the first case swift gives "error: unsatisfiable" and in the second case swift crashes if the pins "version" is anything but a valid semantic version), so again I am missing what benefit the pins file has over simply giving an exact `Version(...)` in the manifest. On the other hand, if the pins file is intended to override the manifest, than what is the point of specifying any version in the manifest at all?

Steven


(orta) #2

It’s normal to define your dependencies using a looser interpretation of a
version, using things like “~> 1.3” implying anything from 1.3.0 -> 1.4.0 (
here’s a cute video from Google showing the use-case in CocoaPods
<https://www.youtube.com/watch?v=x4ARXyovvPc> ) so you would define your
dependencies pretty loosely in the manifest ( e.g. package.swift ) but then
let the lock/pin file keep track of the exact resolution of those
dependencies.

This tends to make more sense when you have more than a few dependencies.

···

--
[·/ ] Orta Therox

w/ Artsy <http://artsy.net/>
CocoaPods <http://cocoapods.org/> / CocoaDocs <http://cocoadocs.org/>
@orta / orta.github.com
Artsy is totally hiring iOS Devs <http://artsy.net/job/developer> ATM

On Mon, Dec 19, 2016 at 4:09 PM, Steven Clukey via swift-build-dev < swift-build-dev@swift.org> wrote:

Perhaps the pinning feature and how to use it together with the version
specification in the manifest could be documented somewhere? I am sorting
through how to use the Package.pins file on my own projects and I am coming
up a bit confused, and I assume that I am just missing the point of this
somewhat intrusive change.

If it is of any interest, my initial impressions of using this behavior
are these:

Currently in my package manifests I have been specifying my dependencies
with exact versions (e.g. `.Package(url: "URL.git", Version(0,1,2))`), so
the pins file seems entirely redundant. The statement in SE-0145 that "there
has heretofore been no way to share that pinning information with other
team members" seems wrong. Hasn't my package manifest with dependency
versions been being shared?

I see that the pins file is supposed to disambiguate the dependency
version "independent from the semantic versioning specification". Does that
mean that I could have a completely different version in the pins file than
the manifest and the pins file would override the manifest? Can the
"version" field in the pins file accept commit hashes or branch names or
other things not supported by semantic version tags? Currently, neither of
these are possible (in the first case swift gives "error: unsatisfiable"
and in the second case swift crashes if the pins "version" is anything but
a valid semantic version), so again I am missing what benefit the pins file
has over simply giving an exact `Version(...)` in the manifest. On the
other hand, if the pins file is intended to override the manifest, than
what is the point of specifying any version in the manifest at all?

Steven

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-build-dev


(Steven Clukey) #3

It's normal to define your dependencies using a looser interpretation of a version, using things like "~> 1.3" implying anything from 1.3.0 -> 1.4.0 ( here's a cute video from Google showing the use-case in CocoaPods<https://www.youtube.com/watch?v=x4ARXyovvPc> ) so you would define your dependencies pretty loosely in the manifest ( e.g. package.swift ) but

I understand that most often the manifest version is less specific; I am very specific because in my experience the swift community is not very stable at this point. I default to strict then loosen as necessary and acceptable. Anyway, I assume that by "looser" you don't mean loose enough to include versions that are incompatible with the project (intentionally or by negligence, I assume this is bad).

then let the lock/pin file keep track of the exact resolution of those dependencies.

But the pins file doesn't just "keep track" of the exact resolution, it actually forces it. Unless you disable automatic pinning the loose specification in the manifest is basically meaningless - you have an exact version defined by the pins file. Then you need to manage two files, the manifest with some meaningless loose range and the pins file with the actual version that is being used. Why? Why not just manage the package manifest directly? I still don't see the point.

This tends to make more sense when you have more than a few dependencies.

I would actually think it the opposite. If I have a project with many dependencies constantly updating and changing I would want to be as strict as possible with the versions that are allowable. I believe many other people would too, this is why the pins file exists to begin with. It allows very specific management of the versions of the dependencies in a way that the package manifest somehow (I do not yet understand this somehow) cannot.

Steven


(Jason Dusek) #4

Loose specifications allow libraries to avoid unnecessarily causing
dependency conflicts for one another. The "pins" file allows application
builds to reliably produce the same resolution, time after time.
Steven Clukey via swift-build-dev <swift-build-dev@swift.org> schrieb am
Mo. 19. Dez. 2016 um 17:18:

···

> It’s normal to define your dependencies using a looser interpretation
of a version, using things like “~> 1.3” implying anything from 1.3.0 ->
1.4.0 ( here’s a cute video from Google showing the use-case in CocoaPods
<https://www.youtube.com/watch?v=x4ARXyovvPc> ) so you would define your
dependencies pretty loosely in the manifest ( e.g. package.swift ) but

I understand that most often the manifest version is less specific; I am
very specific because in my experience the swift community is not very
stable at this point. I default to strict then loosen as necessary and
acceptable. Anyway, I assume that by "looser" you don't mean loose enough
to include versions that are incompatible with the project (intentionally
or by negligence, I assume this is bad).

> then let the lock/pin file keep track of the exact resolution of those
dependencies.

But the pins file doesn't just "keep track" of the exact resolution, it
actually forces it. Unless you disable automatic pinning the loose
specification in the manifest is basically meaningless - you have an exact
version defined by the pins file. Then you need to manage two files, the
manifest with some meaningless loose range and the pins file with the
actual version that is being used. Why? Why not just manage the package
manifest directly? I still don't see the point.

> This tends to make more sense when you have more than a few
dependencies.

I would actually think it the opposite. If I have a project with many
dependencies constantly updating and changing I would want to be as strict
as possible with the versions that are allowable. I believe many other
people would too, this is why the pins file exists to begin with. It allows
very specific management of the versions of the dependencies in a way that
the package manifest somehow (I do not yet understand this somehow) cannot.

Steven

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-build-dev


(Steven Clukey) #5

Loose specifications allow libraries to avoid unnecessarily causing dependency conflicts for one another.

I agree, and SE-0145 specifically recommends against using pinning for libraries.

The "pins" file allows application builds to reliably produce the same resolution, time after time.

If an application requires the exact same dependency version resolution, then why not put an exact version in the manifest? What is the point, or the benefit, of using a loose version in the application's manifest plus an exact version in the "pins" file instead of just using an exact version in the manifest to begin with?

Steven


(Daniel Dunbar) #6

The intended use is that:

1. Your manifest specifies your "ideal" range. If your dependencies are using semver properly, then this should be the "lowest version your app requires", based on the API it uses from that dependency. The only intended reason to deviate from this is if there are bugs or known incompatibles between the package and its dependency.

2. The pin file is used to select the exact version, so that different team members see consistent behavior (in a nutshell).

3. The flexibility in the manifest specification *documents* the compatibility your app *should* have, so that the tools can provide you with workflows to, for example, update to a newer version of a dependency to try it out (maybe they made it faster, fixed bugs, etc.).

#3 is the "benefit" you are gaining from having similar information in two different places.

One way to think of it is that #1 is simply a "fact" -- "what is the absolute minimum version of this package the code requires", and #2 is a choice "what version would *I* like to use".

- Daniel

···

On Dec 20, 2016, at 6:13 AM, Steven Clukey via swift-build-dev <swift-build-dev@swift.org> wrote:

Loose specifications allow libraries to avoid unnecessarily causing dependency conflicts for one another.

I agree, and SE-0145 specifically recommends against using pinning for libraries.

The "pins" file allows application builds to reliably produce the same resolution, time after time.

If an application requires the exact same dependency version resolution, then why not put an exact version in the manifest? What is the point, or the benefit, of using a loose version in the application's manifest plus an exact version in the "pins" file instead of just using an exact version in the manifest to begin with?

Steven

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-build-dev


(Steven Clukey) #7

The flexibility in the manifest specification *documents* the compatibility your app *should* have

So the only purpose is to turn the manifest into a documentation file? Lets say the manifest specifies something like "majorVersion:3, minor:4" and the pins file says "3.4.2". In this case are you saying that the only purpose the manifest serves is to indicate that the package uses a feature first introduced in version 3.4? Wouldn't a simple comment or even the git log serve that purpose equally well?

so that the tools can provide you with workflows to, for example, update to a newer version of a dependency to try it out (maybe they made it faster, fixed bugs, etc.).

If the dependencies use semver properly then it should be obvious to the tools what newer versions *should* be compatible: any greater version with the same major number. What lower versions should be compatible is less clear, but why would any tools want to suggest a downgrade? Creating this easy version understanding is a major part of semver. OTOH people often do not follow semver exactly, so it's probably just a crapshoot no matter what the manifest says.

Anyway, I suppose I now see the intended point. I thank you. That said I disagree with its value and usefulness. I'm sure that doesn't matter so I'll not take any more of your time, and I do appreciate what you've all spared already.

Steven