<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="">To some length I have discussed the filename issue with Rick and I think I agree with him that `.lock` was a bad choice from the packaging community in general.<div class=""><br class=""></div><div class="">This is a command line tool and there is a long history of .lock files meaning “the file is locked because it is in use, do not edit the file without the .lock extension” on UNIX.</div><div class=""><br class=""></div><div class="">Carthage agreed, they chose ‘.resolved’.</div><div class=""><br class=""></div><div class="">NPM creates a “npm-shrinkwrap.json” file (although it will only do this on demand). I like the name “shrink-wrap” since it conveys the ‘sealed’ nature of the process.</div><div class=""><br class=""></div><div class="">We should consider using a proper format like JSON and using its extension too.</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 4, 2016, at 1:17 PM, Ankit Agarwal &lt;<a href="mailto:ankit@ankit.im" class="">ankit@ankit.im</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">Hi&nbsp;<div class="">any updates on this?<br class=""><br class="">On Wednesday 23 December 2015, Ankit Agarwal &lt;<a href="mailto:ankit@ankit.im" class="">ankit@ankit.im</a>&gt; wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class="">Thank you all for the valuable feedback I have updated the proposal to reflect the changes which are agreed upon by majority. Please go through the updated proposal below and provide more feedback.&nbsp;</div><div class=""><br class=""></div><div class=""><div class=""><br class=""></div><h1 style="margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding: 0px; font-size: 28px; font-family: Helvetica, arial, sans-serif; margin-top: 0px !important;" class="">Lock File for Swift Package Manager</h1><h2 style="margin: 0px 0px 10px; padding: 0px; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;" class="">Introduction</h2><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class="">A Package.lock file containing list of resolved dependencies generated by swiftpm.</p><h2 style="margin: 20px 0px 10px; padding: 0px; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;" class="">Motivation</h2><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.lock</code>&nbsp;file can be helpful in situations like :</p><h3 style="margin: 20px 0px 10px; padding: 0px; font-size: 18px; font-family: Helvetica, arial, sans-serif;" class="">Reproduce exact versions of dependencies on different machine</h3><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class="">Multiple developers working on a package would want to use the exact versions(including minor and patch) of the dependencies declared in the manifest file</li><li style="margin:0px" class="">When a build is being performed on a remote machine eg CI&nbsp;</li></ul><h3 style="margin: 20px 0px 10px; padding: 0px; font-size: 18px; font-family: Helvetica, arial, sans-serif;" class="">Pointing a dependency to an untagged commit</h3><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class="">Sometimes it might be helpful to lock a dependency to a particular commit ref for which a tagged version is unavailable in cases such as :</p><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class="">Forking a 3rd party library and making it swiftpm compatible for temporary use until officially supported by the author</li><li style="margin:0px" class="">Package is in active development and not ready for a release tag</li></ul><h2 style="margin: 20px 0px 10px; padding: 0px; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;" class="">Proposed Solution</h2><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class="">swiftpm generates a simple&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.lock</code>&nbsp;file after resolving the dependency graph for that package in some simple format.</p><h2 style="margin: 20px 0px 10px; padding: 0px; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;" class="">Detailed Design</h2><h2 style="margin: 20px 0px 10px; padding: 0px; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;" class="">Package.lock aka the lock file</h2><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.lock</code>&nbsp;is a plain text auto-generated file containing list of resolved dependencies: one line per dependency in format</p><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class="">&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">&lt;gitURL&gt; &lt;resolvedVersion&gt;</code></p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 13px; 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;" 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" class="">"<a href="http://github.com/foo/bar" target="_blank" class="">github.com/foo/bar</a>" "v1.1"
"../mygitdir" "v2.3"
"<a href="http://github.com/my/forked/dep" target="_blank" class="">github.com/my/forked/dep</a>" "8b3989be184375ae6e84e8a0254e5258789b23e5"</code></pre><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class=""><code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.lock</code>&nbsp;will always contain the exact version of the dependency resolved by SPM</li><li style="margin:0px" class="">User is expected to commit the lock file into the git repo for others to reproduce the exact versions of dependencies on their system</li><li style="margin:0px" class="">lock file of dependencies are ignored and only their Package.swift is taken into consideration for resolving all the dependencies</li></ul><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class="">User is not expected to interact with this file as it'll always be generated by SPM so it might make sense to:</p><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class="">not to use swift syntax in this file.</li><li style="margin:0px" class="">keep it seperate from Package.swift to avoid confusion for new users.</li></ul><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class="">Another option could be using very minimal valid swift syntax for eg :</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 13px; 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;" 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" class="">[
 ("<a href="http://github.com/foo/bar" target="_blank" class="">github.com/foo/bar</a>", "v1.1"), 
 ("../mygitdir","v2.3"),
 ("<a href="http://github.com/my/forked/dep" target="_blank" class="">github.com/my/forked/dep</a>","8b3989be184375ae6e84e8a0254e5258789b23e5")
]</code></pre><h2 style="margin: 20px 0px 10px; padding: 0px; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;" class="">Workflow</h2><h3 style="margin: 20px 0px 10px; padding: 0px; font-size: 18px; font-family: Helvetica, arial, sans-serif;" class=""><code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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;font-size:inherit" class="">$ swift build</code>&nbsp;:</h3><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class=""><p style="margin:0px 0px 15px" class="">Dependencies declared in&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.swift</code>&nbsp;and&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.lock</code>&nbsp;is not present :</p><p style="margin:15px 0px" class="">Resolves&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.swift</code>&nbsp;and generates&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.lock</code>; uses the generated&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.lock</code>&nbsp;to fetch and build the dependencies</p></li><li style="margin:0px" class=""><p style="margin:0px 0px 15px" class=""><code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.lock</code>&nbsp;already present :</p><p style="margin:15px 0px" class="">Uses the generated&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.lock</code>&nbsp;to fetch and build the dependencies.</p><p style="margin:15px 0px" class="">if&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.swift</code>&nbsp;has been modified SPM generates a warning for user to consider updating the lock file using&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">$ swift build --update</code>&nbsp;(explained below)</p></li><li style="margin:0px" class=""><p style="margin:0px 0px 15px" class="">Packages/ is out of sync with lock file :</p><p style="margin:15px 0px" class=""><strong style="margin-top:0px" class="">Uncommited changes in Packages/</strong>&nbsp;: User is probably trying to modify the dep so suggest him to use the&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">$ swift build --ignore-lock</code>&nbsp;command (explained below)</p><p style="margin:15px 0px" class=""><strong style="margin-top:0px" class="">Commited changes in Packages/</strong>&nbsp;: User is done making changes in the dependency but forgot to lock them so HEADs don't match, suggest him to use&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">$ swift build --lock</code>&nbsp;command (explained below)</p></li></ul><h3 style="margin: 20px 0px 10px; padding: 0px; font-size: 18px; font-family: Helvetica, arial, sans-serif;" class=""><code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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;font-size:inherit" class="">$ swift build --update</code>&nbsp;:</h3><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class="">Remove current Package.lock if present and re-resolve Package.swift to generate a new Package.lock file for all the deps.</li><li style="margin:0px" class="">To update only one dependency use&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">$ swift build --update=&lt;dep_name&gt;</code></li></ul><h3 style="margin: 20px 0px 10px; padding: 0px; font-size: 18px; font-family: Helvetica, arial, sans-serif;" class=""><code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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;font-size:inherit" class="">$ swift build --lock</code>&nbsp;:</h3><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class="">Locks the current HEAD packages in Packages/ and writes them into the lock file uses tags where available otherwise refs</li><li style="margin:0px" class="">To lock only one dependency use&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">$ swift build --lock=&lt;dep_name&gt;</code></li></ul><h3 style="margin: 20px 0px 10px; padding: 0px; font-size: 18px; font-family: Helvetica, arial, sans-serif;" class=""><code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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;font-size:inherit" class="">$ swift build --ignore-lock</code>&nbsp;:</h3><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class="">Ignores the lock file and use HEAD of Package/ to build the deps without writing to lock file</li><li style="margin:0px" class="">Useful for development</li></ul><h3 style="margin: 20px 0px 10px; padding: 0px; font-size: 18px; font-family: Helvetica, arial, sans-serif;" class="">Workflow for Pointing a dependency to an untagged commit</h3><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class="">Create&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">Package.swift</code>&nbsp;and declare dependencies</li><li style="margin:0px" class="">Run&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">$ swift build</code>&nbsp;to resolve and build the Package</li><li style="margin:0px" class="">Modify and play with the checkedout dependencies in Packages/</li><li style="margin:0px" class="">Commit and push the changes to the git remote mentioned in Package.swift</li><li style="margin:0px" class="">Once satisfied with the current state of a package lock it using&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">$ swift build --lock=&lt;dep_name&gt;</code></li><li style="margin:0px" class="">Commit the lock file and push for others to use</li></ul><h3 style="margin: 20px 0px 10px; padding: 0px; font-size: 18px; font-family: Helvetica, arial, sans-serif;" class="">If a dependency(foo) is using a dependency(bar) with an untagged commit</h3><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class=""><li style="margin:0px" class="">Author of foo mentions in their readme that they're using bar on an untagged commit</li><li style="margin:0px" class="">Package(baz) wanting to use foo and bar both will need to lock his bar package to same untagged commit</li></ul><h2 style="margin: 20px 0px 10px; padding: 0px; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;" class="">Impact on existing code</h2><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px;" class="">None on the code but old users will not be able to run&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">$ swift build</code>&nbsp;with changes in their Packages/ which is possible right now, they'll need to use&nbsp;<code style="margin:0px 2px;padding:0px 5px;white-space:nowrap;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" class="">$ swift build --ignore-lock</code>&nbsp;instead which will be communicated using warnings as stated above.</p><h2 style="margin: 20px 0px 10px; padding: 0px; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;" class="">Alternatives Considered</h2><p style="margin-top: 15px; margin-right: 0px; margin-left: 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; margin-bottom: 0px !important;" class="">One alternative is to allow mentioning refs in manifest file while declaring a dependency but as discussed in&nbsp;<a style="color:rgb(65,131,196)" class="">this</a>&nbsp;thread it might not be the best idea.</p></div><div class=""><br class=""></div><div class=""><br class=""></div><br class=""><div class="gmail_extra"><div class=""><br class=""></div>
</div></div>
</blockquote></div><br class=""><br class="">-- <br class="">Ankit<br class=""><br class=""><br class="">
</div></blockquote></div><br class=""></div></body></html>