Skip to content

Commit

Permalink
Pre-release 0.25.87
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Oct 21, 2024
1 parent b1d1755 commit 6d437d5
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/sparkle-project/Sparkle",
"state" : {
"revision" : "87e4fcbac39912f9cdb9a9acf205cad60e1ca3bc",
"version" : "2.4.2"
"revision" : "0ef1ee0220239b3776f433314515fd849025673f",
"version" : "2.6.4"
}
},
{
Expand Down
15 changes: 14 additions & 1 deletion Copilot for Xcode/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool { true }
}

class AppUpdateCheckerDelegate: UpdateCheckerDelegate {
func prepareForRelaunch(finish: @escaping () -> Void) {
Task {
let service = try? getService()
try? await service?.quitService()
finish()
}
}
}

@main
struct CopilotForXcodeApp: App {
@NSApplicationDelegateAdaptor private var appDelegate: AppDelegate
Expand All @@ -28,9 +38,12 @@ struct CopilotForXcodeApp: App {
UserDefaults.setupDefaultSettings()
}
.copilotIntroSheet()
.environment(\.updateChecker, UpdateChecker(
hostBundle: Bundle.main,
checkerDelegate: AppUpdateCheckerDelegate()
))
}
}
}

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

8 changes: 2 additions & 6 deletions Core/Sources/HostApp/GeneralSettings/AppInfoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ struct AppInfoView: View {
@StateObject var settings = Settings()
@StateObject var viewModel: GitHubCopilotViewModel

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

let store: StoreOf<General>
Expand Down Expand Up @@ -48,11 +47,8 @@ struct AppInfoView: View {
}
HStack {
Toggle(isOn: .init(
get: { automaticallyCheckForUpdate ?? updateChecker.automaticallyChecksForUpdates },
set: {
updateChecker.automaticallyChecksForUpdates = $0
automaticallyCheckForUpdate = $0
}
get: { updateChecker.getAutomaticallyChecksForUpdates() },
set: { updateChecker.setAutomaticallyChecksForUpdates($0) }
)) {
Text("Automatically Check for Updates")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import ComposableArchitecture
import SwiftUI

struct GeneralSettingsView: View {
@Environment(\.updateChecker) var updateChecker
@AppStorage(\.extensionPermissionShown) var extensionPermissionShown: Bool
@AppStorage(\.quitXPCServiceOnXcodeAndAppQuit) var quitXPCServiceOnXcodeAndAppQuit: Bool
@State private var shouldPresentExtensionPermissionAlert = false
Expand Down
4 changes: 2 additions & 2 deletions Core/Sources/HostApp/TabContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,11 @@ private extension EnvironmentValues {
}

struct UpdateCheckerKey: EnvironmentKey {
static var defaultValue: UpdateChecker = .init(hostBundle: Bundle.main)
static var defaultValue: UpdateCheckerProtocol = NoopUpdateChecker()
}

public extension EnvironmentValues {
var updateChecker: UpdateChecker {
var updateChecker: UpdateCheckerProtocol {
get { self[UpdateCheckerKey.self] }
set { self[UpdateCheckerKey.self] = newValue }
}
Expand Down
60 changes: 46 additions & 14 deletions Core/Sources/UpdateChecker/UpdateChecker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,74 @@ import Logger
import Preferences
import Sparkle

public final class UpdateChecker {
public protocol UpdateCheckerProtocol {
func checkForUpdates()
func getAutomaticallyChecksForUpdates() -> Bool
func setAutomaticallyChecksForUpdates(_ value: Bool)
}

public protocol UpdateCheckerDelegate: AnyObject {
func prepareForRelaunch(finish: @escaping () -> Void)
}

public final class NoopUpdateChecker: UpdateCheckerProtocol {
public init() {}
public func checkForUpdates() {}
public func getAutomaticallyChecksForUpdates() -> Bool { false }
public func setAutomaticallyChecksForUpdates(_ value: Bool) {}
}

public final class UpdateChecker: UpdateCheckerProtocol {
let updater: SPUUpdater
let hostBundleFound: Bool
let delegate = UpdaterDelegate()

public init(hostBundle: Bundle?) {
if hostBundle == nil {
hostBundleFound = false
Logger.updateChecker.error("Host bundle not found")
} else {
hostBundleFound = true
}
public init(hostBundle: Bundle, checkerDelegate: UpdateCheckerDelegate) {
updater = SPUUpdater(
hostBundle: hostBundle ?? Bundle.main,
hostBundle: hostBundle,
applicationBundle: Bundle.main,
userDriver: SPUStandardUserDriver(hostBundle: hostBundle ?? Bundle.main, delegate: nil),
userDriver: SPUStandardUserDriver(hostBundle: hostBundle, delegate: nil),
delegate: delegate
)
delegate.updateCheckerDelegate = checkerDelegate
do {
try updater.start()
} catch {
Logger.updateChecker.error(error.localizedDescription)
}
}

public convenience init?(hostBundle: Bundle?, checkerDelegate: UpdateCheckerDelegate) {
guard let hostBundle = hostBundle else { return nil }
self.init(hostBundle: hostBundle, checkerDelegate: checkerDelegate)
}

public func checkForUpdates() {
updater.checkForUpdates()
}

public var automaticallyChecksForUpdates: Bool {
get { updater.automaticallyChecksForUpdates }
set { updater.automaticallyChecksForUpdates = newValue }
public func getAutomaticallyChecksForUpdates() -> Bool {
updater.automaticallyChecksForUpdates
}

public func setAutomaticallyChecksForUpdates(_ value: Bool) {
updater.automaticallyChecksForUpdates = value
}
}

class UpdaterDelegate: NSObject, SPUUpdaterDelegate {
weak var updateCheckerDelegate: UpdateCheckerDelegate?

func updater(
_ updater: SPUUpdater,
shouldPostponeRelaunchForUpdate item: SUAppcastItem,
untilInvokingBlock installHandler: @escaping () -> Void) -> Bool {
if let updateCheckerDelegate {
updateCheckerDelegate.prepareForRelaunch(finish: installHandler)
return true
}
return false
}

func allowedChannels(for updater: SPUUpdater) -> Set<String> {
if UserDefaults.shared.value(for: \.installPrereleases) {
Set(["prerelease"])
Expand Down
30 changes: 21 additions & 9 deletions ExtensionService/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,24 @@ let bundleIdentifierBase = Bundle.main
.object(forInfoDictionaryKey: "BUNDLE_IDENTIFIER_BASE") as! String
let serviceIdentifier = bundleIdentifierBase + ".ExtensionService"

class ExtensionUpdateCheckerDelegate: UpdateCheckerDelegate {
func prepareForRelaunch(finish: @escaping () -> Void) {
Task {
await Service.shared.prepareForExit()
finish()
}
}
}

@main
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
let service = Service.shared
var statusBarItem: NSStatusItem!
var xpcController: XPCController?
let updateChecker =
UpdateChecker(
hostBundle: locateHostBundleURL(url: Bundle.main.bundleURL)
.flatMap(Bundle.init(url:))
hostBundle: Bundle(url: locateHostBundleURL(url: Bundle.main.bundleURL)),
checkerDelegate: ExtensionUpdateCheckerDelegate()
)
let statusChecker: AuthStatusChecker = AuthStatusChecker()
var xpcExtensionService: XPCExtensionService?
Expand Down Expand Up @@ -57,12 +66,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {

@objc func openCopilotForXcode() {
let task = Process()
if let appPath = locateHostBundleURL(url: Bundle.main.bundleURL)?.absoluteString {
task.launchPath = "/usr/bin/open"
task.arguments = [appPath]
task.launch()
task.waitUntilExit()
}
let appPath = locateHostBundleURL(url: Bundle.main.bundleURL)
task.launchPath = "/usr/bin/open"
task.arguments = [appPath.absoluteString]
task.launch()
task.waitUntilExit()
}

@objc func openGlobalChat() {
Expand Down Expand Up @@ -140,6 +148,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
}

@objc func checkForUpdate() {
guard let updateChecker = updateChecker else {
Logger.service.error("Unable to check for updates: updateChecker is nil.")
return
}
updateChecker.checkForUpdates()
}

Expand All @@ -160,7 +172,7 @@ extension NSRunningApplication {
}
}

func locateHostBundleURL(url: URL) -> URL? {
func locateHostBundleURL(url: URL) -> URL {
var nextURL = url
while nextURL.path != "/" {
nextURL = nextURL.deletingLastPathComponent()
Expand Down

0 comments on commit 6d437d5

Please sign in to comment.