Skip to content

Commit 64331d3

Browse files
Merge pull request #6 from SwiftPackageIndex/parse-new-package-updates
Parse new package updates
2 parents 2fdf8b0 + 1688261 commit 64331d3

File tree

4 files changed

+116
-7
lines changed

4 files changed

+116
-7
lines changed

Sources/ReleaseNotesCore/Parser.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,27 @@ enum Parser {
5050
static let revision = semanticVersion
5151
.orElse(Prefix { $0 != " " }.map { .branch(String($0)) })
5252

53-
static let upToTwiddle = Prefix { $0 != "~" }
53+
static let newPackageToken: Character = "+"
54+
static let updatedRevisionToken: Character = "~"
55+
static let upToStart = Prefix { $0 != newPackageToken && $0 != updatedRevisionToken }
5456

55-
static let update = Skip(upToTwiddle)
56-
.skip("~ ")
57+
static let newPackage = Skip(upToStart)
58+
.skip("\(newPackageToken) ")
59+
.take(Prefix { $0 != " " }.map(String.init))
60+
.skip(Prefix { $0 != "\n" })
61+
.map { Update(packageName: $0, oldRevision: nil) }
62+
63+
static let updatedRevision = Skip(upToStart)
64+
.skip("\(updatedRevisionToken) ")
5765
.take(Prefix { $0 != " " }.map(String.init))
5866
.skip(" ")
5967
.take(revision)
6068
.skip(" -> ")
6169
.skip(Prefix { $0 != "\n" })
6270
.map(Update.init(packageName:oldRevision:))
6371

72+
static let update = updatedRevision.orElse(newPackage)
73+
6474
static let updates = Many(update, separator: "\n")
6575

6676
static let packageUpdate = Skip(anyProgress)

Sources/ReleaseNotesCore/ReleaseNotes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ struct ReleaseNotes: AsyncParsableCommand {
5050
for update in updates {
5151
let releasesURL = packageMap[update.packageName]
5252
.map { $0.absoluteString.droppingGitExtension + "/releases" }
53-
?? "could not construct releases URL"
54-
print(releasesURL, "(\(update.oldRevision))")
53+
?? "\(update.packageName)"
54+
print(releasesURL, "(\(update.oldRevision?.description ?? "new package"))")
5555
}
5656
}
5757

Sources/ReleaseNotesCore/Update.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@
1414

1515
struct Update: CustomStringConvertible, Equatable {
1616
var packageName: PackageName
17-
var oldRevision: Revision
17+
var oldRevision: Revision?
1818

1919
var description: String {
20-
"\(packageName) @ \(oldRevision)"
20+
if let oldRevision = oldRevision {
21+
return "\(packageName) @ \(oldRevision)"
22+
} else {
23+
return "\(packageName) (new package)"
24+
}
2125
}
2226
}

Tests/ReleaseNotesTests/ParserCoreTests.swift

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,24 @@ final class ParserCoreTests: XCTestCase {
9090
}
9191
}
9292

93+
func test_upToStart() throws {
94+
do {
95+
var input = "~ foo"[...]
96+
XCTAssertNotNil(Parser.upToStart.parse(&input))
97+
XCTAssertEqual(input, "~ foo")
98+
}
99+
do {
100+
var input = "+ foo"[...]
101+
XCTAssertNotNil(Parser.upToStart.parse(&input))
102+
XCTAssertEqual(input, "+ foo")
103+
}
104+
do {
105+
var input = "other"[...]
106+
XCTAssertNotNil(Parser.upToStart.parse(&input))
107+
XCTAssertEqual(input, "")
108+
}
109+
}
110+
93111
func test_semanticVersion() throws {
94112
do {
95113
var input = "1.2.3"[...]
@@ -118,23 +136,85 @@ final class ParserCoreTests: XCTestCase {
118136
}
119137
}
120138

139+
func test_newPackage() throws {
140+
do {
141+
var input = "+ swift-collections 1.0.2"[...]
142+
XCTAssertEqual(Parser.newPackage.parse(&input), .init(packageName: "swift-collections"))
143+
XCTAssertEqual(input, "")
144+
}
145+
do {
146+
var input = "~ swift-collections 1.0.2"[...]
147+
XCTAssertNil(Parser.newPackage.parse(&input))
148+
XCTAssertEqual(input, "~ swift-collections 1.0.2")
149+
}
150+
}
151+
121152
func test_update() throws {
122153
do {
123154
var input = #"~ swift-tools-support-core main -> swift-tools-support-core Revision(identifier: "4afd18e40eb028cd9fbe7342e3f98020ea9fdf1a") main"#[...]
124155
XCTAssertEqual(Parser.update.parse(&input),
125156
.init(packageName: "swift-tools-support-core",
126157
oldRevision: .branch("main")))
158+
XCTAssertEqual(input, "")
127159
}
128160
do {
129161
var input = #"~ vapor 4.54.0 -> vapor 4.54.1"#[...]
130162
XCTAssertEqual(Parser.update.parse(&input),
131163
.init(packageName: "vapor",
132164
oldRevision: .tag(.init(4, 54, 0))))
165+
XCTAssertEqual(input, "")
166+
}
167+
do {
168+
var input = "+ swift-collections 1.0.2"[...]
169+
XCTAssertEqual(Parser.update.parse(&input),
170+
.init(packageName: "swift-collections"))
171+
XCTAssertEqual(input, "")
133172
}
134173
}
135174

136175
func test_updates() throws {
176+
do {
177+
var input = #"~ vapor 4.54.0 -> vapor 4.54.1"#[...]
178+
XCTAssertEqual(Parser.updates.parse(&input),
179+
[.init(packageName: "vapor",
180+
oldRevision: .tag(.init(4, 54, 0)))])
181+
XCTAssertEqual(input, "")
182+
}
183+
do {
184+
var input = "+ swift-collections 1.0.2"[...]
185+
XCTAssertEqual(Parser.updates.parse(&input),
186+
[.init(packageName: "swift-collections")])
187+
XCTAssertEqual(input, "")
188+
}
189+
do {
190+
var input = """
191+
~ vapor 4.54.0 -> vapor 4.54.1
192+
+ swift-collections 1.0.2
193+
"""[...]
194+
195+
XCTAssertEqual(Parser.updates.parse(&input),
196+
[.init(packageName: "vapor",
197+
oldRevision: .tag(.init(4, 54, 0))),
198+
.init(packageName: "swift-collections")])
199+
XCTAssertEqual(input, "")
200+
}
201+
do {
202+
var input = """
203+
+ swift-collections 1.0.2
204+
~ vapor 4.54.0 -> vapor 4.54.1
205+
"""[...]
206+
207+
XCTAssertEqual(Parser.updates.parse(&input),
208+
[.init(packageName: "swift-collections"),
209+
.init(packageName: "vapor",
210+
oldRevision: .tag(.init(4, 54, 0)))])
211+
XCTAssertEqual(input, "")
212+
}
213+
}
214+
215+
func test_updates_full_list() throws {
137216
var input = """
217+
+ swift-collections 1.0.2
138218
~ swift-tools-support-core main -> swift-tools-support-core Revision(identifier: "4afd18e40eb028cd9fbe7342e3f98020ea9fdf1a") main
139219
~ vapor 4.54.0 -> vapor 4.54.1
140220
~ swift-nio-ssl 2.17.1 -> swift-nio-ssl 2.17.2
@@ -147,6 +227,7 @@ final class ParserCoreTests: XCTestCase {
147227
~ llbuild main -> llbuild Revision(identifier: "db8311d7d284cae487dff582de980db5a918692f") main
148228
"""[...]
149229
XCTAssertEqual(Parser.updates.parse(&input), [
230+
.init(packageName: "swift-collections"),
150231
.init(packageName: "swift-tools-support-core", oldRevision: .branch("main")),
151232
.init(packageName: "vapor", oldRevision: .tag(.init(4, 54, 0))),
152233
.init(packageName: "swift-nio-ssl", oldRevision: .tag(.init(2, 17, 1))),
@@ -158,6 +239,7 @@ final class ParserCoreTests: XCTestCase {
158239
.init(packageName: "swift-nio", oldRevision: .tag(.init(2, 36, 0))),
159240
.init(packageName: "llbuild", oldRevision: .branch("main")),
160241
])
242+
XCTAssertEqual(input, "")
161243
}
162244

163245
func test_packageUpdate() throws {
@@ -205,4 +287,17 @@ final class ParserCoreTests: XCTestCase {
205287
}
206288
}
207289

290+
func test_regression_new_package() throws {
291+
var input = """
292+
6 dependencies have changed:
293+
+ swift-collections 1.0.2
294+
~ fluent-postgres-driver 2.2.2 -> fluent-postgres-driver 2.2.3
295+
~ swift-driver main -> swift-driver Revision(identifier: "a034b0bc0cc1366e289e25e00b3e0b21089c98fe") main
296+
~ swift-tools-support-core main -> swift-tools-support-core Revision(identifier: "d318eaafe60f20be0f0bbc658793f64bf83847d8") main
297+
~ swift-argument-parser 1.0.2 -> swift-argument-parser 1.0.3
298+
~ SwiftPM main -> SwiftPM Revision(identifier: "658654765f5a7dfb3456c37dafd3ed8cd8b363b4") main
299+
"""[...]
300+
XCTAssertEqual(Parser.packageUpdate.parse(&input)?.count, 6)
301+
}
302+
208303
}

0 commit comments

Comments
 (0)