File: Product.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (129 lines) | stat: -rw-r--r-- 4,678 bytes parent folder | download
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
    }
}