Skip to content

Commit 6d437d5

Browse files
committed
Pre-release 0.25.87
1 parent b1d1755 commit 6d437d5

File tree

7 files changed

+87
-35
lines changed

7 files changed

+87
-35
lines changed

Copilot for Xcode.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Copilot for Xcode/App.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
1515
func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool { true }
1616
}
1717

18+
class AppUpdateCheckerDelegate: UpdateCheckerDelegate {
19+
func prepareForRelaunch(finish: @escaping () -> Void) {
20+
Task {
21+
let service = try? getService()
22+
try? await service?.quitService()
23+
finish()
24+
}
25+
}
26+
}
27+
1828
@main
1929
struct CopilotForXcodeApp: App {
2030
@NSApplicationDelegateAdaptor private var appDelegate: AppDelegate
@@ -28,9 +38,12 @@ struct CopilotForXcodeApp: App {
2838
UserDefaults.setupDefaultSettings()
2939
}
3040
.copilotIntroSheet()
41+
.environment(\.updateChecker, UpdateChecker(
42+
hostBundle: Bundle.main,
43+
checkerDelegate: AppUpdateCheckerDelegate()
44+
))
3145
}
3246
}
3347
}
3448

3549
var isPreview: Bool { ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" }
36-

Core/Sources/HostApp/GeneralSettings/AppInfoView.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ struct AppInfoView: View {
1616
@StateObject var settings = Settings()
1717
@StateObject var viewModel: GitHubCopilotViewModel
1818

19-
@State var automaticallyCheckForUpdate: Bool?
2019
@State var appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
2120

2221
let store: StoreOf<General>
@@ -48,11 +47,8 @@ struct AppInfoView: View {
4847
}
4948
HStack {
5049
Toggle(isOn: .init(
51-
get: { automaticallyCheckForUpdate ?? updateChecker.automaticallyChecksForUpdates },
52-
set: {
53-
updateChecker.automaticallyChecksForUpdates = $0
54-
automaticallyCheckForUpdate = $0
55-
}
50+
get: { updateChecker.getAutomaticallyChecksForUpdates() },
51+
set: { updateChecker.setAutomaticallyChecksForUpdates($0) }
5652
)) {
5753
Text("Automatically Check for Updates")
5854
}

Core/Sources/HostApp/GeneralSettings/GeneralSettingsView.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import ComposableArchitecture
22
import SwiftUI
33

44
struct GeneralSettingsView: View {
5-
@Environment(\.updateChecker) var updateChecker
65
@AppStorage(\.extensionPermissionShown) var extensionPermissionShown: Bool
76
@AppStorage(\.quitXPCServiceOnXcodeAndAppQuit) var quitXPCServiceOnXcodeAndAppQuit: Bool
87
@State private var shouldPresentExtensionPermissionAlert = false

Core/Sources/HostApp/TabContainer.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,11 @@ private extension EnvironmentValues {
201201
}
202202

203203
struct UpdateCheckerKey: EnvironmentKey {
204-
static var defaultValue: UpdateChecker = .init(hostBundle: Bundle.main)
204+
static var defaultValue: UpdateCheckerProtocol = NoopUpdateChecker()
205205
}
206206

207207
public extension EnvironmentValues {
208-
var updateChecker: UpdateChecker {
208+
var updateChecker: UpdateCheckerProtocol {
209209
get { self[UpdateCheckerKey.self] }
210210
set { self[UpdateCheckerKey.self] = newValue }
211211
}

Core/Sources/UpdateChecker/UpdateChecker.swift

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,74 @@ import Logger
22
import Preferences
33
import Sparkle
44

5-
public final class UpdateChecker {
5+
public protocol UpdateCheckerProtocol {
6+
func checkForUpdates()
7+
func getAutomaticallyChecksForUpdates() -> Bool
8+
func setAutomaticallyChecksForUpdates(_ value: Bool)
9+
}
10+
11+
public protocol UpdateCheckerDelegate: AnyObject {
12+
func prepareForRelaunch(finish: @escaping () -> Void)
13+
}
14+
15+
public final class NoopUpdateChecker: UpdateCheckerProtocol {
16+
public init() {}
17+
public func checkForUpdates() {}
18+
public func getAutomaticallyChecksForUpdates() -> Bool { false }
19+
public func setAutomaticallyChecksForUpdates(_ value: Bool) {}
20+
}
21+
22+
public final class UpdateChecker: UpdateCheckerProtocol {
623
let updater: SPUUpdater
7-
let hostBundleFound: Bool
824
let delegate = UpdaterDelegate()
925

10-
public init(hostBundle: Bundle?) {
11-
if hostBundle == nil {
12-
hostBundleFound = false
13-
Logger.updateChecker.error("Host bundle not found")
14-
} else {
15-
hostBundleFound = true
16-
}
26+
public init(hostBundle: Bundle, checkerDelegate: UpdateCheckerDelegate) {
1727
updater = SPUUpdater(
18-
hostBundle: hostBundle ?? Bundle.main,
28+
hostBundle: hostBundle,
1929
applicationBundle: Bundle.main,
20-
userDriver: SPUStandardUserDriver(hostBundle: hostBundle ?? Bundle.main, delegate: nil),
30+
userDriver: SPUStandardUserDriver(hostBundle: hostBundle, delegate: nil),
2131
delegate: delegate
2232
)
33+
delegate.updateCheckerDelegate = checkerDelegate
2334
do {
2435
try updater.start()
2536
} catch {
2637
Logger.updateChecker.error(error.localizedDescription)
2738
}
2839
}
2940

41+
public convenience init?(hostBundle: Bundle?, checkerDelegate: UpdateCheckerDelegate) {
42+
guard let hostBundle = hostBundle else { return nil }
43+
self.init(hostBundle: hostBundle, checkerDelegate: checkerDelegate)
44+
}
45+
3046
public func checkForUpdates() {
3147
updater.checkForUpdates()
3248
}
3349

34-
public var automaticallyChecksForUpdates: Bool {
35-
get { updater.automaticallyChecksForUpdates }
36-
set { updater.automaticallyChecksForUpdates = newValue }
50+
public func getAutomaticallyChecksForUpdates() -> Bool {
51+
updater.automaticallyChecksForUpdates
52+
}
53+
54+
public func setAutomaticallyChecksForUpdates(_ value: Bool) {
55+
updater.automaticallyChecksForUpdates = value
3756
}
3857
}
3958

4059
class UpdaterDelegate: NSObject, SPUUpdaterDelegate {
60+
weak var updateCheckerDelegate: UpdateCheckerDelegate?
61+
62+
func updater(
63+
_ updater: SPUUpdater,
64+
shouldPostponeRelaunchForUpdate item: SUAppcastItem,
65+
untilInvokingBlock installHandler: @escaping () -> Void) -> Bool {
66+
if let updateCheckerDelegate {
67+
updateCheckerDelegate.prepareForRelaunch(finish: installHandler)
68+
return true
69+
}
70+
return false
71+
}
72+
4173
func allowedChannels(for updater: SPUUpdater) -> Set<String> {
4274
if UserDefaults.shared.value(for: \.installPrereleases) {
4375
Set(["prerelease"])

ExtensionService/AppDelegate.swift

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,24 @@ let bundleIdentifierBase = Bundle.main
1717
.object(forInfoDictionaryKey: "BUNDLE_IDENTIFIER_BASE") as! String
1818
let serviceIdentifier = bundleIdentifierBase + ".ExtensionService"
1919

20+
class ExtensionUpdateCheckerDelegate: UpdateCheckerDelegate {
21+
func prepareForRelaunch(finish: @escaping () -> Void) {
22+
Task {
23+
await Service.shared.prepareForExit()
24+
finish()
25+
}
26+
}
27+
}
28+
2029
@main
2130
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
2231
let service = Service.shared
2332
var statusBarItem: NSStatusItem!
2433
var xpcController: XPCController?
2534
let updateChecker =
2635
UpdateChecker(
27-
hostBundle: locateHostBundleURL(url: Bundle.main.bundleURL)
28-
.flatMap(Bundle.init(url:))
36+
hostBundle: Bundle(url: locateHostBundleURL(url: Bundle.main.bundleURL)),
37+
checkerDelegate: ExtensionUpdateCheckerDelegate()
2938
)
3039
let statusChecker: AuthStatusChecker = AuthStatusChecker()
3140
var xpcExtensionService: XPCExtensionService?
@@ -57,12 +66,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
5766

5867
@objc func openCopilotForXcode() {
5968
let task = Process()
60-
if let appPath = locateHostBundleURL(url: Bundle.main.bundleURL)?.absoluteString {
61-
task.launchPath = "/usr/bin/open"
62-
task.arguments = [appPath]
63-
task.launch()
64-
task.waitUntilExit()
65-
}
69+
let appPath = locateHostBundleURL(url: Bundle.main.bundleURL)
70+
task.launchPath = "/usr/bin/open"
71+
task.arguments = [appPath.absoluteString]
72+
task.launch()
73+
task.waitUntilExit()
6674
}
6775

6876
@objc func openGlobalChat() {
@@ -140,6 +148,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
140148
}
141149

142150
@objc func checkForUpdate() {
151+
guard let updateChecker = updateChecker else {
152+
Logger.service.error("Unable to check for updates: updateChecker is nil.")
153+
return
154+
}
143155
updateChecker.checkForUpdates()
144156
}
145157

@@ -160,7 +172,7 @@ extension NSRunningApplication {
160172
}
161173
}
162174

163-
func locateHostBundleURL(url: URL) -> URL? {
175+
func locateHostBundleURL(url: URL) -> URL {
164176
var nextURL = url
165177
while nextURL.path != "/" {
166178
nextURL = nextURL.deletingLastPathComponent()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy