1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
/*
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 http://swift.org/LICENSE.txt for license information
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
import func XCTest.XCTFail
import class Foundation.ProcessInfo
import TSCBasic
import TSCUtility
#if canImport(Darwin)
import class Foundation.Bundle
#endif
@available(*, deprecated, message: "moved to SwiftPM")
public enum SwiftPMProductError: Swift.Error {
case packagePathNotFound
case executionFailure(error: Swift.Error, output: String, stderr: String)
}
/// Defines the executables used by SwiftPM.
/// Contains path to the currently built executable and
/// helper method to execute them.
@available(*, deprecated, message: "moved to SwiftPM")
public protocol Product {
var exec: RelativePath { get }
}
@available(*, deprecated, message: "moved to SwiftPM")
extension Product {
/// Path to currently built binary.
public var path: AbsolutePath {
#if canImport(Darwin)
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
return try! AbsolutePath(AbsolutePath(validating: bundle.bundlePath).parentDirectory, self.exec)
}
fatalError()
#else
return try! AbsolutePath(CommandLine.arguments.first!, relativeTo: localFileSystem.currentWorkingDirectory!)
.parentDirectory.appending(self.exec)
#endif
}
/// Executes the product with specified arguments.
///
/// - Parameters:
/// - args: The arguments to pass.
/// - env: Additional environment variables to pass. The values here are merged with default env.
/// - packagePath: Adds argument `--package-path <path>` if not nil.
///
/// - Returns: The output of the process.
@discardableResult
public func execute(
_ args: [String],
packagePath: AbsolutePath? = nil,
env: [String: String]? = nil
) throws -> (stdout: String, stderr: String) {
let result = try executeProcess(
args, packagePath: packagePath,
env: env)
let output = try result.utf8Output()
let stderr = try result.utf8stderrOutput()
if result.exitStatus == .terminated(code: 0) {
return (stdout: output, stderr: stderr)
}
throw SwiftPMProductError.executionFailure(
error: ProcessResult.Error.nonZeroExit(result),
output: output,
stderr: stderr
)
}
public func executeProcess(
_ args: [String],
packagePath: AbsolutePath? = nil,
env: [String: String]? = nil
) throws -> ProcessResult {
var environment = ProcessInfo.processInfo.environment
for (key, value) in (env ?? [:]) {
environment[key] = value
}
#if Xcode
// Unset these variables which causes issues when running tests via Xcode.
environment["XCTestConfigurationFilePath"] = nil
environment["XCTestSessionIdentifier"] = nil
environment["XCTestBundlePath"] = nil
environment["NSUnbufferedIO"] = nil
#endif
// FIXME: We use this private environment variable hack to be able to
// create special conditions in swift-build for swiftpm tests.
environment["SWIFTPM_TESTS_MODULECACHE"] = self.path.parentDirectory.pathString
#if !os(Windows)
environment["SDKROOT"] = nil
#endif
// Unset the internal env variable that allows skipping certain tests.
environment["_SWIFTPM_SKIP_TESTS_LIST"] = nil
var completeArgs = [path.pathString]
if let packagePath = packagePath {
completeArgs += ["--package-path", packagePath.pathString]
}
completeArgs += args
return try Process.popen(arguments: completeArgs, environment: environment)
}
public static func packagePath(for packageName: String, packageRoot: AbsolutePath) throws -> AbsolutePath {
// FIXME: The directory paths are hard coded right now and should be replaced by --get-package-path
// whenever we design that. https://bugs.swift.org/browse/SR-2753
let packagesPath = packageRoot.appending(components: ".build", "checkouts")
for name in try localFileSystem.getDirectoryContents(packagesPath) {
if name.hasPrefix(packageName) {
return try AbsolutePath(validating: name, relativeTo: packagesPath)
}
}
throw SwiftPMProductError.packagePathNotFound
}
}
|