移行戦略
アプリコンテナ分類
AppPorts は、移行前にアプリを分類して移行の粒度を決定します:
| 分類 | 定義 | 例 |
|---|---|---|
standaloneApp | トップレベルディレクトリに単一の .app パッケージ | Safari、Finder |
singleAppContainer | 1つの .app パッケージのみを含むディレクトリ | 一部のサードパーティアプリインストールディレクトリ |
appSuiteFolder | 2つ以上の .app パッケージを含むディレクトリ | Microsoft Office、Adobe Creative Cloud |
分類結果は移行戦略の選択に影響し、singleAppContainer と appSuiteFolder は、中の個々の .app ファイルを処理するのではなく、ディレクトリ全体を単位として移行します。
3つの移行戦略
AppPorts は、移行後もアプリをローカルから起動可能にするための3つのローカルエントリ(Portal)戦略を定義しています:
Whole App Symlink
.app ディレクトリ全体(またはディレクトリ)をシンボリックリンクとして外部ストレージに作成します。
/Applications/SomeApp.app → /Volumes/External/SomeApp.app使用ケース:
- アプリコンテナ分類が
singleAppContainerまたはappSuiteFolder(ディレクトリ操作) .app以外のパス拡張子を持つ非標準アプリ
特徴: Finder にアイコンに矢印ショートカットマークが表示されます。
Deep Contents Wrapper(Contents ディレクトリ移行)
ローカルに実際の .app ディレクトリを作成し、Contents/ サブディレクトリのみをシンボリックリンクで外部ストレージにリンクします。
/Applications/SomeApp.app/
└── Contents → /Volumes/External/SomeApp.app/Contents (symlink)現在のステータス: 非推奨。新しい移行ではこの戦略は使用されず、旧バージョンで移行されたアプリを復元する場合にのみ認識・処理されます。
非推奨の理由: 自動更新プログラムが Contents/ シンボリックリンクをたどって外部ストレージファイルを直接操作し、アプリケーションを破損する可能性があるため。
Stub Portal
ローカルに最小限の .app シェルを作成し、open を呼び出してランチスクリプト経由で外部ストレージ上の実際のアプリを起動します。
/Applications/SomeApp.app/
├── Contents/
│ ├── MacOS/launcher # bash ランチスクリプト
│ ├── Resources/AppIcon.icns # 実際のアプリからコピーしたアイコン
│ ├── Info.plist # 簡略化された設定ファイル
│ └── PkgInfo # 標準識別子ファイル使用ケース: .app 拡張子を持つすべてのアプリ(デフォルト戦略)。
特徴: ローカルにシンボリックリンクが存在しない;Finder に矢印マークが表示されない;自動更新プログラムは侵入できない。
macOS Stub Portal
ネイティブ macOS アプリの場合:
Contents/MacOS/launcherランチスクリプトを作成(内容:open "<外部アプリパス>")- 外部アプリから
PkgInfoとアイコンファイルをコピー - 外部アプリの
Info.plistから簡略化されたInfo.plistを生成:CFBundleExecutableをlauncherに設定LSUIElementをtrueに設定(Dock に非表示)- Sparkle/Electron 関連の設定キーを削除
- Bundle ID に
.appports.stubサフィックスを追加
- Ad-hoc コード署名を実行
iOS Stub Portal
iOS アプリ(Mac で動作する iOS アプリ)の場合、macOS 版との違い:
Wrapper/またはWrappedBundle/ディレクトリ内の.appパッケージからアイコンを抽出sipsを使用して PNG を 256×256 にスケーリングし、.icnsフォーマットに変換Info.plistはiTunesMetadata.plistから生成(iOS アプリには標準のInfo.plistが含まれていない)- コード署名なし;拡張属性のクリーンアップのみ(
xattr -cr)
戦略選択の決定木
flowchart TD
A[移行開始] --> B{ディレクトリ操作ですか?}
B -->|はい: singleAppContainer または appSuiteFolder| C[Whole App Symlink]
B -->|いいえ| D{パス拡張子は .app で終わりますか?}
D -->|いいえ| C
D -->|はい| E{iOS アプリですか?}
E -->|はい| F[iOS Stub Portal]
E -->|いいえ| G[macOS Stub Portal]Deep Contents Wrapper について
現在のバージョンでは、新しい移行に対してこの戦略は選択されなくなりました。preferredPortalKind() メソッドはすべての .app アプリに対して stubPortal を返します。Deep Contents Wrapper は、過去に移行されたアプリを復元する場合にのみレガシースキームとして認識されます。
