66
77import Foundation
88
9- struct SwiftPackageDescription : Codable {
9+ // See: https://docs.swift.org/package-manager/PackageDescription/index.html
10+ // See: https://github.com/swiftlang/swift-package-manager/blob/main/Sources/PackageDescription/PackageDescriptionSerialization.swift
11+
12+ struct SwiftPackageDescription : Codable , Equatable {
1013
14+ let name : String
15+ let platforms : [ Platform ]
1116 let defaultLocalization : String ?
12- let products : [ Product ]
17+
1318 let targets : [ Target ]
19+ let products : [ Product ]
20+ let dependencies : [ Dependency ]
21+
1422 let toolsVersion : String
1523
1624 var warnings = [ String] ( )
1725
26+ init (
27+ defaultLocalization: String ? ,
28+ name: String ,
29+ platforms: [ Platform ] = [ ] ,
30+ products: [ Product ] = [ ] ,
31+ targets: [ Target ] = [ ] ,
32+ dependencies: [ Dependency ] = [ ] ,
33+ toolsVersion: String ,
34+ warnings: [ String ] = [ ]
35+ ) {
36+ self . defaultLocalization = defaultLocalization
37+ self . name = name
38+ self . platforms = platforms
39+ self . products = products
40+ self . targets = targets
41+ self . dependencies = dependencies
42+ self . toolsVersion = toolsVersion
43+ self . warnings = warnings
44+ }
45+
1846 enum CodingKeys : String , CodingKey {
1947 case defaultLocalization = " default_localization "
48+ case name
49+ case platforms
2050 case products
2151 case targets
52+ case dependencies
2253 case toolsVersion = " tools_version "
2354 }
2455}
2556
2657extension SwiftPackageDescription {
2758
28- struct Product : Codable {
59+ struct Platform : Codable , Equatable , Hashable {
60+
61+ let name : String
62+ let version : String
63+ }
64+ }
65+
66+ extension SwiftPackageDescription . Platform : CustomStringConvertible {
67+ var description : String {
68+ " \( name) ( \( version) ) "
69+ }
70+ }
71+
72+ extension SwiftPackageDescription {
73+
74+ struct Product : Codable , Equatable , Hashable {
75+
76+ // TODO: Add `rule` property
2977
3078 let name : String
3179 let targets : [ String ]
3280 }
3381}
3482
83+ extension SwiftPackageDescription . Product : CustomStringConvertible {
84+ var description : String {
85+ let targetsDescription = targets. map { " \" \( $0) \" " } . joined ( separator: " , " )
86+ return " .library(name: \" \( name) \" , targets: [ \( targetsDescription) ]) "
87+ }
88+ }
89+
90+ extension SwiftPackageDescription {
91+
92+ struct Dependency : Codable , Equatable {
93+
94+ let identity : String
95+ let requirement : Requirement
96+ let type : String
97+ let url : String ?
98+ }
99+ }
100+
101+ extension SwiftPackageDescription . Dependency : CustomStringConvertible {
102+
103+ var description : String {
104+ var description = " .package( "
105+
106+ var fields = [ String] ( )
107+
108+ if let url {
109+ fields += [ " url: \" \( url) \" " ]
110+ }
111+
112+ fields += [ requirement. description]
113+
114+ description += fields. joined ( separator: " , " )
115+
116+ description += " ) "
117+ return description
118+ }
119+ }
120+
121+ extension SwiftPackageDescription . Dependency {
122+
123+ struct Requirement : Codable , Equatable {
124+
125+ // TODO: Which other requirements exist?
126+
127+ let exact : [ String ] ?
128+ }
129+ }
130+
131+ extension SwiftPackageDescription . Dependency . Requirement : CustomStringConvertible {
132+
133+ var description : String {
134+ if let exactVersion = exact? . first {
135+ return " exact: \" \( exactVersion) \" "
136+ }
137+
138+ return " UNKNOWN_REQUIREMENT "
139+ }
140+ }
141+
35142extension SwiftPackageDescription {
36143
37- struct Target : Codable {
144+ struct Target : Codable , Equatable {
38145
39- enum ModuleType : String , Codable {
146+ enum ModuleType : String , Codable , Equatable {
40147 case swiftTarget = " SwiftTarget "
41148 case binaryTarget = " BinaryTarget "
42149 case clangTarget = " ClangTarget "
43150 }
44151
45- enum TargetType : String , Codable {
152+ enum TargetType : String , Codable , Equatable {
46153 case library = " library "
47154 case binary = " binary "
48155 case test = " test "
@@ -53,30 +160,88 @@ extension SwiftPackageDescription {
53160 let path : String
54161 let moduleType : ModuleType
55162
163+ /// `.product(name: ...)` dependency
56164 let productDependencies : [ String ] ?
57- let productMemberships : [ String ] ?
58- let sources : [ String ]
165+ /// `.target(name: ...) dependency
59166 let targetDependencies : [ String ] ?
60167
61- let resources : [ Resource ] ?
168+ // Ignoring following properties for now as they are not handled in the `PackageAnalyzer`
169+ // and thus would produce changes that are not visible
170+ //
171+ // let productMemberships: [String]?
172+ // let sources: [String]
173+ // let resources: [Resource]?
174+
175+ init (
176+ name: String ,
177+ type: TargetType ,
178+ path: String ,
179+ moduleType: ModuleType ,
180+ productDependencies: [ String ] ? = nil ,
181+ targetDependencies: [ String ] ? = nil
182+ ) {
183+ self . name = name
184+ self . type = type
185+ self . path = path
186+ self . moduleType = moduleType
187+ self . productDependencies = productDependencies
188+ self . targetDependencies = targetDependencies
189+ }
62190
63191 enum CodingKeys : String , CodingKey {
64192 case moduleType = " module_type "
65193 case name
66194 case productDependencies = " product_dependencies "
67- case productMemberships = " product_memberships "
68- case sources
69195 case targetDependencies = " target_dependencies "
70196 case type
71197 case path
72- case resources
73198 }
74199 }
75200}
76201
202+ extension SwiftPackageDescription . Target . TargetType : CustomStringConvertible {
203+ var description : String {
204+ switch self {
205+ case . binary: " binaryTarget "
206+ case . library: " target "
207+ case . test: " testTarget "
208+ }
209+ }
210+ }
211+
212+ extension SwiftPackageDescription . Target : CustomStringConvertible {
213+
214+ var description : String {
215+ var description = " . \( type. description) (name: \" \( name) \" "
216+
217+ var dependencyDescriptions = [ String] ( )
218+
219+ if let targetDependenciesDescriptions = targetDependencies? . map ( { " .target(name: \" \( $0) \" ) " } ) {
220+ dependencyDescriptions += targetDependenciesDescriptions
221+ }
222+
223+ if let productDependenciesDescriptions = productDependencies? . map ( { " .product(name: \" \( $0) \" , ...) " } ) {
224+ dependencyDescriptions += productDependenciesDescriptions
225+ }
226+
227+ if !dependencyDescriptions. isEmpty {
228+ // `, dependencies: [.target(name: ...), .target(name: ...), .product(name: ...), ...]`
229+ description += " , dependencies: [ \( dependencyDescriptions. joined ( separator: " , " ) ) ] "
230+ }
231+
232+ description += " , path: \" \( path) \" "
233+
234+ description += " ) "
235+
236+ return description
237+ }
238+ }
239+
77240extension SwiftPackageDescription . Target {
78241
79- struct Resource : Codable {
242+ struct Resource : Codable , Equatable {
243+
244+ // TODO: Add `rule` property
80245
81246 let path : String
82247 }
0 commit comments