<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="">My thoughts on this proposal:<div class=""><br class=""></div><div class="">1. I agree with some of the other comments that I would prefer the version file be adjacent to "Package.swift". When the Packages directory isn't being checked in, I really would like to think of it as an "implementation detail" and not embed functionality inside it that would make it hard to remove or change in the future.</div><div class=""><br class=""></div><div class="">2. I like VersionLocks.json well enough, but would like to see a discussion about possible alternatives. My personal proposal (in line with #1) is to use "PackageVersions.json" which has a nice agreement with Package.swift and would mean two common metadata files show up adjacent. I don't really want to bike shed on the name, but I suspect whatever we pick first will last for a while so I would at least like to review the various alternatives. I also will throw out that my personal opinion is we don't need to pick a name that bears much resemblance with existing terminology, whatever we pick will eventually become "the standard" for the SwiftPM ecosystem so I would prefer to pick the most-descriptive-possible name up front, not one that alludes to the same concept in other systems.</div><div class=""><br class=""></div><div class="">3. I like the terminology section here, I almost feel like we should adopt that as official terminology in our documentation (which I don't think we have yet, correct me if I am wrong).</div><div class=""><br class=""></div><div class="">4. I would like it if the lock file recorded the exact SHA it received, and validate that when retrieving. This helps protect users against MITM attacks or unexpected changes if an upstream modifies a tag. It also can be used as part of safety checks when migrating to an alternate repository host which is expected to have the same content.</div><div class=""><br class=""></div><div class="">5. The "workflow - build" sections #2,3,4 are rather complicated. Is this because the proposal is trying to work with existing Packages layouts, or because the proposal is trying to handle the various variations of what the user may have checked in inside the Packages subdirectory?</div><div class=""><br class=""></div><div class="">6. I wonder if we should be defining, as Eloy alludes to, two different things:</div><div class="">&nbsp;- The version lock file, which defines the expected versions for the package manager to use when it is doing package resolution.</div><div class="">&nbsp;- The package state file (in Packages.swift), which is used by the package manager to track information on the Packages/ subdir state in order to provide useful features primarily focused at the scenarios when the user is modifying those files.</div><div class="">Currently it seems like a lot of the behaviors in the proposal are focused at the latter case, but they feel like they should be decoupled problems to me.</div><div class=""><br class=""></div><div class="">&nbsp;- Daniel</div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On Mar 17, 2016, at 11:23 AM, Max Howell via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; 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="">The following is a draft proposal, feedback welcome.</div><div class=""><br class=""></div><div class="">____________</div><div class=""><h1 style="font-size: 28px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">SwiftPM Dependency Version Locking</h1><ul style="margin: 15px 0px; padding-left: 30px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px;" class=""><li class="">Proposal:&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-swiftpm-dependency-lockfiles.md" style="color: rgb(65, 131, 196); text-decoration: none;" class="">SE-NNNN</a></li><li class="">Author(s):&nbsp;<a href="https://github.com/aciidb0mb3r" style="color: rgb(65, 131, 196); text-decoration: none;" class="">Ankit Agarwal</a>,&nbsp;<a href="https://github.com/mxcl" style="color: rgb(65, 131, 196); text-decoration: none;" class="">Max Howell</a></li><li class="">Status:&nbsp;<strong class="">Discussion</strong></li><li class="">Review manager: Rick Ballard</li></ul><h2 style="font-size: 24px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Introduction</h2><p style="font-size: 14px; margin: 0px 0px 15px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">This proposal seeks to declare a new, generated file&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/VersionLocks.json</code>&nbsp;that describes the exact state of a package’s dependency graph and then by default will be respected when executing most package manager commands. Thus it is considered a “version lock” for a package’s dependency sources.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class=""><a href="https://lists.swift.org/pipermail/swift-build-dev/Week-of-Mon-20151214/000067.html" style="color: rgb(65, 131, 196); text-decoration: none;" class="">Swift-evolution thread</a></p><h2 style="font-size: 24px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Terminology</h2><ul style="margin: 15px 0px; padding-left: 30px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px;" class=""><li class="">A&nbsp;<em class="">package</em>&nbsp;refers to a published, versioned git repository designed to be consumed as a dependency by SwiftPM.</li><li class="">A&nbsp;<em class="">project</em>&nbsp;refers to an end-user workspace that uses SwiftPM (via a&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Package.swift</code>&nbsp;and&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build</code>) fetching and building packages as part of its build</li></ul><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Describing this distinction is required because both the above have the same form, but are used differently by an end-user. An end-user may publish packages, but will eventually consume those packages in a project.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">As justification for this confusion, it is considered a feature that projects can easily and trivially become packages when using SwiftPM. Encouraging a vibrant packaging ecosystem is one of our goals.</p><h2 style="font-size: 24px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Motivation</h2><p style="font-size: 14px; margin: 0px 0px 15px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">In a vibrant packaging ecosystem, dependencies update continuously with bug-fixes and new features. A development team needs:</p><ol style="margin: 15px 0px; padding-left: 30px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px;" class=""><li class="">To ensure they are all using the same versions of their dependencies for any given version-control commit.</li><li class="">Ensure they are all using the same versions of the underlying Swift toolchain</li><li class="">Be able to override or modify dependency specifications for the whole team for specific commits.</li></ol><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Currently with SwiftPM it is possible to fulfill&nbsp;<em class="">1.</em>&nbsp;by committing the sources of a package’s dependencies with the package itself, but this is not always desirable. There is no way to achieve 2. and 3. with SwiftPM alone.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Additionally, there is not currently a way to know which version of Swift a package requires to build. At this time this situation is particularly precarious because Swift itself is not backwards compatible. As a Swift developer at the very least recording which Swift version a package was built with by the package developer is essential information in order to assess a package's suitability. Practically the package manager could in the future use this information to aid an end-user or even fix the problem when packages fail to compile.</p><h2 style="font-size: 24px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Proposed Solution</h2><p style="font-size: 14px; margin: 0px 0px 15px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">A file:&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/VersionLocks.json</code>&nbsp;will be created alongside the Package.swift file. Its contents will describe:</p><ul style="margin: 15px 0px; padding-left: 30px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px;" class=""><li class="">The URL and versions of cloned dependencies</li><li class="">An inline diff of any&nbsp;<em class="">local</em>&nbsp;modifications made to those packages relative to their pristine cloned states</li><li class="">The exact version of the Swift toolchain used as part of the last successful build of the package</li></ul><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">This file is generated by SwiftPM.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">This file&nbsp;<em class="">should</em>&nbsp;be checked-in with projects.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">This file is&nbsp;<em class="">generated</em>&nbsp;and should not be edited by users. If the file is edited by users the behavior is undefined.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">This file&nbsp;<em class="">should</em>&nbsp;be checked-in with packages designed for consumption in projects,&nbsp;<em class="">however</em>&nbsp;SwiftPM will not use the checkout files of dependencies when determining a project’s dependency graph (this would make dependency graphs much less likely to resolve due to overly strict versioning requirements). In the future we may choose to make it possible for end-users to attempt to build a package using all checkout files since in certain deployment scenarios where an exact graph has already been tested, this is a solid reliabiity feature.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Any local, modifications made to the clones in&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages</code>&nbsp;are recorded in&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/VersionLocks.json</code>&nbsp;as part of the flow described in the next section. Modifications here means: changes to git remotes and the git-ref of the checked-out HEAD.</p><h2 style="font-size: 24px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Detailed Design</h2><p style="font-size: 14px; margin: 0px 0px 15px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">In a fresh clone that does not contain a&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages</code>&nbsp;directory&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build</code>&nbsp;will determine the dependency graph, clone the packages into&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages</code>&nbsp;and generate a&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/VersionLocks.json</code>&nbsp;file.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">The user can now step into the Packages directory and modify package sources. If the user then runs&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build</code>&nbsp;again the package manager will error out:</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 12px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: Consolas, 'Liberation Mono', Courier, monospace; color: rgb(51, 51, 51);" class=""><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">error: dependency sources have been modified
execute `swift build --lock` or `swift build --ignore-lock`</code></pre><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">It is an error to build against an unlocked dependency graph, but to facilitate fixing bugs etc. an ignore flag can be specified.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">When&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build --lock</code>&nbsp;is specified the package manager regenerates the lockfile detailing the active git remote and the SHA that is checked-out.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Every time&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build</code>&nbsp;completes a build the lockfile is updated (if necessary) recording the current version of the Swift toolchain that achieved the build.</p><h3 style="font-size: 18px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class=""><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: inherit; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/VersionLocks.json</code></h3><p style="font-size: 14px; margin: 0px 0px 15px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">The exact design of the contents of this file will be explored during iterative development, but here is a possible example:</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class=""><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">json { "packages": [ { "clone": "Packages/PromiseKit-3.0.3", "origin": "<a href="https://github.com/mxcl/PromiseKit" class="">https://github.com/mxcl/PromiseKit</a>" "ref": "3.0.3" }, { "clone": "Packages/Alamofire-1.2.3", "origin": "<a href="https://github.com/a-fork-somewhere/Alamofire" class="">https://github.com/a-fork-somewhere/Alamofire</a>" "ref": "crucial-fix" }, { "clone": "Packages/Quick-1.2.3", "origin": "<a href="https://github.com/Quick/Quick" class="">https://github.com/Quick/Quick</a>" "ref": "1.2.3" } ] }</code></p><h3 style="font-size: 18px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Workflow — Regular Build</h3><ol style="margin: 15px 0px; padding-left: 30px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px;" class=""><li class="">User runs&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build</code></li><li class="">If&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/</code>&nbsp;contains clones and a&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">VersionLocks.json</code>SwiftPM skips to 7.</li><li class="">If&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/</code>&nbsp;contains clones and no&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">VersionLocks.json</code>&nbsp;the lockfile is generated from the clones</li><li class="">If&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/</code>&nbsp;contains checked out sources without git information and no&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">VersionLocks.json</code>&nbsp;SwiftPM fetches the git information and provided there is no diff, generates the Lockfile, if there is variation it is an error *</li><li class="">If&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/VersionLocks.json</code>&nbsp;is present its dependency graph is used</li><li class="">If&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages</code>&nbsp;doesn't exist or is empty the dependency graph is resolved, packages are cloned and the Lockfile is generated</li><li class=""><p style="font-size: 1em; margin: 15px 0px; padding: 0px;" class="">Build, if&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages</code>&nbsp;are missing because we skipped from 2. the build will error, it is the user's responsibility to instruct SwiftPM to&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">--update</code>&nbsp;or to fix their dependency graph some other way.</p><ul style="margin: 15px 0px 0px; padding-left: 30px;" class=""><li class=""><p style="font-size: 1em; margin: 15px 0px; padding: 0px;" class="">This scenario is so users can check in their complete dependency sources to their tree instead of / as well as the&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">VersionLocks.json</code>&nbsp;file: a situation which sometimes is necessary if your dependencies are removed from their third party online location, etc.</p></li></ul></li></ol><h3 style="font-size: 18px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Workflow — Making Modifications</h3><ol style="margin: 15px 0px; padding-left: 30px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px;" class=""><li class="">User makes local modification to a dependency’s sources</li><li class="">User runs&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build</code></li><li class=""><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build</code>&nbsp;errors out.</li><li class="">User must either lock the graph or run with&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">--ignore-lock</code></li></ol><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">The error-out is likely to be considered tedious by users, however we consider it important that users are made aware and forced to act when they modify their dependencies and thus are exposing their team/users to so-called “dependency hell”.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Runing&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build --lock</code>&nbsp;regenerates the lockfile, but does not build.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Modifications must be committed. This means that if the modifications are not uploaded to a location accessible to the rest of the team they will fail to build when they update their checkouts.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">The package manager could check for this by asking git if the specified origin has the current locked ref and error out as appropriate.</p><h3 style="font-size: 18px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Workflow — Overriding Packages</h3><ol style="margin: 15px 0px; padding-left: 30px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px;" class=""><li class="">User steps into a Package directory eg.&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Packages/Foo-1.2.3</code></li><li class="">User changes the&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">origin</code>&nbsp;of&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Foo</code>&nbsp;to their own fork</li><li class="">User alters HEAD to point to a fix in their own fork</li><li class=""><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build</code>&nbsp;errors out.</li><li class="">User must either lock the graph or run with&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">--ignore-lock</code></li></ol><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Running&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build --lock</code>&nbsp;regenerates the lockfile, the new origin and tag is stored. Thus a fresh clone of this project would use these overrides.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">It is important to note that this workflow will not be respected for dependencies, only for projects.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">If a package author requires an override they have a few options:</p><ol style="margin: 15px 0px; padding-left: 30px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px;" class=""><li class="">Change the&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">Package.swift</code>&nbsp;dependency specification. This should only be done as a last resort, for example, a critical bug must be fixed in a dependency and that dependency author is not being responsive. It is up to the Package author to ensure this scenario goes well. SwiftPM itself wants to guard against these conditions with our proposed “publish &amp; lint” step that validates such decisions before signing a published package tag. But we are not there yet and thus package authors should be responsible.</li><li class="">Advise end-users in a package README that they should override the dependency themselves.</li></ol><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class=""><em class="">2</em>&nbsp;is preferred, but&nbsp;<em class="">1</em>&nbsp;will happen. We consider it our responsibility to develop tooling that makes&nbsp;<em class="">1.</em>&nbsp;safe or unnecessary, but we are not there yet.</p><h3 style="font-size: 18px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Workflow — Updating Packages</h3><p style="font-size: 14px; margin: 0px 0px 15px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">SwiftPM has no update mechanism yet, but once it does running&nbsp;<code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap; font-size: 12px; font-family: Consolas, 'Liberation Mono', Courier, monospace;" class="">swift build --update</code>&nbsp;will fetch the latest versions of all dependencies and update the lockfile.</p><h2 style="font-size: 24px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Impact on existing code</h2><p style="font-size: 14px; margin: 0px 0px 15px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">This proposal will have no impact on existing code.</p><h2 style="font-size: 24px; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Alternatives Considered</h2><p style="font-size: 14px; margin: 0px 0px 15px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">One alternative is to allow mentioning refs in manifest file while declaring a dependency but as discussed in&nbsp;<a href="http://markdownlivepreview.com/%22https://lists.swift.org/pipermail/swift-build-dev/Week-of-Mon-20151214/" style="color: rgb(65, 131, 196); text-decoration: none;" class="">this</a>&nbsp;thread it might not be the best idea.</p><p style="font-size: 14px; margin: 15px 0px; padding: 0px; color: rgb(51, 51, 51); font-family: Helvetica, arial, freesans, clean, sans-serif;" class="">Using Git submodules for this feature was considered. However something additionally would be required to specify swift version and record local diffs. Also this would lock us into git, and despite the fact that currently we only use git, we have not yet ruled out supporting other version control systems.</p></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=""></div></body></html>