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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 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
/// Wrapper around `swift build` and `swift test` to build and test SwiftPM packages.
struct SwiftPMBuilder {
/// The path to the toolchain that shall be used to build SwiftSyntax.
let toolchain: URL
/// The directory in which build products shall be put.
///
/// If omitted a directory named ".build" will be put in the swift-syntax directory.
let buildDir: URL?
/// Path to an Xcode workspace to create a unified build of SwiftSyntax with other projects.
let multirootDataFile: URL?
/// Build in release mode.
let release: Bool
/// When constructing RawSyntax nodes validate that their layout matches that
/// defined in `CodeGeneration` and that TokenSyntax nodes have a `tokenKind`
/// matching the ones specified in `CodeGeneration`.
let enableRawSyntaxValidation: Bool
/// For each `assertParse` test, perform mutations of the test case based on
/// alternate token choices that the parser checks, validating that there are
/// no round-trip or assertion failures.
let enableTestFuzzing: Bool
/// A flag indicating whether to use local dependencies during the build process.
let useLocalDeps: Bool
/// Enable verbose logging.
let verbose: Bool
init(
toolchain: URL,
buildDir: URL? = nil,
multirootDataFile: URL? = nil,
release: Bool = false,
enableRawSyntaxValidation: Bool = false,
enableTestFuzzing: Bool = false,
useLocalDeps: Bool = true,
verbose: Bool = false
) {
self.toolchain = toolchain
self.buildDir = buildDir
self.multirootDataFile = multirootDataFile
self.release = release
self.enableRawSyntaxValidation = enableRawSyntaxValidation
self.enableTestFuzzing = enableTestFuzzing
self.useLocalDeps = useLocalDeps
self.verbose = verbose
}
func buildTarget(packageDir: URL, targetName: String, warningsAsErrors: Bool = false) throws {
logSection("Building target " + targetName)
try build(packageDir: packageDir, name: targetName, isProduct: false)
}
@discardableResult
func invokeSwiftPM(
action: String,
packageDir: URL,
warningsAsErrors: Bool = false,
additionalArguments: [String],
additionalEnvironment: [String: String],
captureStdout: Bool = true,
captureStderr: Bool = true
) throws -> ProcessResult {
var args = [action]
if action == "test" {
args += ["--disable-testable-imports"]
}
args += ["--package-path", packageDir.path]
if let buildDir = buildDir?.path {
args += ["--scratch-path", buildDir]
}
if warningsAsErrors {
args += ["-Xswiftc", "-warnings-as-errors"]
}
if release {
args += ["--configuration", "release"]
}
if let multirootDataFile = multirootDataFile?.path {
args += ["--multiroot-data-file", multirootDataFile]
}
if verbose {
args += ["--verbose"]
}
args += additionalArguments
let processRunner = ProcessRunner(
executableURL: toolchain.appendingPathComponent("bin").appendingPathComponent("swift"),
arguments: args,
additionalEnvironment: additionalEnvironment
)
let result = try processRunner.run(
captureStdout: captureStdout,
captureStderr: captureStderr,
verbose: verbose
)
return result
}
/// Environment variables that should be set when invoking `swift build` or
/// `swift test`.
var swiftPMEnvironmentVariables: [String: String] {
var additionalEnvironment: [String: String] = [:]
additionalEnvironment["SWIFT_BUILD_SCRIPT_ENVIRONMENT"] = "1"
if enableRawSyntaxValidation {
additionalEnvironment["SWIFTSYNTAX_ENABLE_RAWSYNTAX_VALIDATION"] = "1"
}
if enableTestFuzzing {
additionalEnvironment["SWIFTPARSER_ENABLE_ALTERNATE_TOKEN_INTROSPECTION"] = "1"
}
if useLocalDeps {
// Tell other projects in the unified build to use local dependencies
additionalEnvironment["SWIFTCI_USE_LOCAL_DEPS"] = "1"
}
return additionalEnvironment
}
private func build(packageDir: URL, name: String, isProduct: Bool, warningsAsErrors: Bool = false) throws {
let args: [String]
if isProduct {
args = ["--product", name]
} else {
args = ["--target", name]
}
try invokeSwiftPM(
action: "build",
packageDir: packageDir,
warningsAsErrors: warningsAsErrors,
additionalArguments: args,
additionalEnvironment: swiftPMEnvironmentVariables,
captureStdout: false,
captureStderr: false
)
}
}
|