diff --git a/Bridgecraft/GenerateCommand.swift b/Bridgecraft/GenerateCommand.swift index c59795a..e2a1cd3 100644 --- a/Bridgecraft/GenerateCommand.swift +++ b/Bridgecraft/GenerateCommand.swift @@ -11,13 +11,15 @@ import SourceKittenFramework import XcodeEdit extension GenerateCommand { - static func execute(assumeNonnull: Bool, + static func execute(verbose: Bool, + assumeNonnull: Bool, sdkOverride: [String], destOverride: [String], outputPath: [String], origProjectPath: String, targetName: String) { - let cmd = GenerateCommand(assumeNonnull: assumeNonnull, + let cmd = GenerateCommand(verbose: verbose, + assumeNonnull: assumeNonnull, sdkOverride: sdkOverride, destOverride: destOverride, outputPath: outputPath, @@ -34,17 +36,20 @@ struct GenerateCommand { private let preprocessedURL: URL private let outputFileURL: URL? + private let verbose: Bool private let assumeNonnull: Bool private let sdkOverride: String? private let destOverride: String? private let targetName: String - init(assumeNonnull: Bool, + init(verbose: Bool, + assumeNonnull: Bool, sdkOverride: [String], destOverride: [String], outputPath: [String], origProjectPath: String, targetName: String) { + self.verbose = verbose self.assumeNonnull = assumeNonnull self.sdkOverride = sdkOverride.first self.destOverride = destOverride.first @@ -130,7 +135,7 @@ struct GenerateCommand { "-showBuildSettings", "-project", tempProjectURL.path, "-target", targetName - ]) + ], verbose: verbose) } catch { printError("cannot query build settings for \(tempProjectURL.path): \(error)") @@ -245,7 +250,7 @@ struct GenerateCommand { let output: String do { - output = try shell("/usr/bin/xcodebuild", args: args) + output = try shell("/usr/bin/xcodebuild", args: args, verbose: verbose) } catch { printError("cannot dry-run build for \(tempProjectURL.path)") @@ -298,7 +303,7 @@ struct GenerateCommand { "-x", "objective-c", "-C", "-fmodules", "-fimplicit-modules", "-E", bridgingSourceURL.path, "-o", preprocessedURL.path - ] + compilerFlags) + ] + compilerFlags, verbose: verbose) } catch { printError("failed to preprocess file at \(bridgingSourceURL.path): \(error)") diff --git a/Bridgecraft/Utils.swift b/Bridgecraft/Utils.swift index b1b6fec..dcb62b7 100644 --- a/Bridgecraft/Utils.swift +++ b/Bridgecraft/Utils.swift @@ -13,27 +13,48 @@ enum BridgecraftError: Error { } @discardableResult -func shell(_ command: String, args: [String]) throws -> String { +func shell(_ command: String, args: [String], verbose: Bool = false) throws -> String { + let ps = Process() ps.launchPath = command ps.arguments = args - let pipe = Pipe() - ps.standardOutput = pipe + let outputPipe = Pipe() + let errorPipe = Pipe() + ps.standardOutput = outputPipe + ps.standardError = errorPipe ps.launch() - var buffer = Data() + var outputPipeResult = Data() + var errorPipeResult = Data() + while ps.isRunning { - buffer.append(pipe.fileHandleForReading.readDataToEndOfFile()) + outputPipeResult.append(outputPipe.fileHandleForReading.readDataToEndOfFile()) + errorPipeResult.append(errorPipe.fileHandleForReading.readDataToEndOfFile()) + } + + guard + let output = String(data: outputPipeResult, encoding: String.Encoding.utf8), + let error = String(data: errorPipeResult, encoding: String.Encoding.utf8) + else { + printError("\(command) \(args.joined(separator: " "))") + printError("Error parsing the output of the previous command.") + throw BridgecraftError.unknown } guard ps.terminationStatus == 0 else { + printError("\(command) \(args.joined(separator: " "))") + printError("Terminated with the status \(ps.terminationStatus).") + printError(output) + printError(error) throw BridgecraftError.unknown } - guard let output = String(data: buffer, encoding: String.Encoding.utf8) else { - throw BridgecraftError.unknown + if verbose { + print("\(command) \(args.joined(separator: " "))") + print(output) + printError(error) } return output diff --git a/Bridgecraft/main.swift b/Bridgecraft/main.swift index e14239a..40dfaed 100644 --- a/Bridgecraft/main.swift +++ b/Bridgecraft/main.swift @@ -12,6 +12,7 @@ import Foundation let version = "0.3.0" let generate = command( + Flag("verbose", description: "output's all terminal commands and their results"), Flag("assume-nonnull", description: "assume that all headers have been audited for nullability"), Options("sdk", default: [], count: 1, description: "override the SDK used for the build (see xcodebuild -sdk)"), Options("destination", default: [], count: 1, description: "override the destination device used for the build (see xcodebuild -destination)"),