Skip to content

Commit 9bdf674

Browse files
authored
[Collections] Improve error message for 'describe' command (#3274)
Motivation: When using `swift-package-collection describe` on local and remote packages that aren’t included in any added collections, we return unrelated errors. For example, with https://github.com/apple/example-package-dealer: ``` $ swift run swift-package-collection describe https://github.com/apple/example-package-dealer Error: invalidResponse("Missing Content-Length header") ``` The `describe` command can display metadata for: - Imported or unimported collections - Packages found in imported collections Modifications: - Update `describe`'s help message - Improve error message for the use-case mentioned
1 parent d3d86f3 commit 9bdf674

File tree

1 file changed

+44
-39
lines changed

1 file changed

+44
-39
lines changed

Sources/Commands/SwiftPackageCollectionsTool.swift

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
5353
List.self,
5454
Refresh.self,
5555
Remove.self,
56-
Search.self
56+
Search.self,
5757
],
58-
helpNames: [.short, .long, .customLong("help", withSingleDash: true)])
58+
helpNames: [.short, .long, .customLong("help", withSingleDash: true)]
59+
)
5960

60-
public init() {
61-
}
61+
public init() {}
6262

6363
// MARK: Collections
6464

@@ -70,10 +70,10 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
7070

7171
mutating func run() throws {
7272
let collections = try with { collections in
73-
return try tsc_await { collections.listCollections(identifiers: nil, callback: $0) }
73+
try tsc_await { collections.listCollections(identifiers: nil, callback: $0) }
7474
}
7575

76-
if jsonOptions.json {
76+
if self.jsonOptions.json {
7777
try JSONEncoder.makeWithDefaults().print(collections)
7878
} else {
7979
collections.forEach {
@@ -88,7 +88,7 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
8888

8989
mutating func run() throws {
9090
let collections = try with { collections in
91-
return try tsc_await { collections.refreshCollections(callback: $0) }
91+
try tsc_await { collections.refreshCollections(callback: $0) }
9292
}
9393
print("Refreshed \(collections.count) configured package collections.")
9494
}
@@ -102,7 +102,7 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
102102

103103
@Option(name: .long, help: "Sort order for the added collection")
104104
var order: Int?
105-
105+
106106
@Flag(name: .long, help: "Trust the collection even if it is unsigned")
107107
var trustUnsigned: Bool = false
108108

@@ -121,7 +121,8 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
121121
order: order,
122122
trustConfirmationProvider: { _, callback in callback(userTrusted) },
123123
callback: $0
124-
) }
124+
)
125+
}
125126
} catch PackageCollectionError.trustConfirmationRequired, PackageCollectionError.untrusted {
126127
throw CollectionsError.unsigned
127128
}
@@ -175,7 +176,7 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
175176
switch searchMethod {
176177
case .keywords:
177178
let results = try tsc_await { collections.findPackages(searchQuery, collections: nil, callback: $0) }
178-
179+
179180
if jsonOptions.json {
180181
try JSONEncoder.makeWithDefaults().print(results.items)
181182
} else {
@@ -203,7 +204,7 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
203204
// MARK: Packages
204205

205206
struct Describe: ParsableCommand {
206-
static var configuration = CommandConfiguration(abstract: "Get metadata for a single package or collection")
207+
static var configuration = CommandConfiguration(abstract: "Get metadata for a collection or a package included in an imported collection")
207208

208209
@OptionGroup
209210
var jsonOptions: JSONOptions
@@ -228,13 +229,13 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
228229
version.verifiedCompatibility?.map { "(\($0.platform.name), \($0.swiftVersion.rawValue))" }.joined(separator: ", ")
229230
)
230231
let license = optionalRow("License", version.license?.type.description)
231-
232+
232233
return """
233234
\(version.version)
234-
\(printManifest(defaultManifest))\(manifests)\(compatibility)\(license)
235+
\(self.printManifest(defaultManifest))\(manifests)\(compatibility)\(license)
235236
"""
236237
}
237-
238+
238239
private func printManifest(_ manifest: PackageCollectionsModel.Package.Version.Manifest) -> String {
239240
let modules = manifest.targets.compactMap { $0.moduleName }.joined(separator: ", ")
240241
let products = optionalRow("Products", manifest.products.isEmpty ? nil : manifest.products.compactMap { $0.name }.joined(separator: ", "), indentationLevel: 3)
@@ -250,15 +251,15 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
250251
try with { collections in
251252
let identity = PackageIdentity(url: packageUrl)
252253
let reference = PackageReference.remote(identity: identity, location: packageUrl)
253-
254-
do { // assume URL is for a package
254+
255+
do { // assume URL is for a package in an imported collection
255256
let result = try tsc_await { collections.getPackageMetadata(reference, callback: $0) }
256-
257+
257258
if let versionString = version {
258259
guard let version = TSCUtility.Version(string: versionString), let result = result.package.versions.first(where: { $0.version == version }), let printedResult = printVersion(result) else {
259260
throw CollectionsError.invalidVersionString(versionString)
260261
}
261-
262+
262263
if jsonOptions.json {
263264
try JSONEncoder.makeWithDefaults().print(result)
264265
} else {
@@ -286,28 +287,32 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
286287
if version != nil {
287288
throw error
288289
}
289-
290+
290291
guard let collectionUrl = URL(string: packageUrl) else {
291292
throw CollectionsError.invalidArgument("collectionUrl")
292293
}
293-
294-
let source = PackageCollectionsModel.CollectionSource(type: .json, url: collectionUrl)
295-
let collection = try tsc_await { collections.getCollection(source, callback: $0) }
296-
297-
let description = optionalRow("Description", collection.overview)
298-
let keywords = optionalRow("Keywords", collection.keywords?.joined(separator: ", "))
299-
let createdAt = optionalRow("Created At", DateFormatter().string(from: collection.createdAt))
300-
let packages = collection.packages.map { "\($0.repository.url)" }.joined(separator: "\n\(indent(levels: 2))")
301-
302-
if jsonOptions.json {
303-
try JSONEncoder.makeWithDefaults().print(collection)
304-
} else {
305-
print("""
306-
Name: \(collection.name)
307-
Source: \(collection.source.url)\(description)\(keywords)\(createdAt)
308-
Packages:
309-
\(packages)
310-
""")
294+
295+
do {
296+
let source = PackageCollectionsModel.CollectionSource(type: .json, url: collectionUrl)
297+
let collection = try tsc_await { collections.getCollection(source, callback: $0) }
298+
299+
let description = optionalRow("Description", collection.overview)
300+
let keywords = optionalRow("Keywords", collection.keywords?.joined(separator: ", "))
301+
let createdAt = optionalRow("Created At", DateFormatter().string(from: collection.createdAt))
302+
let packages = collection.packages.map { "\($0.repository.url)" }.joined(separator: "\n\(indent(levels: 2))")
303+
304+
if jsonOptions.json {
305+
try JSONEncoder.makeWithDefaults().print(collection)
306+
} else {
307+
print("""
308+
Name: \(collection.name)
309+
Source: \(collection.source.url)\(description)\(keywords)\(createdAt)
310+
Packages:
311+
\(packages)
312+
""")
313+
}
314+
} catch {
315+
print("Failed to get metadata. The given URL neither belongs to a valid collection nor a package in an imported collection.")
311316
}
312317
}
313318
}
@@ -328,7 +333,7 @@ private func optionalRow(_ title: String, _ contents: String?, indentationLevel:
328333
}
329334

330335
private extension JSONEncoder {
331-
func print<T>(_ value: T) throws where T : Encodable {
336+
func print<T>(_ value: T) throws where T: Encodable {
332337
let jsonData = try self.encode(value)
333338
let jsonString = String(data: jsonData, encoding: .utf8)!
334339
Swift.print(jsonString)
@@ -345,7 +350,7 @@ private extension ParsableCommand {
345350
Self.exit(withError: error)
346351
}
347352
}
348-
353+
349354
return try handler(collections)
350355
}
351356
}

0 commit comments

Comments
 (0)