データ移行の基本実装

AppPorts のデータ移行機能は、アプリに関連するデータディレクトリ(~/Library/Application Support、~/Library/Caches など)を外部ストレージに移行し、ローカルのディスク容量を解放します。
コア戦略:シンボリックリンク
データディレクトリの移行にはWhole Symlink戦略を使用します:
- 元のローカルディレクトリ全体を外部ストレージにコピー
- 管理リンクメタデータ(
.appports-link-metadata.plist)を外部ディレクトリに書き込む - 元のローカルディレクトリを同じボリューム上の隠し安全バックアップにリネーム
- 元のパスに外部コピーを指すシンボリックリンクを作成
- シンボリックリンク作成後にローカル安全バックアップを削除
~/Library/Application Support/SomeApp
→ /Volumes/External/AppPortsData/SomeApp (symlink)移行フロー
flowchart TD
A[データディレクトリを選択] --> B{権限と保護チェック}
B -->|失敗| Z[終了]
B -->|成功| C{ターゲットパスの競合検出}
C -->|管理メタデータあり| D[自動回復モード]
C -->|競合なし| E[外部ストレージにコピー]
D --> E
E --> F[管理リンクメタデータを書き込み]
F --> G[ローカルディレクトリを安全バックアップにリネーム]
G -->|失敗| H[外部コピーを保持して停止]
G -->|成功| I[シンボリックリンクを作成]
I -->|失敗| J[ローカル安全バックアップを復元し外部コピーを保持]
I -->|成功| K[ローカル安全バックアップを削除]
K -->|成功| L[移行完了]
K -->|失敗| M[移行完了、ただし安全バックアップは残る]管理リンクメタデータ
AppPorts は、そのディレクトリが AppPorts によって管理されていることを識別するために、外部ディレクトリに .appports-link-metadata.plist ファイルを書き込みます。メタデータには以下の情報が含まれます:
| フィールド | 説明 |
|---|---|
schemaVersion | メタデータバージョン番号(現在は1) |
managedBy | 管理者識別子(com.shimoko.AppPorts) |
sourcePath | 元のローカルパス |
destinationPath | 外部ストレージのターゲットパス |
dataDirType | データディレクトリタイプ |
このメタデータはスキャン時に使用され、AppPorts 管理のリンクとユーザーが作成したシンボリックリンクを区別し、移行中断時の自動回復をサポートします。
自動回復では厳密な一致を使用します。外部ターゲットがすでに存在する場合、schemaVersion、managedBy、sourcePath、destinationPath、dataDirType が現在の操作とすべて一致するときだけ、AppPorts は回復可能な対象として扱います。一致するメタデータがない実ディレクトリは競合として扱われ、ディレクトリサイズが近いだけでは回復や引き継ぎを行いません。
再リンクと正規化はディレクトリだけを対象にします。AppPorts は外部の通常ファイルをデータディレクトリとして再リンクまたは移動することを拒否し、ファイルがローカルのシンボリックリンクに置き換わることを防ぎます。
サポートされるデータディレクトリタイプ
| タイプ | パスの例 |
|---|---|
applicationSupport | ~/Library/Application Support/ |
preferences | ~/Library/Preferences/ |
containers | ~/Library/Containers/ |
groupContainers | ~/Library/Group Containers/ |
caches | ~/Library/Caches/ |
webKit | ~/Library/WebKit/ |
httpStorages | ~/Library/HTTPStorages/ |
applicationScripts | ~/Library/Application Scripts/ |
logs | ~/Library/Logs/ |
savedState | ~/Library/Saved Application State/ |
dotFolder | ~/.npm、~/.vscode など |
custom | ユーザー定義パス |
復元フロー
- ローカルパスが有効な外部ディレクトリを指すシンボリックリンクであることを確認
- ローカルのシンボリックリンクを削除
- 外部ディレクトリをローカルにコピー
- 外部ディレクトリを削除(ベストエフォート)
コピーに失敗した場合、一貫性を維持するためにシンボリックリンクを自動的に再構築します。
エラーハンドリングとロールバック
移行プロセスの各重要なステップには、ロールバックメカニズムが含まれています:
- コピー失敗: それ以上のアクションは実行されない;コピーされた外部ファイルをクリーンアップ
- ローカル安全バックアップへの移動失敗: 移行を停止し、外部コピーを保持します。ローカルの元ディレクトリは削除されません
- シンボリックリンク作成失敗: 可能な場合はローカル安全バックアップを元のパスへ復元し、外部コピーも保持して両側のデータ消失を避けます
- 安全バックアップ削除失敗: 移行自体は完了扱いです。ローカルに
.appports-migration-backup-*フォルダが残るため、確認後に手動削除できます
この設計により、どの段階で失敗が発生してもデータの損失がなく、システム状態の一貫性が保証されます。
