diff --git a/CHANGELOG.md b/CHANGELOG.md index 22fea78af..4a811e34e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## next version +### Changed +- Support for `XCConfig` project-relative includes https://github.com/xcodeswift/xcproj/pull/238 by @briantkelley + ## 4.1.0 ### Added diff --git a/Sources/xcproj/XCConfig.swift b/Sources/xcproj/XCConfig.swift index fd7bd38d1..6dda1b9d8 100644 --- a/Sources/xcproj/XCConfig.swift +++ b/Sources/xcproj/XCConfig.swift @@ -29,12 +29,13 @@ final public class XCConfig { /// Initializes the XCConfig reading the content from the file at the given path and parsing it. /// /// - Parameter path: path where the .xcconfig file is. + /// - Parameter projectPath: path where the .xcodeproj is, for resolving project-relative includes. /// - Throws: an error if the config file cannot be found or it has an invalid format. - public init(path: Path) throws { + public init(path: Path, projectPath: Path? = nil) throws { if !path.exists { throw XCConfigError.notFound(path: path) } let fileLines = try path.read().components(separatedBy: "\n") self.includes = fileLines - .flatMap(XCConfigParser.configFrom(path: path)) + .flatMap(XCConfigParser.configFrom(path: path, projectPath: projectPath)) var buildSettings: [String: String] = [:] fileLines .flatMap(XCConfigParser.settingFrom) @@ -49,8 +50,9 @@ final class XCConfigParser { /// and returns the include path and the config that the include is pointing to. /// /// - Parameter path: path of the config file that the line belongs to. + /// - Parameter projectPath: path where the .xcodeproj is, for resolving project-relative includes. /// - Returns: function that parses the line. - static func configFrom(path: Path) -> (String) -> (include: Path, config: XCConfig)? { + static func configFrom(path: Path, projectPath: Path?) -> (String) -> (include: Path, config: XCConfig)? { return { line in return includeRegex.matches(in: line, options: NSRegularExpression.MatchingOptions(rawValue: 0), @@ -66,9 +68,17 @@ final class XCConfigParser { let includePath: Path = Path(pathString) var config: XCConfig? if includePath.isRelative { - config = try? XCConfig(path: path.parent() + includePath) + do { + // first try to load the included xcconfig relative to the current xcconfig + config = try XCConfig(path: path.parent() + includePath, projectPath: projectPath) + } catch (XCConfigError.notFound(_)) where projectPath != nil { + // if that fails, try to load the included xcconfig relative to the project + config = try? XCConfig(path: projectPath!.parent() + includePath, projectPath: projectPath) + } catch { + config = nil + } } else { - config = try? XCConfig(path: includePath) + config = try? XCConfig(path: includePath, projectPath: projectPath) } return config.map { (includePath, $0) } }