Swift Digest
SE-0219 | Swift Evolution

Package Manager Dependency Mirroring

Proposal
SE-0219
Authors
Ankit Aggarwal
Review Manager
Boris Bügling
Status
Implemented (Swift 5.0)

01 何が問題だったのか

SwiftPM では、パッケージが依存するライブラリは Package.swift に書かれた URL から取得されます。通常はこれで問題ありませんが、運用上は元の URL をそのまま使いたくない場面がいくつかあります。

  • 可用性: 元のリポジトリが一時的にダウンしていたり、削除されてしまったりしても、手元のビルドを通したい。
  • キャッシュ: 社内ネットワークから元のホストへのアクセスが遅い、あるいは禁止されている環境でも依存を取得したい。
  • 検証: 上流の更新を社内に取り込む前に、ミラーを挟んでスクリーニングや検証を行いたい。

こうした用途に応えるには、依存の取得先を元のリポジトリとは別の場所(ミラー)に差し替える仕組みが必要です。SE-0219 以前の SwiftPM にはその仕組みがなく、Package.swift の URL を書き換える以外に取得先を切り替える手段がありませんでした。しかし Package.swift はパッケージの構成を記述するファイルで、利用者の環境ごとに異なるミラーを当てる用途には向きません。自分で編集権限を持たないパッケージの依存先をミラーに差し替えたい、というケースにも対応できません。

つまり、パッケージの定義とは独立に、利用者側(トップレベルのパッケージ)の都合で依存の取得先をミラーに差し替える仕組み が求められていました。

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

SwiftPM に、依存のミラーを登録するための パッケージ設定ファイル と、それを操作するコマンドが追加されました。元の URL とミラー URL の対応を設定しておくと、以降 SwiftPM はその依存に対する fetch や update などすべての git 操作を、ミラー URL に対して行います。直接の依存だけでなく、推移的な依存(依存の依存)に対してもミラーを設定できます。

ミラーの登録と解除

ミラーの登録には swift package config set-mirror を使います。

$ swift package config set-mirror \
    --package-url <元の URL> \
    --mirror-url <ミラー URL>

# 例:
$ swift package config set-mirror \
    --package-url https://github.com/Core/libCore.git \
    --mirror-url https://mygithub.com/myOrg/libCore.git

ひとつの依存に対してミラー URL は1つだけ登録でき、既に設定済みの場合は set-mirror で上書きされます。

解除には swift package config unset-mirror を使います。元の URL、ミラー URL、あるいは --all のいずれかで指定できます。

$ swift package config unset-mirror --package-url https://github.com/Core/libCore.git
$ swift package config unset-mirror --mirror-url https://mygithub.com/myOrg/libCore.git
$ swift package config unset-mirror --all

設定ファイルの場所

ミラーの設定は、パッケージルート直下の次のファイルに保存されます。

<package-root>/.swiftpm/config

フォーマットは実装詳細ですが、実体としては JSON です。このファイルは SwiftPM のコマンド経由で管理されることを想定しており、手で編集することは意図されていません。また、Package.resolved と同様に、依存側のパッケージに置かれた設定ファイルはトップレベルのパッケージに影響しません。ミラーが効くのは、あくまで自分がトップレベルとしてビルドしているパッケージの設定だけです。これにより、依存側から勝手に取得先を差し替えられる心配はありません。

環境変数によるオーバーライド

環境変数 SWIFTPM_MIRROR_CONFIG を設定すると、設定ファイルのパスをその値で上書きできます。設定ファイルを持たないパッケージに対してミラーを当てたい場合や、CI と開発マシンで異なるミラー設定を使い分けたい場合に便利です。この環境変数はミラー設定のみを上書きし、将来的に設定ファイルに他の項目が入った場合でもそこまでは差し替えません。

依存解決への影響

依存解決で実際に使われたミラー URL は Package.resolved にも記録されます。これにより、どのミラーから取得された状態でロックされているかが明確になります。

プライバシー上の注意

ミラー自体が依存側から影響を受けることはないため、セキュリティ上の新たな懸念はありません。ただし、社内ミラーの URL を含む .swiftpm/config を公開リポジトリに誤ってコミットしてしまうと、内部の情報が外部に漏れる可能性があります。公開パッケージで運用する場合は、このファイルを誤ってコミットしないよう注意が必要です。