From d255ebe370a727fc831fdba9288bc236fbf930d9 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 18 Jan 2024 10:32:56 -0500 Subject: [PATCH] Adopt new XCConfig resolution API --- Package.resolved | 2 +- Package.swift | 2 +- .../Extensions/PBXProj+BuildSettings.swift | 22 ++++++++++++++----- .../XCBuildConfiguration+BuildSettings.swift | 12 ++-------- .../Rules/ValidateBuildSettingsRule.swift | 9 +++++--- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Package.resolved b/Package.resolved index 08e77b6..d0bec1d 100644 --- a/Package.resolved +++ b/Package.resolved @@ -41,7 +41,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/mattmassicotte/XCConfig", "state" : { - "revision" : "586308908873a212c17019163afea02847f782a3" + "revision" : "38fe6d21eaf34c36c3835cb4c5b81b4654de1abc" } }, { diff --git a/Package.swift b/Package.swift index 3da7f7c..13d7bf8 100644 --- a/Package.swift +++ b/Package.swift @@ -12,7 +12,7 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/tuist/XcodeProj", from: "8.15.0"), - .package(url: "https://github.com/mattmassicotte/XCConfig", revision: "586308908873a212c17019163afea02847f782a3"), + .package(url: "https://github.com/mattmassicotte/XCConfig", revision: "38fe6d21eaf34c36c3835cb4c5b81b4654de1abc"), .package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.3"), .package(url: "https://github.com/jpsim/Yams.git", from: "5.0.0"), ], diff --git a/Sources/XCLinting/Extensions/PBXProj+BuildSettings.swift b/Sources/XCLinting/Extensions/PBXProj+BuildSettings.swift index 16d09e3..380982a 100644 --- a/Sources/XCLinting/Extensions/PBXProj+BuildSettings.swift +++ b/Sources/XCLinting/Extensions/PBXProj+BuildSettings.swift @@ -3,6 +3,14 @@ import Foundation import XCConfig import XcodeProj +extension Parser { + func parse(contentsOf url: URL) throws -> [Statement] { + let string = try String(contentsOf: url) + + return parse(string) + } +} + extension PBXProj { func enumerateBuildConfigurations(_ block: (String, XCConfigurationList) throws -> Void) rethrows { for target in legacyTargets { @@ -28,7 +36,7 @@ extension PBXProj { func enumerateBuildSettingStatements( rootURL: URL, - _ block: (PBXProject, PBXTarget, XCBuildConfiguration, [[Statement]]) throws -> Void + _ block: (PBXProject, PBXTarget, XCBuildConfiguration, [[Statement]], URL?) throws -> Void ) throws { let sourceRootPath = rootURL.path @@ -38,20 +46,22 @@ extension PBXProj { for target in proj.targets { for config in target.buildConfigurationList?.buildConfigurations ?? [] { let projConfig = projConfigList?.configuration(name: config.name) - let projConfigStatements = try projConfig?.baseConfigurationStatements(with: sourceRootPath) ?? [] + let baseConfigURL = try projConfig?.baseConfigurationURL(with: sourceRootPath) + let projConfigStatements = try baseConfigURL.map { try Parser().parse(contentsOf: $0) } let projStatements = projConfig?.buildSettingsStatements ?? [] - let configStatements = try config.baseConfigurationStatements(with: sourceRootPath) + let configURL = try config.baseConfigurationURL(with: sourceRootPath) + let configStatements = try configURL.map {try Parser().parse(contentsOf: $0) } let statements = config.buildSettingsStatements let heirarchy = [ - projConfigStatements, + projConfigStatements ?? [], projStatements, - configStatements, + configStatements ?? [], statements ] - try block(proj, target, config, heirarchy) + try block(proj, target, config, heirarchy, configURL) } } } diff --git a/Sources/XCLinting/Extensions/XCBuildConfiguration+BuildSettings.swift b/Sources/XCLinting/Extensions/XCBuildConfiguration+BuildSettings.swift index 40834ee..395d6a9 100644 --- a/Sources/XCLinting/Extensions/XCBuildConfiguration+BuildSettings.swift +++ b/Sources/XCLinting/Extensions/XCBuildConfiguration+BuildSettings.swift @@ -4,20 +4,12 @@ import XCConfig import XcodeProj extension XCBuildConfiguration { - func baseConfigurationContent(with sourceRoot: String) throws -> String? { + func baseConfigurationURL(with sourceRoot: String) throws -> URL? { guard let fullPath = try baseConfiguration?.fullPath(sourceRoot: sourceRoot) else { return nil } - return try String(contentsOf: URL(fileURLWithPath: fullPath)) - } - - func baseConfigurationStatements(with sourceRoot: String) throws -> [Statement] { - guard let content = try baseConfigurationContent(with: sourceRoot) else { - return [] - } - - return Parser().parse(content) + return URL(fileURLWithPath: fullPath, isDirectory: false) } var buildSettingsStatements: [Statement] { diff --git a/Sources/XCLinting/Rules/ValidateBuildSettingsRule.swift b/Sources/XCLinting/Rules/ValidateBuildSettingsRule.swift index c27c22f..bd9f047 100644 --- a/Sources/XCLinting/Rules/ValidateBuildSettingsRule.swift +++ b/Sources/XCLinting/Rules/ValidateBuildSettingsRule.swift @@ -43,13 +43,16 @@ struct ValidateBuildSettingsRule { ) throws { let project = environment.project let sourceRootURL = environment.projectRootURL.deletingLastPathComponent() - let evaluator = Evaluator(rootURL: sourceRootURL) + let evaluator = Evaluator() let platformStatements: [Statement] = [] - try project.pbxproj.enumerateBuildSettingStatements(rootURL: sourceRootURL) { proj, target, config, statementsList in + try project.pbxproj.enumerateBuildSettingStatements(rootURL: sourceRootURL) { proj, target, config, statementsList, url in let heirarchy = [platformStatements] + statementsList - let settings = try evaluator.evaluate(heirarchy: heirarchy) + // This is bogus. But the only solution I can come up with is to change how evaluation works, and that's complex. + let effectiveURL = url ?? sourceRootURL + + let settings = try evaluator.evaluate(heirarchy: heirarchy, for: effectiveURL) try block(target, config, settings) }