[swift-evolution] [swift-build-dev] [Proposal] Lock file for Swift Package Manager
Ankit Agarwal
ankit at ankit.im
Wed Dec 23 10:02:51 CST 2015
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.
Lock File for Swift Package ManagerIntroduction
A Package.lock file containing list of resolved dependencies generated by
swiftpm.
Motivation
Package.lock file can be helpful in situations like :
Reproduce exact versions of dependencies on different machine
- 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
- When a build is being performed on a remote machine eg CI
Pointing a dependency to an untagged commit
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 :
- Forking a 3rd party library and making it swiftpm compatible for
temporary use until officially supported by the author
- Package is in active development and not ready for a release tag
Proposed Solution
swiftpm generates a simple Package.lock file after resolving the dependency
graph for that package in some simple format.
Detailed DesignPackage.lock aka the lock file
Package.lock is a plain text auto-generated file containing list of
resolved dependencies: one line per dependency in format
<gitURL> <resolvedVersion>
"github.com/foo/bar" "v1.1"
"../mygitdir" "v2.3"
"github.com/my/forked/dep" "8b3989be184375ae6e84e8a0254e5258789b23e5"
- Package.lock will always contain the exact version of the dependency
resolved by SPM
- User is expected to commit the lock file into the git repo for others
to reproduce the exact versions of dependencies on their system
- lock file of dependencies are ignored and only their Package.swift is
taken into consideration for resolving all the dependencies
User is not expected to interact with this file as it'll always be
generated by SPM so it might make sense to:
- not to use swift syntax in this file.
- keep it seperate from Package.swift to avoid confusion for new users.
Another option could be using very minimal valid swift syntax for eg :
[
("github.com/foo/bar", "v1.1"),
("../mygitdir","v2.3"),
("github.com/my/forked/dep","8b3989be184375ae6e84e8a0254e5258789b23e5")
]
Workflow$ swift build :
-
Dependencies declared in Package.swift and Package.lock is not present :
Resolves Package.swift and generates Package.lock; uses the generated
Package.lock to fetch and build the dependencies
-
Package.lock already present :
Uses the generated Package.lock to fetch and build the dependencies.
if Package.swift has been modified SPM generates a warning for user to
consider updating the lock file using $ swift build --update (explained
below)
-
Packages/ is out of sync with lock file :
*Uncommited changes in Packages/* : User is probably trying to modify
the dep so suggest him to use the $ swift build --ignore-lock command
(explained below)
*Commited changes in Packages/* : User is done making changes in the
dependency but forgot to lock them so HEADs don't match, suggest
him to use $
swift build --lock command (explained below)
$ swift build --update :
- Remove current Package.lock if present and re-resolve Package.swift to
generate a new Package.lock file for all the deps.
- To update only one dependency use $ swift build --update=<dep_name>
$ swift build --lock :
- Locks the current HEAD packages in Packages/ and writes them into the
lock file uses tags where available otherwise refs
- To lock only one dependency use $ swift build --lock=<dep_name>
$ swift build --ignore-lock :
- Ignores the lock file and use HEAD of Package/ to build the deps
without writing to lock file
- Useful for development
Workflow for Pointing a dependency to an untagged commit
- Create Package.swift and declare dependencies
- Run $ swift build to resolve and build the Package
- Modify and play with the checkedout dependencies in Packages/
- Commit and push the changes to the git remote mentioned in
Package.swift
- Once satisfied with the current state of a package lock it using $
swift build --lock=<dep_name>
- Commit the lock file and push for others to use
If a dependency(foo) is using a dependency(bar) with an untagged commit
- Author of foo mentions in their readme that they're using bar on an
untagged commit
- Package(baz) wanting to use foo and bar both will need to lock his bar
package to same untagged commit
Impact on existing code
None on the code but old users will not be able to run $ swift build with
changes in their Packages/ which is possible right now, they'll need to use $
swift build --ignore-lock instead which will be communicated using warnings
as stated above.
Alternatives Considered
One alternative is to allow mentioning refs in manifest file while
declaring a dependency but as discussed in this
<file:///Users/aciid/Dropbox/notes/%22https://lists.swift.org/pipermail/swift-build-dev/Week-of-Mon-20151214/>
thread
it might not be the best idea.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151223/2f4dac73/attachment.html>
More information about the swift-evolution
mailing list