|
1 | 1 | import Foundation |
| 2 | +import GitHubCopilotService |
2 | 3 | import Preferences |
3 | 4 |
|
4 | 5 | extension UserDefaultPreferenceKeys { |
5 | 6 | struct OldMigrationVersion: UserDefaultPreferenceKey { |
6 | | - typealias PreferenceValueType = String |
7 | | - static let key = "OldMigrationVersion" |
| 7 | + var defaultValue: String = "0" |
| 8 | + let key = "OldMigrationVersion" |
8 | 9 | } |
9 | | - |
| 10 | + |
10 | 11 | var oldMigrationVersion: OldMigrationVersion { .init() } |
11 | 12 | } |
12 | 13 |
|
13 | | -struct ServiceUpdateMigrator { |
14 | | - func migrate() { |
15 | | - migrate( |
16 | | - from: UserDefaults.shared.value(for: \.oldMigrationVersion), |
17 | | - to: Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") |
18 | | - ) |
19 | | - } |
| 14 | +public struct ServiceUpdateMigrator { |
| 15 | + public init() {} |
20 | 16 |
|
21 | | - func migrate(from oldVersion: String, to currentVersion: String) { |
22 | | - guard let old = Int(oldVersion), let new = Int(currentVersion) else { return } |
23 | | - guard old != new else { return } |
| 17 | + public func migrate() async throws { |
| 18 | + let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String ?? "0" |
| 19 | + |
| 20 | + try await migrate(from: UserDefaults.shared.value(for: \.oldMigrationVersion), to: version) |
| 21 | + UserDefaults.shared.set(version, for: \.oldMigrationVersion) |
| 22 | + } |
| 23 | + |
| 24 | + func migrate(from oldVersion: String, to currentVersion: String) async throws { |
| 25 | + guard let old = Int(oldVersion) else { return } |
24 | 26 | if old <= 135 { |
25 | | - migrateFromLowerThanOrEqualToVersion135() |
| 27 | + try migrateFromLowerThanOrEqualToVersion135() |
26 | 28 | } |
27 | 29 | } |
28 | 30 | } |
29 | 31 |
|
30 | | -func migrateFromLowerThanOrEqualToVersion135() {} |
| 32 | +func migrateFromLowerThanOrEqualToVersion135() throws { |
| 33 | + // 0. Create the application support folder if it doesn't exist |
| 34 | + |
| 35 | + let urls = try GitHubCopilotBaseService.createFoldersIfNeeded() |
| 36 | + |
| 37 | + // 1. Move the undefined folder in application support into a sub folder called `GitHub |
| 38 | + // Copilot/support` |
| 39 | + |
| 40 | + let undefinedFolderURL = urls.applicationSupportURL.appendingPathComponent("undefined") |
| 41 | + var isUndefinedADirectory: ObjCBool = false |
| 42 | + let isUndefinedExisted = FileManager.default.fileExists( |
| 43 | + atPath: undefinedFolderURL.path, |
| 44 | + isDirectory: &isUndefinedADirectory |
| 45 | + ) |
| 46 | + if isUndefinedExisted, isUndefinedADirectory.boolValue { |
| 47 | + try FileManager.default.moveItem( |
| 48 | + at: undefinedFolderURL, |
| 49 | + to: urls.supportURL.appendingPathComponent("undefined") |
| 50 | + ) |
| 51 | + } |
| 52 | + |
| 53 | + // 2. Copy the GitHub copilot language service to `GitHub Copilot/executable` |
| 54 | + |
| 55 | + let copilotFolderURL = urls.executableURL.appendingPathComponent("copilot") |
| 56 | + var copilotIsFolder: ObjCBool = false |
| 57 | + let executable = Bundle.main.resourceURL?.appendingPathComponent("copilot") |
| 58 | + if let executable, |
| 59 | + FileManager.default.fileExists(atPath: executable.path, isDirectory: &copilotIsFolder), |
| 60 | + !FileManager.default.fileExists(atPath: copilotFolderURL.path) |
| 61 | + { |
| 62 | + try FileManager.default.copyItem( |
| 63 | + at: executable, |
| 64 | + to: urls.executableURL.appendingPathComponent("copilot") |
| 65 | + ) |
| 66 | + } |
| 67 | + |
| 68 | + // 3. Use chmod to change the permission of the executable to 755 |
| 69 | + |
| 70 | + try FileManager.default.setAttributes( |
| 71 | + [.posixPermissions: 0o755], |
| 72 | + ofItemAtPath: copilotFolderURL.path |
| 73 | + ) |
| 74 | +} |
| 75 | + |
0 commit comments