Commit 8a497f67 authored by Drew's avatar Drew

Improve XCTest integration

We need to parse the xcode groups correctly in order to handle the case where multiple test targets refer to the same sourcefile.  This is commonly the case e.g. for iOS/OSX combined projects.
parent e7c4e784
......@@ -18,6 +18,9 @@ import Glibc
import Darwin
#endif
//test via
//WRAPPER_EXTENSION=xctest PROJECT_FILE_PATH=~/Downloads/NaOH.xcodeproj TARGETNAME=NaOHiOSTestHostAppTests .atllbuild/products/caroline-static-tool
func env_(_ variable: String) -> String? {
let env = getenv(variable)
if env == nil { return nil }
......@@ -33,7 +36,6 @@ func performXcodeIntegration() -> Bool {
let xcodeProject = env_("PROJECT_FILE_PATH")!
let target = env_("TARGETNAME")!
let paths = parseXcodeProj(xcodeProject, targetName: target)
print(paths)
let tests = findTests(paths)
var xcTestFile = ""
......@@ -57,7 +59,7 @@ func performXcodeIntegration() -> Bool {
try! xcTestFile.write(file: generatedFilePath)
if !paths.contains(generatedFilePath) {
print("error: You need to add CarolineXCTest.swift to your Xcode Project.")
print("error: You need to add CarolineXCTest.swift to your Xcode Project. (See \(generatedFilePath))")
exit(1)
}
......@@ -67,7 +69,10 @@ func performXcodeIntegration() -> Bool {
func parseXcodeProj(_ fileName: String, targetName: String) -> [String] {
let pathToXcodeProject = fileName.directoryPath
let file = try! String(file: fileName + "/project.pbxproj")
let plistCharacters = "[[:space:][:alnum:]/\\*={};_\"\\(\\),\\.\\-]"
let plistCharacters = "[-[:space:][:alnum:]/}{;_,=<>\"*\\().+]"
//note that inside a character class, we only escape `^ - [ ]`
// `\` is literal, not escape, so we have to use "clever placement"
let allTargetsRegex = try! Regex(pattern: "/\\* Begin PBXNativeTarget section \\*/\(plistCharacters)*/\\* End PBXNativeTarget section \\*/")
guard let allTargets = try! allTargetsRegex.findFirst(inString: file)?.entireMatch.description else {
......@@ -95,6 +100,30 @@ func parseXcodeProj(_ fileName: String, targetName: String) -> [String] {
fatalError("Can't find filesListing for source phase.")
}
//calculate groups
//This maps a filename to the path of its group
//we do this up-front to avoid O(N^2)
let allGroupsRegex = try! Regex(pattern: "/\\* Begin PBXGroup section \\*/\(plistCharacters)*/\\* End PBXGroup section \\*/")
guard let allGroups = try! allGroupsRegex.findFirst(inString: file)?.entireMatch.description else {
fatalError("Can't find group section")
}
let groupRegex = try! Regex(pattern: "([[:upper:][:digit:]]{24}) /\\*[^\n]*\\*/ = \\{[^\\}]+};")
let groupChildSectionRegex = try! Regex(pattern: "children = \\([^\\)]+\\);")
let groupIndividualChildRegex = try! Regex(pattern: "[[:upper:][:digit:]]{24}")
let pathRegex = try! Regex(pattern: "path = ([^;]+);")
var pbxBuildRefToGroupPath: [String:String] = [:]
for group in groupRegex.findAll(inString: allGroups) {
let childSection = try! groupChildSectionRegex.findFirst(inString: group.entireMatch.description)!
("got child section",childSection)
guard let path = try! pathRegex.findFirst(inString: group.entireMatch.description) else {
continue
}
for child in groupIndividualChildRegex.findAll(inString: childSection.entireMatch.description) {
pbxBuildRefToGroupPath[child.entireMatch.description] = path.groups[0]!.description
}
}
var paths: [String] = []
let fileIDRegex = try! Regex(pattern: "([[:upper:][:digit:]]{24}) /\\*")
for fileID_ in fileIDRegex.findAll(inString: filesListing) {
......@@ -110,8 +139,10 @@ func parseXcodeProj(_ fileName: String, targetName: String) -> [String] {
fatalError("Can't find path for file \(fileRef)")
}
if path.hasSuffix("\"") { path.remove(at: path.characters.index(before: path.characters.endIndex))}
//this is cheating; the targetName may not be the same as the group, but fuck it
paths.append("\(pathToXcodeProject)/\(targetName)/\(path)")
guard let groupPath = pbxBuildRefToGroupPath[fileRef] else {
fatalError("Can't calculate group path for file \(fileRef)")
}
paths.append("\(pathToXcodeProject)/\(groupPath)/\(path)")
}
return paths
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment