I will explain the operations
- resolve
- reset
- update
and how these commands affect a Swift Package. I will further show how to invoke those operations from the command line or within Xcode.
I use the following example: a package with a single package dependency pinned to an exact version (Alamofire 5.4.0). The Package.swift
manifest file:
// swift-tools-version: 5.6
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Package1",
products: [
.library(
name: "Package1",
targets: ["Package1"]),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire", .exactItem("5.4.0")),
],
targets: [
.target(
name: "Package1",
dependencies: [
"AlamoFire"
])
]
)
Initially the package, created with swift package init
command, had no Package.resolved
file.
When I opened the package in Xcode and added the following line in Package.swift
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire", .exactItem("5.4.0")),
],
then Xcode automatically started the dependency resolution and created a Package.resolved
file in the top level of the package to record the result of the dependency resolution.
{
"pins" : [
{
"identity" : "alamofire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire",
"state" : {
"revision" : "9e0328127dfb801cefe8ac53a13c0c90a7770448",
"version" : "5.4.0"
}
}
],
"version" : 2
}
If I had edited the Package.swift
file in a text editor, I would have had to manually trigger the dependency resolution. See the next chapter :)
Resolve
swift package resolve
The
swift package resolve
command resolves the dependencies, taking into account the current version restrictions in thePackage.swift
manifest andPackage.resolved
resolved versions file, and issuing an error if the graph cannot be resolved.
Source: SPM Documentation
Key takeaway:
- no changes to an existing
Package.resolved
file !! - creates a
Package.resolved
file if such does not exist.
The equivalent Xcode option is named "Resolve Package Versions".
When changing the Package.manifest
to use a different version requirement, e.g.
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/Alamofire/Alamofire", .upToNextMinor(from: "5.4.0"))
],
and running swift package resolve
, then you need to understand that this will not bring any changes! Because Package.resolved
was not changed.
Reset
swift package reset
This will reset the complete cache/build directory. For SPM (command-line) this will affect the .build
folder.
The equivalent Xcode option is named "Reset Package Caches". This will affect the SourcePackages
of the related folder in DerivedData.
Update
The swift package update
command will touch the Package.resolved
file.
Running
swift package update
updates all dependencies to the latest eligible versions and updates the Package.resolved file accordingly.
Source: SPM Documentation
Remember I changed Package.swift
to use a newer version of my package dependency:
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/Alamofire/Alamofire", .upToNextMinor(from: "5.4.0"))
],
Running swift package update
will change Package.resolved
{
"pins" : [
{
"identity" : "alamofire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire",
"state" : {
"revision" : "d120af1e8638c7da36c8481fd61a66c0c08dc4fc",
"version" : "5.4.4"
}
}
],
"version" : 2
}
and will download the new version.
In Xcode the same can be achieved from the top-level menu
but also in the Package Dependency pane you can select "Update Package" on an individual package.
"Update Package" actually affects the whole Package.resolved
file and is not truly package-specific.
Summary
If a download was interrupted then use "reset" and "resolve".
If you want to use a newer version or you changed version requirements in your
Package.swift
file then use "update".