Skip to content

Commit 8591d2c

Browse files
committed
Merge branch 'feature/check-for-update-by-rss' into develop
2 parents 78c5052 + 4714371 commit 8591d2c

8 files changed

Lines changed: 83 additions & 95 deletions

File tree

Config.debug.xcconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include "Version.xcconfig"
2-
#include "Secrets.xcconfig"
32

43
BUNDLE_IDENTIFIER_BASE = dev.com.intii.CopilotForXcode
54
EXTENSION_BUNDLE_NAME = Copilot Dev

Config.xcconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include "Version.xcconfig"
2-
#include "Secrets.xcconfig"
32

43
BUNDLE_IDENTIFIER_BASE = com.intii.CopilotForXcode
54
EXTENSION_BUNDLE_NAME = Copilot

Copilot for Xcode.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@
145145
C800DBB0294C624D00B04CAC /* PrefetchSuggestionsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefetchSuggestionsCommand.swift; sourceTree = "<group>"; };
146146
C81291D52994FE6900196E12 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
147147
C81291D92994FE7900196E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
148-
C813B41E29B7B0F100FADAE3 /* Secrets.sample.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Secrets.sample.xcconfig; sourceTree = "<group>"; };
149148
C814588C2939EFDC00135263 /* Copilot.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Copilot.appex; sourceTree = BUILT_PRODUCTS_DIR; };
150149
C814588E2939EFDC00135263 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
151150
C81458902939EFDC00135263 /* XcodeKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XcodeKit.framework; path = Library/Frameworks/XcodeKit.framework; sourceTree = DEVELOPER_DIR; };
@@ -155,7 +154,6 @@
155154
C81458982939EFDC00135263 /* EditorExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = EditorExtension.entitlements; sourceTree = "<group>"; };
156155
C81458AD293A009600135263 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
157156
C81458AE293A009800135263 /* Config.debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.debug.xcconfig; sourceTree = "<group>"; };
158-
C815034B29B3A7CC00751CAC /* Secrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Secrets.xcconfig; sourceTree = "<group>"; };
159157
C8189B162938972F00C9DCDA /* Copilot for Xcode Dev.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Copilot for Xcode Dev.app"; sourceTree = BUILT_PRODUCTS_DIR; };
160158
C8189B192938972F00C9DCDA /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
161159
C8189B1B2938972F00C9DCDA /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
@@ -264,8 +262,6 @@
264262
C887BC832965D96000931567 /* DEVELOPMENT.md */,
265263
C8520308293D805800460097 /* README.md */,
266264
C81E867D296FE4420026E908 /* Version.xcconfig */,
267-
C813B41E29B7B0F100FADAE3 /* Secrets.sample.xcconfig */,
268-
C815034B29B3A7CC00751CAC /* Secrets.xcconfig */,
269265
C81458AD293A009600135263 /* Config.xcconfig */,
270266
C81458AE293A009800135263 /* Config.debug.xcconfig */,
271267
C8CD828229B88006008D044D /* TestPlan.xctestplan */,

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

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

Core/Package.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ let package = Package(
3434
.package(url: "https://github.com/apple/swift-async-algorithms", from: "0.1.0"),
3535
.package(url: "https://github.com/raspu/Highlightr", from: "2.1.0"),
3636
.package(url: "https://github.com/JohnSundell/Splash", from: "0.1.0"),
37+
.package(url: "https://github.com/nmdias/FeedKit", from: "9.1.2"),
3738
],
3839
targets: [
3940
.target(name: "CGEventObserver"),
@@ -116,7 +117,10 @@ let package = Package(
116117
"Splash",
117118
]
118119
),
119-
.target(name: "UpdateChecker", dependencies: ["Logger"]),
120+
.target(
121+
name: "UpdateChecker",
122+
dependencies: ["Logger", .product(name: "FeedKit", package: "FeedKit")]
123+
),
120124
.target(name: "AXExtension"),
121125
.target(name: "Logger"),
122126
]
Lines changed: 69 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
import AppKit
2+
import FeedKit
23
import Foundation
34
import Logger
45
import SwiftUI
56

6-
struct Release: Codable {
7-
let tag_name: String?
8-
let html_url: String?
9-
let body: String?
10-
let published_at: String?
11-
}
12-
137
let skippedUpdateVersionKey = "skippedUpdateVersion"
148

159
public struct UpdateChecker {
@@ -19,94 +13,85 @@ public struct UpdateChecker {
1913

2014
public init() {}
2115

22-
public func checkForUpdate() async {
23-
let url =
24-
URL(string: "https://api.github.com/repos/intitni/CopilotForXcode/releases/latest")!
25-
do {
26-
var request = URLRequest(url: url)
27-
let token = (Bundle.main.infoDictionary?["GITHUB_TOKEN"] as? String) ?? ""
28-
if !token.isEmpty {
29-
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
16+
public func checkForUpdate() {
17+
let url = URL(string: "https://github.com/intitni/CopilotForXcode/releases.atom")!
18+
let parser = FeedParser(URL: url)
19+
parser.parseAsync { result in
20+
switch result {
21+
case let .success(.atom(feed)):
22+
if let entry = feed.entries?.first(where: {
23+
guard let title = $0.title else { return false }
24+
return !title.contains("-")
25+
}) {
26+
self.alertIfUpdateAvailable(entry)
27+
}
28+
case let .failure(error):
29+
Logger.updateChecker.error(error)
30+
default: break
3031
}
31-
request.setValue("application/vnd.github+json", forHTTPHeaderField: "Accept")
32-
request.setValue("X-GitHub-Api-Version", forHTTPHeaderField: "2022-11-28")
33-
34-
let (data, _) = try await URLSession.shared.data(for: request)
35-
let decoder = JSONDecoder()
36-
let release = try decoder.decode(Release.self, from: data)
37-
guard let version = release.tag_name,
38-
version != skippedUpdateVersion,
39-
version != Bundle.main
40-
.infoDictionary?["CFBundleShortVersionString"] as? String
41-
else { return }
32+
}
33+
}
4234

43-
Task { @MainActor in
44-
let alert = NSAlert()
45-
alert.messageText = "Copilot for Xcode \(version) is available!"
46-
alert.informativeText = "Would you like to visit the release page?"
47-
let view = NSHostingView(
48-
rootView:
49-
AccessoryView(releaseNote: release.body)
50-
)
51-
view.frame = .init(origin: .zero, size: .init(width: 400, height: 200))
52-
alert.accessoryView = view
35+
func alertIfUpdateAvailable(_ entry: AtomFeedEntry) {
36+
guard let version = entry.title,
37+
let currentVersion = Bundle.main
38+
.infoDictionary?["CFBundleShortVersionString"] as? String,
39+
version != skippedUpdateVersion,
40+
version.compare(currentVersion, options: .numeric) == .orderedDescending
41+
else { return }
5342

54-
alert.addButton(withTitle: "Visit Release Page")
55-
alert.addButton(withTitle: "Skip This Version")
56-
alert.addButton(withTitle: "Cancel")
57-
alert.alertStyle = .informational
58-
let screenFrame = NSScreen.main?.frame ?? .zero
59-
let window = NSWindow(
60-
contentRect: .init(
61-
x: screenFrame.midX,
62-
y: screenFrame.midY,
63-
width: 1,
64-
height: 1
65-
),
66-
styleMask: .borderless,
67-
backing: .buffered,
68-
defer: true
69-
)
70-
window.level = .floating
71-
window.isReleasedWhenClosed = false
72-
alert.beginSheetModal(for: window) { [window] response in
73-
switch response {
74-
case .alertFirstButtonReturn:
75-
if let url = URL(string: release.html_url ?? "") {
76-
NSWorkspace.shared.open(url)
77-
}
78-
case .alertSecondButtonReturn:
79-
UserDefaults.standard.set(version, forKey: skippedUpdateVersionKey)
80-
default:
81-
break
82-
}
83-
window.close()
84-
}
85-
}
86-
} catch {
87-
Logger.updateChecker.error(error)
43+
Task { @MainActor in
44+
let screenFrame = NSScreen.main?.frame ?? .zero
45+
let window = NSWindow(
46+
contentRect: .init(
47+
x: screenFrame.midX,
48+
y: screenFrame.midY + 200,
49+
width: 500,
50+
height: 500
51+
),
52+
styleMask: .borderless,
53+
backing: .buffered,
54+
defer: true
55+
)
56+
window.level = .floating
57+
window.isReleasedWhenClosed = false
58+
window.contentViewController = NSHostingController(
59+
rootView: AlertView(entry: entry, window: window)
60+
)
61+
window.makeKeyAndOrderFront(nil)
8862
}
8963
}
9064
}
9165

92-
struct AccessoryView: View {
93-
let releaseNote: String?
66+
struct AlertView: View {
67+
let entry: AtomFeedEntry
68+
let window: NSWindow
9469

9570
var body: some View {
96-
if let releaseNote {
97-
ScrollView {
98-
Text(releaseNote)
99-
.padding()
100-
101-
Spacer()
71+
let version = entry.title ?? "0.0.0"
72+
Color.clear.alert(
73+
"Copilot for Xcode \(version) is available!",
74+
isPresented: .constant(true)
75+
) {
76+
Button {
77+
if let url = URL(string: entry.links?.first?.attributes?.href ?? "") {
78+
NSWorkspace.shared.open(url)
79+
}
80+
window.close()
81+
} label: {
82+
Text("Visit Release Page")
10283
}
103-
.background(Color(nsColor: .textBackgroundColor))
104-
.overlay {
105-
Rectangle()
106-
.stroke(Color(nsColor: .separatorColor), style: .init(lineWidth: 2))
84+
85+
Button {
86+
UserDefaults.standard.set(version, forKey: skippedUpdateVersionKey)
87+
window.close()
88+
} label: {
89+
Text("Skip This Version")
10790
}
108-
} else {
109-
EmptyView()
91+
92+
Button { window.close() } label: { Text("Cancel") }
93+
} message: {
94+
Text("Would you like to visit the release page?")
11095
}
11196
}
11297
}

ExtensionService/Info.plist

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
<string>$(BUNDLE_IDENTIFIER_BASE)</string>
77
<key>EXTENSION_BUNDLE_NAME</key>
88
<string>$(EXTENSION_BUNDLE_NAME)</string>
9-
<key>GITHUB_TOKEN</key>
10-
<string>$(GITHUB_TOKEN)</string>
119
<key>XPCService</key>
1210
<dict>
1311
<key>ServiceType</key>

Secrets.sample.xcconfig

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)