Skip to content

Commit 6fb5138

Browse files
authored
[Collections] Support 'v' prefix in version (#3495)
Motivation: Package versions with 'v' prefix (e.g., `v1.0.0`) in a collection are dropped because they are not semver, but SwiftPM actually supports checking out git tags that have 'v' prefix. Modifications: - Move `TSCUtility.Verson.init(tag:)` to `Basics` for sharing - Use `Version(tag:)`, which strips away any 'v' prefix, instead of `Version(string:)`
1 parent ec94b77 commit 6fb5138

12 files changed

+144
-25
lines changed

Fixtures/Collections/GitHub/releases.json

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,78 @@
11
[
2+
{
3+
"url": "https://api.github.com/repos/octocat/Hello-World/releases/1",
4+
"html_url": "https://github.com/octocat/Hello-World/releases/v1.0.0",
5+
"assets_url": "https://api.github.com/repos/octocat/Hello-World/releases/1/assets",
6+
"upload_url": "https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label}",
7+
"tarball_url": "https://api.github.com/repos/octocat/Hello-World/tarball/v1.0.0",
8+
"zipball_url": "https://api.github.com/repos/octocat/Hello-World/zipball/v1.0.0",
9+
"id": 1,
10+
"node_id": "MDc6UmVsZWFzZTE=",
11+
"tag_name": "v2.0.0",
12+
"target_commitish": "master",
13+
"name": "2.0.0",
14+
"body": "Description of the release",
15+
"draft": false,
16+
"prerelease": false,
17+
"created_at": "2013-02-27T19:35:32Z",
18+
"published_at": "2013-02-27T19:35:32Z",
19+
"author": {
20+
"login": "octocat",
21+
"id": 1,
22+
"node_id": "MDQ6VXNlcjE=",
23+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
24+
"gravatar_id": "",
25+
"url": "https://api.github.com/users/octocat",
26+
"html_url": "https://github.com/octocat",
27+
"followers_url": "https://api.github.com/users/octocat/followers",
28+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
29+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
30+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
31+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
32+
"organizations_url": "https://api.github.com/users/octocat/orgs",
33+
"repos_url": "https://api.github.com/users/octocat/repos",
34+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
35+
"received_events_url": "https://api.github.com/users/octocat/received_events",
36+
"type": "User",
37+
"site_admin": false
38+
},
39+
"assets": [
40+
{
41+
"url": "https://api.github.com/repos/octocat/Hello-World/releases/assets/1",
42+
"browser_download_url": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/example.zip",
43+
"id": 1,
44+
"node_id": "MDEyOlJlbGVhc2VBc3NldDE=",
45+
"name": "example.zip",
46+
"label": "short description",
47+
"state": "uploaded",
48+
"content_type": "application/zip",
49+
"size": 1024,
50+
"download_count": 42,
51+
"created_at": "2013-02-27T19:35:32Z",
52+
"updated_at": "2013-02-27T19:35:32Z",
53+
"uploader": {
54+
"login": "octocat",
55+
"id": 1,
56+
"node_id": "MDQ6VXNlcjE=",
57+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
58+
"gravatar_id": "",
59+
"url": "https://api.github.com/users/octocat",
60+
"html_url": "https://github.com/octocat",
61+
"followers_url": "https://api.github.com/users/octocat/followers",
62+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
63+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
64+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
65+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
66+
"organizations_url": "https://api.github.com/users/octocat/orgs",
67+
"repos_url": "https://api.github.com/users/octocat/repos",
68+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
69+
"received_events_url": "https://api.github.com/users/octocat/received_events",
70+
"type": "User",
71+
"site_admin": false
72+
}
73+
}
74+
]
75+
},
276
{
377
"url": "https://api.github.com/repos/octocat/Hello-World/releases/1",
478
"html_url": "https://github.com/octocat/Hello-World/releases/v1.0.0",

Fixtures/Collections/JSON/good.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
"defaultToolsVersion": "5.2"
101101
},
102102
{
103-
"version": "1.8.3",
103+
"version": "v1.8.3",
104104
"manifests": {
105105
"5.0": {
106106
"toolsVersion": "5.0",

Fixtures/Collections/JSON/good_signed.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
"defaultToolsVersion": "5.2"
101101
},
102102
{
103-
"version": "1.8.3",
103+
"version": "v1.8.3",
104104
"manifests": {
105105
"5.0": {
106106
"toolsVersion": "5.0",

Sources/Basics/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ add_library(Basics
1818
JSON+Extensions.swift
1919
Sandbox.swift
2020
SwiftVersion.swift
21-
SQLiteBackedCache.swift)
21+
SQLiteBackedCache.swift
22+
Version+Extensions.swift)
2223
target_link_libraries(Basics PUBLIC
2324
TSCBasic
2425
TSCUtility)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2021 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import TSCUtility
12+
13+
extension Version {
14+
/// Try a version from a git tag.
15+
///
16+
/// - Parameter tag: A version string possibly prepended with "v".
17+
public init?(tag: String) {
18+
if tag.first == "v" {
19+
self.init(string: String(tag.dropFirst()))
20+
} else {
21+
self.init(string: tag)
22+
}
23+
}
24+
}

Sources/PackageCollections/PackageCollections+Validation.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import TSCBasic
1212

13+
import Basics
1314
import PackageCollectionsModel
1415
import PackageModel
1516

@@ -89,7 +90,7 @@ extension PackageCollectionModel.V1 {
8990

9091
var nonSemanticVersions = [String]()
9192
let semanticVersions: [TSCUtility.Version] = package.versions.compactMap {
92-
let semver = TSCUtility.Version(string: $0.version)
93+
let semver = TSCUtility.Version(tag: $0.version)
9394
if semver == nil {
9495
nonSemanticVersions.append($0.version)
9596
}

Sources/PackageCollections/Providers/GitHubPackageMetadataProvider.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ struct GitHubPackageMetadataProvider: PackageMetadataProvider {
143143
keywords: metadata.topics,
144144
// filters out non-semantic versioned tags
145145
versions: releases.compactMap {
146-
guard let version = $0.tagName.flatMap(TSCUtility.Version.init(string:)) else {
146+
guard let version = $0.tagName.flatMap(TSCUtility.Version.init(tag:)) else {
147147
return nil
148148
}
149149
return Model.PackageBasicVersionMetadata(version: version, title: $0.name, summary: $0.body, createdAt: $0.createdAt, publishedAt: $0.publishedAt)

Sources/PackageCollections/Providers/JSONPackageCollectionProvider.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ struct JSONPackageCollectionProvider: PackageCollectionProvider {
190190
let packages = collection.packages.map { package -> Model.Package in
191191
let versions = package.versions.compactMap { version -> Model.Package.Version? in
192192
// note this filters out / ignores missing / bad data in attempt to make the most out of the provided set
193-
guard let parsedVersion = TSCUtility.Version(string: version.version) else {
193+
guard let parsedVersion = TSCUtility.Version(tag: version.version) else {
194194
return nil
195195
}
196196

Sources/PackageGraph/RepositoryPackageContainer.swift

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
4+
Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See http://swift.org/LICENSE.txt for license information
@@ -437,16 +437,3 @@ extension Git {
437437
}
438438
}
439439
}
440-
441-
extension Version {
442-
/// Try a version from a git tag.
443-
///
444-
/// - Parameter tag: A version string possibly prepended with "v".
445-
init?(tag: String) {
446-
if tag.first == "v" {
447-
self.init(string: String(tag.dropFirst()))
448-
} else {
449-
self.init(string: tag)
450-
}
451-
}
452-
}

Tests/PackageCollectionsTests/GitHubPackageMetadataProviderTests.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,13 @@ class GitHubPackageMetadataProviderTests: XCTestCase {
140140
let metadata = try tsc_await { callback in provider.get(reference, callback: callback) }
141141

142142
XCTAssertEqual(metadata.summary, "This your first repo!")
143-
XCTAssertEqual(metadata.versions.count, 1)
144-
XCTAssertEqual(metadata.versions[0].version, TSCUtility.Version("1.0.0"))
145-
XCTAssertEqual(metadata.versions[0].title, "1.0.0")
143+
XCTAssertEqual(metadata.versions.count, 2)
144+
XCTAssertEqual(metadata.versions[0].version, TSCUtility.Version(tag: "v2.0.0"))
145+
XCTAssertEqual(metadata.versions[0].title, "2.0.0")
146146
XCTAssertEqual(metadata.versions[0].summary, "Description of the release")
147+
XCTAssertEqual(metadata.versions[1].version, TSCUtility.Version("1.0.0"))
148+
XCTAssertEqual(metadata.versions[1].title, "1.0.0")
149+
XCTAssertEqual(metadata.versions[1].summary, "Description of the release")
147150
XCTAssertEqual(metadata.authors, [PackageCollectionsModel.Package.Author(username: "octocat",
148151
url: URL(string: "https://api.github.com/users/octocat")!,
149152
service: .init(name: "GitHub"))])

Tests/PackageCollectionsTests/JSONPackageCollectionProviderTests.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class JSONPackageCollectionProviderTests: XCTestCase {
5454
XCTAssertEqual(collection.keywords, ["sample package collection"])
5555
XCTAssertEqual(collection.createdBy?.name, "Jane Doe")
5656
XCTAssertEqual(collection.packages.count, 2)
57+
5758
let package = collection.packages.first!
5859
XCTAssertEqual(package.repository, .init(url: "https://www.example.com/repos/RepoOne.git"))
5960
XCTAssertEqual(package.summary, "Package One")
@@ -75,6 +76,9 @@ class JSONPackageCollectionProviderTests: XCTestCase {
7576
XCTAssertEqual(version.license, .init(type: .Apache2_0, url: URL(string: "https://www.example.com/repos/RepoOne/LICENSE")!))
7677
XCTAssertNotNil(version.createdAt)
7778
XCTAssertFalse(collection.isSigned)
79+
80+
// "1.8.3" is originally "v1.8.3"
81+
XCTAssertEqual(["2.1.0", "1.8.3"], collection.packages[1].versions.map { $0.version.description })
7882
}
7983
}
8084

@@ -94,6 +98,7 @@ class JSONPackageCollectionProviderTests: XCTestCase {
9498
XCTAssertEqual(collection.keywords, ["sample package collection"])
9599
XCTAssertEqual(collection.createdBy?.name, "Jane Doe")
96100
XCTAssertEqual(collection.packages.count, 2)
101+
97102
let package = collection.packages.first!
98103
XCTAssertEqual(package.repository, .init(url: "https://www.example.com/repos/RepoOne.git"))
99104
XCTAssertEqual(package.summary, "Package One")
@@ -113,6 +118,9 @@ class JSONPackageCollectionProviderTests: XCTestCase {
113118
XCTAssertEqual(version.verifiedCompatibility!.first!.swiftVersion, SwiftLanguageVersion(string: "5.1")!)
114119
XCTAssertEqual(version.license, .init(type: .Apache2_0, url: URL(string: "https://www.example.com/repos/RepoOne/LICENSE")!))
115120
XCTAssertFalse(collection.isSigned)
121+
122+
// "1.8.3" is originally "v1.8.3"
123+
XCTAssertEqual(["2.1.0", "1.8.3"], collection.packages[1].versions.map { $0.version.description })
116124
}
117125
}
118126

@@ -386,6 +394,7 @@ class JSONPackageCollectionProviderTests: XCTestCase {
386394
XCTAssertEqual(collection.keywords, ["sample package collection"])
387395
XCTAssertEqual(collection.createdBy?.name, "Jane Doe")
388396
XCTAssertEqual(collection.packages.count, 2)
397+
389398
let package = collection.packages.first!
390399
XCTAssertEqual(package.repository, .init(url: "https://www.example.com/repos/RepoOne.git"))
391400
XCTAssertEqual(package.summary, "Package One")
@@ -411,6 +420,9 @@ class JSONPackageCollectionProviderTests: XCTestCase {
411420
XCTAssertTrue(signature.isVerified)
412421
XCTAssertEqual("Sample Subject", signature.certificate.subject.commonName)
413422
XCTAssertEqual("Sample Issuer", signature.certificate.issuer.commonName)
423+
424+
// "1.8.3" is originally "v1.8.3"
425+
XCTAssertEqual(["2.1.0", "1.8.3"], collection.packages[1].versions.map { $0.version.description })
414426
}
415427
}
416428

Tests/PackageCollectionsTests/PackageCollectionValidationTests.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2020 Apple Inc. and the Swift project authors
4+
Copyright (c) 2020-2021 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See http://swift.org/LICENSE.txt for license information
@@ -42,6 +42,23 @@ class PackageCollectionValidationTests: XCTestCase {
4242
license: nil,
4343
createdAt: nil
4444
),
45+
Model.Collection.Package.Version(
46+
version: "v1.3.0",
47+
summary: nil,
48+
manifests: [
49+
"5.2": Model.Collection.Package.Version.Manifest(
50+
toolsVersion: "5.2",
51+
packageName: "Foobar",
52+
targets: [.init(name: "Foo", moduleName: "Foo")],
53+
products: [.init(name: "Bar", type: .library(.automatic), targets: ["Foo"])],
54+
minimumPlatformVersions: nil
55+
),
56+
],
57+
defaultToolsVersion: "5.2",
58+
verifiedCompatibility: nil,
59+
license: nil,
60+
createdAt: nil
61+
),
4562
],
4663
readmeURL: nil,
4764
license: nil
@@ -245,7 +262,7 @@ class PackageCollectionValidationTests: XCTestCase {
245262
keywords: ["test package"],
246263
versions: [
247264
Model.Collection.Package.Version(
248-
version: "v1.3.2",
265+
version: "x1.3.2",
249266
summary: nil,
250267
manifests: [
251268
"5.2": Model.Collection.Package.Version.Manifest(

0 commit comments

Comments
 (0)