@@ -72,6 +72,7 @@ public enum PIF {
7272 required public init ( from decoder: Decoder ) throws {
7373 let container = try decoder. container ( keyedBy: CodingKeys . self)
7474 type = try container. decode ( String . self, forKey: . type)
75+ logger. trace ( " ---> Decoded TypedObject \( String ( describing: type) ) " )
7576 }
7677 }
7778
@@ -95,13 +96,16 @@ public enum PIF {
9596 guid = try container. decode ( GUID . self, forKey: . guid)
9697 name = try container. decode ( String . self, forKey: . name)
9798 path = try container. decodeIfPresent ( URL . self, forKey: . path)
98-
99+ logger . trace ( " ---> Decoded Workspace: guid \( guid ) name \( name ) path \( path ? . absoluteString ?? " <nil> " ) " )
99100 let projectPaths = try container. decode ( [ String ] . self, forKey: . projects)
100101 . map {
101102 cachePath
102103 . appendingPathComponent ( " project " )
103104 . appendingPathComponent ( " \( $0) \( PIF . cacheFileExtension) " )
104105 }
106+ projectPaths. forEach { URL in
107+ logger. trace ( " \t project path \( URL) " )
108+ }
105109
106110 let projectContents = try projectPaths
107111 . map {
@@ -147,6 +151,7 @@ public enum PIF {
147151 projectDirectory = try container. decode ( URL . self, forKey: . projectDirectory)
148152 developmentRegion = try container. decodeIfPresent ( String . self, forKey: . developmentRegion)
149153 buildConfigurations = try container. decode ( [ BuildConfiguration ] . self, forKey: . buildConfigurations)
154+ logger. trace ( " ---> Decoded Project: guid \( guid) name \( projectName ?? " <nil> " ) path \( path? . absoluteString ?? " <nil> " ) " )
150155
151156 let targetContents = try container. decode ( [ String ] . self, forKey: . targets)
152157 . map {
@@ -165,6 +170,7 @@ public enum PIF {
165170 targets = try targetContents. compactMap { targetData in
166171 let pifDecoder = PIFDecoder ( cache: cachePath)
167172 let untypedTarget = try pifDecoder. decode ( PIF . TypedObject. self, from: targetData)
173+ logger. trace ( " \t untyped target type: \( untypedTarget) " )
168174 switch untypedTarget. type {
169175 case " aggregate " :
170176 return try pifDecoder. decode ( PIF . AggregateTarget. self, from: targetData)
@@ -182,26 +188,6 @@ public enum PIF {
182188 /// Abstract base class for all items in the group hierarchy.
183189 public class Reference : TypedObject {
184190 /// Determines the base path for a reference's relative path.
185- public enum SourceTree : String , Decodable {
186- /// Indicates that the path is relative to the source root (i.e. the "project directory").
187- case sourceRoot = " SOURCE_ROOT "
188-
189- /// Indicates that the path is relative to the path of the parent group.
190- case group = " <group> "
191-
192- /// Indicates that the path is relative to the effective build directory (which varies depending on active
193- /// scheme, active run destination, or even an overridden build setting.
194- case builtProductsDir = " BUILT_PRODUCTS_DIR "
195-
196- /// Indicates that the path is an absolute path.
197- case absolute = " <absolute> "
198-
199- /// Indicates that the path is relative to the SDKROOT
200- case sdkRoot = " SDKROOT "
201-
202- /// Indicates that the path is relative to the DEVELOPER_DIR (normally in the Xcode.app bundle)
203- case developerDir = " DEVELOPER_DIR "
204- }
205191
206192 public let guid : GUID
207193
@@ -228,6 +214,77 @@ public enum PIF {
228214 name = try container. decodeIfPresent ( String . self, forKey: . name)
229215
230216 try super. init ( from: decoder)
217+ logger. trace ( " ---> Decoded Reference guid \( guid) name \( name ?? " <nil> " ) path ( \( path) ) " )
218+ }
219+ }
220+
221+ public enum SourceTree : RawRepresentable , Decodable {
222+
223+ public typealias RawValue = String
224+
225+ /// Indicates that the path is relative to the source root (i.e. the "project directory").
226+ case sourceRoot
227+
228+ /// Indicates that the path is relative to the path of the parent group.
229+ case group
230+
231+ /// Indicates that the path is relative to the effective build directory (which varies depending on active
232+ /// scheme, active run destination, or even an overridden build setting.
233+ case builtProductsDir
234+
235+ /// Indicates that the path is an absolute path.
236+ case absolute
237+
238+ /// Indicates that the path is relative to the SDKROOT
239+ case sdkRoot
240+
241+ /// Indicates that the path is relative to the DEVELOPER_DIR (normally in the Xcode.app bundle)
242+ case developerDir
243+
244+ case unknown
245+
246+ public var rawValue : Self . RawValue {
247+ switch self {
248+ case . sourceRoot:
249+ return " SOURCE_ROOT "
250+ case . group:
251+ return " <group> "
252+ case . builtProductsDir:
253+ return " BUILT_PRODUCTS_DIR "
254+ case . absolute:
255+ return " <absolute> "
256+ case . sdkRoot:
257+ return " SDKROOT "
258+ case . developerDir:
259+ return " DEVELOPER_DIR "
260+ case . unknown:
261+ return " <unknown> "
262+ }
263+ }
264+
265+ public init ( rawValue: Self . RawValue ) {
266+ switch rawValue {
267+ case " SOURCE_ROOT " :
268+ self = . sourceRoot
269+ case " <group> " :
270+ self = . group
271+ case " BUILT_PRODUCTS_DIR " :
272+ self = . builtProductsDir
273+ case " <absolute> " :
274+ self = . absolute
275+ case " SDKROOT " :
276+ self = . sdkRoot
277+ case " DEVELOPER_DIR " :
278+ self = . developerDir
279+ default :
280+ self = . unknown
281+ }
282+ }
283+
284+ public init ( from decoder: Decoder ) throws {
285+ let container = try decoder. singleValueContainer ( )
286+ let rawValue = try container. decode ( String . self)
287+ self = SourceTree ( rawValue: rawValue)
231288 }
232289 }
233290
@@ -245,6 +302,7 @@ public enum PIF {
245302 let container = try decoder. container ( keyedBy: CodingKeys . self)
246303
247304 fileType = try container. decode ( String . self, forKey: . fileType)
305+ logger. trace ( " ---> Decoded FileType \( fileType) " )
248306
249307 try super. init ( from: decoder)
250308 }
@@ -295,6 +353,7 @@ public enum PIF {
295353 var childrenContainer = try container. nestedUnkeyedContainer ( forKey: . children)
296354
297355 children = try untypedChildren. compactMap { child in
356+ logger. trace ( " ---> Decoded Group Type \( child. type ?? " <nil> " ) " )
298357 switch child. type {
299358 case Group . type:
300359 return try childrenContainer. decode ( Group . self)
@@ -334,6 +393,7 @@ public enum PIF {
334393
335394 targetGUID = try container. decode ( String . self, forKey: . guid)
336395 platformFilters = try container. decodeIfPresent ( [ PlatformFilter ] . self, forKey: . platformFilters) ?? [ ]
396+ logger. trace ( " ---> Decoded TargetDependency: \( targetGUID) " )
337397 }
338398 }
339399
@@ -393,6 +453,7 @@ public enum PIF {
393453
394454 let dependencies = try container. decode ( [ TargetDependency ] . self, forKey: . dependencies)
395455 let impartedBuildProperties = try container. decodeIfPresent ( BuildSettings . self, forKey: . impartedBuildProperties)
456+ logger. trace ( " ---> Decoded BaseTarget: guid \( guid) name \( name) " )
396457
397458 super. init (
398459 guid: guid,
@@ -449,6 +510,8 @@ public enum PIF {
449510 public required init ( from decoder: Decoder ) throws {
450511 let container = try decoder. container ( keyedBy: CodingKeys . self)
451512
513+ // The swift package manager drops the length of schemaVersion from the end of the guid-string. However,
514+ // this doesn't work for all guids, because some are names and not guid strings (PackageProduct?).
452515 let guid = try container. decode ( GUID . self, forKey: . guid)
453516 let name = try container. decode ( String . self, forKey: . name)
454517 let buildConfigurations = try container. decode ( [ BuildConfiguration ] . self, forKey: . buildConfigurations)
@@ -457,6 +520,7 @@ public enum PIF {
457520
458521 let buildPhases : [ BuildPhase ]
459522 let impartedBuildProperties : ImpartedBuildProperties
523+ logger. trace ( " ---> Decoded Target: guid \( guid) name \( name) " )
460524
461525 if type == " packageProduct " {
462526 self . productType = . packageProduct
@@ -493,12 +557,14 @@ public enum PIF {
493557 dependencies: dependencies,
494558 impartedBuildSettings: impartedBuildProperties. buildSettings
495559 )
560+ logger. trace ( " ---> Target \( name) with guid \( guid) and product type \( productType) and product name \( productName) decoded " )
496561 }
497562 }
498563
499564 /// Abstract base class for all build phases in a target.
500565 public class BuildPhase : TypedObject {
501566 static func decode( container: inout UnkeyedDecodingContainer , type: String ) throws -> BuildPhase ? {
567+ logger. trace ( " ---> Decoded BuildPhase: type \( type) " )
502568 switch type {
503569 case HeadersBuildPhase . type:
504570 return try container. decode ( HeadersBuildPhase . self)
@@ -508,15 +574,13 @@ public enum PIF {
508574 return try container. decode ( FrameworksBuildPhase . self)
509575 case ResourcesBuildPhase . type:
510576 return try container. decode ( ResourcesBuildPhase . self)
577+ case CopyFilesBuildPhase . type:
578+ return try container. decode ( CopyFilesBuildPhase . self)
579+ case ShellScriptBuildPhase . type:
580+ return try container. decode ( ShellScriptBuildPhase . self)
511581 default :
512582 logger. debug ( " Ignoring build phase: \( type) " )
513583 return nil
514- // TODO: we should probably handle these:
515- /*
516- case copyFiles = "com.apple.buildphase.copy-files"
517- case shellScript = "com.apple.buildphase.shell-script"
518- case sources = "com.apple.buildphase.sources"*/
519- // throw Error.decodingError("unknown build phase \(type)")
520584 }
521585 }
522586
@@ -532,6 +596,7 @@ public enum PIF {
532596
533597 guid = try container. decode ( GUID . self, forKey: . guid)
534598 buildFiles = try container. decode ( [ BuildFile ] . self, forKey: . buildFiles)
599+ logger. trace ( " \t BuildPhase guid \( guid) " )
535600
536601 try super. init ( from: decoder)
537602 }
@@ -558,6 +623,14 @@ public enum PIF {
558623 override class var type : String { " com.apple.buildphase.resources " }
559624 }
560625
626+ public final class CopyFilesBuildPhase : BuildPhase {
627+ override class var type : String { " com.apple.buildphase.copy-files " }
628+ }
629+
630+ public final class ShellScriptBuildPhase : BuildPhase {
631+ override class var type : String { " com.apple.buildphase.shell-script " }
632+ }
633+
561634 /// A build file, representing the membership of either a file or target product reference in a build phase.
562635 public struct BuildFile : Decodable {
563636 public enum Reference {
@@ -585,6 +658,7 @@ public enum PIF {
585658 guid = try container. decode ( GUID . self, forKey: . guid)
586659 platformFilters = try container. decodeIfPresent ( [ PlatformFilter ] . self, forKey: . platformFilters) ?? [ ]
587660 headerVisibility = try container. decodeIfPresent ( HeaderVisibility . self, forKey: . headerVisibility) ?? nil
661+ logger. trace ( " ---> Decoded BuildFile: guid \( guid) visibility \( headerVisibility? . rawValue ?? " <nil> " ) " )
588662
589663 if container. allKeys. contains ( . fileReference) {
590664 reference = try . file( guid: container. decode ( GUID . self, forKey: . fileReference) )
@@ -627,6 +701,7 @@ public enum PIF {
627701 name = try container. decode ( String . self, forKey: . name)
628702 buildSettings = try container. decode ( BuildSettings . self, forKey: . buildSettings)
629703 impartedBuildProperties = try container. decodeIfPresent ( ImpartedBuildProperties . self, forKey: . impartedBuildProperties) ?? . init( buildSettings: . init( ) )
704+ logger. trace ( " ---> Decoded BuildConfiguration: guid \( guid) name \( name) " )
630705 }
631706 }
632707
@@ -835,65 +910,6 @@ public struct XCBuildFileType: CaseIterable {
835910 }
836911}
837912
838- extension PIF . FileReference {
839- // fileprivate static func fileTypeIdentifier(forPath path: String) -> String {
840- // let pathExtension: String?
841- // if let path = try? URL(validating: path) {
842- // pathExtension = path.extension
843- // } else if let path = try? RelativePath(validating: path) {
844- // pathExtension = path.extension
845- // } else {
846- // pathExtension = nil
847- // }
848-
849- // switch pathExtension {
850- // case "a":
851- // return "archive.ar"
852- // case "s", "S":
853- // return "sourcecode.asm"
854- // case "c":
855- // return "sourcecode.c.c"
856- // case "cl":
857- // return "sourcecode.opencl"
858- // case "cpp", "cp", "cxx", "cc", "c++", "C", "tcc":
859- // return "sourcecode.cpp.cpp"
860- // case "d":
861- // return "sourcecode.dtrace"
862- // case "defs", "mig":
863- // return "sourcecode.mig"
864- // case "m":
865- // return "sourcecode.c.objc"
866- // case "mm", "M":
867- // return "sourcecode.cpp.objcpp"
868- // case "metal":
869- // return "sourcecode.metal"
870- // case "l", "lm", "lmm", "lpp", "lp", "lxx":
871- // return "sourcecode.lex"
872- // case "swift":
873- // return "sourcecode.swift"
874- // case "y", "ym", "ymm", "ypp", "yp", "yxx":
875- // return "sourcecode.yacc"
876-
877- // case "xcassets":
878- // return "folder.assetcatalog"
879- // case "xcstrings":
880- // return "text.json.xcstrings"
881- // case "storyboard":
882- // return "file.storyboard"
883- // case "xib":
884- // return "file.xib"
885-
886- // case "xcframework":
887- // return "wrapper.xcframework"
888-
889- // default:
890- // return pathExtension.flatMap({ pathExtension in
891- // XCBuildFileType.allCases.first(where: ({ $0.fileTypes.contains(pathExtension) }))
892- // })?.fileTypeIdentifier ?? "file"
893- // }
894- // }
895- }
896-
897913private struct UntypedTarget : Decodable {
898914 struct TargetContents : Decodable {
899915 let type : String
0 commit comments