forked from swiftlang/swift-package-manager
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPackageCollectionModel+v1.swift
492 lines (404 loc) · 16 KB
/
PackageCollectionModel+v1.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2020-2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import Foundation
extension PackageCollectionModel {
public enum V1 {}
}
extension PackageCollectionModel.V1 {
public struct Collection: Equatable, Codable {
/// The name of the package collection, for display purposes only.
public let name: String
/// A description of the package collection.
public let overview: String?
/// An array of keywords that the collection is associated with.
public let keywords: [String]?
/// An array of package metadata objects
public let packages: [PackageCollectionModel.V1.Collection.Package]
/// The version of the format to which the collection conforms.
public let formatVersion: PackageCollectionModel.FormatVersion
/// The revision number of this package collection.
public let revision: Int?
/// When the package collection was generated.
public let generatedAt: Date
/// The author of this package collection.
public let generatedBy: Author?
/// Creates a `Collection`
public init(
name: String,
overview: String?,
keywords: [String]?,
packages: [PackageCollectionModel.V1.Collection.Package],
formatVersion: PackageCollectionModel.FormatVersion,
revision: Int?,
generatedAt: Date = Date(),
generatedBy: Author?
) {
precondition(formatVersion == .v1_0, "Unsupported format version: \(formatVersion)")
self.name = name
self.overview = overview
self.keywords = keywords
self.packages = packages
self.formatVersion = formatVersion
self.revision = revision
self.generatedAt = generatedAt
self.generatedBy = generatedBy
}
public struct Author: Equatable, Codable {
/// The author name.
public let name: String
/// Creates an `Author`
public init(name: String) {
self.name = name
}
}
}
}
extension PackageCollectionModel.V1.Collection {
public struct Package: Equatable, Codable {
/// The URL of the package. Currently only Git repository URLs are supported.
public let url: URL
/// A description of the package.
public let summary: String?
/// An array of keywords that the package is associated with.
public let keywords: [String]?
/// An array of version objects representing the most recent and/or relevant releases of the package.
public let versions: [PackageCollectionModel.V1.Collection.Package.Version]
/// The URL of the package's README.
public let readmeURL: URL?
/// The package's current license info
public let license: PackageCollectionModel.V1.License?
/// Creates a `Package`
public init(
url: URL,
summary: String?,
keywords: [String]?,
versions: [PackageCollectionModel.V1.Collection.Package.Version],
readmeURL: URL?,
license: PackageCollectionModel.V1.License?
) {
self.url = url
self.summary = summary
self.keywords = keywords
self.versions = versions
self.readmeURL = readmeURL
self.license = license
}
}
}
extension PackageCollectionModel.V1.Collection.Package {
public struct Version: Equatable, Codable {
/// The semantic version string.
public let version: String
/// A description of the package version.
public let summary: String?
/// Manifests by tools version.
public let manifests: [String: Manifest]
/// Tools version of the default manifest.
public let defaultToolsVersion: String
/// An array of compatible platforms and Swift versions that has been tested and verified for.
public let verifiedCompatibility: [PackageCollectionModel.V1.Compatibility]?
/// The package version's license.
public let license: PackageCollectionModel.V1.License?
/// When the package version was created.
public let createdAt: Date?
/// Creates a `Version`
public init(
version: String,
summary: String?,
manifests: [String: Manifest],
defaultToolsVersion: String,
verifiedCompatibility: [PackageCollectionModel.V1.Compatibility]?,
license: PackageCollectionModel.V1.License?,
createdAt: Date?
) {
self.version = version
self.summary = summary
self.manifests = manifests
self.defaultToolsVersion = defaultToolsVersion
self.verifiedCompatibility = verifiedCompatibility
self.license = license
self.createdAt = createdAt
}
public struct Manifest: Equatable, Codable {
/// The tools (semantic) version specified in `Package.swift`.
public let toolsVersion: String
/// The name of the package.
public let packageName: String
/// An array of the package version's targets.
public let targets: [PackageCollectionModel.V1.Target]
/// An array of the package version's products.
public let products: [PackageCollectionModel.V1.Product]
/// An array of the package version’s supported platforms specified in `Package.swift`.
public let minimumPlatformVersions: [PackageCollectionModel.V1.PlatformVersion]?
/// Creates a `Manifest`
public init(
toolsVersion: String,
packageName: String,
targets: [PackageCollectionModel.V1.Target],
products: [PackageCollectionModel.V1.Product],
minimumPlatformVersions: [PackageCollectionModel.V1.PlatformVersion]?
) {
self.toolsVersion = toolsVersion
self.packageName = packageName
self.targets = targets
self.products = products
self.minimumPlatformVersions = minimumPlatformVersions
}
}
}
}
extension PackageCollectionModel.V1 {
public struct Target: Equatable, Codable {
/// The target name.
public let name: String
/// The module name if this target can be imported as a module.
public let moduleName: String?
/// Creates a `Target`
public init(name: String, moduleName: String?) {
self.name = name
self.moduleName = moduleName
}
}
public struct Product: Equatable, Codable {
/// The product name.
public let name: String
/// The product type.
public let type: ProductType
/// An array of the product’s targets.
public let targets: [String]
/// Creates a `Product`
public init(
name: String,
type: ProductType,
targets: [String]
) {
self.name = name
self.type = type
self.targets = targets
}
}
public struct PlatformVersion: Equatable, Codable {
/// The name of the platform (e.g., macOS, Linux, etc.).
public let name: String
/// The semantic version of the platform.
public let version: String
/// Creates a `PlatformVersion`
public init(name: String, version: String) {
self.name = name
self.version = version
}
}
public struct Platform: Equatable, Codable {
/// The name of the platform (e.g., macOS, Linux, etc.).
public let name: String
/// Creates a `Platform`
public init(name: String) {
self.name = name
}
}
/// Compatible platform and Swift version.
public struct Compatibility: Equatable, Codable {
/// The platform (e.g., macOS, Linux, etc.)
public let platform: Platform
/// The Swift version
public let swiftVersion: String
/// Creates a `Compatibility`
public init(platform: Platform, swiftVersion: String) {
self.platform = platform
self.swiftVersion = swiftVersion
}
}
public struct License: Equatable, Codable {
/// License name (e.g., Apache-2.0, MIT, etc.)
public let name: String?
/// The URL of the license file.
public let url: URL
/// Creates a `License`
public init(name: String?, url: URL) {
self.name = name
self.url = url
}
}
}
extension PackageCollectionModel.V1.Platform: Hashable {
public var hashValue: Int { name.hashValue }
public func hash(into hasher: inout Hasher) {
name.hash(into: &hasher)
}
}
extension PackageCollectionModel.V1.Platform: Comparable {
public static func < (lhs: Self, rhs: Self) -> Bool {
lhs.name < rhs.name
}
}
extension PackageCollectionModel.V1.Compatibility: Comparable {
public static func < (lhs: Self, rhs: Self) -> Bool {
if lhs.platform != rhs.platform { return lhs.platform < rhs.platform }
return lhs.swiftVersion < rhs.swiftVersion
}
}
// MARK: - Copy `PackageModel.ProductType` to minimize the module's dependencies
extension PackageCollectionModel.V1 {
/// The type of product.
public enum ProductType: Equatable {
/// The type of library.
public enum LibraryType: String, Codable {
/// Static library.
case `static`
/// Dynamic library.
case dynamic
/// The type of library is unspecified and should be decided by package manager.
case automatic
}
/// A library product.
case library(LibraryType)
/// An executable product.
case executable
/// An plugin product.
case plugin
/// An executable code snippet.
case snippet
/// A test product.
case test
}
}
extension PackageCollectionModel.V1.ProductType: Codable {
private enum CodingKeys: String, CodingKey {
case library, executable, plugin, snippet, test
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .library(let a1):
var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .library)
try unkeyedContainer.encode(a1)
case .executable:
try container.encodeNil(forKey: .executable)
case .plugin:
try container.encodeNil(forKey: .plugin)
case .snippet:
try container.encodeNil(forKey: .snippet)
case .test:
try container.encodeNil(forKey: .test)
}
}
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
guard let key = values.allKeys.first(where: values.contains) else {
throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Did not find a matching key"))
}
switch key {
case .library:
var unkeyedValues = try values.nestedUnkeyedContainer(forKey: key)
let a1 = try unkeyedValues.decode(PackageCollectionModel.V1.ProductType.LibraryType.self)
self = .library(a1)
case .executable:
self = .executable
case .plugin:
self = .plugin
case .snippet:
self = .snippet
case .test:
self = .test
}
}
}
// MARK: - Signed package collection
extension PackageCollectionModel.V1 {
/// A signed package collection. The only difference between this and `Collection`
/// is the presence of `signature`.
public struct SignedCollection: Equatable {
/// The package collection
public let collection: PackageCollectionModel.V1.Collection
/// The signature and metadata
public let signature: PackageCollectionModel.V1.Signature
/// Creates a `SignedCollection`
public init(collection: PackageCollectionModel.V1.Collection, signature: PackageCollectionModel.V1.Signature) {
self.collection = collection
self.signature = signature
}
}
/// Package collection signature and associated metadata
public struct Signature: Equatable, Codable {
/// The signature
public let signature: String
/// Details about the certificate used to generate the signature
public let certificate: Certificate
public init(signature: String, certificate: Certificate) {
self.signature = signature
self.certificate = certificate
}
public struct Certificate: Equatable, Codable {
/// Subject of the certificate
public let subject: Name
/// Issuer of the certificate
public let issuer: Name
/// Creates a `Certificate`
public init(subject: Name, issuer: Name) {
self.subject = subject
self.issuer = issuer
}
/// Generic certificate name (e.g., subject, issuer)
public struct Name: Equatable, Codable {
/// User ID
public let userID: String?
/// Common name
public let commonName: String?
/// Organizational unit
public let organizationalUnit: String?
/// Organization
public let organization: String?
/// Creates a `Name`
public init(userID: String?,
commonName: String?,
organizationalUnit: String?,
organization: String?) {
self.userID = userID
self.commonName = commonName
self.organizationalUnit = organizationalUnit
self.organization = organization
}
}
}
}
}
extension PackageCollectionModel.V1.SignedCollection: Codable {
enum CodingKeys: String, CodingKey {
// Collection properties
case name
case overview
case keywords
case packages
case formatVersion
case revision
case generatedAt
case generatedBy
case signature
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.collection.name, forKey: .name)
try container.encodeIfPresent(self.collection.overview, forKey: .overview)
try container.encodeIfPresent(self.collection.keywords, forKey: .keywords)
try container.encode(self.collection.packages, forKey: .packages)
try container.encode(self.collection.formatVersion, forKey: .formatVersion)
try container.encodeIfPresent(self.collection.revision, forKey: .revision)
try container.encode(self.collection.generatedAt, forKey: .generatedAt)
try container.encodeIfPresent(self.collection.generatedBy, forKey: .generatedBy)
try container.encode(self.signature, forKey: .signature)
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.collection = try PackageCollectionModel.V1.Collection(from: decoder)
self.signature = try container.decode(PackageCollectionModel.V1.Signature.self, forKey: .signature)
}
}