Skip to content

Commit 6d437d5

Browse files
committedOct 21, 2024·
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
 

Diff for: ‎Copilot for Xcode.xcworkspace/xcshareddata/swiftpm/Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@
131131
"kind" : "remoteSourceControl",
132132
"location" : "https://github.com/sparkle-project/Sparkle",
133133
"state" : {
134-
"revision" : "87e4fcbac39912f9cdb9a9acf205cad60e1ca3bc",
135-
"version" : "2.4.2"
134+
"revision" : "0ef1ee0220239b3776f433314515fd849025673f",
Has a conversation. Original line has a conversation.
135+
"version" : "2.6.4"
136136
}
137137
},
138138
{

Diff for: ‎Copilot for Xcode/App.swift

+14-1
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()
Has a conversation. Original line has a conversation.
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-

Diff for: ‎Core/Sources/HostApp/GeneralSettings/AppInfoView.swift

+2-6
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
}

Diff for: ‎Core/Sources/HostApp/GeneralSettings/GeneralSettingsView.swift

-1
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

Diff for: ‎Core/Sources/HostApp/TabContainer.swift

+2-2
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
}

Diff for: ‎Core/Sources/UpdateChecker/UpdateChecker.swift

+46-14
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"])

Diff for: ‎ExtensionService/AppDelegate.swift

+21-9
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()

1 commit comments

Comments
 (1)

bejorkasoki commented on Dec 23, 2024

@bejorkasoki

Hello

Please sign in to comment.