Skip to content

Commit ca36d07

Browse files
authored
Sync script updates (#81)
* Tidepool Sync * Make sure diffs exist, merge in LoopKit updates
1 parent 7236425 commit ca36d07

File tree

2 files changed

+66
-80
lines changed

2 files changed

+66
-80
lines changed

Scripts/sync.swift

Lines changed: 65 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,57 @@ import Foundation
66
import Cocoa
77

88
import AsyncSwiftGit // @bdewey
9-
import OctoKit // /Users/pete/dev/octokit.swift
9+
import OctoKit // nerdishbynature/octokit.swift == main
10+
11+
let createPRs = false
12+
13+
guard CommandLine.arguments.count == 3 else {
14+
print("usage: sync.swift <pull-request-title> <branch-name>")
15+
exit(1)
16+
}
17+
let pullRequestName = CommandLine.arguments[1] // example: "LOOP-4688 DIY Sync"
18+
let syncBranch = CommandLine.arguments[2] // example: "ps/LOOP-4688/diy-sync"
19+
20+
enum EnvError: Error {
21+
case missing(String)
22+
}
23+
24+
func getEnv(_ name: String) throws -> String {
25+
guard let value = ProcessInfo.processInfo.environment[name] else {
26+
throw EnvError.missing(name)
27+
}
28+
return value
29+
}
30+
31+
let ghUsername = try getEnv("GH_USERNAME")
32+
let ghToken = try getEnv("GH_TOKEN")
33+
let ghCommitterName = try getEnv("GH_COMMITTER_NAME")
34+
let ghCommitterEmail = try getEnv("GH_COMMITTER_EMAIL")
1035

1136
struct Project {
1237
let project: String
1338
let branch: String
39+
let subdir: String
1440

15-
init(_ project: String, _ branch: String) {
41+
init(_ project: String, _ branch: String, _ subdir: String = "") {
1642
self.project = project
1743
self.branch = branch
44+
self.subdir = subdir
45+
}
46+
47+
var path: String {
48+
if subdir.isEmpty {
49+
return project
50+
} else {
51+
return subdir + "/" + project
52+
}
1853
}
1954
}
2055

2156
let projects = [
2257
Project("Loop", "dev"),
2358
Project("LoopKit", "dev"),
59+
Project("TidepoolService", "dev"),
2460
Project("CGMBLEKit", "dev"),
2561
Project("dexcom-share-client-swift", "dev"),
2662
Project("RileyLinkKit", "dev"),
@@ -32,49 +68,31 @@ let projects = [
3268
Project("NightscoutRemoteCGM", "dev"),
3369
Project("LoopSupport", "dev"),
3470
Project("G7SensorKit", "main"),
35-
Project("TidepoolService", "dev"),
36-
Project("TidepoolKit", "dev"),
3771
Project("OmniKit", "main"),
38-
Project("MinimedKit", "main")
72+
Project("MinimedKit", "main"),
73+
Project("LibreTransmitter", "main")
3974
]
4075

4176
let fm = FileManager.default
4277
let loopkit = URL(string: "https://github.com/LoopKit")!
4378
let tidepool = URL(string: "https://github.com/tidepool-org")!
44-
let syncBranch = "tidepool-sync"
4579
let incomingRemote = "tidepool"
4680

47-
enum EnvError: Error {
48-
case missing(String)
49-
}
50-
51-
func getEnv(_ name: String) throws -> String {
52-
guard let value = ProcessInfo.processInfo.environment[name] else {
53-
throw EnvError.missing(name)
54-
}
55-
return value
56-
}
57-
58-
let ghUsername = try getEnv("GH_USERNAME")
59-
let ghToken = try getEnv("GH_TOKEN")
60-
let ghCommitterName = try getEnv("GH_COMMITTER_NAME")
61-
let ghCommitterEmail = try getEnv("GH_COMMITTER_EMAIL")
62-
6381
let octokit = Octokit(TokenConfiguration(ghToken))
6482

6583
let credentials = Credentials.plaintext(username: ghUsername, password: ghToken)
6684
let signature = try! Signature(name: ghCommitterName, email: ghCommitterEmail)
6785

6886
for project in projects {
69-
let dest = URL(string: fm.currentDirectoryPath)!.appendingPathComponent(project.project)
87+
let dest = URL(string: fm.currentDirectoryPath)!.appendingPathComponent(project.path)
7088
let repository: AsyncSwiftGit.Repository
71-
if !fm.fileExists(atPath: project.project) {
89+
if !fm.fileExists(atPath: dest.path) {
7290
print("Cloning \(project.project)")
7391
let url = loopkit.appendingPathComponent(project.project)
7492
repository = try await Repository.clone(from: url, to: dest)
7593
print("Cloned \(project.project)")
7694
} else {
77-
print("Already Exists: \(project.project)")
95+
print("Already Exists: \(project.path)")
7896
repository = try Repository(openAt: dest)
7997
}
8098

@@ -95,11 +113,10 @@ for project in projects {
95113
// Merge changes from tidepool to diy
96114
try await repository.merge(revisionSpecification: "\(incomingRemote)/\(project.branch)", signature: signature)
97115

98-
let (ahead, behind) = try repository.commitsAheadBehind(other: "origin/\(project.branch)")
99-
print("Ahead = \(ahead)")
100-
print("Behind = \(behind)")
116+
let originTree = try repository.lookupTree(for: "origin/\(project.branch)")
117+
let diff = try repository.diff(originTree, repository.headTree)
101118

102-
guard ahead > 0 else {
119+
guard diff.count > 0 else {
103120
print("No incoming changes; skipping PR creation.")
104121
try await repository.checkout(revspec: project.branch)
105122
continue
@@ -110,55 +127,24 @@ for project in projects {
110127
print("Pushing \(refspec) to \(project.project)")
111128
try await repository.push(remoteName: "origin", refspecs: [refspec], credentials: credentials)
112129

113-
// Make sure a PR exists, or create it
114-
let prs = try await octokit.listPullRequests(owner: "LoopKit", repo: project.project, base: project.branch, head:"LoopKit:tidepool-sync")
115-
let pr: PullRequest
116-
if prs.count == 0 {
117-
pr = try await octokit.createPullRequest(owner: "LoopKit", repo: project.project, title: "Tidepool Sync", head: "LoopKit:" + syncBranch, base: project.branch, body: "")
118-
print("PR = \(pr)")
119-
} else {
120-
pr = prs.first!
121-
}
122-
if let url = pr.htmlURL {
123-
if NSWorkspace.shared.open(url) {
124-
print("default browser was successfully opened")
125-
126-
}
127-
}
130+
if createPRs {
131+
// Make sure a PR exists, or create it
132+
133+
let prs = try await octokit.pullRequests(owner: "LoopKit", repository: project.project, base: project.branch, head:"LoopKit:" + syncBranch)
134+
let pr: PullRequest
135+
if prs.count == 0 {
136+
pr = try await octokit.createPullRequest(owner: "LoopKit", repo: project.project, title: pullRequestName, head: "LoopKit:" + syncBranch, base: project.branch, body: "")
137+
print("PR = \(pr)")
138+
} else {
139+
pr = prs.first!
140+
}
141+
if let url = pr.htmlURL {
142+
if NSWorkspace.shared.open(url) {
143+
print("default browser was successfully opened")
144+
}
145+
}
146+
} else {
147+
print("Skipping PR creation")
148+
}
128149
}
129150

130-
extension Octokit {
131-
func createPullRequest(owner: String,
132-
repo: String,
133-
title: String,
134-
head: String,
135-
headRepo: String? = nil,
136-
base: String,
137-
body: String? = nil,
138-
maintainerCanModify: Bool? = nil,
139-
draft: Bool? = nil) async throws -> PullRequest
140-
{
141-
return try await withCheckedThrowingContinuation { continuation in
142-
octokit.createPullRequest(owner: owner, repo: repo, title: title, head: head, headRepo: headRepo, base: base, body: body, maintainerCanModify: maintainerCanModify, draft: draft)
143-
{ response in
144-
continuation.resume(with: response)
145-
}
146-
}
147-
}
148-
149-
func listPullRequests(owner: String,
150-
repo: String,
151-
base: String? = nil,
152-
head: String? = nil,
153-
state: Openness = .open,
154-
sort: SortType = .created,
155-
direction: SortDirection = .desc) async throws -> [PullRequest]
156-
{
157-
return try await withCheckedThrowingContinuation { continuation in
158-
octokit.pullRequests(owner: owner, repository: repo, base: base, head: head, state: state, sort: sort, direction: direction)
159-
{ response in
160-
continuation.resume(with: response)
161-
}
162-
}
163-
}
164-
}

0 commit comments

Comments
 (0)