swift package resolveは、Package.swiftに書いたパッケージの依存関係を解決する。パッケージの取得とPackage.resolvedの更新だけを実行し、ビルドはしない。

$ swift package resolve
Fetching https://github.com/jpsim/Yams from cache
Fetched https://github.com/jpsim/Yams from cache (0.56s)
Computing version for https://github.com/jpsim/Yams
Computed https://github.com/jpsim/Yams at 6.2.2 (0.63s)
Creating working copy for https://github.com/jpsim/Yams
Working copy of https://github.com/jpsim/Yams resolved at 6.2.2

swift package resolveは、Package.swiftのあるフォルダで実行する。Xcodeプロジェクト(.xcodeproj)の依存関係には使えない。Xcodeプロジェクトの依存関係は、xcodebuild -resolvePackageDependenciesで解決する。

参考: 【xcodebuild】SwiftPMの依存関係の解決だけを先に実行する (-resolvePackageDependencies)

実行例はSwift 6.4、macOS 27.0.1のもの。

作られるファイル

Package.resolvedが、パッケージのルートに作られる。取得したパッケージは、.buildフォルダに保存される。

$ ls -A
.build
Package.resolved
Package.swift
Sources
$ ls .build
artifacts
CACHEDIR.TAG
checkouts
repositories
workspace-state.json

.buildの中のartifacts、checkouts、repositories、workspace-state.jsonは、xcodebuildがDerivedDataのSourcePackagesに保存するファイルと同じ構成である。

Package.resolvedのバージョンは維持される

Package.resolvedに記録済みのバージョンが、Package.swiftの要件を満たしているときは、より新しいバージョンがあっても、記録されたバージョンのまま解決される。要件が6.0.0以上のパッケージで、Package.resolvedを6.0.0に書き換えて解決すると、6.0.0が維持された。

$ swift package resolve
Working copy of https://github.com/jpsim/Yams resolved at 6.0.0

Package.swiftの要件をfrom: "6.1.0"に変更すると、記録されたバージョンが要件を満たさなくなる。この状態で解決すると、Package.resolvedが更新された。

$ swift package resolve
Updating https://github.com/jpsim/Yams
Computed https://github.com/jpsim/Yams at 6.2.2 (0.60s)
Working copy of https://github.com/jpsim/Yams resolved at 6.2.2

最新のバージョンに更新する

swift package updateは、Package.resolvedのバージョンを無視して、要件を満たす最新のバージョンに更新する。Package.resolvedを6.0.0にした状態で実行すると、6.2.2になった。

$ swift package update
Updating https://github.com/jpsim/Yams
Updated https://github.com/jpsim/Yams (0.51s)
Computing version for https://github.com/jpsim/Yams
Computed https://github.com/jpsim/Yams at 6.2.2 (0.57s)
Working copy of https://github.com/jpsim/Yams resolved at 6.2.2
コマンドPackage.resolvedのバージョン
swift package resolve要件を満たしていれば維持する
swift package update要件を満たす最新のバージョンに更新する

バージョンを指定して解決する

swift package resolveにパッケージ名と--versionを指定すると、そのバージョンで解決する。Package.swiftは変更されない。

$ swift package resolve Yams --version 6.1.0
Updating https://github.com/jpsim/Yams
Updated https://github.com/jpsim/Yams (0.52s)
Computing version for https://github.com/jpsim/Yams
Computed https://github.com/jpsim/Yams at 6.1.0 (0.57s)
Working copy of https://github.com/jpsim/Yams resolved at 6.1.0

--versionの代わりに、--branchと--revisionも指定できる。

Package.resolvedの更新を禁止する

swift buildに--force-resolved-versionsを付けると、Package.resolvedに記録されたバージョン以外には解決しない。--disable-automatic-resolutionと--only-use-versions-from-resolved-fileは、--force-resolved-versionsの別名である。

.buildのないクリーンな状態で、Package.resolvedがないと、ビルドは終了コード1で失敗する。

$ swift build --force-resolved-versions
error: a resolved file is required when automatic dependency resolution is disabled and should be placed at [パッケージのパス]/Package.resolved. Running resolver because the following dependencies were added: ...
$ echo $?
1

swift package resolveの後にPackage.resolvedだけを削除した状態では、.build/workspace-state.jsonに解決済みの状態が残っているので、同じコマンドが成功した。CIのクリーンな環境では、Package.resolvedをコミットしておく。

Package.swiftの要件を変更して、Package.resolvedが古くなったときも、終了コード1で失敗する。

error: an out-of-date resolved file was detected at [パッケージのパス]/Package.resolved, which is not allowed when automatic dependency resolution is disabled; please make sure to update the file to reflect the changes in dependencies. ...

Package.resolvedが要件を満たしていれば、ビルドは成功する。

$ swift build --force-resolved-versions
Build complete!

--force-resolved-versionsを付けないswift buildは、Package.resolvedがなくても、自動で依存関係を解決してビルドに成功する。Package.resolvedも作られる。

パッケージの保存先を指定する

--scratch-pathは、.buildの代わりに使うフォルダを指定する。解決とビルドで同じフォルダを指定すると、ビルドでは取得が実行されない。

$ swift package --scratch-path [保存先のフォルダ] resolve
Working copy of https://github.com/jpsim/Yams resolved at 6.1.0
$ swift build --scratch-path [保存先のフォルダ] --force-resolved-versions
Build complete!

実行例のビルドは、FetchingやCreating working copyは出力されずに成功した。

Package.swiftがないとき

Package.swiftがないフォルダで実行すると、エラーで終了コード1になる。

$ swift package resolve
error: Could not find Package.swift in this directory or any of its parent directories.
$ echo $?
1

.xcodeprojだけがあるフォルダも同じである。

どちらの方法を選ぶか

やりたいことxcodebuild(Xcodeプロジェクト)swift(Package.swift)
依存関係の解決だけを実行する-resolvePackageDependenciesswift package resolve
Package.resolvedのバージョンだけで実行する-disableAutomaticPackageResolution--force-resolved-versions
保存先を指定する-clonedSourcePackagesDirPath--scratch-path
失敗時の終了コード741

Package.swiftのあるパッケージは、CIの最初のステップにswift package resolveを置き、ビルドには--force-resolved-versionsを付ける。Xcodeプロジェクトは、xcodebuildのオプションを使う。