Skip to content
This repository was archived by the owner on Feb 26, 2026. It is now read-only.

Commit 7e542a9

Browse files
authored
refactor: migrate to xcodeproj 9 (#147)
* Remove unused `toAny` method * First draft of using Strogly Typed build settings in XcodeProj 9 * Fix an issue that stripped all attributes * Update for strongly typed build settings mapping * Update Tests for strongly typed build settings * Finish removal of tuist specific information from build settings * Linting * Remove leftover test * Update to XcodeProj 9.0
1 parent bcbef4b commit 7e542a9

23 files changed

Lines changed: 44 additions & 455 deletions

Package.resolved

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ let package = Package(
8080
dependencies: [
8181
.package(url: "https://github.com/Flight-School/AnyCodable", .upToNextMajor(from: "0.6.7")),
8282
.package(url: "https://github.com/tuist/Path.git", .upToNextMajor(from: "0.3.8")),
83-
.package(url: "https://github.com/tuist/XcodeProj", .upToNextMajor(from: "8.27.7")),
83+
.package(url: "https://github.com/tuist/XcodeProj", .upToNextMajor(from: "9.0.0")),
8484
.package(url: "https://github.com/tuist/Command.git", from: "0.13.0"),
8585
.package(url: "https://github.com/tuist/FileSystem.git", .upToNextMajor(from: "0.7.7")),
8686
.package(url: "https://github.com/apple/swift-service-context", .upToNextMajor(from: "1.2.0")),

Sources/XcodeGraph/Models/Settings.swift

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,6 @@ extension [BuildConfiguration: Configuration?] {
145145
}
146146
}
147147

148-
extension [String: SettingValue] {
149-
public func toAny() -> [String: Any] {
150-
mapValues { value in
151-
switch value {
152-
case let .array(array):
153-
return array
154-
case let .string(string):
155-
return string
156-
}
157-
}
158-
}
159-
}
160-
161148
#if DEBUG
162149
extension Configuration {
163150
public static func test(

Sources/XcodeGraphMapper/Extensions/PBXProject+Extensions.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ extension PBXProject {
55
///
66
/// - Parameter attr: The attribute key to look up.
77
/// - Returns: The value of the attribute if it exists, or `nil` if not found.
8-
func attribute(for attr: ProjectAttribute) -> String? {
9-
attributes[attr.rawValue] as? String
8+
func attribute(for attr: ProjectAttributeKey) -> String? {
9+
attributes[attr.rawValue]?.stringValue
1010
}
1111
}

Sources/XcodeGraphMapper/Mappers/Phases/PBXCopyFilesBuildPhaseMapper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct PBXCopyFilesBuildPhaseMapper: PBXCopyFilesBuildPhaseMapping {
5959
}
6060

6161
let absolutePath = try AbsolutePath(validating: pathString)
62-
let attributes = buildFile.settings?.stringArray(for: .attributes)
62+
let attributes = buildFile.attributes
6363
let codeSignOnCopy = attributes?.contains(BuildFileAttribute.codeSignOnCopy.rawValue) ?? false
6464

6565
return .file(path: absolutePath, condition: nil, codeSignOnCopy: codeSignOnCopy)

Sources/XcodeGraphMapper/Mappers/Phases/PBXFrameworksBuildPhaseMapper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct PBXFrameworksBuildPhaseMapper: PBXFrameworksBuildPhaseMapping {
6565
)
6666
if let path = fileRef.path {
6767
let name = path.replacingOccurrences(of: ".framework", with: "")
68-
let linkingStatus: LinkingStatus = (buildFile.settings?["ATTRIBUTES"] as? [String])?
68+
let linkingStatus: LinkingStatus = buildFile.attributes?
6969
.contains("Weak") == true ? .optional : .required
7070
switch fileRef.sourceTree {
7171
case .buildProductsDir:

Sources/XcodeGraphMapper/Mappers/Phases/PBXHeadersBuildPhaseMapper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct PBXHeadersBuildPhaseMapper: PBXHeadersBuildPhaseMapping {
5454
}
5555

5656
let absolutePath = try AbsolutePath(validating: pathString)
57-
let attributes = buildFile.settings?.stringArray(for: .attributes)
57+
let attributes = buildFile.attributes
5858

5959
let visibility: HeaderInfo.HeaderVisibility
6060
if attributes?.contains(HeaderAttribute.public.rawValue) == true {

Sources/XcodeGraphMapper/Mappers/Phases/PBXSourcesBuildPhaseMapper.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ struct PBXSourcesBuildPhaseMapper: PBXSourcesBuildPhaseMapping {
4040
}
4141

4242
let path = try AbsolutePath(validating: pathString)
43-
let settings = buildFile.settings ?? [:]
44-
let compilerFlags: String? = settings.string(for: .compilerFlags)
45-
let attributes: [String]? = settings.stringArray(for: .attributes)
43+
let compilerFlags: String? = buildFile.compilerFlags
44+
let attributes: [String]? = buildFile.attributes
4645

4746
return SourceFile(
4847
path: path,

Sources/XcodeGraphMapper/Mappers/Project/ProjectAttribute.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Foundation
22

33
/// Attributes for project settings that can be retrieved from a `PBXProject`.
4-
enum ProjectAttribute: String {
4+
enum ProjectAttributeKey: String {
55
case classPrefix = "CLASSPREFIX"
66
case organization = "ORGANIZATIONNAME"
77
case lastUpgradeCheck = "LastUpgradeCheck"
Lines changed: 4 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
11
import Foundation
2+
import XcodeProj
23

34
/// Keys representing various build settings that may appear in an Xcode project or workspace configuration.
45
enum BuildSettingKey: String {
56
case sdkroot = "SDKROOT"
6-
case compilerFlags = "COMPILER_FLAGS"
7-
case attributes = "ATTRIBUTES"
8-
case environmentVariables = "ENVIRONMENT_VARIABLES"
97
case codeSignOnCopy = "CODE_SIGN_ON_COPY"
10-
case dependencyFile = "DEPENDENCY_FILE"
11-
case inputPaths = "INPUT_PATHS"
12-
case outputPaths = "OUTPUT_PATHS"
13-
case showEnvVarsInLog = "SHOW_ENV_VARS_IN_LOG"
14-
case shellPath = "SHELL_PATH"
15-
case launchArguments = "LAUNCH_ARGUMENTS"
16-
case tags = "TAGS"
178
case mergedBinaryType = "MERGED_BINARY_TYPE"
18-
case prune = "PRUNE"
19-
case mergeable = "MERGEABLE"
209
case productBundleIdentifier = "PRODUCT_BUNDLE_IDENTIFIER"
2110
case infoPlistFile = "INFOPLIST_FILE"
2211
case codeSignEntitlements = "CODE_SIGN_ENTITLEMENTS"
@@ -27,74 +16,8 @@ enum BuildSettingKey: String {
2716
case visionOSDeploymentTarget = "VISIONOS_DEPLOYMENT_TARGET"
2817
}
2918

30-
/// A protocol representing a type that can parse a build setting value from a generic `Any`.
31-
protocol BuildSettingValue {
32-
associatedtype Value
33-
static func parse(_ any: Any) -> Value?
34-
}
35-
36-
/// A type that parses build settings as strings.
37-
enum BuildSettingString: BuildSettingValue {
38-
static func parse(_ any: Any) -> String? {
39-
any as? String
40-
}
41-
}
42-
43-
/// A type that parses build settings as arrays of strings.
44-
enum BuildSettingStringArray: BuildSettingValue {
45-
static func parse(_ any: Any) -> [String]? {
46-
let arr = any as? [Any]
47-
return arr?.compactMap { $0 as? String }
48-
}
49-
}
50-
51-
/// A type that parses build settings as booleans.
52-
enum BuildSettingBool: BuildSettingValue {
53-
static func parse(_ any: Any) -> Bool? {
54-
any as? Bool
55-
}
56-
}
57-
58-
/// A type that parses build settings as dictionaries of strings to strings.
59-
enum BuildSettingStringDict: BuildSettingValue {
60-
static func parse(_ any: Any) -> [String: String]? {
61-
any as? [String: String]
62-
}
63-
}
64-
65-
extension [String: Any] {
66-
/// Extracts a build setting value of a specified type from the dictionary.
67-
///
68-
/// - Parameters:
69-
/// - key: The `BuildSettingKey` to look up.
70-
/// - type: The type conforming to `BuildSettingValue` indicating the expected value type.
71-
/// - Returns: The parsed value if found and valid, or `nil` otherwise.
72-
func extractBuildSetting<T: BuildSettingValue>(_ key: BuildSettingKey, as _: T.Type = T.self)
73-
-> T.Value?
74-
{
75-
guard let value = self[key.rawValue] else { return nil }
76-
return T.parse(value)
77-
}
78-
}
79-
80-
extension [String: Any] {
81-
/// Retrieves a string value for the given build setting key.
82-
func string(for key: BuildSettingKey) -> String? {
83-
extractBuildSetting(key, as: BuildSettingString.self)
84-
}
85-
86-
/// Retrieves an array of strings for the given build setting key.
87-
func stringArray(for key: BuildSettingKey) -> [String]? {
88-
extractBuildSetting(key, as: BuildSettingStringArray.self)
89-
}
90-
91-
/// Retrieves a boolean value for the given build setting key.
92-
func bool(for key: BuildSettingKey) -> Bool? {
93-
extractBuildSetting(key, as: BuildSettingBool.self)
94-
}
95-
96-
/// Retrieves a dictionary of strings for the given build setting key.
97-
func stringDict(for key: BuildSettingKey) -> [String: String]? {
98-
extractBuildSetting(key, as: BuildSettingStringDict.self)
19+
extension BuildSettings {
20+
subscript(_ key: BuildSettingKey) -> BuildSetting? {
21+
self[key.rawValue]
9922
}
10023
}

0 commit comments

Comments
 (0)