Skip to content

Commit 38f9dba

Browse files
committed
Update with proposal changes
1 parent 95af8c0 commit 38f9dba

File tree

1 file changed

+85
-119
lines changed

1 file changed

+85
-119
lines changed

Sources/Commands/SwiftPackageCollectionsTool.swift

Lines changed: 85 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,6 @@ struct JSONOptions: ParsableArguments {
3636
var json: Bool = false
3737
}
3838

39-
struct ProfileOptions: ParsableArguments {
40-
@Option(name: .long, help: "Profile to use for the given command")
41-
var profile: String?
42-
43-
var usedProfile: PackageCollectionsModel.Profile? {
44-
if let profile = profile {
45-
return .init(name: profile)
46-
} else {
47-
return nil
48-
}
49-
}
50-
}
51-
5239
public struct SwiftPackageCollectionsTool: ParsableCommand {
5340
public static var configuration = CommandConfiguration(
5441
commandName: "package-collections",
@@ -59,9 +46,7 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
5946
subcommands: [
6047
Add.self,
6148
Describe.self,
62-
DescribeCollection.self,
6349
List.self,
64-
ProfileList.self,
6550
Refresh.self,
6651
Remove.self,
6752
Search.self
@@ -71,27 +56,6 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
7156
public init() {
7257
}
7358

74-
// MARK: Profiles
75-
76-
struct ProfileList: ParsableCommand {
77-
static let configuration = CommandConfiguration(abstract: "List configured profiles")
78-
79-
@OptionGroup
80-
var jsonOptions: JSONOptions
81-
82-
mutating func run() throws {
83-
let profiles: [PackageCollectionsModel.Profile] = try tsc_await { self.collections.listProfiles(callback: $0) }
84-
85-
if jsonOptions.json {
86-
try JSONEncoder().print(profiles)
87-
} else {
88-
profiles.forEach {
89-
print($0)
90-
}
91-
}
92-
}
93-
}
94-
9559
// MARK: Collections
9660

9761
struct List: ParsableCommand {
@@ -100,11 +64,10 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
10064
@OptionGroup
10165
var jsonOptions: JSONOptions
10266

103-
@OptionGroup
104-
var profileOptions: ProfileOptions
105-
10667
mutating func run() throws {
107-
let collections = try tsc_await { self.collections.listCollections(identifiers: nil, in: profileOptions.usedProfile, callback: $0) }
68+
let collections = try with { collections in
69+
return try tsc_await { collections.listCollections(identifiers: nil, callback: $0) }
70+
}
10871

10972
if jsonOptions.json {
11073
try JSONEncoder().print(collections)
@@ -119,11 +82,10 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
11982
struct Refresh: ParsableCommand {
12083
static let configuration = CommandConfiguration(abstract: "Refresh configured collections")
12184

122-
@OptionGroup
123-
var profileOptions: ProfileOptions
124-
12585
mutating func run() throws {
126-
let collections = try tsc_await { self.collections.refreshCollections(in: profileOptions.usedProfile, callback: $0) }
86+
let collections = try with { collections in
87+
return try tsc_await { collections.refreshCollections(callback: $0) }
88+
}
12789
print("Refreshed \(collections.count) configured package collections.")
12890
}
12991
}
@@ -137,16 +99,15 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
13799
@Option(name: .long, help: "Sort order for the added collection")
138100
var order: Int?
139101

140-
@OptionGroup
141-
var profileOptions: ProfileOptions
142-
143102
mutating func run() throws {
144103
guard let collectionUrl = URL(string: collectionUrl) else {
145104
throw CollectionsError.invalidArgument("collectionUrl")
146105
}
147106

148-
let source = PackageCollectionsModel.CollectionSource(type: .feed, url: collectionUrl)
149-
let collection = try tsc_await { self.collections.addCollection(source, order: order, to: profileOptions.usedProfile, callback: $0) }
107+
let source = PackageCollectionsModel.CollectionSource(type: .json, url: collectionUrl)
108+
let collection = try with { collections in
109+
return try tsc_await { collections.addCollection(source, order: order, callback: $0) }
110+
}
150111

151112
print("Added \"\(collection.name)\" to your package collections.")
152113
}
@@ -155,9 +116,6 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
155116
struct Remove: ParsableCommand {
156117
static let configuration = CommandConfiguration(abstract: "Remove a configured collection")
157118

158-
@OptionGroup
159-
var profileOptions: ProfileOptions
160-
161119
@Argument(help: "URL of the collection to remove")
162120
var collectionUrl: String
163121

@@ -166,43 +124,13 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
166124
throw CollectionsError.invalidArgument("collectionUrl")
167125
}
168126

169-
let source = PackageCollectionsModel.CollectionSource(type: .feed, url: collectionUrl)
170-
let collection = try tsc_await { self.collections.getCollection(source, callback: $0) }
171-
172-
_ = try tsc_await { self.collections.removeCollection(source, from: profileOptions.usedProfile, callback: $0) }
173-
print("Removed \"\(collection.name)\" from your package collections.")
174-
}
175-
}
176-
177-
struct DescribeCollection: ParsableCommand {
178-
static let configuration = CommandConfiguration(abstract: "Get metadata for a configured collection")
179-
180-
@Argument(help: "URL of the collection to describe")
181-
var collectionUrl: String
182-
183-
@OptionGroup
184-
var profileOptions: ProfileOptions
185-
186-
mutating func run() throws {
187-
guard let collectionUrl = URL(string: collectionUrl) else {
188-
throw CollectionsError.invalidArgument("collectionUrl")
127+
let source = PackageCollectionsModel.CollectionSource(type: .json, url: collectionUrl)
128+
let collection = try with { collections in
129+
return try tsc_await { collections.getCollection(source, callback: $0) }
189130
}
190131

191-
let source = PackageCollectionsModel.CollectionSource(type: .feed, url: collectionUrl)
192-
let collection = try tsc_await { self.collections.getCollection(source, callback: $0) }
193-
194-
let description = optionalRow("Description", collection.description)
195-
let keywords = optionalRow("Keywords", collection.keywords?.joined(separator: ", "))
196-
let createdAt = DateFormatter().string(from: collection.createdAt)
197-
let packages = collection.packages.map { "\($0.repository.url)" }.joined(separator: "\n")
198-
199-
print("""
200-
Name: \(collection.name)
201-
Source: \(collection.source.url)\(description)\(keywords)
202-
Created At: \(createdAt)
203-
Packages:
204-
\(packages)
205-
""")
132+
_ = try with { collections in try tsc_await { collections.removeCollection(source, callback: $0) } }
133+
print("Removed \"\(collection.name)\" from your package collections.")
206134
}
207135
}
208136

@@ -219,9 +147,6 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
219147
@OptionGroup
220148
var jsonOptions: JSONOptions
221149

222-
@OptionGroup
223-
var profileOptions: ProfileOptions
224-
225150
@Flag(help: "Pick the method for searching")
226151
var searchMethod: SearchMethod
227152

@@ -231,18 +156,22 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
231156
mutating func run() throws {
232157
switch searchMethod {
233158
case .keywords:
234-
let results = try tsc_await { collections.findPackages(searchQuery, collections: nil, profile: profileOptions.usedProfile, callback: $0) }
159+
let results = try with { collections in
160+
return try tsc_await { collections.findPackages(searchQuery, collections: nil, callback: $0) }
161+
}
235162

236163
results.items.forEach {
237164
print("\($0.package.repository.url): \($0.package.summary ?? "")")
238165
}
239166

240167
case .module:
241-
let results = try tsc_await { collections.findTargets(searchQuery, searchType: .exactMatch, collections: nil, profile: profileOptions.usedProfile, callback: $0) }
168+
let results = try with { collections in
169+
return try tsc_await { collections.findTargets(searchQuery, searchType: .exactMatch, collections: nil, callback: $0) }
170+
}
242171

243172
let packages = Set(results.items.flatMap { $0.packages })
244173
packages.forEach {
245-
print("\($0.repository.url): \($0.description ?? "")")
174+
print("\($0.repository.url): \($0.summary ?? "")")
246175
}
247176
}
248177
}
@@ -251,15 +180,12 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
251180
// MARK: Packages
252181

253182
struct Describe: ParsableCommand {
254-
static var configuration = CommandConfiguration(abstract: "Get metadata for a single package")
183+
static var configuration = CommandConfiguration(abstract: "Get metadata for a single package or collection")
255184

256185
@OptionGroup
257186
var jsonOptions: JSONOptions
258187

259-
@OptionGroup
260-
var profileOptions: ProfileOptions
261-
262-
@Argument(help: "URL of the package to get information for")
188+
@Argument(help: "URL of the package or collection to get information for")
263189
var packageUrl: String
264190

265191
@Option(name: .long, help: "Version of the package to get information for")
@@ -283,28 +209,59 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
283209
}
284210

285211
mutating func run() throws {
286-
let identity = PackageReference.computeIdentity(packageURL: packageUrl)
212+
let identity = PackageIdentity(url: packageUrl)
287213
let reference = PackageReference(identity: identity, path: packageUrl)
288-
289-
let result = try tsc_await { self.collections.getPackageMetadata(reference, profile: profileOptions.usedProfile, callback: $0) }
290-
291-
if let versionString = version {
292-
guard let version = TSCUtility.Version(string: versionString), let result = result.package.versions.first(where: { $0.version == version }), let printedResult = printVersion(result) else {
293-
throw CollectionsError.invalidVersionString(versionString)
214+
215+
do { // assume URL is for a package
216+
let result = try with { collections in
217+
return try tsc_await { collections.getPackageMetadata(reference, callback: $0) }
294218
}
295-
296-
print("Version: \(printedResult)")
297-
} else {
298-
let description = optionalRow("Description", result.package.description)
299-
let versions = result.package.versions.map { "\($0.version)" }.joined(separator: ", ")
300-
let watchers = optionalRow("Watchers", result.package.watchersCount?.description)
301-
let readme = optionalRow("Readme", result.package.readmeURL?.absoluteString)
302-
let authors = optionalRow("Authors", result.package.authors?.map { $0.username }.joined(separator: ", "))
303-
let latestVersion = optionalRow("--------------------------------------------------------------\nLatest Version", printVersion(result.package.latestVersion))
304-
219+
220+
if let versionString = version {
221+
guard let version = TSCUtility.Version(string: versionString), let result = result.package.versions.first(where: { $0.version == version }), let printedResult = printVersion(result) else {
222+
throw CollectionsError.invalidVersionString(versionString)
223+
}
224+
225+
print("Version: \(printedResult)")
226+
} else {
227+
let description = optionalRow("Description", result.package.summary)
228+
let versions = result.package.versions.map { "\($0.version)" }.joined(separator: ", ")
229+
let watchers = optionalRow("Watchers", result.package.watchersCount?.description)
230+
let readme = optionalRow("Readme", result.package.readmeURL?.absoluteString)
231+
let authors = optionalRow("Authors", result.package.authors?.map { $0.username }.joined(separator: ", "))
232+
let latestVersion = optionalRow("--------------------------------------------------------------\nLatest Version", printVersion(result.package.latestVersion))
233+
234+
print("""
235+
\(description)Available Versions: \(versions)\(watchers)\(readme)\(authors)\(latestVersion)
236+
""")
237+
}
238+
} catch { // assume URL is for a collection
239+
// If a version argument was given, we do not perform the fallback.
240+
if version != nil {
241+
throw error
242+
}
243+
244+
guard let collectionUrl = URL(string: packageUrl) else {
245+
throw CollectionsError.invalidArgument("collectionUrl")
246+
}
247+
248+
let source = PackageCollectionsModel.CollectionSource(type: .json, url: collectionUrl)
249+
let collection = try with { collections in
250+
try tsc_await { collections.getCollection(source, callback: $0) }
251+
}
252+
253+
let description = optionalRow("Description", collection.overview)
254+
let keywords = optionalRow("Keywords", collection.keywords?.joined(separator: ", "))
255+
let createdAt = DateFormatter().string(from: collection.createdAt)
256+
let packages = collection.packages.map { "\($0.repository.url)" }.joined(separator: "\n")
257+
305258
print("""
306-
\(description)Available Versions: \(versions)\(watchers)\(readme)\(authors)\(latestVersion)
307-
""")
259+
Name: \(collection.name)
260+
Source: \(collection.source.url)\(description)\(keywords)
261+
Created At: \(createdAt)
262+
Packages:
263+
\(packages)
264+
""")
308265
}
309266
}
310267
}
@@ -331,7 +288,16 @@ private extension JSONEncoder {
331288
}
332289

333290
private extension ParsableCommand {
334-
var collections: PackageCollectionsProtocol {
335-
fatalError("not implemented")
291+
func with<T>(handler: (_ collections: PackageCollectionsProtocol) throws -> T) throws -> T {
292+
let collections = PackageCollections()
293+
defer {
294+
do {
295+
try collections.shutdown()
296+
} catch {
297+
Self.exit(withError: error)
298+
}
299+
}
300+
301+
return try handler(collections)
336302
}
337303
}

0 commit comments

Comments
 (0)