diff --git a/Sources/XcodeProj/Objects/Project/PBXProj.swift b/Sources/XcodeProj/Objects/Project/PBXProj.swift index 1319ac847..71e241bd2 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProj.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProj.swift @@ -284,13 +284,24 @@ extension PBXProj: Equatable { // MARK: - Writable extension PBXProj: Writable { + public func dataRepresentation(outputSettings: PBXOutputSettings) throws -> Data? { + let encoder = PBXProjEncoder(outputSettings: outputSettings) + return try encoder.encode(proj: self).data(using: .utf8) + } + + public func dataRepresentation() throws -> Data? { + let encoder = PBXProjEncoder(outputSettings: PBXOutputSettings()) + return try encoder.encode(proj: self).data(using: .utf8) + } + public func write(path: Path, override: Bool) throws { try write(path: path, override: override, outputSettings: PBXOutputSettings()) } public func write(path: Path, override: Bool, outputSettings: PBXOutputSettings) throws { - let encoder = PBXProjEncoder(outputSettings: outputSettings) - let output = try encoder.encode(proj: self) + guard let output = try dataRepresentation(outputSettings: outputSettings) else { + return + } if override, path.exists { try path.delete() } diff --git a/Sources/XcodeProj/Project/WorkspaceSettings.swift b/Sources/XcodeProj/Project/WorkspaceSettings.swift index c8f775735..5d9b37e73 100644 --- a/Sources/XcodeProj/Project/WorkspaceSettings.swift +++ b/Sources/XcodeProj/Project/WorkspaceSettings.swift @@ -144,14 +144,24 @@ public class WorkspaceSettings: Codable, Equatable, Writable { /// - Parameter override: True if the content should be overriden if it already exists. /// - Throws: writing error if something goes wrong. public func write(path: Path, override: Bool) throws { - let encoder = PropertyListEncoder() - encoder.outputFormat = .xml - let data = try encoder.encode(self) + guard let data = try dataRepresentation() else { + return + } if override, path.exists { try path.delete() } try path.write(data) } + + /// Get the workspace settings. + /// + /// - Throws: reading error if something goes wrong. + public func dataRepresentation() throws -> Data? { + let encoder = PropertyListEncoder() + encoder.outputFormat = .xml + let data = try encoder.encode(self) + return data + } } extension WorkspaceSettings { diff --git a/Sources/XcodeProj/Project/XCBreakpointList.swift b/Sources/XcodeProj/Project/XCBreakpointList.swift index 1b7d8e6c6..361ce3e9f 100644 --- a/Sources/XcodeProj/Project/XCBreakpointList.swift +++ b/Sources/XcodeProj/Project/XCBreakpointList.swift @@ -403,6 +403,15 @@ public final class XCBreakpointList: Equatable, Writable { // MARK: - Writable public func write(path: Path, override: Bool) throws { + let document = getAEXMLDocument() + + if override, path.exists { + try path.delete() + } + try path.write(document.xmlXcodeFormat) + } + + private func getAEXMLDocument() -> AEXMLDocument { let document = AEXMLDocument() var schemeAttributes: [String: String] = [:] schemeAttributes["type"] = type @@ -412,11 +421,11 @@ public final class XCBreakpointList: Equatable, Writable { let breakpoints = AEXMLElement(name: "Breakpoints", value: nil, attributes: [:]) self.breakpoints.map { $0.xmlElement() }.forEach { breakpoints.addChild($0) } bucket.addChild(breakpoints) + return document + } - if override, path.exists { - try path.delete() - } - try path.write(document.xmlXcodeFormat) + public func dataRepresentation() throws -> Data? { + getAEXMLDocument().xmlXcodeFormat.data(using: .utf8) } // MARK: - Equatable diff --git a/Sources/XcodeProj/Protocols/Writable.swift b/Sources/XcodeProj/Protocols/Writable.swift index b41ecfcda..b21456756 100644 --- a/Sources/XcodeProj/Protocols/Writable.swift +++ b/Sources/XcodeProj/Protocols/Writable.swift @@ -16,6 +16,11 @@ public protocol Writable { /// - Parameter override: True if the content should be overridden if it already exists. /// - Throws: writing error if something goes wrong. func write(pathString: String, override: Bool) throws + + /// Gets the data representation of the object that conforms to the protocol. + /// + /// - Throws: error if encoding to Data fails. + func dataRepresentation() throws -> Data? } extension Writable { @@ -23,4 +28,6 @@ extension Writable { let path = Path(pathString) try write(path: path, override: override) } + + public func dataRepresentation() throws -> Data? { nil } } diff --git a/Sources/XcodeProj/Scheme/XCScheme.swift b/Sources/XcodeProj/Scheme/XCScheme.swift index c64a8e0fb..2333d790b 100644 --- a/Sources/XcodeProj/Scheme/XCScheme.swift +++ b/Sources/XcodeProj/Scheme/XCScheme.swift @@ -83,6 +83,18 @@ public final class XCScheme: Writable, Equatable { // MARK: - Writable public func write(path: Path, override: Bool) throws { + let document = getAEXMLDocument() + if override, path.exists { + try path.delete() + } + try path.write(document.xmlXcodeFormat) + } + + public func dataRepresentation() throws -> Data? { + getAEXMLDocument().xmlXcodeFormat.data(using: .utf8) + } + + private func getAEXMLDocument() -> AEXMLDocument { let document = AEXMLDocument() var schemeAttributes: [String: String] = [:] schemeAttributes["LastUpgradeVersion"] = lastUpgradeVersion @@ -109,10 +121,7 @@ public final class XCScheme: Writable, Equatable { if let wasCreatedForAppExtension = wasCreatedForAppExtension { scheme.attributes["wasCreatedForAppExtension"] = wasCreatedForAppExtension.xmlString } - if override, path.exists { - try path.delete() - } - try path.write(document.xmlXcodeFormat) + return document } // MARK: - Equatable diff --git a/Sources/XcodeProj/Scheme/XCSchemeManagement.swift b/Sources/XcodeProj/Scheme/XCSchemeManagement.swift index 09cc01d8a..4c00d95ca 100644 --- a/Sources/XcodeProj/Scheme/XCSchemeManagement.swift +++ b/Sources/XcodeProj/Scheme/XCSchemeManagement.swift @@ -138,9 +138,21 @@ public struct XCSchemeManagement: Codable, Equatable, Writable { try path.delete() } + let encoder = getEncoder() + try encoder.encode(self).write(to: path.url) + } + + /// Gets the data representation of the property list representation of the object. + /// + /// - Throws: Error if encoding fails. + public func dataRepresentation() throws -> Data? { + return try getEncoder().encode(self) + } + + private func getEncoder() -> PropertyListEncoder { let encoder = PropertyListEncoder() encoder.outputFormat = .xml - try encoder.encode(self).write(to: path.url) + return encoder } // MARK: - Codable diff --git a/Sources/XcodeProj/Utils/XCConfig.swift b/Sources/XcodeProj/Utils/XCConfig.swift index 640ad7668..11f25784d 100644 --- a/Sources/XcodeProj/Utils/XCConfig.swift +++ b/Sources/XcodeProj/Utils/XCConfig.swift @@ -143,15 +143,24 @@ extension XCConfig { extension XCConfig: Writable { public func write(path: Path, override: Bool) throws { - var content = "" - content.append(writeIncludes()) - content.append("\n") - content.append(writeBuildSettings()) + let content = getContent() if override, path.exists { try path.delete() } try path.write(content) } + + public func dataRepresentation() throws -> Data? { + getContent().data(using: .utf8) + } + + private func getContent() -> String { + var content = "" + content.append(writeIncludes()) + content.append("\n") + content.append(writeBuildSettings()) + return content + } private func writeIncludes() -> String { var content = "" diff --git a/Sources/XcodeProj/Workspace/XCWorkspace.swift b/Sources/XcodeProj/Workspace/XCWorkspace.swift index a2b549a6d..4707d9305 100644 --- a/Sources/XcodeProj/Workspace/XCWorkspace.swift +++ b/Sources/XcodeProj/Workspace/XCWorkspace.swift @@ -67,6 +67,10 @@ public final class XCWorkspace: Writable, Equatable { try dataPath.mkpath() try data.write(path: dataPath) } + + public func dataRepresentation() throws -> Data? { + self.data.rawContents().data(using: .utf8) + } // MARK: - Equatable diff --git a/Sources/XcodeProj/Workspace/XCWorkspaceData.swift b/Sources/XcodeProj/Workspace/XCWorkspaceData.swift index 2c2ff3a92..9cd95c7c9 100644 --- a/Sources/XcodeProj/Workspace/XCWorkspaceData.swift +++ b/Sources/XcodeProj/Workspace/XCWorkspaceData.swift @@ -55,6 +55,10 @@ extension XCWorkspaceData: Writable { } try path.write(rawXml) } + + public func dataRepresentation() throws -> Data? { + rawContents().data(using: .utf8) + } } // MARK: - XCWorkspaceDataElement AEXMLElement decoding and encoding