Swift Digest
SE-0149 | Swift Evolution

Package Manager Support for Top of Tree development

Proposal
SE-0149
Authors
Boris Bügling
Review Manager
Daniel Dunbar
Status
Implemented (Swift 4.0)

01 何が問題だったのか

Swift Package Manager(SwiftPM)の依存パッケージは、通常はセマンティックバージョニングに従ってタグ付けされたバージョンを取得して利用します。すでに swift package edit により、SwiftPMが管理しているチェックアウトをその場で編集することは可能でしたが、開発者が自分でクローンしたリポジトリを「上書き(override)」として指定する方法はありませんでした。

このため、互いに依存する複数のパッケージを同時に開発したいケースで不便が生じます。たとえば次のような場面です。

  • 自分が管理する複数のパッケージにまたがる機能追加や修正を、いちいちバージョンタグを切らずに進めたい。
  • アプリケーション本体と、それが依存するパッケージを同時に改修しながら、アプリ側の文脈でパッケージをイテレーションしたい。

このような「top of tree(最新のブランチ先端)」での開発では、開発者は通常、対象リポジトリのチェックアウトを自分の手元に持っており、ブランチ切り替えなどのSCM操作も自分でおこないたいと考えます。しかし既存の仕組みでは、そのような手元のチェックアウトをSwiftPMに素直に使わせることができず、暫定的なバージョンをリリースしたり手作業でシンボリックリンクを張ったりといった回避策が必要でした。

02 どのように解決されるのか

swift package edit サブコマンドに、既存のチェックアウトへのパスを指定する --path オプションを追加します。これにより、開発者が手元で管理しているリポジトリを、そのパッケージの override としてSwiftPMに使わせることができます。

$ swift package edit bar --path ../bar

上の例では、依存パッケージ bar に対して ../bar にある既存のチェックアウトを使うよう指示しています。実行後の挙動は次のようになります。

  • ./Packages/bar が、指定したパス(../bar)へのシンボリックリンクになります。
  • SwiftPMは、このマッピングをワークスペースに記録します。
  • 以降、bar のソース管理(ブランチ切り替え、コミット、プル、プッシュなど)はSwiftPMではなく開発者自身の責任となります。これは従来の swift package edit と同じ考え方です。
  • 指定したパスにまだチェックアウトが存在しない場合は、SwiftPMが初回クローンを代行します。

override を解除したいときは、従来どおり swift package unedit を使います。この場合、Packages/bar のシンボリックリンクは削除されますが、手元のチェックアウト本体(../bar)は残ります。開発者が自分で管理しているリポジトリなので、勝手に削除されないようになっています。

これにより、複数パッケージを横断する開発や、アプリとパッケージを同時に改修するワークフローにおいて、暫定バージョンをリリースせずに手元のブランチ先端を使い続けられるようになります。