From 9013a5f543c0edcfdd332c6f362dafb40ccf6549 Mon Sep 17 00:00:00 2001 From: Ankit Aggarwal Date: Sat, 28 Sep 2019 10:25:17 -0700 Subject: [PATCH] Sync with SwiftPM trunk --- Sources/TSCBasic/Await.swift | 2 +- Sources/TSCBasic/CMakeLists.txt | 1 + Sources/TSCBasic/CodableResult.swift | 62 +++++++++ Sources/TSCBasic/Process.swift | 10 +- Sources/TSCBasic/Result.swift | 125 +----------------- Sources/TSCBasic/TemporaryFile.swift | 15 ++- Sources/TSCBasic/TerminalController.swift | 15 +++ Sources/TSCLibc/libc.swift | 2 +- Sources/TSCTestSupport/Product.swift | 3 + Sources/TSCUtility/CMakeLists.txt | 1 + Sources/TSCUtility/IndexStore.swift | 2 +- Sources/TSCUtility/PkgConfig.swift | 31 +++-- Sources/TSCUtility/Versioning.swift | 2 +- .../TSCclibc/include/{clibc.h => TSCclibc.h} | 0 Sources/TSCclibc/include/module.modulemap | 4 +- Tests/TSCBasicTests/AwaitTests.swift | 2 +- Tests/TSCBasicTests/ResultTests.swift | 89 +------------ Tests/TSCBasicTests/TemporaryFileTests.swift | 6 + Tests/TSCBasicTests/XCTestManifests.swift | 4 +- .../PkgConfigParserTests.swift | 27 +++- 20 files changed, 170 insertions(+), 233 deletions(-) create mode 100644 Sources/TSCBasic/CodableResult.swift rename Sources/TSCclibc/include/{clibc.h => TSCclibc.h} (100%) diff --git a/Sources/TSCBasic/Await.swift b/Sources/TSCBasic/Await.swift index 83f7978f..5d846b4b 100644 --- a/Sources/TSCBasic/Await.swift +++ b/Sources/TSCBasic/Await.swift @@ -15,7 +15,7 @@ /// - Returns: The value wrapped by the async method's result. /// - Throws: The error wrapped by the async method's result public func await(_ body: (@escaping (Result) -> Void) -> Void) throws -> T { - return try await(body).dematerialize() + return try await(body).get() } public func await(_ body: (@escaping (T) -> Void) -> Void) -> T { diff --git a/Sources/TSCBasic/CMakeLists.txt b/Sources/TSCBasic/CMakeLists.txt index b32ee280..07d17a57 100644 --- a/Sources/TSCBasic/CMakeLists.txt +++ b/Sources/TSCBasic/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(TSCBasic Await.swift ByteString.swift CacheableSequence.swift + CodableResult.swift CollectionAlgorithms.swift CollectionExtensions.swift Condition.swift diff --git a/Sources/TSCBasic/CodableResult.swift b/Sources/TSCBasic/CodableResult.swift new file mode 100644 index 00000000..d91654ab --- /dev/null +++ b/Sources/TSCBasic/CodableResult.swift @@ -0,0 +1,62 @@ +/* + This source file is part of the Swift.org open source project + + Copyright (c) 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 +*/ + +/// Codable wrapper for Result +public struct CodableResult: Codable where Success: Codable, Failure: Codable & Error { + private enum CodingKeys: String, CodingKey { + case success, failure + } + + public let result: Result + public init(result: Result) { + self.result = result + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + switch self.result { + case .success(let value): + var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .success) + try unkeyedContainer.encode(value) + case .failure(let error): + var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .failure) + try unkeyedContainer.encode(error) + } + } + + public init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + guard let key = values.allKeys.first(where: values.contains) else { + throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Did not find a matching key")) + } + switch key { + case .success: + var unkeyedValues = try values.nestedUnkeyedContainer(forKey: key) + let value = try unkeyedValues.decode(Success.self) + self.init(result: .success(value)) + case .failure: + var unkeyedValues = try values.nestedUnkeyedContainer(forKey: key) + let error = try unkeyedValues.decode(Failure.self) + self.init(result: .failure(error)) + } + } +} + +extension CodableResult where Failure == StringError { + public init(body: () throws -> Success) { + do { + self.init(result: .success(try body())) + } catch let error as StringError { + self.init(result: .failure(error)) + } catch { + self.init(result: .failure(StringError(String(describing: error)))) + } + } +} diff --git a/Sources/TSCBasic/Process.swift b/Sources/TSCBasic/Process.swift index 684ab85d..9d53054d 100644 --- a/Sources/TSCBasic/Process.swift +++ b/Sources/TSCBasic/Process.swift @@ -89,12 +89,12 @@ public struct ProcessResult: CustomStringConvertible { /// Converts stdout output bytes to string, assuming they're UTF8. public func utf8Output() throws -> String { - return String(decoding: try output.dematerialize(), as: Unicode.UTF8.self) + return String(decoding: try output.get(), as: Unicode.UTF8.self) } /// Converts stderr output bytes to string, assuming they're UTF8. public func utf8stderrOutput() throws -> String { - return String(decoding: try stderrOutput.dematerialize(), as: Unicode.UTF8.self) + return String(decoding: try stderrOutput.get(), as: Unicode.UTF8.self) } public var description: String { @@ -201,10 +201,10 @@ public final class Process: ObjectIdentifierProtocol { #endif /// If redirected, stdout result and reference to the thread reading the output. - private var stdout: (result: Result<[UInt8], AnyError>, thread: Thread?) = (Result([]), nil) + private var stdout: (result: Result<[UInt8], AnyError>, thread: Thread?) = (.success([]), nil) /// If redirected, stderr result and reference to the thread reading the output. - private var stderr: (result: Result<[UInt8], AnyError>, thread: Thread?) = (Result([]), nil) + private var stderr: (result: Result<[UInt8], AnyError>, thread: Thread?) = (.success([]), nil) /// Queue to protect concurrent reads. private let serialQueue = DispatchQueue(label: "org.swift.swiftpm.process") @@ -516,7 +516,7 @@ public final class Process: ObjectIdentifierProtocol { // Close the read end of the output pipe. close(fd) // Construct the output result. - return error.map(Result.init) ?? Result(out) + return error.map(Result.init) ?? .success(out) } #endif diff --git a/Sources/TSCBasic/Result.swift b/Sources/TSCBasic/Result.swift index 32f37a81..8e2e2e4c 100644 --- a/Sources/TSCBasic/Result.swift +++ b/Sources/TSCBasic/Result.swift @@ -1,87 +1,13 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors + 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 */ -/// An simple enum which is either a value or an error. -/// It can be used for error handling in situations where try catch is -/// problematic to use, for eg: asynchronous APIs. -public enum Result { - /// Indicates success with value in the associated object. - case success(Value) - - /// Indicates failure with error inside the associated object. - case failure(ErrorType) - - /// Initialiser for value. - public init(_ value: Value) { - self = .success(value) - } - - /// Initialiser for error. - public init(_ error: ErrorType) { - self = .failure(error) - } - - /// Initialise with something that can throw ErrorType. - public init(_ body: () throws -> Value) throws { - do { - self = .success(try body()) - } catch let error as ErrorType { - self = .failure(error) - } - } - - /// Get the value if success else throw the saved error. - public func dematerialize() throws -> Value { - switch self { - case .success(let value): - return value - case .failure(let error): - throw error - } - } - - /// Evaluates the given closure when this Result instance has a value. - public func map(_ transform: (Value) throws -> U) rethrows -> Result { - switch self { - case .success(let value): - return Result(try transform(value)) - case .failure(let error): - return Result(error) - } - } - - /// Evaluates the given closure when this Result instance has a value, passing the unwrapped value as a parameter. - /// - /// The closure returns a Result instance itself which can have value or not. - public func flatMap(_ transform: (Value) -> Result) -> Result { - switch self { - case .success(let value): - return transform(value) - case .failure(let error): - return Result(error) - } - } - -} - -extension Result: CustomStringConvertible { - public var description: String { - switch self { - case .success(let value): - return "Result(\(value))" - case .failure(let error): - return "Result(\(error))" - } - } -} - /// A type erased error enum. public struct AnyError: Swift.Error, CustomStringConvertible { /// The underlying error. @@ -114,9 +40,9 @@ public struct StringError: Equatable, Codable, CustomStringConvertible, Error { } // AnyError specific helpers. -extension Result where ErrorType == AnyError { +extension Result where Failure == AnyError { /// Initialise with something that throws AnyError. - public init(anyError body: () throws -> Value) { + public init(anyError body: () throws -> Success) { do { self = .success(try body()) } catch { @@ -132,11 +58,11 @@ extension Result where ErrorType == AnyError { /// Evaluates the given throwing closure when this Result instance has a value. /// /// The final result will either be the transformed value or any error thrown by the closure. - public func mapAny(_ transform: (Value) throws -> U) -> Result { + public func mapAny(_ transform: (Success) throws -> U) -> Result { switch self { case .success(let value): do { - return Result(try transform(value)) + return Result.success(try transform(value)) } catch { return Result(error) } @@ -146,11 +72,11 @@ extension Result where ErrorType == AnyError { } } -extension Result where ErrorType == StringError { +extension Result where Failure == StringError { /// Create an instance of Result. /// /// Errors will be encoded as StringError using their description. - public init(string body: () throws -> Value) { + public init(string body: () throws -> Success) { do { self = .success(try body()) } catch let error as StringError { @@ -160,40 +86,3 @@ extension Result where ErrorType == StringError { } } } - -extension Result: Equatable where Value: Equatable, ErrorType: Equatable {} - -extension Result: Codable where Value: Codable, ErrorType: Codable { - private enum CodingKeys: String, CodingKey { - case success, failure - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - switch self { - case .success(let value): - var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .success) - try unkeyedContainer.encode(value) - case .failure(let error): - var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .failure) - try unkeyedContainer.encode(error) - } - } - - public init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - guard let key = values.allKeys.first(where: values.contains) else { - throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Did not find a matching key")) - } - switch key { - case .success: - var unkeyedValues = try values.nestedUnkeyedContainer(forKey: key) - let value = try unkeyedValues.decode(Value.self) - self = .success(value) - case .failure: - var unkeyedValues = try values.nestedUnkeyedContainer(forKey: key) - let error = try unkeyedValues.decode(ErrorType.self) - self = .failure(error) - } - } -} diff --git a/Sources/TSCBasic/TemporaryFile.swift b/Sources/TSCBasic/TemporaryFile.swift index 049e0a6b..6963a3c1 100644 --- a/Sources/TSCBasic/TemporaryFile.swift +++ b/Sources/TSCBasic/TemporaryFile.swift @@ -45,14 +45,23 @@ private extension TempFileError { /// /// - Returns: Path to directory in which temporary file should be created. public func determineTempDirectory(_ dir: AbsolutePath? = nil) throws -> AbsolutePath { - // FIXME: Add other platform specific locations. - let tmpDir = dir ?? AbsolutePath(NSTemporaryDirectory()) + let tmpDir = dir ?? cachedTempDirectory guard localFileSystem.isDirectory(tmpDir) else { throw TempFileError.couldNotFindTmpDir } return tmpDir } +/// Returns temporary directory location by searching relevant env variables. +/// +/// Evaluates once per execution. +private var cachedTempDirectory: AbsolutePath = { + let override = ProcessEnv.vars["TMPDIR"] ?? ProcessEnv.vars["TEMP"] ?? ProcessEnv.vars["TMP"] + if let path = override.flatMap({ try? AbsolutePath(validating: $0) }) { + return path + } + return AbsolutePath(NSTemporaryDirectory()) +}() /// The closure argument of the `body` closue of `withTemporaryFile`. public struct TemporaryFile { @@ -86,7 +95,7 @@ public struct TemporaryFile { // Convert path to a C style string terminating with null char to be an valid input // to mkstemps method. The XXXXXX in this string will be replaced by a random string // which will be the actual path to the temporary file. - var template = [UInt8](path.pathString.utf8).map({ Int8($0) }) + [Int8(0)] + var template = Array(path.pathString.utf8CString) fd = TSCLibc.mkstemps(&template, Int32(suffix.utf8.count)) // If mkstemps failed then throw error. diff --git a/Sources/TSCBasic/TerminalController.swift b/Sources/TSCBasic/TerminalController.swift index f6616ca6..94954938 100644 --- a/Sources/TSCBasic/TerminalController.swift +++ b/Sources/TSCBasic/TerminalController.swift @@ -9,6 +9,9 @@ */ import TSCLibc +#if os(Windows) +import MSVCRT +#endif /// A class to have better control on tty output streams: standard output and standard error. /// Allows operations like cursor movement and colored text output on tty. @@ -84,6 +87,18 @@ public final class TerminalController { } else { width = 80 } + +#if os(Windows) + // Enable VT100 interpretation + let hOut = GetStdHandle(STD_OUTPUT_HANDLE) + var dwMode: DWORD = 0 + + guard hOut != INVALID_HANDLE_VALUE else { return nil } + guard GetConsoleMode(hOut, &dwMode) else { return nil } + + dwMode |= DWORD(ENABLE_VIRTUAL_TERMINAL_PROCESSING) + guard SetConsoleMode(hOut, dwMode) else { return nil } +#endif self.stream = stream } diff --git a/Sources/TSCLibc/libc.swift b/Sources/TSCLibc/libc.swift index d7d964d5..8fcc9353 100644 --- a/Sources/TSCLibc/libc.swift +++ b/Sources/TSCLibc/libc.swift @@ -17,4 +17,4 @@ @_exported import Darwin.C #endif -@_exported import clibc +@_exported import TSCclibc diff --git a/Sources/TSCTestSupport/Product.swift b/Sources/TSCTestSupport/Product.swift index 17182584..3751721d 100644 --- a/Sources/TSCTestSupport/Product.swift +++ b/Sources/TSCTestSupport/Product.swift @@ -97,6 +97,9 @@ extension Product { environment["SWIFTPM_TESTS_MODULECACHE"] = self.path.parentDirectory.pathString environment["SDKROOT"] = nil + // 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] diff --git a/Sources/TSCUtility/CMakeLists.txt b/Sources/TSCUtility/CMakeLists.txt index 2faabe4e..7186c6b2 100644 --- a/Sources/TSCUtility/CMakeLists.txt +++ b/Sources/TSCUtility/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(TSCUtility IndexStore.swift InterruptHandler.swift misc.swift + OSLog.swift PkgConfig.swift Platform.swift ProgressAnimation.swift diff --git a/Sources/TSCUtility/IndexStore.swift b/Sources/TSCUtility/IndexStore.swift index 65fcaead..16caf98a 100644 --- a/Sources/TSCUtility/IndexStore.swift +++ b/Sources/TSCUtility/IndexStore.swift @@ -9,7 +9,7 @@ */ import TSCBasic -import clibc +import TSCclibc public final class IndexStore { diff --git a/Sources/TSCUtility/PkgConfig.swift b/Sources/TSCUtility/PkgConfig.swift index cc264445..dcf5938a 100644 --- a/Sources/TSCUtility/PkgConfig.swift +++ b/Sources/TSCUtility/PkgConfig.swift @@ -143,26 +143,31 @@ public struct PkgConfig { var parser = PkgConfigParser(pcFile: pcFile, fileSystem: fileSystem) try parser.parse() - var cFlags = parser.cFlags - var libs = parser.libs - - // If parser found dependencies in pc file, get their flags too. - if !parser.dependencies.isEmpty { - for dep in parser.dependencies { + func getFlags(from dependencies: [String]) throws -> (cFlags: [String], libs: [String]) { + var cFlags = [String]() + var libs = [String]() + + for dep in dependencies { // FIXME: This is wasteful, we should be caching the PkgConfig result. let pkg = try PkgConfig( name: dep, additionalSearchPaths: additionalSearchPaths, - diagnostics: self.diagnostics, + diagnostics: diagnostics, brewPrefix: brewPrefix ) + cFlags += pkg.cFlags libs += pkg.libs } + + return (cFlags: cFlags, libs: libs) } - self.cFlags = cFlags - self.libs = libs + let dependencyFlags = try getFlags(from: parser.dependencies) + let privateDependencyFlags = try getFlags(from: parser.privateDependencies) + + self.cFlags = parser.cFlags + dependencyFlags.cFlags + privateDependencyFlags.cFlags + self.libs = parser.libs + dependencyFlags.libs } private static var envSearchPaths: [AbsolutePath] { @@ -183,6 +188,7 @@ struct PkgConfigParser { private let fileSystem: FileSystem private(set) var variables = [String: String]() var dependencies = [String]() + var privateDependencies = [String]() var cFlags = [String]() var libs = [String]() @@ -200,9 +206,12 @@ struct PkgConfigParser { return line } - // Add pcfiledir variable. This is path to the directory containing the pc file. + // Add pcfiledir variable. This is the path of the directory containing this pc file. variables["pcfiledir"] = pcFile.parentDirectory.pathString + // Add pc_sysrootdir variable. This is the path of the sysroot directory for pc files. + variables["pc_sysrootdir"] = ProcessEnv.vars["PKG_CONFIG_SYSROOT_DIR"] ?? "/" + let fileContents = try fileSystem.readFileContents(pcFile) // FIXME: Should we error out instead if content is not UTF8 representable? for line in fileContents.validDescription?.components(separatedBy: "\n") ?? [] { @@ -233,6 +242,8 @@ struct PkgConfigParser { switch key { case "Requires": dependencies = try parseDependencies(value) + case "Requires.private": + privateDependencies = try parseDependencies(value) case "Libs": libs = try splitEscapingSpace(value) case "Cflags": diff --git a/Sources/TSCUtility/Versioning.swift b/Sources/TSCUtility/Versioning.swift index 9a7af90e..6f5b848a 100644 --- a/Sources/TSCUtility/Versioning.swift +++ b/Sources/TSCUtility/Versioning.swift @@ -8,7 +8,7 @@ See http://swift.org/CONTRIBUTORS.txt for Swift project authors */ -import clibc +import TSCclibc /// A Swift version number. /// diff --git a/Sources/TSCclibc/include/clibc.h b/Sources/TSCclibc/include/TSCclibc.h similarity index 100% rename from Sources/TSCclibc/include/clibc.h rename to Sources/TSCclibc/include/TSCclibc.h diff --git a/Sources/TSCclibc/include/module.modulemap b/Sources/TSCclibc/include/module.modulemap index 2f908650..eee2ffcb 100644 --- a/Sources/TSCclibc/include/module.modulemap +++ b/Sources/TSCclibc/include/module.modulemap @@ -1,5 +1,5 @@ -module clibc { - header "clibc.h" +module TSCclibc { + header "TSCclibc.h" header "indexstore_functions.h" export * } diff --git a/Tests/TSCBasicTests/AwaitTests.swift b/Tests/TSCBasicTests/AwaitTests.swift index dc43ee7a..6e3bcea6 100644 --- a/Tests/TSCBasicTests/AwaitTests.swift +++ b/Tests/TSCBasicTests/AwaitTests.swift @@ -21,7 +21,7 @@ class AwaitTests: XCTestCase { func async(_ param: String, _ completion: @escaping (Result) -> Void) { DispatchQueue.global().async { - completion(Result(param)) + completion(.success(param)) } } diff --git a/Tests/TSCBasicTests/ResultTests.swift b/Tests/TSCBasicTests/ResultTests.swift index 94daf8a0..6c3c72b6 100644 --- a/Tests/TSCBasicTests/ResultTests.swift +++ b/Tests/TSCBasicTests/ResultTests.swift @@ -24,55 +24,10 @@ private enum OtherDummyError: Swift.Error { class ResultTests: XCTestCase { - func testBasics() throws { - - func doSomething(right: Bool) -> Result { - if right { - return Result("All OK.") - } - return Result(DummyError.somethingWentWrong) - } - // Success. - switch doSomething(right: true) { - case .success(let string): - XCTAssertEqual(string, "All OK.") - case .failure(let error): - XCTFail("Unexpected failure: \(error)") - } - - // Error. - switch doSomething(right: false) { - case .success(let string): - XCTFail("Unexpected success: \(string)") - case .failure(let error): - XCTAssertEqual(error, DummyError.somethingWentWrong) - } - - // Test dematerialize. - XCTAssertEqual(try doSomething(right: true).dematerialize(), "All OK.") - do { - _ = try doSomething(right: false).dematerialize() - XCTFail("Unexpected success") - } catch DummyError.somethingWentWrong {} - - func should(`throw`: Bool) throws -> Int { - if `throw` { - throw DummyError.somethingWentWrong - } - return 1 - } - - // Test closure. - let result: Result = try Result { - return try should(throw: false) - } - XCTAssertEqual(try result.dematerialize(), 1) - } - func testAnyError() { func doSomething(right: Bool) -> Result { if right { - return Result("All OK.") + return .success("All OK.") } return Result(DummyError.somethingWentWrong) } @@ -123,14 +78,6 @@ class ResultTests: XCTestCase { } } - func testMap() throws { - XCTAssertEqual(try Result("Hello").map { $0 + " World" }.dematerialize(), "Hello World") - - XCTAssertThrows(DummyError.somethingWentWrong) { - _ = try Result(.somethingWentWrong).map { $0 + " World" }.dematerialize() - } - } - func testMapAny() throws { func throwing(_ shouldThrow: Bool) throws -> String { if shouldThrow { @@ -140,11 +87,11 @@ class ResultTests: XCTestCase { } // We should be able to map when we have value in result and our closure doesn't throw. - let success = Result("Hello").mapAny { value -> String in + let success = Result.success("Hello").mapAny { value -> String in let second = try throwing(false) return value + second } - XCTAssertEqual(try success.dematerialize(), "Hello World") + XCTAssertEqual(try success.get(), "Hello World") // We don't have a value, closure shouldn't matter. let failure1 = Result(DummyError.somethingWentWrong).mapAny { value -> String in @@ -152,40 +99,16 @@ class ResultTests: XCTestCase { return value + second } XCTAssertThrowsAny(DummyError.somethingWentWrong) { - _ = try failure1.dematerialize() + _ = try failure1.get() } // We have a value, but our closure throws. - let failure2 = Result("Hello").mapAny { value -> String in + let failure2 = Result.success("Hello").mapAny { value -> String in let second = try throwing(true) return value + second } XCTAssertThrowsAny(DummyError.somethingWentWrong) { - _ = try failure2.dematerialize() - } - } - - func testFlatMap() throws { - XCTAssertEqual(try Result("Hello").flatMap { .success($0.utf8.count ) }.dematerialize(), 5) - - XCTAssertThrows(DummyError.somethingWentWrong) { - _ = try Result.failure(.somethingWentWrong).flatMap { .success($0 + " World") }.dematerialize() - } - - XCTAssertThrows(DummyError.somethingWentWrong) { - _ = try Result.failure(.somethingWentWrong).flatMap { (x: String) -> Result in - XCTFail("should not be executed") - return .success(x + " World") - }.dematerialize() - } - - XCTAssertThrows(DummyError.somethingWentWrong) { - _ = try Result("Hello").flatMap { String -> Result in .failure(.somethingWentWrong) }.dematerialize() - } - - XCTAssertThrows(OtherDummyError.somethingElseWentWrong) { - _ = try Result.failure(.somethingElseWentWrong) - .flatMap { String -> Result in .failure(.andYetAnotherThingToGoWrong) }.dematerialize() + _ = try failure2.get() } } } diff --git a/Tests/TSCBasicTests/TemporaryFileTests.swift b/Tests/TSCBasicTests/TemporaryFileTests.swift index 412e643a..ca75afd0 100644 --- a/Tests/TSCBasicTests/TemporaryFileTests.swift +++ b/Tests/TSCBasicTests/TemporaryFileTests.swift @@ -84,6 +84,12 @@ class TemporaryFileTests: XCTestCase { XCTAssertFalse(localFileSystem.isFile(filePathOne)) XCTAssertFalse(localFileSystem.isFile(filePathTwo)) } + + func testNonStandardASCIIName() throws { + try withTemporaryFile(prefix: "Héllo") { file in + XCTAssertTrue(localFileSystem.isFile(file.path)) + } + } func testBasicTemporaryDirectory() throws { // Test can create and remove temp directory. diff --git a/Tests/TSCBasicTests/XCTestManifests.swift b/Tests/TSCBasicTests/XCTestManifests.swift index e8716793..ba51f7ca 100644 --- a/Tests/TSCBasicTests/XCTestManifests.swift +++ b/Tests/TSCBasicTests/XCTestManifests.swift @@ -344,9 +344,6 @@ extension ResultTests { // to regenerate. static let __allTests__ResultTests = [ ("testAnyError", testAnyError), - ("testBasics", testBasics), - ("testFlatMap", testFlatMap), - ("testMap", testMap), ("testMapAny", testMapAny), ] } @@ -406,6 +403,7 @@ extension TemporaryFileTests { ("testCanCreateUniqueTempFiles", testCanCreateUniqueTempFiles), ("testLeaks", testLeaks), ("testNoCleanupTemporaryFile", testNoCleanupTemporaryFile), + ("testNonStandardASCIIName", testNonStandardASCIIName), ] } diff --git a/Tests/TSCUtilityTests/PkgConfigParserTests.swift b/Tests/TSCUtilityTests/PkgConfigParserTests.swift index 2d5cdfea..47e9028d 100644 --- a/Tests/TSCUtilityTests/PkgConfigParserTests.swift +++ b/Tests/TSCUtilityTests/PkgConfigParserTests.swift @@ -26,9 +26,11 @@ final class PkgConfigParserTests: XCTestCase { "gtk_binary_version": "3.0.0", "exec_prefix": "/usr/local/Cellar/gtk+3/3.18.9", "targets": "quartz", - "pcfiledir": parser.pcFile.parentDirectory.pathString + "pcfiledir": parser.pcFile.parentDirectory.pathString, + "pc_sysrootdir": "/" ]) XCTAssertEqual(parser.dependencies, ["gdk-3.0", "atk", "cairo", "cairo-gobject", "gdk-pixbuf-2.0", "gio-2.0"]) + XCTAssertEqual(parser.privateDependencies, ["atk", "epoxy", "gio-unix-2.0"]) XCTAssertEqual(parser.cFlags, ["-I/usr/local/Cellar/gtk+3/3.18.9/include/gtk-3.0"]) XCTAssertEqual(parser.libs, ["-L/usr/local/Cellar/gtk+3/3.18.9/lib", "-lgtk-3"]) } @@ -36,7 +38,12 @@ final class PkgConfigParserTests: XCTestCase { func testEmptyCFlags() { try! loadPCFile("empty_cflags.pc") { parser in - XCTAssertEqual(parser.variables, ["prefix": "/usr/local/bin", "exec_prefix": "/usr/local/bin", "pcfiledir": parser.pcFile.parentDirectory.pathString]) + XCTAssertEqual(parser.variables, [ + "prefix": "/usr/local/bin", + "exec_prefix": "/usr/local/bin", + "pcfiledir": parser.pcFile.parentDirectory.pathString, + "pc_sysrootdir": "/" + ]) XCTAssertEqual(parser.dependencies, ["gdk-3.0", "atk"]) XCTAssertEqual(parser.cFlags, []) XCTAssertEqual(parser.libs, ["-L/usr/local/bin", "-lgtk-3"]) @@ -45,7 +52,13 @@ final class PkgConfigParserTests: XCTestCase { func testVariableinDependency() { try! loadPCFile("deps_variable.pc") { parser in - XCTAssertEqual(parser.variables, ["prefix": "/usr/local/bin", "exec_prefix": "/usr/local/bin", "my_dep": "atk", "pcfiledir": parser.pcFile.parentDirectory.pathString]) + XCTAssertEqual(parser.variables, [ + "prefix": "/usr/local/bin", + "exec_prefix": "/usr/local/bin", + "my_dep": "atk", + "pcfiledir": parser.pcFile.parentDirectory.pathString, + "pc_sysrootdir": "/" + ]) XCTAssertEqual(parser.dependencies, ["gdk-3.0", "atk"]) XCTAssertEqual(parser.cFlags, ["-I"]) XCTAssertEqual(parser.libs, ["-L/usr/local/bin", "-lgtk-3"]) @@ -63,7 +76,13 @@ final class PkgConfigParserTests: XCTestCase { func testEscapedSpaces() { try! loadPCFile("escaped_spaces.pc") { parser in - XCTAssertEqual(parser.variables, ["prefix": "/usr/local/bin", "exec_prefix": "/usr/local/bin", "my_dep": "atk", "pcfiledir": parser.pcFile.parentDirectory.pathString]) + XCTAssertEqual(parser.variables, [ + "prefix": "/usr/local/bin", + "exec_prefix": "/usr/local/bin", + "my_dep": "atk", + "pcfiledir": parser.pcFile.parentDirectory.pathString, + "pc_sysrootdir": "/" + ]) XCTAssertEqual(parser.dependencies, ["gdk-3.0", "atk"]) XCTAssertEqual(parser.cFlags, ["-I/usr/local/Wine Cellar/gtk+3/3.18.9/include/gtk-3.0", "-I/after/extra/spaces"]) XCTAssertEqual(parser.libs, ["-L/usr/local/bin", "-lgtk 3", "-wantareal\\here", "-one\\", "-two"])