Skip to content

[tibs] Consolidate uses of Process and fix warnings #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions Sources/ISDBTibs/Process.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import Foundation

extension Process {

enum TibsProcessError: Error {
case nonZeroExit(TerminationReason, Int32)
case invalidUTF8Output(Data)
}

/// Runs a subprocess and returns its output as a String if it has a zero exit.
static func tibs_checkNonZeroExit(
arguments: [String],
environment: [String: String]? = nil
) throws -> String {
let p = Process()
let out = Pipe()

if #available(macOS 10.13, *) {
p.executableURL = URL(fileURLWithPath: arguments[0], isDirectory: false)
} else {
p.launchPath = arguments[0]
}

p.arguments = Array(arguments[1...])
if let environment = environment {
p.environment = environment
}
p.standardOutput = out

if #available(macOS 10.13, *) {
try p.run()
} else {
p.launch()
}

p.waitUntilExit()

if p.terminationReason != .exit || p.terminationStatus != 0 {
throw TibsProcessError.nonZeroExit(p.terminationReason, p.terminationStatus)
}

let data = out.fileHandleForReading.readDataToEndOfFile()
guard let str = String(data: data, encoding: .utf8) else {
throw TibsProcessError.invalidUTF8Output(data)
}
return str
}
}
50 changes: 8 additions & 42 deletions Sources/ISDBTibs/TibsBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,7 @@ extension TibsBuilder {

/// *For Testing* Build and collect a list of commands that were (re)built.
public func _buildTest() throws -> Set<String> {
let pipe = Pipe()

do {
try buildImpl { process in
process.standardOutput = pipe
}
} catch TibsBuilder.Error.buildFailure(let tc, let ts) {
let out = String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)!
print(out)
throw TibsBuilder.Error.buildFailure(tc, exitCode: ts)
}

let out = String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)!
let out = try buildImpl()
var rest = out.startIndex..<out.endIndex

var result = Set<String>()
Expand All @@ -144,21 +132,16 @@ extension TibsBuilder {
return result
}

func buildImpl(processCustomization: (Process) -> () = { _ in }) throws {
@discardableResult
func buildImpl() throws -> String {
guard let ninja = toolchain.ninja?.path else {
throw Error.noNinjaBinaryConfigured
}

let p = Process()
p.launchPath = ninja
p.arguments = ["-C", buildRoot.path]

processCustomization(p)

p.launch()
p.waitUntilExit()
if p.terminationReason != .exit || p.terminationStatus != 0 {
throw Error.buildFailure(p.terminationReason, exitCode: p.terminationStatus)
do {
return try Process.tibs_checkNonZeroExit(arguments: [ninja, "-C", buildRoot.path])
} catch Process.TibsProcessError.nonZeroExit(let reason, let code) {
throw Error.buildFailure(reason, exitCode: code)
}
}
}
Expand Down Expand Up @@ -367,24 +350,7 @@ extension TibsBuilder {
}

func xcrunSDKPath() -> String {
let p = Process()
p.launchPath = "/usr/bin/xcrun"
p.arguments = ["--show-sdk-path"]

let out = Pipe()
p.standardOutput = out

p.launch()
p.waitUntilExit()

if p.terminationReason != .exit || p.terminationStatus != 0 {
fatalError("unexpected non-zero exit \(p.terminationStatus) from xcrun --show-sdkpath")
}

let data = out.fileHandleForReading.readDataToEndOfFile()
guard var path = String(data: data, encoding: .utf8) else {
fatalError("invalid output \(data) from xcrun --show-sdkpath")
}
var path = try! Process.tibs_checkNonZeroExit(arguments: ["/usr/bin/xcrun", "--show-sdk-path"])
if path.last == "\n" {
path = String(path.dropLast())
}
Expand Down
46 changes: 6 additions & 40 deletions Sources/ISDBTibs/TibsToolchain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,7 @@ public final class TibsToolchain {
#endif

public private(set) lazy var clangVersionOutput: String = {
let p = Process()
p.launchPath = clang.path
p.arguments = ["--version"]
let pipe = Pipe()
p.standardOutput = pipe
p.launch()
p.waitUntilExit()
guard p.terminationReason == .exit && p.terminationStatus == 0 else {
fatalError("could not get clang --version")
}
return String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)!
return try! Process.tibs_checkNonZeroExit(arguments: [clang.path, "--version"])
}()

public private(set) lazy var clangHasIndexSupport: Bool = {
Expand All @@ -59,18 +49,7 @@ public final class TibsToolchain {

public private(set) lazy var ninjaVersion: (Int, Int, Int) = {
precondition(ninja != nil, "expected non-nil ninja in ninjaVersion")
let p = Process()
p.launchPath = ninja!.path
p.arguments = ["--version"]
let pipe = Pipe()
p.standardOutput = pipe
p.launch()
p.waitUntilExit()
guard p.terminationReason == .exit && p.terminationStatus == 0 else {
fatalError("could not get ninja --version")
}

var out = String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)!
var out = try! Process.tibs_checkNonZeroExit(arguments: [ninja!.path, "--version"])
out = out.trimmingCharacters(in: .whitespacesAndNewlines)
let components = out.split(separator: ".", maxSplits: 3)
guard let maj = Int(String(components[0])),
Expand Down Expand Up @@ -179,30 +158,17 @@ extension TibsToolchain {

/// Returns the path to the given tool, as found by `xcrun --find` on macOS, or `which` on Linux.
public func findTool(name: String) -> URL? {
let p = Process()
#if os(macOS)
p.launchPath = "/usr/bin/xcrun"
p.arguments = ["--find", name]
let cmd = ["/usr/bin/xcrun", "--find", name]
#else
p.launchPath = "/usr/bin/which"
p.arguments = [name]
let cmd = ["/usr/bin/which", name]
#endif
let out = Pipe()
p.standardOutput = out

p.launch()
p.waitUntilExit()

if p.terminationReason != .exit || p.terminationStatus != 0 {
return nil
}

let data = out.fileHandleForReading.readDataToEndOfFile()
guard var path = String(data: data, encoding: .utf8) else {
guard var path = try? Process.tibs_checkNonZeroExit(arguments: cmd) else {
return nil
}
if path.last == "\n" {
path = String(path.dropLast())
}
return URL(fileURLWithPath: path)
return URL(fileURLWithPath: path, isDirectory: false)
}