Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]: Add support for PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet #874

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ XcodeProj is a library written in Swift for parsing and working with Xcode proje
| XcodeGen | [github.com/yonaskolb/XcodeGen](https://github.com/yonaskolb/XcodeGen) |
| xspm | [gitlab.com/Pyroh/xspm](https://gitlab.com/Pyroh/xspm) |
| Privacy Manifest| [github.com/stelabouras/privacy-manifest](https://github.com/stelabouras/privacy-manifest) |
| Function | [github.com/fxnai/fxnios](https://github.com/fxnai/fxnios) |

If you are also leveraging XcodeProj in your project, feel free to open a PR to include it in the list above.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Class representing an element that may contain other elements.
public class PBXFileSystemSynchronizedBuildFileExceptionSet: PBXObject, PlistSerializable {
public class PBXFileSystemSynchronizedBuildFileExceptionSet: PBXFileSystemSynchronizedExceptionSet, PlistSerializable {
// MARK: - Attributes

/// A list of relative paths to children subfolders for which exceptions are applied.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Foundation

public class PBXFileSystemSynchronizedExceptionSet: PBXObject { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import Foundation

public class PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet: PBXFileSystemSynchronizedExceptionSet, PlistSerializable {

// MARK: - Attributes

/// A list of relative paths to children subfolders for which exceptions are applied.
public var membershipExceptions: [String]?

/// Build phase that this exception set applies to.
public var buildPhase: PBXBuildPhase! {
get {
buildPhaseReference.getObject() as? PBXBuildPhase
}
set {
buildPhaseReference = newValue.reference
}
}

/// Attributes by relative path.
/// Every item in the list is the relative path inside the root synchronized group.
/// For example `RemoveHeadersOnCopy` and `CodeSignOnCopy`.
public var attributesByRelativePath: [String: [String]]?

var buildPhaseReference: PBXObjectReference

// MARK: - Init

public init(
buildPhase: PBXBuildPhase,
membershipExceptions: [String]?,
attributesByRelativePath: [String: [String]]?
) {
buildPhaseReference = buildPhase.reference
self.membershipExceptions = membershipExceptions
self.attributesByRelativePath = attributesByRelativePath
super.init()
}

// MARK: - Decodable
fileprivate enum CodingKeys: String, CodingKey {
case buildPhase
case membershipExceptions
case attributesByRelativePath
}

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let referenceRepository = decoder.context.objectReferenceRepository
let objects = decoder.context.objects
let buildPhaseReference: String = try container.decode(.buildPhase)
self.buildPhaseReference = referenceRepository.getOrCreate(reference: buildPhaseReference, objects: objects)
membershipExceptions = try container.decodeIfPresent(.membershipExceptions)
attributesByRelativePath = try container.decodeIfPresent(.attributesByRelativePath)
try super.init(from: decoder)
}

// MARK: - Equatable

override func isEqual(to object: Any?) -> Bool {
guard let rhs = object as? PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet else {
return false
}
return isEqual(to: rhs)
}

// MARK: - PlistSerializable

func plistKeyAndValue(proj _: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) {
var dictionary: [CommentedString: PlistValue] = [:]
dictionary["isa"] = .string(CommentedString(type(of: self).isa))
if let membershipExceptions {
dictionary["membershipExceptions"] = .array(membershipExceptions.map { .string(CommentedString($0)) })
}
if let attributesByRelativePath {
dictionary["attributesByRelativePath"] = .dictionary(Dictionary(uniqueKeysWithValues: attributesByRelativePath.map { key, value in
(CommentedString(key), .array(value.map { .string(CommentedString($0)) }))
}))
}
dictionary["buildPhase"] = .string(CommentedString(buildPhase.reference.value, comment: buildPhase.name() ?? "CopyFiles"))
return (key: CommentedString(reference, comment: "PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet"), value: .dictionary(dictionary))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class PBXFileSystemSynchronizedRootGroup: PBXFileElement {

/// It returns a list of exception objects that override the configuration for some children
/// in the synchronized root group.
public var exceptions: [PBXFileSystemSynchronizedBuildFileExceptionSet]? {
public var exceptions: [PBXFileSystemSynchronizedExceptionSet]? {
set {
exceptionsReferences = newValue?.references()
}
Expand Down Expand Up @@ -47,7 +47,7 @@ public class PBXFileSystemSynchronizedRootGroup: PBXFileElement {
tabWidth: UInt? = nil,
wrapsLines: Bool? = nil,
explicitFileTypes: [String: String] = [:],
exceptions: [PBXFileSystemSynchronizedBuildFileExceptionSet] = [],
exceptions: [PBXFileSystemSynchronizedExceptionSet] = [],
explicitFolders: [String] = []) {
self.explicitFileTypes = explicitFileTypes
exceptionsReferences = exceptions.references()
Expand Down Expand Up @@ -88,9 +88,9 @@ public class PBXFileSystemSynchronizedRootGroup: PBXFileElement {
override func plistKeyAndValue(proj: PBXProj, reference: String) throws -> (key: CommentedString, value: PlistValue) {
var dictionary: [CommentedString: PlistValue] = try super.plistKeyAndValue(proj: proj, reference: reference).value.dictionary ?? [:]
dictionary["isa"] = .string(CommentedString(type(of: self).isa))
if let exceptionsReferences, !exceptionsReferences.isEmpty {
dictionary["exceptions"] = .array(exceptionsReferences.map { exceptionReference in
.string(CommentedString(exceptionReference.value, comment: "PBXFileSystemSynchronizedBuildFileExceptionSet"))
if let exceptions, !exceptions.isEmpty {
dictionary["exceptions"] = .array(exceptions.map { exception in
.string(CommentedString(exception.reference.value, comment: type(of: exception).isa))
})
}
if let explicitFileTypes {
Expand Down
2 changes: 2 additions & 0 deletions Sources/XcodeProj/Objects/Project/PBXObjectParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ final class PBXObjectParser {
return try decoder.decode(PBXFileSystemSynchronizedRootGroup.self, from: data)
case PBXFileSystemSynchronizedBuildFileExceptionSet.isa:
return try decoder.decode(PBXFileSystemSynchronizedBuildFileExceptionSet.self, from: data)
case PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet.isa:
return try decoder.decode(PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet.self, from: data)
default:
throw PBXObjectError.unknownElement(isa)
}
Expand Down
16 changes: 15 additions & 1 deletion Sources/XcodeProj/Objects/Project/PBXObjects.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ class PBXObjects: Equatable {
var fileSystemSynchronizedBuildFileExceptionSets: [PBXObjectReference: PBXFileSystemSynchronizedBuildFileExceptionSet] {
lock.whileLocked { _fileSystemSynchronizedBuildFileExceptionSets }
}

private var _fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet: [PBXObjectReference: PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet] = [:]
var fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet: [PBXObjectReference: PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet] {
lock.whileLocked { _fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet }
}



// XCSwiftPackageProductDependency

Expand Down Expand Up @@ -185,7 +192,8 @@ class PBXObjects: Equatable {
lhs.swiftPackageProductDependencies == rhs._swiftPackageProductDependencies &&
lhs.remoteSwiftPackageReferences == rhs.remoteSwiftPackageReferences &&
lhs.fileSystemSynchronizedRootGroups == rhs.fileSystemSynchronizedRootGroups &&
lhs.fileSystemSynchronizedBuildFileExceptionSets == rhs.fileSystemSynchronizedBuildFileExceptionSets
lhs.fileSystemSynchronizedBuildFileExceptionSets == rhs.fileSystemSynchronizedBuildFileExceptionSets &&
lhs.fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet == rhs.fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet
}

// MARK: - Helpers
Expand Down Expand Up @@ -232,6 +240,7 @@ class PBXObjects: Equatable {
case let object as XCSwiftPackageProductDependency: _swiftPackageProductDependencies[objectReference] = object
case let object as PBXFileSystemSynchronizedRootGroup: _fileSystemSynchronizedRootGroups[objectReference] = object
case let object as PBXFileSystemSynchronizedBuildFileExceptionSet: _fileSystemSynchronizedBuildFileExceptionSets[objectReference] = object
case let object as PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet: _fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet[objectReference] = object
default: fatalError("Unhandled PBXObject type for \(object), this is likely a bug / todo")
}
}
Expand Down Expand Up @@ -296,6 +305,8 @@ class PBXObjects: Equatable {
return _fileSystemSynchronizedRootGroups.remove(at: index).value
} else if let index = fileSystemSynchronizedBuildFileExceptionSets.index(forKey: reference) {
return _fileSystemSynchronizedBuildFileExceptionSets.remove(at: index).value
} else if let index = fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet.index(forKey: reference) {
return _fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet.remove(at: index).value
}

return nil
Expand Down Expand Up @@ -363,6 +374,8 @@ class PBXObjects: Equatable {
return object
} else if let object = fileSystemSynchronizedBuildFileExceptionSets[reference] {
return object
} else if let object = fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet[reference] {
return object
} else {
return nil
}
Expand Down Expand Up @@ -456,5 +469,6 @@ extension PBXObjects {
swiftPackageProductDependencies.values.forEach(closure)
fileSystemSynchronizedRootGroups.values.forEach(closure)
fileSystemSynchronizedBuildFileExceptionSets.values.forEach(closure)
fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet.values.forEach(closure)
}
}
6 changes: 6 additions & 0 deletions Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ final class PBXProjEncoder {
outputSettings: outputSettings,
stateHolder: &stateHolder,
to: &output)
try write(section: "PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet",
proj: proj,
objects: proj.objects.fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet,
outputSettings: outputSettings,
stateHolder: &stateHolder,
to: &output)
try write(section: "PBXFileSystemSynchronizedRootGroup",
proj: proj,
objects: proj.objects.fileSystemSynchronizedRootGroups,
Expand Down
9 changes: 9 additions & 0 deletions Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,12 @@ extension PBXFileSystemSynchronizedBuildFileExceptionSet {
return super.isEqual(to: rhs)
}
}

extension PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet {
/// :nodoc:
func isEqual(to rhs: PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet) -> Bool {
if membershipExceptions != rhs.membershipExceptions { return false }
if buildPhaseReference != rhs.buildPhaseReference { return false }
return super.isEqual(to: rhs)
}
}