Skip to content

Commit

Permalink
Update tests to be async, address a stupid issue with Xcode not setti…
Browse files Browse the repository at this point in the history
…ng attributes
  • Loading branch information
NinjaLikesCheez committed Jul 28, 2023
1 parent 338122a commit fd1c6f0
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 39 deletions.
39 changes: 9 additions & 30 deletions Sources/GenIR/GenIR.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,42 +112,21 @@ struct IREmitterCommand: ParsableCommand {

// swiftlint:disable function_parameter_count
mutating func run(project: URL, log: String, archive: URL, output: URL, level: Logger.Level, dryRun: Bool) throws {
// let project = try ProjectParser(path: project, logLevel: level)
// var targets = Targets(for: project)

// let log = try logParser(for: log)
// try log.parse(&targets)

// let buildCacheManipulator = try BuildCacheManipulator(
// buildCachePath: log.buildCachePath,
// buildSettings: log.settings,
// archive: archive
// )

// let runner = CompilerCommandRunner(
// output: output,
// buildCacheManipulator: buildCacheManipulator,
// dryRun: dryRun
// )
// try runner.run(targets: targets)

// let postprocessor = try OutputPostprocessor(archive: archive, output: output)
// try postprocessor.process(targets: &targets)
// TODO: We can't use async parsable commands here as SPM relies on swift-driver which, until Swift 5.9 uses Argument Parser 1.0.3.
// Remove these declarations etc when we can use Swift 5.9
guard let projectPath = projectPath else {
throw ValidationError("Failed to infer project path. Please rerun providing --project-path")
}
let logPath = logPath
let quieter = quieter
let outputPath = outputPath
let project = project
let log = log
let archive = archive
let output = output
let level = level
let quieter = dryRun

let semaphore = DispatchSemaphore(value: 0)

Task {
let project = try await ProjectParser(path: projectPath, logLevel: logger.logLevel)
let project = try await ProjectParser(path: project, logLevel: logger.logLevel)
var targets = Targets(for: project)
let log = try IREmitterCommand.logParser(for: logPath, quieter)
let log = try IREmitterCommand.logParser(for: log, quieter)
try log.parse(&targets)

let buildCacheManipulator = try BuildCacheManipulator(
Expand All @@ -157,7 +136,7 @@ struct IREmitterCommand: ParsableCommand {
)

let runner = CompilerCommandRunner(
output: outputPath,
output: output,
buildCacheManipulator: buildCacheManipulator,
dryRun: dryRun
)
Expand Down
4 changes: 2 additions & 2 deletions Tests/GenIRTests/MultipleAppTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ final class MultipleAppTests: XCTestCase {
.appendingPathComponent("MultipleApp.xcodeproj")
}()

func testExpectedTargetLookup() throws {
func testExpectedTargetLookup() async throws {
let context = try TestContext()
let result = try context.build(test: Self.testPath, scheme: "MultipleApp")

let project: ProjectParser = try ProjectParser(path: Self.testPath, logLevel: .debug)
let project: ProjectParser = try await ProjectParser(path: Self.testPath, logLevel: .debug)
var targets = Targets(for: project)

let logContents = try String(contentsOf: context.buildLog).components(separatedBy: .newlines)
Expand Down
41 changes: 39 additions & 2 deletions Tests/GenIRTests/TestContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class TestContext {
func clean(test path: URL) throws -> Process.ReturnValue {
return try Process.runShell(
"/usr/bin/xcodebuild",
arguments: ["clean"],
arguments: [
"clean"
],
runInDirectory: path.deletingLastPathComponent(),
joinPipes: true
)
Expand All @@ -29,6 +31,14 @@ class TestContext {
scheme: String,
additionalArguments: [String] = []
) throws -> Process.ReturnValue {
if shouldDeployPodsBuildSystemHack {
if let returnValue = try deployPodsBuildSystemHack(path) {
guard returnValue.code == 0 else {
throw Error.commandFailed(returnValue)
}
}
}

let clean = try clean(test: path)

guard clean.code == 0 else {
Expand Down Expand Up @@ -70,10 +80,37 @@ class TestContext {
let archive: URL
let buildLog: URL
let temporaryDirectory: URL
let shouldDeployPodsBuildSystemHack: Bool

init() throws {
init(podsBuildSystemHack: Bool = false) throws {
temporaryDirectory = try FileManager.default.temporaryDirectory(named: "gen-ir-tests-\(UUID().uuidString)")
archive = temporaryDirectory.appendingPathComponent("x.xcarchive")
buildLog = temporaryDirectory.appendingPathComponent("build.log")
shouldDeployPodsBuildSystemHack = podsBuildSystemHack
}
}

extension TestContext {
// TODO: we should look into how this will effect users and whether we should do this on their behalf.... (probably yes)
/// Pods has a weird default for legacy build systems where they set SYMROOT to ${SRCROOT}../build
/// Then, Apple has this stupid bug where they don't mark this folder as being generated by the build system
/// This dates back until at _least_ iOS 12 - with no fix. Because Apple is Apple and they hate developers
/// This function will mark the build folder as created by the build system so `xcodebuild clean` works.
private func deployPodsBuildSystemHack(_ path: URL) throws -> Process.ReturnValue? {
let buildPath = path.deletingLastPathComponent().appendingPath(component: "build")

if !FileManager.default.directoryExists(at: buildPath.appendingPath(component: "Pods.build")) {
return nil
}

return try Process.runShell(
"/usr/bin/xattr",
arguments: [
"-w",
"com.apple.xcode.CreatedByBuildSystem",
"true",
buildPath.filePath
]
)
}
}
6 changes: 3 additions & 3 deletions Tests/GenIRTests/UmbrellaTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ final class UmbrellaTests: XCTestCase {
"Umbrella.framework": ["GetOrg.bc", "Umbrella_vers.bc"].sorted()
]

func testUmbrellaTargets() throws {
func testUmbrellaTargets() async throws {
let context = try TestContext()
let process = try context.build(test: Self.testPath, scheme: Self.scheme)
XCTAssertEqual(process.code, 0, "Failed to build test case")

let projectParser = try ProjectParser(path: Self.testPath, logLevel: .info)
let projectParser = try await ProjectParser(path: Self.testPath, logLevel: .info)
let targets = Targets(for: projectParser)

XCTAssertEqual(targets.count, 4, "Expected 4 targets, got \(targets.count)")
Expand Down Expand Up @@ -69,7 +69,7 @@ final class UmbrellaTests: XCTestCase {
}

func testCustomDerivedDataAndSkipInstallNo() throws {
let context = try TestContext()
let context = try TestContext(podsBuildSystemHack: true)
defer { try? FileManager.default.removeItem(at: context.temporaryDirectory) }
_ = try context.build(test: Self.testPath, scheme: Self.scheme, additionalArguments: ["SKIP_INSTALL=NO", "-derivedDataPath", "_build"])

Expand Down
4 changes: 2 additions & 2 deletions Tests/GenIRTests/gen_irTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import XCTest
import PBXProjParser

final class GenIRTests: XCTestCase {
func testManyTargetTestTargets() throws {
func testManyTargetTestTargets() async throws {
let projectPath = TestContext.baseTestingPath
.appendingPathComponent("TestAssets")
.appendingPathComponent("ManyTargetTest")
.appendingPathComponent("ManyTargetTest.xcodeproj")
let project = try ProjectParser(path: projectPath, logLevel: logger.logLevel)
let project = try await ProjectParser(path: projectPath, logLevel: logger.logLevel)
let targets = Targets(for: project)

XCTAssert(targets.count == 3, "Targets count expected to be 3, was \(targets.count)")
Expand Down

0 comments on commit fd1c6f0

Please sign in to comment.