diff --git a/Package.swift b/Package.swift index dcd5cc927..3e4982687 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.8 +// swift-tools-version:5.10 import PackageDescription diff --git a/Sources/XcodeProj/Extensions/NSLocking+withLock.swift b/Sources/XcodeProj/Extensions/NSLocking+withLock.swift new file mode 100644 index 000000000..20aa8acc4 --- /dev/null +++ b/Sources/XcodeProj/Extensions/NSLocking+withLock.swift @@ -0,0 +1,11 @@ +import Foundation + +// reimplemention of `withLock` from `NSLocking` extension that is exclusive to the macOS version of `Foundation` +extension NSLocking { + func withLock(_ body: () throws -> T) rethrows -> T { + lock() + defer { unlock() } + return try body() + } +} + diff --git a/Sources/XcodeProj/Extensions/NSRecursiveLock+Sync.swift b/Sources/XcodeProj/Extensions/NSRecursiveLock+Sync.swift deleted file mode 100644 index 6e96234ca..000000000 --- a/Sources/XcodeProj/Extensions/NSRecursiveLock+Sync.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation - -extension NSRecursiveLock { - func whileLocked(closure: () -> T) -> T { - lock() - defer { - unlock() - } - let value = closure() - return value - } -} diff --git a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildFile.swift b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildFile.swift index 99e8c8445..3d9c889fe 100644 --- a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildFile.swift +++ b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildFile.swift @@ -10,7 +10,7 @@ public final class PBXBuildFile: PBXObject { /// Returns the file the build file refers to. public var file: PBXFileElement? { get { - fileReference?.getObject() + fileReference?.object() } set { fileReference = newValue?.reference @@ -23,7 +23,7 @@ public final class PBXBuildFile: PBXObject { /// Product. public var product: XCSwiftPackageProductDependency? { get { - productReference?.getObject() + productReference?.object() } set { productReference = newValue?.reference @@ -104,8 +104,8 @@ extension PBXBuildFile { /// - Returns: file name. /// - Throws: an error if the name cannot be obtained. func fileName() throws -> String? { - if let fileElement: PBXFileElement = fileReference?.getObject(), let name = fileElement.fileName() { return name } - if let product: XCSwiftPackageProductDependency = productReference?.getObject() { return product.productName } + if let fileElement: PBXFileElement = fileReference?.object(), let name = fileElement.fileName() { return name } + if let product: XCSwiftPackageProductDependency = productReference?.object() { return product.productName } return nil } @@ -171,7 +171,7 @@ final class PBXBuildPhaseFile: PlistSerializable, Equatable { var dictionary: [CommentedString: PlistValue] = [:] dictionary["isa"] = .string(CommentedString(PBXBuildFile.isa)) if let fileReference = buildFile.fileReference { - let fileElement: PBXFileElement? = fileReference.getObject() + let fileElement: PBXFileElement? = fileReference.object() dictionary["fileRef"] = .string(CommentedString(fileReference.value, comment: fileElement?.fileName())) } if let product = buildFile.product { diff --git a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift index b6f261a19..b0d1f1f61 100644 --- a/Sources/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift +++ b/Sources/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift @@ -88,7 +88,7 @@ public class PBXBuildPhase: PBXContainerItem { dictionary["buildActionMask"] = .string(CommentedString("\(buildActionMask)")) if let fileReferences = fileReferences { let files: PlistValue = .array(fileReferences.map { fileReference in - let buildFile: PBXBuildFile? = fileReference.getObject() + let buildFile: PBXBuildFile? = fileReference.object() let name = buildFile.flatMap { try? $0.fileName() } ?? nil let fileName: String = name ?? "(null)" let type = self.name() diff --git a/Sources/XcodeProj/Objects/Configuration/BuildSettings.swift b/Sources/XcodeProj/Objects/Configuration/BuildSettings.swift index 066dbb50d..5b626eabf 100644 --- a/Sources/XcodeProj/Objects/Configuration/BuildSettings.swift +++ b/Sources/XcodeProj/Objects/Configuration/BuildSettings.swift @@ -1,4 +1,53 @@ import Foundation /// Build settings. -public typealias BuildSettings = [String: Any] +public typealias BuildSettings = [String: BuildSetting] + +public enum BuildSetting: Sendable, Equatable { + case string(String) + case array([String]) + + var valueForWriting: String { + switch self { + case .string(let string): + return string + case .array(let array): + return array.joined(separator: " ") + } + } +} + +extension BuildSetting: Codable { + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + do { + let string = try container.decode(String.self) + self = .string(string) + } catch { + let array = try container.decode([String].self) + self = .array(array) + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + switch self { + case .string(let string): + try container.encode(string) + case .array(let array): + try container.encode(array) + } + } +} + +extension BuildSetting: ExpressibleByArrayLiteral { + public init(arrayLiteral elements: String...) { + self = .array(elements) + } +} + +extension BuildSetting: ExpressibleByStringLiteral { + public init(stringLiteral value: StringLiteralType) { + self = .string(value) + } +} diff --git a/Sources/XcodeProj/Objects/Configuration/XCBuildConfiguration.swift b/Sources/XcodeProj/Objects/Configuration/XCBuildConfiguration.swift index 468984cc4..e5ea97eca 100644 --- a/Sources/XcodeProj/Objects/Configuration/XCBuildConfiguration.swift +++ b/Sources/XcodeProj/Objects/Configuration/XCBuildConfiguration.swift @@ -10,7 +10,7 @@ public final class XCBuildConfiguration: PBXObject { /// Base xcconfig file reference. public var baseConfiguration: PBXFileReference? { get { - baseConfigurationReference?.getObject() + baseConfigurationReference?.object() } set { if let newValue = newValue { @@ -43,26 +43,26 @@ public final class XCBuildConfiguration: PBXObject { } // MARK: - Decodable - - fileprivate enum CodingKeys: String, CodingKey { - case baseConfigurationReference - case buildSettings - case name - } - - public required init(from decoder: Decoder) throws { - let objects = decoder.context.objects - let objectReferenceRepository = decoder.context.objectReferenceRepository - let container = try decoder.container(keyedBy: CodingKeys.self) - if let baseConfigurationReference: String = try container.decodeIfPresent(.baseConfigurationReference) { - self.baseConfigurationReference = objectReferenceRepository.getOrCreate(reference: baseConfigurationReference, objects: objects) - } else { - baseConfigurationReference = nil - } - buildSettings = try container.decode([String: Any].self, forKey: .buildSettings) - name = try container.decode(.name) - try super.init(from: decoder) + + fileprivate enum CodingKeys: String, CodingKey { + case baseConfigurationReference + case buildSettings + case name + } + + public required init(from decoder: Decoder) throws { + let objects = decoder.context.objects + let objectReferenceRepository = decoder.context.objectReferenceRepository + let container = try decoder.container(keyedBy: CodingKeys.self) + if let baseConfigurationReference: String = try container.decodeIfPresent(.baseConfigurationReference) { + self.baseConfigurationReference = objectReferenceRepository.getOrCreate(reference: baseConfigurationReference, objects: objects) + } else { + baseConfigurationReference = nil } + buildSettings = try container.decode(BuildSettings.self, forKey: .buildSettings) + name = try container.decode(.name) + try super.init(from: decoder) + } // MARK: - Public @@ -75,16 +75,16 @@ public final class XCBuildConfiguration: PBXObject { public func append(setting name: String, value: String) { guard !value.isEmpty else { return } - let existing: Any = buildSettings[name] ?? "$(inherited)" + let existing: BuildSetting = buildSettings[name] ?? "$(inherited)" switch existing { - case let string as String where string != value: + case let .string(string) where string != value: let newValue = [string, value].joined(separator: " ") - buildSettings[name] = newValue - case let array as [String]: + buildSettings[name] = .string(newValue) + case let .array(array): var newValue = array newValue.append(value) - buildSettings[name] = newValue.uniqued() + buildSettings[name] = .array(newValue.uniqued()) default: break } @@ -105,7 +105,7 @@ extension XCBuildConfiguration: PlistSerializable { dictionary["name"] = .string(CommentedString(name)) dictionary["buildSettings"] = buildSettings.plist() if let baseConfigurationReference = baseConfigurationReference { - let fileElement: PBXFileElement? = baseConfigurationReference.getObject() + let fileElement: PBXFileElement? = baseConfigurationReference.object() dictionary["baseConfigurationReference"] = .string(CommentedString(baseConfigurationReference.value, comment: fileElement?.fileName())) } return (key: CommentedString(reference, comment: name), value: .dictionary(dictionary)) diff --git a/Sources/XcodeProj/Objects/Configuration/XCConfigurationList.swift b/Sources/XcodeProj/Objects/Configuration/XCConfigurationList.swift index 0bf2cfe35..b16525a9a 100644 --- a/Sources/XcodeProj/Objects/Configuration/XCConfigurationList.swift +++ b/Sources/XcodeProj/Objects/Configuration/XCConfigurationList.swift @@ -116,7 +116,7 @@ extension XCConfigurationList: PlistSerializable { dictionary["isa"] = .string(CommentedString(XCConfigurationList.isa)) dictionary["buildConfigurations"] = .array(buildConfigurationReferences .map { configReference in - let config: XCBuildConfiguration? = configReference.getObject() + let config: XCBuildConfiguration? = configReference.object() return .string(CommentedString(configReference.value, comment: config?.name)) }) dictionary["defaultConfigurationIsVisible"] = .string(CommentedString("\(defaultConfigurationIsVisible.int)")) diff --git a/Sources/XcodeProj/Objects/Files/PBXContainerItemProxy.swift b/Sources/XcodeProj/Objects/Files/PBXContainerItemProxy.swift index f244aeada..2ef17aee2 100644 --- a/Sources/XcodeProj/Objects/Files/PBXContainerItemProxy.swift +++ b/Sources/XcodeProj/Objects/Files/PBXContainerItemProxy.swift @@ -28,7 +28,7 @@ public final class PBXContainerItemProxy: PBXObject { var id: RemoteGlobalID { switch self { case let .reference(reference): - if let object = reference.getObject() { + if let object = reference.object() { return .object(object) } else { return .string(reference.value) @@ -65,7 +65,7 @@ public final class PBXContainerItemProxy: PBXObject { /// Use isContainerPortalFileReference to check if you can use the getter public var containerPortal: ContainerPortal { get { - ContainerPortal(object: containerPortalReference.getObject()) + ContainerPortal(object: containerPortalReference.object()) } set { guard let reference = newValue.reference else { diff --git a/Sources/XcodeProj/Objects/Files/PBXFileElement.swift b/Sources/XcodeProj/Objects/Files/PBXFileElement.swift index 573e8ee8e..c404f8d3a 100644 --- a/Sources/XcodeProj/Objects/Files/PBXFileElement.swift +++ b/Sources/XcodeProj/Objects/Files/PBXFileElement.swift @@ -199,10 +199,10 @@ public extension PBXFileElement { /// - Returns: path to the variant group base file. /// - Throws: an error if the path cannot be obtained. private func baseVariantGroupPath() throws -> String? { - guard let variantGroup: PBXVariantGroup = reference.getObject() else { return nil } - guard let baseReference = try variantGroup + guard let variantGroup: PBXVariantGroup = reference.object() else { return nil } + guard let baseReference = variantGroup .childrenReferences - .compactMap({ try $0.getThrowingObject() as PBXFileElement }) + .compactMap({ $0.object(as: PBXFileElement.self) }) .first(where: { $0.name == "Base" }) else { return nil } return baseReference.path } diff --git a/Sources/XcodeProj/Objects/Files/PBXGroup.swift b/Sources/XcodeProj/Objects/Files/PBXGroup.swift index 34add940c..41065836e 100644 --- a/Sources/XcodeProj/Objects/Files/PBXGroup.swift +++ b/Sources/XcodeProj/Objects/Files/PBXGroup.swift @@ -72,7 +72,7 @@ public class PBXGroup: PBXFileElement { var dictionary: [CommentedString: PlistValue] = try super.plistKeyAndValue(proj: proj, reference: reference).value.dictionary ?? [:] dictionary["isa"] = .string(CommentedString(type(of: self).isa)) dictionary["children"] = .array(childrenReferences.map { (fileReference) -> PlistValue in - let fileElement: PBXFileElement? = fileReference.getObject() + let fileElement: PBXFileElement? = fileReference.object() return .string(CommentedString(fileReference.value, comment: fileElement?.fileName())) }) diff --git a/Sources/XcodeProj/Objects/Files/XCVersionGroup.swift b/Sources/XcodeProj/Objects/Files/XCVersionGroup.swift index 3087294f2..02845b717 100644 --- a/Sources/XcodeProj/Objects/Files/XCVersionGroup.swift +++ b/Sources/XcodeProj/Objects/Files/XCVersionGroup.swift @@ -12,7 +12,7 @@ public final class XCVersionGroup: PBXGroup { /// Returns the current version file reference. public var currentVersion: PBXFileReference? { get { - currentVersionReference?.getObject() + currentVersionReference?.object() } set { currentVersionReference = newValue?.reference @@ -91,7 +91,7 @@ public final class XCVersionGroup: PBXGroup { dictionary["versionGroupType"] = .string(CommentedString(versionGroupType)) } if let currentVersionReference = currentVersionReference { - let fileElement: PBXFileElement? = currentVersionReference.getObject() + let fileElement: PBXFileElement? = currentVersionReference.object() dictionary["currentVersion"] = .string(CommentedString(currentVersionReference.value, comment: fileElement?.fileName())) } return (key: CommentedString(reference, comment: path?.split(separator: "/").last.map(String.init)), diff --git a/Sources/XcodeProj/Objects/Project/PBXObjectReference.swift b/Sources/XcodeProj/Objects/Project/PBXObjectReference.swift index c72a943af..9abc65671 100644 --- a/Sources/XcodeProj/Objects/Project/PBXObjectReference.swift +++ b/Sources/XcodeProj/Objects/Project/PBXObjectReference.swift @@ -1,72 +1,121 @@ import Foundation /// Object used as a reference to PBXObjects from PBXObjects. -class PBXObjectReference: NSObject, Comparable, NSCopying { +class PBXObjectReference: NSObject, Comparable, NSCopying, @unchecked Sendable { + private let lock = NSRecursiveLock() + /// Boolean that indicates whether the id is temporary and needs /// to be regenerated when saving it to disk. - private(set) var temporary: Bool + var temporary: Bool { + lock.withLock { _temporary } + } + private var _temporary: Bool /// String reference. - private(set) var value: String + var value: String { + lock.withLock { _value } + } + private var _value: String + /// Weak reference to the objects instance that contains the project objects. - weak var objects: PBXObjects? + var objects: PBXObjects? { + get { + lock.withLock { _objects } + } + set { + lock.withLock { + _objects = newValue + } + } + } + private weak var _objects: PBXObjects? - /// A weak reference to the object - private weak var object: PBXObject? + + /// The object referenced by this instance. + /// + /// - Returns: object the reference is referring to. Returns nil if the objects property has been released or the reference doesn't exist + func object() -> T? { + lock.withLock { + if let object = _object as? T { + return object + } + + guard let object = objects?.get(reference: self) else { return nil } + _object = object + + return object as? T + + } + } + + + /// Typed object referenced by this instance. + /// - Parameter as: Type to cast to + /// - Returns: returns casted object if successful + func object(as: T.Type) -> T? { + lock.withLock { _object } as? T + } + + private weak var _object: PBXObject? /// Initializes a non-temporary reference. /// /// - Parameter reference: reference. init(_ reference: String, objects: PBXObjects) { - value = reference - temporary = false - self.objects = objects + _value = reference + _temporary = false + _objects = objects } /// Initializes a temporary reference init(objects: PBXObjects? = nil) { - value = "TEMP_\(UUID().uuidString)" - temporary = true - self.objects = objects + _value = "TEMP_\(UUID().uuidString)" + _temporary = true + _objects = objects } /// Initializes the reference without objects. /// /// - Parameter reference: reference. init(_ reference: String) { - value = reference - temporary = false + _value = reference + _temporary = false } /// Initializes the object reference with another object reference, copying its values. /// /// - Parameter objectReference: object reference to be initialized from. required init(_ objectReference: PBXObjectReference) { - value = objectReference.value - temporary = objectReference.temporary + _value = objectReference.value + _temporary = objectReference.temporary } /// Fixes its value making it permanent. /// /// - Parameter value: value. func fix(_ value: String) { - let object = objects?.delete(reference: self) - self.value = value - temporary = false - if let object = object { - objects?.add(object: object) + lock.withLock { + let object = objects?.delete(reference: self) + _value = value + _temporary = false + if let object = object { + objects?.add(object: object) + } } } /// Invalidates the reference making it temporary. func invalidate() { - let object = objects?.delete(reference: self) - value = "TEMP_\(UUID().uuidString)" - temporary = true - if let object = object { - objects?.add(object: object) + lock.withLock { + let object = _objects?.delete(reference: self) + _value = "TEMP_\(UUID().uuidString)" + _temporary = true + if let object = object { + _objects?.add(object: object) + } } + } /// Hash value. @@ -112,33 +161,11 @@ class PBXObjectReference: NSObject, Comparable, NSCopying { /// /// - Parameter object: The object func setObject(_ object: PBXObject) { - self.object = object - } - - /// Returns the object the reference is referfing to. - /// - /// - Returns: object the reference is referring to. Returns nil if the objects property has been released or the reference doesn't exist - func getObject() -> T? { - try? getThrowingObject() - } - - /// Returns the object the reference is referfing to. - /// - /// - Returns: object the reference is referring to. - /// - Throws: an errof it the objects property has been released or the reference doesn't exist. - func getThrowingObject() throws -> T { - if let object = object as? T { - return object - } - guard let objects = objects else { - throw PBXObjectError.objectsReleased + lock.withLock { + _object = object } - guard let object = objects.get(reference: self) as? T else { - throw PBXObjectError.objectNotFound(value) - } - self.object = object - return object } + } extension Array where Element: PBXObject { @@ -149,6 +176,6 @@ extension Array where Element: PBXObject { extension Array where Element: PBXObjectReference { func objects() -> [T] { - compactMap { $0.getObject() } + compactMap { $0.object() } } } diff --git a/Sources/XcodeProj/Objects/Project/PBXObjects.swift b/Sources/XcodeProj/Objects/Project/PBXObjects.swift index 5f8a568f4..646a8311d 100644 --- a/Sources/XcodeProj/Objects/Project/PBXObjects.swift +++ b/Sources/XcodeProj/Objects/Project/PBXObjects.swift @@ -8,131 +8,131 @@ class PBXObjects: Equatable { private var _projects: [PBXObjectReference: PBXProject] = [:] var projects: [PBXObjectReference: PBXProject] { - lock.whileLocked { _projects } + lock.withLock { _projects } } private var _referenceProxies: [PBXObjectReference: PBXReferenceProxy] = [:] var referenceProxies: [PBXObjectReference: PBXReferenceProxy] { - lock.whileLocked { _referenceProxies } + lock.withLock { _referenceProxies } } // File elements private var _fileReferences: [PBXObjectReference: PBXFileReference] = [:] var fileReferences: [PBXObjectReference: PBXFileReference] { - lock.whileLocked { _fileReferences } + lock.withLock { _fileReferences } } private var _versionGroups: [PBXObjectReference: XCVersionGroup] = [:] var versionGroups: [PBXObjectReference: XCVersionGroup] { - lock.whileLocked { _versionGroups } + lock.withLock { _versionGroups } } private var _variantGroups: [PBXObjectReference: PBXVariantGroup] = [:] var variantGroups: [PBXObjectReference: PBXVariantGroup] { - lock.whileLocked { _variantGroups } + lock.withLock { _variantGroups } } private var _groups: [PBXObjectReference: PBXGroup] = [:] var groups: [PBXObjectReference: PBXGroup] { - lock.whileLocked { _groups } + lock.withLock { _groups } } // Configuration private var _buildConfigurations: [PBXObjectReference: XCBuildConfiguration] = [:] var buildConfigurations: [PBXObjectReference: XCBuildConfiguration] { - lock.whileLocked { _buildConfigurations } + lock.withLock { _buildConfigurations } } private var _configurationLists: [PBXObjectReference: XCConfigurationList] = [:] var configurationLists: [PBXObjectReference: XCConfigurationList] { - lock.whileLocked { _configurationLists } + lock.withLock { _configurationLists } } // Targets private var _legacyTargets: [PBXObjectReference: PBXLegacyTarget] = [:] var legacyTargets: [PBXObjectReference: PBXLegacyTarget] { - lock.whileLocked { _legacyTargets } + lock.withLock { _legacyTargets } } private var _aggregateTargets: [PBXObjectReference: PBXAggregateTarget] = [:] var aggregateTargets: [PBXObjectReference: PBXAggregateTarget] { - lock.whileLocked { _aggregateTargets } + lock.withLock { _aggregateTargets } } private var _nativeTargets: [PBXObjectReference: PBXNativeTarget] = [:] var nativeTargets: [PBXObjectReference: PBXNativeTarget] { - lock.whileLocked { _nativeTargets } + lock.withLock { _nativeTargets } } private var _targetDependencies: [PBXObjectReference: PBXTargetDependency] = [:] var targetDependencies: [PBXObjectReference: PBXTargetDependency] { - lock.whileLocked { _targetDependencies } + lock.withLock { _targetDependencies } } private var _containerItemProxies: [PBXObjectReference: PBXContainerItemProxy] = [:] var containerItemProxies: [PBXObjectReference: PBXContainerItemProxy] { - lock.whileLocked { _containerItemProxies } + lock.withLock { _containerItemProxies } } private var _buildRules: [PBXObjectReference: PBXBuildRule] = [:] var buildRules: [PBXObjectReference: PBXBuildRule] { - lock.whileLocked { _buildRules } + lock.withLock { _buildRules } } // Build Phases private var _buildFiles: [PBXObjectReference: PBXBuildFile] = [:] var buildFiles: [PBXObjectReference: PBXBuildFile] { - lock.whileLocked { _buildFiles } + lock.withLock { _buildFiles } } private var _copyFilesBuildPhases: [PBXObjectReference: PBXCopyFilesBuildPhase] = [:] var copyFilesBuildPhases: [PBXObjectReference: PBXCopyFilesBuildPhase] { - lock.whileLocked { _copyFilesBuildPhases } + lock.withLock { _copyFilesBuildPhases } } private var _shellScriptBuildPhases: [PBXObjectReference: PBXShellScriptBuildPhase] = [:] var shellScriptBuildPhases: [PBXObjectReference: PBXShellScriptBuildPhase] { - lock.whileLocked { _shellScriptBuildPhases } + lock.withLock { _shellScriptBuildPhases } } private var _resourcesBuildPhases: [PBXObjectReference: PBXResourcesBuildPhase] = [:] var resourcesBuildPhases: [PBXObjectReference: PBXResourcesBuildPhase] { - lock.whileLocked { _resourcesBuildPhases } + lock.withLock { _resourcesBuildPhases } } private var _frameworksBuildPhases: [PBXObjectReference: PBXFrameworksBuildPhase] = [:] var frameworksBuildPhases: [PBXObjectReference: PBXFrameworksBuildPhase] { - lock.whileLocked { _frameworksBuildPhases } + lock.withLock { _frameworksBuildPhases } } private var _headersBuildPhases: [PBXObjectReference: PBXHeadersBuildPhase] = [:] var headersBuildPhases: [PBXObjectReference: PBXHeadersBuildPhase] { - lock.whileLocked { _headersBuildPhases } + lock.withLock { _headersBuildPhases } } private var _sourcesBuildPhases: [PBXObjectReference: PBXSourcesBuildPhase] = [:] var sourcesBuildPhases: [PBXObjectReference: PBXSourcesBuildPhase] { - lock.whileLocked { _sourcesBuildPhases } + lock.withLock { _sourcesBuildPhases } } private var _carbonResourcesBuildPhases: [PBXObjectReference: PBXRezBuildPhase] = [:] var carbonResourcesBuildPhases: [PBXObjectReference: PBXRezBuildPhase] { - lock.whileLocked { _carbonResourcesBuildPhases } + lock.withLock { _carbonResourcesBuildPhases } } private var _remoteSwiftPackageReferences: [PBXObjectReference: XCRemoteSwiftPackageReference] = [:] var remoteSwiftPackageReferences: [PBXObjectReference: XCRemoteSwiftPackageReference] { - lock.whileLocked { _remoteSwiftPackageReferences } + lock.withLock { _remoteSwiftPackageReferences } } private var _localSwiftPackageReferences: [PBXObjectReference: XCLocalSwiftPackageReference] = [:] var localSwiftPackageReferences: [PBXObjectReference: XCLocalSwiftPackageReference] { - lock.whileLocked { _localSwiftPackageReferences } + lock.withLock { _localSwiftPackageReferences } } private var _swiftPackageProductDependencies: [PBXObjectReference: XCSwiftPackageProductDependency] = [:] var swiftPackageProductDependencies: [PBXObjectReference: XCSwiftPackageProductDependency] { - lock.whileLocked { _swiftPackageProductDependencies } + lock.withLock { _swiftPackageProductDependencies } } // XCSwiftPackageProductDependency diff --git a/Sources/XcodeProj/Objects/Project/PBXProj.swift b/Sources/XcodeProj/Objects/Project/PBXProj.swift index 6248aed4e..4c820737a 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProj.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProj.swift @@ -25,7 +25,7 @@ public final class PBXProj: Decodable { rootObjectReference = newValue?.reference } get { - rootObjectReference?.getObject() + rootObjectReference?.object() } } @@ -47,7 +47,7 @@ public final class PBXProj: Decodable { self.classes = classes rootObjectReference = rootObject?.reference self.objects = PBXObjects(objects: objects) - if let rootGroup = try? rootGroup() { + if let rootGroup = rootGroup() { rootGroup.assignParentToChildren() } } @@ -154,7 +154,7 @@ public final class PBXProj: Decodable { } self.objects = objects - try rootGroup()?.assignParentToChildren() + rootGroup()?.assignParentToChildren() } // MARK: Static Methods @@ -169,7 +169,7 @@ public final class PBXProj: Decodable { let plistDecoder = XcodeprojPropertyListDecoder(context: context) let pbxproj: PBXProj = try plistDecoder.decode(PBXProj.self, from: pbxProjData) - try pbxproj.updateProjectName(path: path) + pbxproj.updateProjectName(path: path) return pbxproj } @@ -228,14 +228,14 @@ public extension PBXProj { var buildPhases: [PBXBuildPhase] { Array(objects.buildPhases.values) } /// Returns root project. - func rootProject() throws -> PBXProject? { - try rootObjectReference?.getThrowingObject() + func rootProject() -> PBXProject? { + rootObjectReference?.object() } /// Returns root project's root group. - func rootGroup() throws -> PBXGroup? { - let project = try rootProject() - return try project?.mainGroupReference.getThrowingObject() + func rootGroup() -> PBXGroup? { + let project = rootProject() + return project?.mainGroupReference.object() } /// Adds a new object to the project. @@ -298,12 +298,12 @@ extension PBXProj { /// /// - Parameters: /// - path: path to .xcodeproj directory. - func updateProjectName(path: Path) throws { + func updateProjectName(path: Path) { guard path.parent().extension == "xcodeproj" else { return } let projectName = path.parent().lastComponent.split(separator: ".").first - try rootProject()?.name = projectName.map(String.init) ?? "" + rootProject()?.name = projectName.map(String.init) ?? "" } } diff --git a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift index 771e38973..553022fe2 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift @@ -350,7 +350,7 @@ final class PBXProjEncoder { var array = [String]() var tmpStateHolder = stateHolder.copy() write(dictionaryKey: element.key, dictionaryValue: element.value, multiline: element.multiline, stateHolder: &tmpStateHolder, to: &array) - lock.whileLocked { + lock.withLock { resultArray[index] = array } } diff --git a/Sources/XcodeProj/Objects/Project/PBXProject.swift b/Sources/XcodeProj/Objects/Project/PBXProject.swift index 9a2ccd661..4b6ba67ca 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProject.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProject.swift @@ -16,7 +16,7 @@ public final class PBXProject: PBXObject { buildConfigurationListReference = newValue.reference } get { - buildConfigurationListReference.getObject() + buildConfigurationListReference.object() } } @@ -41,7 +41,7 @@ public final class PBXProject: PBXObject { mainGroupReference = newValue.reference } get { - mainGroupReference.getObject() + mainGroupReference.object() } } @@ -54,7 +54,7 @@ public final class PBXProject: PBXObject { productsGroupReference = newValue?.reference } get { - productsGroupReference?.getObject() + productsGroupReference?.object() } } @@ -77,7 +77,7 @@ public final class PBXProject: PBXObject { } get { projectReferences.map { project in - project.mapValues { $0.getObject()! } + project.mapValues { $0.object()! } } } } @@ -117,7 +117,7 @@ public final class PBXProject: PBXObject { } get { var attributes: [PBXTarget: [String: Any]] = [:] targetAttributeReferences.forEach { - if let object: PBXTarget = $0.key.getObject() { + if let object: PBXTarget = $0.key.object() { attributes[object] = $0.value } } @@ -156,7 +156,7 @@ public final class PBXProject: PBXObject { private func setPackageReferences(_ packages: [T]) { let newReferences = packages.references() - var finalReferences: [PBXObjectReference] = packageReferences?.filter { !($0.getObject() is T) } ?? [] + var finalReferences: [PBXObjectReference] = packageReferences?.filter { !($0.object() is T) } ?? [] for reference in newReferences { if !finalReferences.contains(reference) { finalReferences.append(reference) @@ -224,7 +224,7 @@ public final class PBXProject: PBXObject { objects.add(object: buildFile) // Link the product - guard let frameworksBuildPhase = try target.frameworksBuildPhase() else { throw PBXProjError.frameworksBuildPhaseNotFound(targetName: targetName) } + guard let frameworksBuildPhase = target.frameworksBuildPhase() else { throw PBXProjError.frameworksBuildPhaseNotFound(targetName: targetName) } frameworksBuildPhase.files?.append(buildFile) return reference @@ -257,7 +257,7 @@ public final class PBXProject: PBXObject { objects.add(object: buildFile) // Link the product - guard let frameworksBuildPhase = try target.frameworksBuildPhase() else { + guard let frameworksBuildPhase = target.frameworksBuildPhase() else { throw PBXProjError.frameworksBuildPhaseNotFound(targetName: targetName) } @@ -492,10 +492,10 @@ extension PBXProject: PlistSerializable { dictionary["knownRegions"] = PlistValue.array(knownRegions .map { .string(CommentedString("\($0)")) }) } - let mainGroupObject: PBXGroup? = mainGroupReference.getObject() + let mainGroupObject: PBXGroup? = mainGroupReference.object() dictionary["mainGroup"] = .string(CommentedString(mainGroupReference.value, comment: mainGroupObject?.fileName())) if let productsGroupReference = productsGroupReference { - let productRefGroupObject: PBXGroup? = productsGroupReference.getObject() + let productRefGroupObject: PBXGroup? = productsGroupReference.object() dictionary["productRefGroup"] = .string(CommentedString(productsGroupReference.value, comment: productRefGroupObject?.fileName())) } @@ -510,7 +510,7 @@ extension PBXProject: PlistSerializable { } dictionary["targets"] = PlistValue.array(targetReferences .map { targetReference in - let target: PBXTarget? = targetReference.getObject() + let target: PBXTarget? = targetReference.object() return .string(CommentedString(targetReference.value, comment: target?.name)) }) @@ -553,9 +553,9 @@ extension PBXProject: PlistSerializable { let projectRef = reference[Xcode.ProjectReference.projectReferenceKey] else { return nil } - let producGroup: PBXGroup? = productGroupReference.getObject() + let producGroup: PBXGroup? = productGroupReference.object() let groupName = producGroup?.fileName() - let project: PBXFileElement? = projectRef.getObject() + let project: PBXFileElement? = projectRef.object() let fileRefName = project?.fileName() return [ diff --git a/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift b/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift index 5d2a1943f..e6fbe98ef 100644 --- a/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift +++ b/Sources/XcodeProj/Objects/Sourcery/Equality.generated.swift @@ -259,7 +259,7 @@ extension XCBuildConfiguration { /// :nodoc: func isEqual(to rhs: XCBuildConfiguration) -> Bool { if baseConfigurationReference != rhs.baseConfigurationReference { return false } - if !NSDictionary(dictionary: buildSettings).isEqual(NSDictionary(dictionary: rhs.buildSettings)) { return false } + if buildSettings != rhs.buildSettings { return false } if name != rhs.name { return false } return super.isEqual(to: rhs) } diff --git a/Sources/XcodeProj/Objects/SwiftPackage/XCSwiftPackageProductDependency.swift b/Sources/XcodeProj/Objects/SwiftPackage/XCSwiftPackageProductDependency.swift index 238e31f9a..2c13d353d 100644 --- a/Sources/XcodeProj/Objects/SwiftPackage/XCSwiftPackageProductDependency.swift +++ b/Sources/XcodeProj/Objects/SwiftPackage/XCSwiftPackageProductDependency.swift @@ -11,7 +11,7 @@ public class XCSwiftPackageProductDependency: PBXContainerItem, PlistSerializabl /// Package the product dependency refers to. public var package: XCRemoteSwiftPackageReference? { get { - packageReference?.getObject() + packageReference?.object() } set { packageReference = newValue?.reference diff --git a/Sources/XcodeProj/Objects/Targets/PBXReferenceProxy.swift b/Sources/XcodeProj/Objects/Targets/PBXReferenceProxy.swift index 67363c585..d2c782cc0 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXReferenceProxy.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXReferenceProxy.swift @@ -15,7 +15,7 @@ public final class PBXReferenceProxy: PBXFileElement { /// Element remote. public var remote: PBXContainerItemProxy? { get { - remoteReference?.getObject() + remoteReference?.object() } set { remoteReference = newValue?.reference diff --git a/Sources/XcodeProj/Objects/Targets/PBXTarget.swift b/Sources/XcodeProj/Objects/Targets/PBXTarget.swift index 07d255493..f79c2c2e4 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXTarget.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXTarget.swift @@ -8,7 +8,7 @@ public class PBXTarget: PBXContainerItem { /// Build configuration list. public var buildConfigurationList: XCConfigurationList? { get { - buildConfigurationListReference?.getObject() + buildConfigurationListReference?.object() } set { buildConfigurationListReference = newValue?.reference @@ -68,7 +68,7 @@ public class PBXTarget: PBXContainerItem { /// Target product. public var product: PBXFileReference? { get { - productReference?.getObject() + productReference?.object() } set { productReference = newValue?.reference @@ -180,7 +180,7 @@ public class PBXTarget: PBXContainerItem { } dictionary["buildPhases"] = .array(buildPhaseReferences .map { (buildPhaseReference: PBXObjectReference) in - let buildPhase: PBXBuildPhase? = buildPhaseReference.getObject() + let buildPhase: PBXBuildPhase? = buildPhaseReference.object() return .string(CommentedString(buildPhaseReference.value, comment: buildPhase?.name())) }) @@ -198,7 +198,7 @@ public class PBXTarget: PBXContainerItem { dictionary["productType"] = .string(CommentedString(productType.rawValue)) } if let productReference = productReference { - let fileElement: PBXFileElement? = productReference.getObject() + let fileElement: PBXFileElement? = productReference.object() dictionary["productReference"] = .string(CommentedString(productReference.value, comment: fileElement?.fileName())) } if !packageProductDependencies.isEmpty { @@ -234,9 +234,9 @@ public extension PBXTarget { /// /// - Returns: frameworks build phase. /// - Throws: an error if the build phase cannot be obtained. - func frameworksBuildPhase() throws -> PBXFrameworksBuildPhase? { - try buildPhaseReferences - .compactMap { try $0.getThrowingObject() as? PBXBuildPhase } + func frameworksBuildPhase() -> PBXFrameworksBuildPhase? { + buildPhaseReferences + .compactMap { $0.object(as: PBXBuildPhase.self) } .filter { $0.buildPhase == .frameworks } .compactMap { $0 as? PBXFrameworksBuildPhase } .first @@ -246,9 +246,9 @@ public extension PBXTarget { /// /// - Returns: sources build phase. /// - Throws: an error if the build phase cannot be obtained. - func sourcesBuildPhase() throws -> PBXSourcesBuildPhase? { - try buildPhaseReferences - .compactMap { try $0.getThrowingObject() as? PBXBuildPhase } + func sourcesBuildPhase() -> PBXSourcesBuildPhase? { + buildPhaseReferences + .compactMap { $0.object(as: PBXBuildPhase.self) } .filter { $0.buildPhase == .sources } .compactMap { $0 as? PBXSourcesBuildPhase } .first @@ -258,22 +258,22 @@ public extension PBXTarget { /// /// - Returns: sources build phase. /// - Throws: an error if the build phase cannot be obtained. - func resourcesBuildPhase() throws -> PBXResourcesBuildPhase? { - try buildPhaseReferences - .compactMap { try $0.getThrowingObject() as? PBXResourcesBuildPhase } + func resourcesBuildPhase() -> PBXResourcesBuildPhase? { + buildPhaseReferences + .compactMap { $0.object(as: PBXResourcesBuildPhase.self) } .filter { $0.buildPhase == .resources } .first } - + /// Returns the target source files. /// /// - Returns: source files. /// - Throws: an error if something goes wrong. - func sourceFiles() throws -> [PBXFileElement] { - try sourcesBuildPhase()?.fileReferences? - .compactMap { try $0.getThrowingObject() as? PBXBuildFile } + func sourceFiles() -> [PBXFileElement] { + sourcesBuildPhase()?.fileReferences? + .compactMap { $0.object(as: PBXBuildFile.self) } .filter { $0.fileReference != nil } - .compactMap { try $0.fileReference!.getThrowingObject() as? PBXFileElement } + .compactMap { $0.fileReference!.object(as: PBXFileElement.self) } ?? [] } diff --git a/Sources/XcodeProj/Objects/Targets/PBXTargetDependency.swift b/Sources/XcodeProj/Objects/Targets/PBXTargetDependency.swift index 22603e5b3..10c8e3b70 100644 --- a/Sources/XcodeProj/Objects/Targets/PBXTargetDependency.swift +++ b/Sources/XcodeProj/Objects/Targets/PBXTargetDependency.swift @@ -13,7 +13,7 @@ public final class PBXTargetDependency: PBXObject { /// Target. public var target: PBXTarget? { get { - targetReference?.getObject() + targetReference?.object() } set { targetReference = newValue?.reference @@ -26,7 +26,7 @@ public final class PBXTargetDependency: PBXObject { /// Target proxy. public var targetProxy: PBXContainerItemProxy? { get { - targetProxyReference?.getObject() + targetProxyReference?.object() } set { targetProxyReference = newValue?.reference @@ -39,7 +39,7 @@ public final class PBXTargetDependency: PBXObject { /// Product. public var product: XCSwiftPackageProductDependency? { get { - productReference?.getObject() + productReference?.object() } set { productReference = newValue?.reference @@ -130,7 +130,7 @@ extension PBXTargetDependency: PlistSerializable { dictionary["platformFilters"] = .array(platformFilters.map { .string(.init($0)) }) } if let targetReference = targetReference { - let targetObject: PBXTarget? = targetReference.getObject() + let targetObject: PBXTarget? = targetReference.object() dictionary["target"] = .string(CommentedString(targetReference.value, comment: targetObject?.name)) } if let targetProxyReference = targetProxyReference { diff --git a/Sources/XcodeProj/Utils/BuildSettingsProvider.swift b/Sources/XcodeProj/Utils/BuildSettingsProvider.swift index 574f50ca2..ed0572efa 100644 --- a/Sources/XcodeProj/Utils/BuildSettingsProvider.swift +++ b/Sources/XcodeProj/Utils/BuildSettingsProvider.swift @@ -46,7 +46,7 @@ public class BuildSettingsProvider { /// - swift: true if the target contains Swift code. /// - Returns: build settings. public static func targetDefault(variant: Variant? = nil, platform: Platform?, product: Product?, swift: Bool? = nil) -> BuildSettings { - var buildSettings: [String: Any] = [:] + var buildSettings: BuildSettings = [:] if let platform = platform { buildSettings.merge(targetSettings(platform: platform), uniquingKeysWith: { $1 }) diff --git a/Sources/XcodeProj/Utils/Decoders.swift b/Sources/XcodeProj/Utils/Decoders.swift index f298d1d5b..4d4739d68 100644 --- a/Sources/XcodeProj/Utils/Decoders.swift +++ b/Sources/XcodeProj/Utils/Decoders.swift @@ -13,7 +13,7 @@ class PBXObjectReferenceRepository { /// - objects: objects. /// - Returns: object reference. func getOrCreate(reference: String, objects: PBXObjects) -> PBXObjectReference { - lock.whileLocked { + lock.withLock { if let objectReference = references[reference] { return objectReference } diff --git a/Sources/XcodeProj/Utils/PlistValue.swift b/Sources/XcodeProj/Utils/PlistValue.swift index abd99a51b..2a710df43 100644 --- a/Sources/XcodeProj/Utils/PlistValue.swift +++ b/Sources/XcodeProj/Utils/PlistValue.swift @@ -85,6 +85,22 @@ extension PlistValue: Equatable { // MARK: - Dictionary Extension (PlistValue) + +extension Dictionary where Key == String, Value == BuildSetting { + func plist() -> PlistValue { + var dictionary: [CommentedString: PlistValue] = [:] + forEach { key, value in + switch value { + case .string(let stringValue): + dictionary[CommentedString(key)] = PlistValue.string(CommentedString(stringValue)) + case .array(let arrayValue): + dictionary[CommentedString(key)] = arrayValue.plist() + } + } + return .dictionary(dictionary) + } +} + extension Dictionary where Key == String { func plist() -> PlistValue { var dictionary: [CommentedString: PlistValue] = [:] diff --git a/Sources/XcodeProj/Utils/ReferenceGenerator.swift b/Sources/XcodeProj/Utils/ReferenceGenerator.swift index e4a5f3da9..495076f85 100644 --- a/Sources/XcodeProj/Utils/ReferenceGenerator.swift +++ b/Sources/XcodeProj/Utils/ReferenceGenerator.swift @@ -25,7 +25,7 @@ final class ReferenceGenerator: ReferenceGenerating { /// /// - Parameter proj: project whose objects references will be generated. func generateReferences(proj: PBXProj) throws { - guard let project: PBXProject = try proj.rootObjectReference?.getThrowingObject() else { + guard let project: PBXProject = proj.rootObjectReference?.object() else { return } @@ -52,8 +52,8 @@ final class ReferenceGenerator: ReferenceGenerating { // Project references try project.projectReferences.forEach { objectReferenceDict in - guard let projectReference = objectReferenceDict[Xcode.ProjectReference.projectReferenceKey]?.getObject() as? PBXFileReference, - let productsGroup = objectReferenceDict[Xcode.ProjectReference.productGroupKey]?.getObject() as? PBXGroup else { return } + guard let projectReference: PBXFileReference = objectReferenceDict[Xcode.ProjectReference.projectReferenceKey]?.object(), + let productsGroup: PBXGroup = objectReferenceDict[Xcode.ProjectReference.productGroupKey]?.object() else { return } try generateFileReference(projectReference, identifiers: identifiers) try generateGroupReferences(productsGroup, identifiers: identifiers + [projectReference.name ?? projectReference.path ?? ""]) } @@ -63,7 +63,7 @@ final class ReferenceGenerator: ReferenceGenerating { try targets.forEach { try generateTargetReferences($0, identifiers: identifiers) } /// Configuration list - if let configurationList: XCConfigurationList = project.buildConfigurationListReference.getObject() { + if let configurationList: XCConfigurationList = project.buildConfigurationListReference.object() { try generateConfigurationListReferences(configurationList, identifiers: identifiers) } } @@ -136,7 +136,7 @@ final class ReferenceGenerator: ReferenceGenerating { // Children try group.childrenReferences.forEach { child in - guard let childFileElement: PBXFileElement = child.getObject() else { return } + guard let childFileElement: PBXFileElement = child.object() else { return } if let childGroup = childFileElement as? PBXGroup { try generateGroupReferences(childGroup, identifiers: identifiers) } else if let childFileReference = childFileElement as? PBXFileReference { @@ -297,12 +297,12 @@ final class ReferenceGenerator: ReferenceGenerating { buildPhase.fileReferences?.forEach { buildFileReference in if !buildFileReference.temporary { return } - guard let buildFile: PBXBuildFile = buildFileReference.getObject() else { return } + guard let buildFile: PBXBuildFile = buildFileReference.object() else { return } var identifiers = identifiers if let fileReference = buildFile.fileReference, - let fileReferenceObject: PBXObject = fileReference.getObject() { + let fileReferenceObject: PBXObject = fileReference.object() { identifiers.append(fileReferenceObject.reference.value) } diff --git a/Sources/XcodeProj/Utils/XCConfig.swift b/Sources/XcodeProj/Utils/XCConfig.swift index 7f7a119a1..1f322e277 100644 --- a/Sources/XcodeProj/Utils/XCConfig.swift +++ b/Sources/XcodeProj/Utils/XCConfig.swift @@ -35,10 +35,10 @@ public final class XCConfig { let fileLines = try path.read().components(separatedBy: "\n") includes = fileLines .compactMap(XCConfigParser.configFrom(path: path, projectPath: projectPath)) - var buildSettings: [String: String] = [:] + var buildSettings: BuildSettings = [:] fileLines .compactMap(XCConfigParser.settingFrom) - .forEach { buildSettings[$0.key] = $0.value } + .forEach { buildSettings[$0.key] = .string($0.value) } self.buildSettings = buildSettings } } @@ -114,7 +114,7 @@ extension XCConfig: Equatable { return false } } - return NSDictionary(dictionary: lhs.buildSettings).isEqual(to: rhs.buildSettings) + return lhs.buildSettings == rhs.buildSettings } } @@ -124,8 +124,8 @@ extension XCConfig { /// It returns the build settings after flattening all the includes. /// /// - Returns: build settings flattening all the includes. - public func flattenedBuildSettings() -> [String: Any] { - var content: [String: Any] = buildSettings + public func flattenedBuildSettings() -> [String: BuildSetting] { + var content: [String: BuildSetting] = buildSettings includes .map { $0.1 } .flattened() @@ -174,7 +174,7 @@ extension XCConfig: Writable { private func writeBuildSettings() -> String { var content = "" buildSettings.forEach { key, value in - content.append("\(key) = \(value)\n") + content.append("\(key) = \(value.valueForWriting)\n") } content.append("\n") return content diff --git a/Tests/XcodeProjTests/Objects/Configuration/BuildSettingTests.swift b/Tests/XcodeProjTests/Objects/Configuration/BuildSettingTests.swift new file mode 100644 index 000000000..575f3b13d --- /dev/null +++ b/Tests/XcodeProjTests/Objects/Configuration/BuildSettingTests.swift @@ -0,0 +1,42 @@ +// +// BuildSettingTests.swift +// XcodeProj +// +// Created by Michael Simons on 7/20/24. +// + +import XCTest +@testable import XcodeProj + +final class BuildSettingTests: XCTestCase { + + func test_BuildSettings_Encode_to_JSON() throws { + let expectedJSON = #"{"one":"one","two":["two","two"]}"# + + let settings: BuildSettings = [ + "one": .string("one"), + "two": .array(["two", "two"]) + ] + + let encoder = JSONEncoder() + encoder.outputFormatting = .sortedKeys + + let result = try encoder.encode(settings) + + XCTAssertEqual(result, expectedJSON.data(using: .utf8)) + } + + func test_buildSettings_decodes_from_JSON() throws { + let json = #"{"one":"one","two":["two","two"]}"# + + let expectedSettings: BuildSettings = [ + "one": .string("one"), + "two": .array(["two", "two"]) + ] + + let result = try JSONDecoder().decode(BuildSettings.self, from: json.data(using: .utf8)!) + + XCTAssertEqual(result, expectedSettings) + } + +} diff --git a/Tests/XcodeProjTests/Objects/Configuration/XCBuildConfigurationTests.swift b/Tests/XcodeProjTests/Objects/Configuration/XCBuildConfigurationTests.swift index c818562b8..e29ef2d54 100644 --- a/Tests/XcodeProjTests/Objects/Configuration/XCBuildConfigurationTests.swift +++ b/Tests/XcodeProjTests/Objects/Configuration/XCBuildConfigurationTests.swift @@ -28,7 +28,7 @@ final class XCBuildConfigurationTests: XCTestCase { subject.append(setting: "PRODUCT_NAME", value: "$(TARGET_NAME:c99extidentifier)") // Then - XCTAssertEqual(subject.buildSettings["PRODUCT_NAME"] as? String, "$(inherited) $(TARGET_NAME:c99extidentifier)") + XCTAssertEqual(subject.buildSettings["PRODUCT_NAME"], "$(inherited) $(TARGET_NAME:c99extidentifier)") } func test_append_when_theSettingExists() { @@ -41,7 +41,7 @@ final class XCBuildConfigurationTests: XCTestCase { subject.append(setting: "OTHER_LDFLAGS", value: "flag2") // Then - XCTAssertEqual(subject.buildSettings["OTHER_LDFLAGS"] as? String, "flag1 flag2") + XCTAssertEqual(subject.buildSettings["OTHER_LDFLAGS"], "flag1 flag2") } func test_append_when_duplicateSettingExists() { @@ -54,7 +54,7 @@ final class XCBuildConfigurationTests: XCTestCase { subject.append(setting: "OTHER_LDFLAGS", value: "flag1") // Then - XCTAssertEqual(subject.buildSettings["OTHER_LDFLAGS"] as? String, "flag1") + XCTAssertEqual(subject.buildSettings["OTHER_LDFLAGS"], "flag1") } func test_append_removesDuplicates_when_theSettingIsAnArray() { @@ -69,7 +69,7 @@ final class XCBuildConfigurationTests: XCTestCase { subject.append(setting: "OTHER_LDFLAGS", value: "flag1") // Then - XCTAssertEqual(subject.buildSettings["OTHER_LDFLAGS"] as? [String], ["flag1", "flag2"]) + XCTAssertEqual(subject.buildSettings["OTHER_LDFLAGS"], ["flag1", "flag2"]) } func test_append_when_theSettingExistsAsAnArray() { @@ -82,7 +82,7 @@ final class XCBuildConfigurationTests: XCTestCase { subject.append(setting: "OTHER_LDFLAGS", value: "flag3") // Then - XCTAssertEqual(subject.buildSettings["OTHER_LDFLAGS"] as? [String], ["flag1", "flag2", "flag3"]) + XCTAssertEqual(subject.buildSettings["OTHER_LDFLAGS"], ["flag1", "flag2", "flag3"]) } private func testDictionary() -> [String: Any] { diff --git a/Tests/XcodeProjTests/Objects/Targets/PBXAggregateTargetTests.swift b/Tests/XcodeProjTests/Objects/Targets/PBXAggregateTargetTests.swift index d16bfd075..bf02a74fe 100644 --- a/Tests/XcodeProjTests/Objects/Targets/PBXAggregateTargetTests.swift +++ b/Tests/XcodeProjTests/Objects/Targets/PBXAggregateTargetTests.swift @@ -47,11 +47,11 @@ final class PBXAggregateTargetTests: XCTestCase { objects.add(object: target) objects.add(object: dependency) _ = try target.addDependency(target: dependency) - let targetDependency: PBXTargetDependency? = target.dependencyReferences.first?.getObject() + let targetDependency: PBXTargetDependency? = target.dependencyReferences.first?.object() XCTAssertEqual(targetDependency?.name, "Dependency") XCTAssertEqual(targetDependency?.targetReference, dependency.reference) - let containerItemProxy: PBXContainerItemProxy? = targetDependency?.targetProxyReference?.getObject() + let containerItemProxy: PBXContainerItemProxy? = targetDependency?.targetProxyReference?.object() XCTAssertEqual(containerItemProxy?.containerPortalReference, project.reference) XCTAssertEqual(containerItemProxy?.remoteGlobalID?.uuid, dependency.reference.value) XCTAssertEqual(containerItemProxy?.proxyType, .nativeTarget) diff --git a/Tests/XcodeProjTests/Objects/Targets/PBXNativeTargetTests.swift b/Tests/XcodeProjTests/Objects/Targets/PBXNativeTargetTests.swift index 5dd690fe5..e5f46bb09 100644 --- a/Tests/XcodeProjTests/Objects/Targets/PBXNativeTargetTests.swift +++ b/Tests/XcodeProjTests/Objects/Targets/PBXNativeTargetTests.swift @@ -48,11 +48,11 @@ final class PBXNativeTargetTests: XCTestCase { objects.add(object: target) objects.add(object: dependency) _ = try target.addDependency(target: dependency) - let targetDependency: PBXTargetDependency? = target.dependencyReferences.first?.getObject() + let targetDependency: PBXTargetDependency? = target.dependencyReferences.first?.object() XCTAssertEqual(targetDependency?.name, "Dependency") XCTAssertEqual(targetDependency?.targetReference, dependency.reference) - let containerItemProxy: PBXContainerItemProxy? = targetDependency?.targetProxyReference?.getObject() + let containerItemProxy: PBXContainerItemProxy? = targetDependency?.targetProxyReference?.object() XCTAssertEqual(containerItemProxy?.containerPortalReference, project.reference) XCTAssertEqual(containerItemProxy?.remoteGlobalID?.uuid, dependency.reference.value) XCTAssertEqual(containerItemProxy?.proxyType, .nativeTarget) diff --git a/Tests/XcodeProjTests/Project/XcodeProjTests.swift b/Tests/XcodeProjTests/Project/XcodeProjTests.swift index 3f4a81948..44d50517d 100644 --- a/Tests/XcodeProjTests/Project/XcodeProjTests.swift +++ b/Tests/XcodeProjTests/Project/XcodeProjTests.swift @@ -33,7 +33,7 @@ final class XcodeProjIntegrationTests: XCTestCase { // When let pbxprojFromData = try PBXProj(data: pbxprojData) - try pbxprojFromData.updateProjectName(path: pbxprojPath) + pbxprojFromData.updateProjectName(path: pbxprojPath) // Then XCTAssertEqual(pbxprojFromData, pbxprojFromDisk) diff --git a/Tests/XcodeProjTests/Utils/BuildSettingsProviderTests.swift b/Tests/XcodeProjTests/Utils/BuildSettingsProviderTests.swift index 4b65f3e19..4fb27b06f 100644 --- a/Tests/XcodeProjTests/Utils/BuildSettingsProviderTests.swift +++ b/Tests/XcodeProjTests/Utils/BuildSettingsProviderTests.swift @@ -9,21 +9,22 @@ class BuildSettingProviderTests: XCTestCase { platform: .iOS, product: .application, swift: true) - + let expected: BuildSettings = [ + "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIcon", + "ENABLE_PREVIEWS": "YES", + "CODE_SIGN_IDENTITY": "iPhone Developer", + "LD_RUNPATH_SEARCH_PATHS": [ + "$(inherited)", + "@executable_path/Frameworks", + ], + "SDKROOT": "iphoneos", + "SWIFT_COMPILATION_MODE": "wholemodule", + "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", + "TARGETED_DEVICE_FAMILY": "1,2", + ] + // Then - assertEqualSettings(results, [ - "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIcon", - "ENABLE_PREVIEWS": "YES", - "CODE_SIGN_IDENTITY": "iPhone Developer", - "LD_RUNPATH_SEARCH_PATHS": [ - "$(inherited)", - "@executable_path/Frameworks", - ], - "SDKROOT": "iphoneos", - "SWIFT_COMPILATION_MODE": "wholemodule", - "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", - "TARGETED_DEVICE_FAMILY": "1,2", - ]) + XCTAssertEqual(results, expected) } func test_targetSettings_iosFramework() { @@ -32,30 +33,31 @@ class BuildSettingProviderTests: XCTestCase { platform: .iOS, product: .framework, swift: true) - + let expected: BuildSettings = [ + "CODE_SIGN_IDENTITY": "", + "CURRENT_PROJECT_VERSION": "1", + "DEFINES_MODULE": "YES", + "DYLIB_COMPATIBILITY_VERSION": "1", + "DYLIB_CURRENT_VERSION": "1", + "DYLIB_INSTALL_NAME_BASE": "@rpath", + "INSTALL_PATH": "$(LOCAL_LIBRARY_DIR)/Frameworks", + "LD_RUNPATH_SEARCH_PATHS": [ + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ], + "PRODUCT_NAME": "$(TARGET_NAME:c99extidentifier)", + "SDKROOT": "iphoneos", + "SKIP_INSTALL": "YES", + "SWIFT_COMPILATION_MODE": "wholemodule", + "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", + "TARGETED_DEVICE_FAMILY": "1,2", + "VERSIONING_SYSTEM": "apple-generic", + "VERSION_INFO_PREFIX": "", + ] + // Then - assertEqualSettings(results, [ - "CODE_SIGN_IDENTITY": "", - "CURRENT_PROJECT_VERSION": "1", - "DEFINES_MODULE": "YES", - "DYLIB_COMPATIBILITY_VERSION": "1", - "DYLIB_CURRENT_VERSION": "1", - "DYLIB_INSTALL_NAME_BASE": "@rpath", - "INSTALL_PATH": "$(LOCAL_LIBRARY_DIR)/Frameworks", - "LD_RUNPATH_SEARCH_PATHS": [ - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ], - "PRODUCT_NAME": "$(TARGET_NAME:c99extidentifier)", - "SDKROOT": "iphoneos", - "SKIP_INSTALL": "YES", - "SWIFT_COMPILATION_MODE": "wholemodule", - "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", - "TARGETED_DEVICE_FAMILY": "1,2", - "VERSIONING_SYSTEM": "apple-generic", - "VERSION_INFO_PREFIX": "", - ]) + XCTAssertEqual(results, expected) } func test_targetSettings_iosExtension() { @@ -64,20 +66,20 @@ class BuildSettingProviderTests: XCTestCase { platform: .iOS, product: .appExtension, swift: true) - + let expected: BuildSettings = [ + "CODE_SIGN_IDENTITY": "iPhone Developer", + "LD_RUNPATH_SEARCH_PATHS": [ + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ], + "SDKROOT": "iphoneos", + "SWIFT_COMPILATION_MODE": "wholemodule", + "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", + "TARGETED_DEVICE_FAMILY": "1,2", + ] // Then - assertEqualSettings(results, [ - "CODE_SIGN_IDENTITY": "iPhone Developer", - "LD_RUNPATH_SEARCH_PATHS": [ - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ], - "SDKROOT": "iphoneos", - "SWIFT_COMPILATION_MODE": "wholemodule", - "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", - "TARGETED_DEVICE_FAMILY": "1,2", - ]) + XCTAssertEqual(results, expected) } func test_targetSettings_macOSAplication() { @@ -87,20 +89,21 @@ class BuildSettingProviderTests: XCTestCase { product: .application, swift: true) + let expected: BuildSettings = [ + "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIcon", + "ENABLE_PREVIEWS": "YES", + "CODE_SIGN_IDENTITY": "-", + "COMBINE_HIDPI_IMAGES": "YES", + "LD_RUNPATH_SEARCH_PATHS": [ + "$(inherited)", + "@executable_path/../Frameworks", + ], + "SDKROOT": "macosx", + "SWIFT_COMPILATION_MODE": "wholemodule", + "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", + ] // Then - assertEqualSettings(results, [ - "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIcon", - "ENABLE_PREVIEWS": "YES", - "CODE_SIGN_IDENTITY": "-", - "COMBINE_HIDPI_IMAGES": "YES", - "LD_RUNPATH_SEARCH_PATHS": [ - "$(inherited)", - "@executable_path/../Frameworks", - ], - "SDKROOT": "macosx", - "SWIFT_COMPILATION_MODE": "wholemodule", - "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", - ]) + XCTAssertEqual(results, expected) } func test_targetSettings_tvOSAplication() { @@ -110,20 +113,22 @@ class BuildSettingProviderTests: XCTestCase { product: .application, swift: true) + let expected: BuildSettings = [ + "ASSETCATALOG_COMPILER_APPICON_NAME": "App Icon & Top Shelf Image", + "ENABLE_PREVIEWS": "YES", + "ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME": "LaunchImage", + "LD_RUNPATH_SEARCH_PATHS": [ + "$(inherited)", + "@executable_path/Frameworks", + ], + "SDKROOT": "appletvos", + "SWIFT_COMPILATION_MODE": "wholemodule", + "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", + "TARGETED_DEVICE_FAMILY": "3", + ] + // Then - assertEqualSettings(results, [ - "ASSETCATALOG_COMPILER_APPICON_NAME": "App Icon & Top Shelf Image", - "ENABLE_PREVIEWS": "YES", - "ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME": "LaunchImage", - "LD_RUNPATH_SEARCH_PATHS": [ - "$(inherited)", - "@executable_path/Frameworks", - ], - "SDKROOT": "appletvos", - "SWIFT_COMPILATION_MODE": "wholemodule", - "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", - "TARGETED_DEVICE_FAMILY": "3", - ]) + XCTAssertEqual(results, expected) } func test_targetSettings_watchOSAplication() { @@ -133,18 +138,20 @@ class BuildSettingProviderTests: XCTestCase { product: .application, swift: true) + let expected: BuildSettings = [ + "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES": "YES", + "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIcon", + "ENABLE_PREVIEWS": "YES", + "LD_RUNPATH_SEARCH_PATHS": ["$(inherited)", "@executable_path/Frameworks"], + "SDKROOT": "watchos", + "SKIP_INSTALL": "YES", + "SWIFT_COMPILATION_MODE": "wholemodule", + "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", + "TARGETED_DEVICE_FAMILY": "4", + ] + // Then - assertEqualSettings(results, [ - "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES": "YES", - "ASSETCATALOG_COMPILER_APPICON_NAME": "AppIcon", - "ENABLE_PREVIEWS": "YES", - "LD_RUNPATH_SEARCH_PATHS": ["$(inherited)", "@executable_path/Frameworks"], - "SDKROOT": "watchos", - "SKIP_INSTALL": "YES", - "SWIFT_COMPILATION_MODE": "wholemodule", - "SWIFT_OPTIMIZATION_LEVEL": "-Owholemodule", - "TARGETED_DEVICE_FAMILY": "4", - ]) + XCTAssertEqual(results, expected) } func test_targetSettings_iOSUnitTests() { @@ -154,20 +161,22 @@ class BuildSettingProviderTests: XCTestCase { product: .unitTests, swift: true) + let expected: BuildSettings = [ + "CODE_SIGN_IDENTITY": "iPhone Developer", + "SDKROOT": "iphoneos", + "LD_RUNPATH_SEARCH_PATHS": [ + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ], + "SWIFT_ACTIVE_COMPILATION_CONDITIONS": ["$(inherited)", "DEBUG"], + "SWIFT_COMPILATION_MODE": "singlefile", + "SWIFT_OPTIMIZATION_LEVEL": "-Onone", + "TARGETED_DEVICE_FAMILY": "1,2", + ] + // Then - assertEqualSettings(results, [ - "CODE_SIGN_IDENTITY": "iPhone Developer", - "SDKROOT": "iphoneos", - "LD_RUNPATH_SEARCH_PATHS": [ - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ], - "SWIFT_ACTIVE_COMPILATION_CONDITIONS": ["$(inherited)", "DEBUG"], - "SWIFT_COMPILATION_MODE": "singlefile", - "SWIFT_OPTIMIZATION_LEVEL": "-Onone", - "TARGETED_DEVICE_FAMILY": "1,2", - ]) + XCTAssertEqual(results, expected) } func test_targetSettings_iOSUITests() { @@ -176,21 +185,23 @@ class BuildSettingProviderTests: XCTestCase { platform: .iOS, product: .uiTests, swift: true) - + let expected: BuildSettings = [ + "CODE_SIGN_IDENTITY": "iPhone Developer", + "SDKROOT": "iphoneos", + "LD_RUNPATH_SEARCH_PATHS": [ + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ], + "SWIFT_ACTIVE_COMPILATION_CONDITIONS": ["$(inherited)", "DEBUG"], + "SWIFT_COMPILATION_MODE": "singlefile", + "SWIFT_OPTIMIZATION_LEVEL": "-Onone", + "TARGETED_DEVICE_FAMILY": "1,2", + ] + + // Then - assertEqualSettings(results, [ - "CODE_SIGN_IDENTITY": "iPhone Developer", - "SDKROOT": "iphoneos", - "LD_RUNPATH_SEARCH_PATHS": [ - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ], - "SWIFT_ACTIVE_COMPILATION_CONDITIONS": ["$(inherited)", "DEBUG"], - "SWIFT_COMPILATION_MODE": "singlefile", - "SWIFT_OPTIMIZATION_LEVEL": "-Onone", - "TARGETED_DEVICE_FAMILY": "1,2", - ]) + XCTAssertEqual(results, expected ) } func test_targetSettings_macOSUnitTests() { @@ -200,19 +211,21 @@ class BuildSettingProviderTests: XCTestCase { product: .unitTests, swift: true) + let expected: BuildSettings = [ + "CODE_SIGN_IDENTITY": "-", + "SDKROOT": "macosx", + "LD_RUNPATH_SEARCH_PATHS": [ + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ], + "SWIFT_ACTIVE_COMPILATION_CONDITIONS": ["$(inherited)", "DEBUG"], + "SWIFT_COMPILATION_MODE": "singlefile", + "SWIFT_OPTIMIZATION_LEVEL": "-Onone", + ] + // Then - assertEqualSettings(results, [ - "CODE_SIGN_IDENTITY": "-", - "SDKROOT": "macosx", - "LD_RUNPATH_SEARCH_PATHS": [ - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/../Frameworks", - ], - "SWIFT_ACTIVE_COMPILATION_CONDITIONS": ["$(inherited)", "DEBUG"], - "SWIFT_COMPILATION_MODE": "singlefile", - "SWIFT_OPTIMIZATION_LEVEL": "-Onone", - ]) + XCTAssertEqual(results, expected) } func test_targetSettings_tvOSUnitTests() { @@ -221,28 +234,29 @@ class BuildSettingProviderTests: XCTestCase { platform: .tvOS, product: .unitTests, swift: true) + let expected: BuildSettings = [ + "SDKROOT": "appletvos", + "LD_RUNPATH_SEARCH_PATHS": [ + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ], + "SWIFT_ACTIVE_COMPILATION_CONDITIONS": ["$(inherited)", "DEBUG"], + "SWIFT_COMPILATION_MODE": "singlefile", + "SWIFT_OPTIMIZATION_LEVEL": "-Onone", + "TARGETED_DEVICE_FAMILY": "3", + ] // Then - assertEqualSettings(results, [ - "SDKROOT": "appletvos", - "LD_RUNPATH_SEARCH_PATHS": [ - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ], - "SWIFT_ACTIVE_COMPILATION_CONDITIONS": ["$(inherited)", "DEBUG"], - "SWIFT_COMPILATION_MODE": "singlefile", - "SWIFT_OPTIMIZATION_LEVEL": "-Onone", - "TARGETED_DEVICE_FAMILY": "3", - ]) + XCTAssertEqual(results, expected) } // MARK: - Helpers - func assertEqualSettings(_ lhs: BuildSettings, _ rhs: BuildSettings, file: StaticString = #file, line: UInt = #line) { - XCTAssertEqual(lhs as NSDictionary, - rhs as NSDictionary, - file: file, - line: line) - } +// func XCTAssertEqual(_ lhs: BuildSettings, _ rhs: BuildSettings, file: StaticString = #file, line: UInt = #line) { +// XCTAssertEqual(lhs as NSDictionary, +// rhs as NSDictionary, +// file: file, +// line: line) +// } } diff --git a/Tests/XcodeProjTests/Utils/ObjectReferenceTests.swift b/Tests/XcodeProjTests/Utils/ObjectReferenceTests.swift index b17ef6999..b56c68d04 100644 --- a/Tests/XcodeProjTests/Utils/ObjectReferenceTests.swift +++ b/Tests/XcodeProjTests/Utils/ObjectReferenceTests.swift @@ -9,9 +9,9 @@ class ObjectReferenceTests: XCTestCase { func test_reference_cachesObject() { let reference = PBXObjectReference() let object = PBXFileReference() - XCTAssertNil(reference.getObject()) + XCTAssertNil(reference.object()) reference.setObject(object) - XCTAssertEqual(object, reference.getObject()) + XCTAssertEqual(object, reference.object()) } func test_reference_fetches() { @@ -19,7 +19,7 @@ class ObjectReferenceTests: XCTestCase { object.reference.fix("a") let objects = PBXObjects(objects: [object]) let reference = PBXObjectReference("a", objects: objects) - XCTAssertEqual(object, reference.getObject()) + XCTAssertEqual(object, reference.object()) } func test_reference_handleReferenceChange() { diff --git a/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift b/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift index 08a3f9760..6528dd76d 100644 --- a/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift +++ b/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift @@ -48,7 +48,7 @@ class ReferenceGeneratorTests: XCTestCase { let referenceGenerator = ReferenceGenerator(outputSettings: PBXOutputSettings()) try referenceGenerator.generateReferences(proj: project) - return [remoteProjectFileReference, containerItemProxy, productReferenceProxy, productsGroup, buildFile, pluginDependency.productReference!.getObject()!] + return [remoteProjectFileReference, containerItemProxy, productReferenceProxy, productsGroup, buildFile, pluginDependency.productReference!.object()!] .map { $0.reference.value } } @@ -143,7 +143,7 @@ private extension PBXProj { let packageReference = XCRemoteSwiftPackageReference(repositoryURL: "repository") let packageDependency = XCSwiftPackageProductDependency(productName: "product", package: packageReference, isPlugin: true) let targetDependency = PBXTargetDependency(product: packageDependency) - add(object: targetDependency.productReference!.getObject()!) + add(object: targetDependency.productReference!.object()!) return targetDependency } diff --git a/Tests/XcodeProjTests/Utils/XCConfigTests.swift b/Tests/XcodeProjTests/Utils/XCConfigTests.swift index ade947b42..d0a462b65 100644 --- a/Tests/XcodeProjTests/Utils/XCConfigTests.swift +++ b/Tests/XcodeProjTests/Utils/XCConfigTests.swift @@ -14,7 +14,7 @@ final class XCConfigTests: XCTestCase { (Path("testB"), configB), ], buildSettings: ["a": "b"]) - XCTAssertEqual(config.buildSettings as! [String: String], ["a": "b"]) + XCTAssertEqual(config.buildSettings, ["a": "b"]) XCTAssertEqual(config.includes[0].config, configA) XCTAssertEqual(config.includes[1].config, configB) } @@ -28,8 +28,8 @@ final class XCConfigTests: XCTestCase { ], buildSettings: ["b": "3"]) let buildSettings = config.flattenedBuildSettings() - XCTAssertEqual(buildSettings["a"] as? String, "2") - XCTAssertEqual(buildSettings["b"] as? String, "3") + XCTAssertEqual(buildSettings["a"], "2") + XCTAssertEqual(buildSettings["b"], "3") } func test_xcconfig_settingRegex() { @@ -101,16 +101,16 @@ final class XCConfigIntegrationTests: XCTestCase { } private func assert(config: XCConfig) { - XCTAssertEqual(config.buildSettings["CONFIGURATION_BUILD_DIR"] as? String, "Test/") - XCTAssertEqual(config.flattenedBuildSettings()["CONFIGURATION_BUILD_DIR"] as? String, "Test/") - XCTAssertEqual(config.buildSettings["GCC_PREPROCESSOR_DEFINITIONS"] as? String, "$(inherited)") - XCTAssertEqual(config.flattenedBuildSettings()["GCC_PREPROCESSOR_DEFINITIONS"] as? String, "$(inherited)") - XCTAssertEqual(config.buildSettings["WARNING_CFLAGS"] as? String, "-Wall -Wno-direct-ivar-access -Wno-objc-missing-property-synthesis -Wno-readonly-iboutlet-property -Wno-switch-enum -Wno-padded") - XCTAssertEqual(config.flattenedBuildSettings()["WARNING_CFLAGS"] as? String, "-Wall -Wno-direct-ivar-access -Wno-objc-missing-property-synthesis -Wno-readonly-iboutlet-property -Wno-switch-enum -Wno-padded") + XCTAssertEqual(config.buildSettings["CONFIGURATION_BUILD_DIR"], "Test/") + XCTAssertEqual(config.flattenedBuildSettings()["CONFIGURATION_BUILD_DIR"], "Test/") + XCTAssertEqual(config.buildSettings["GCC_PREPROCESSOR_DEFINITIONS"], "$(inherited)") + XCTAssertEqual(config.flattenedBuildSettings()["GCC_PREPROCESSOR_DEFINITIONS"], "$(inherited)") + XCTAssertEqual(config.buildSettings["WARNING_CFLAGS"], "-Wall -Wno-direct-ivar-access -Wno-objc-missing-property-synthesis -Wno-readonly-iboutlet-property -Wno-switch-enum -Wno-padded") + XCTAssertEqual(config.flattenedBuildSettings()["WARNING_CFLAGS"], "-Wall -Wno-direct-ivar-access -Wno-objc-missing-property-synthesis -Wno-readonly-iboutlet-property -Wno-switch-enum -Wno-padded") XCTAssertEqual(config.includes.count, 1) - XCTAssertEqual(config.flattenedBuildSettings()["OTHER_SWIFT_FLAGS_XCODE_0821"] as? String, "$(inherited)") - XCTAssertEqual(config.flattenedBuildSettings()["OTHER_SWIFT_FLAGS_XCODE_0830"] as? String, "$(inherited) -enable-bridging-pch") - XCTAssertEqual(config.flattenedBuildSettings()["PRODUCT_NAME"] as? String, "$(TARGET_NAME)") - XCTAssertEqual(config.flattenedBuildSettings()["SWIFT_OPTIMIZATION_LEVEL"] as? String, "-Onone") + XCTAssertEqual(config.flattenedBuildSettings()["OTHER_SWIFT_FLAGS_XCODE_0821"], "$(inherited)") + XCTAssertEqual(config.flattenedBuildSettings()["OTHER_SWIFT_FLAGS_XCODE_0830"], "$(inherited) -enable-bridging-pch") + XCTAssertEqual(config.flattenedBuildSettings()["PRODUCT_NAME"], "$(TARGET_NAME)") + XCTAssertEqual(config.flattenedBuildSettings()["SWIFT_OPTIMIZATION_LEVEL"], "-Onone") } }