[swift-build-dev] [swift-evolution] [Proposal] Lock file for Swift Package Manager

Joshua Scott Emmons skia at skia.net
Tue Dec 22 16:28:15 CST 2015

> On Dec 22, 2015, at 2:50 PM, Max Howell <max.howell at apple.com> wrote:
>>> I’d prefer a workflow that omits —bootstrap, to repeat my previous email:
>>> If the lock file is committed I think swift-build should always use it. If the user wants newer updates they can execute `swift build —update`.
>>> This makes understanding what happens simpler: `swift build` always uses the lock file if it is present.
>>> This makes reliably building apps possible since you will always be building what everyone else built when the sources where committed.
>> Maybe it's me, but I've been burned by "Why isn't this updating — oh, there's a lock file!" more than once. Having "`swift build` always use a lock file if present" isn't simpler. It requires I reason about the state of the lock file every time I build.
> There will be a dedicated `—update` command that updates and it will update the lock per the current proposal. Expecting the build command to update the checked out dependencies every time seems unintuitive. It is after all a build command.


> If we didn’t have lock files I still would not want `swift build` to update my dependencies before building, I would still want a separate --update switch, and in this case it would thus behave the same as if there is a lock file.
> Updating your dependencies every build is asking for trouble, you wouldn’t want to be debugging and then also possibly have your underlying library dependencies change in behavior.

Right. I didn't mean to insinuate we should be pulling fresh dependencies before each build. Here's the scenario 

* I'm working on a package that depends on FooPackage Version(1,0,0)..<Version(2,0,0)
* I `swift --update`. This pulls FooPackage v1.1 and sets the lockfile. I commit the lockfile to git.
* FooPackage v1.2 is released
* A co-worker `swift --update`s to FooPackage v1.2, her lockfile is updated and she pushes it to git.
* Version 1.3 is released.
* I pull my co-worker's commits.

Here's the state of things at this point:
* The FooPackage currently checked out in my Packages directory is v1.1
* My lockfile points at FooPackage v1.2
* The latest FooPackage I could be using is v1.3

There are three things that should be possible at this point:
1. Build with the existing v1.1 dep.
2. Update deps to the lockfile version (v1.2).
3. Update deps and lockfile to the latest conforming version (1.3).

I'm simply saying that I'd expect vanilla `swift build` to perform option #1 (perhaps with a warning message that we're out of sync with the lockfile). Like you say, "expecting the build command to update the checked out dependencies every time seems unintuitive. It is after all a build command." So I'd expect it to build with what's already there. If I wanted to update deps to the lockfile version, I could be explicit: `swift build --use-locked-deps`. 

My understanding, though, is that if a lockfile is present, `swift build` would operate like option #2 and I'd need to be explicit about my desire to ignore the lockfile (maybe with `swift build --ignore-locked-deps` or the like). This feels inconsistent in that sometimes `swift build` just builds what's there, and sometimes updates and builds depending on the state of the lockfile. It also feels a little wrong that vanilla `build` could checkout other branches without me passing `--something`.

But it certainly sounds like I'm in the minority here, so no big deal.


More information about the swift-build-dev mailing list