Skip to content

Commit 6a93875

Browse files
authored
Merge pull request #33 from hartbit/update
Import for SwiftPM #2523
2 parents 5ec233e + c689ab1 commit 6a93875

File tree

7 files changed

+111
-58
lines changed

7 files changed

+111
-58
lines changed

Sources/TSCBasic/CollectionAlgorithms.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11-
extension Sequence where Iterator.Element: Hashable {
11+
extension Sequence where Element: Hashable {
1212

1313
/// Finds duplicates in given sequence of Hashables.
1414
/// - Returns: duplicated elements in the invoking sequence.
15-
public func spm_findDuplicates() -> [Iterator.Element] {
16-
var unique: Set<Iterator.Element> = []
17-
return filter {
18-
!unique.insert($0).inserted
15+
public func spm_findDuplicates() -> [Element] {
16+
var counts: [Element: Int] = [:]
17+
for element in self {
18+
counts[element, default: 0] += 1
1919
}
20+
return Array(counts.lazy.filter({ $0.value > 1 }).map({ $0.key }))
2021
}
2122
}
2223

Sources/TSCBasic/DiagnosticsEngine.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,23 +101,27 @@ public final class DiagnosticsEngine: CustomStringConvertible {
101101
/// The handler will be called on an unknown queue.
102102
private let handlers: [DiagnosticsHandler]
103103

104+
/// The default location to apply to location-less diagnostics.
105+
public let defaultLocation: DiagnosticLocation
106+
104107
/// Returns true if there is an error diagnostics in the engine.
105108
public var hasErrors: Bool {
106109
return diagnostics.contains(where: { $0.message.behavior == .error })
107110
}
108111

109-
public init(handlers: [DiagnosticsHandler] = []) {
112+
public init(handlers: [DiagnosticsHandler] = [], defaultLocation: DiagnosticLocation = UnknownLocation.location) {
110113
self.handlers = handlers
114+
self.defaultLocation = defaultLocation
111115
}
112116

113117
public func emit(
114118
_ message: Diagnostic.Message,
115-
location: DiagnosticLocation = UnknownLocation.location
119+
location: DiagnosticLocation? = nil
116120
) {
117-
emit(Diagnostic(message: message, location: location))
121+
emit(Diagnostic(message: message, location: location ?? defaultLocation))
118122
}
119123

120-
private func emit(_ diagnostic: Diagnostic) {
124+
public func emit(_ diagnostic: Diagnostic) {
121125
queue.sync {
122126
_diagnostics.append(diagnostic)
123127
}

Sources/TSCBasic/FileSystem.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ public protocol FileSystem: class {
148148
/// This follows the POSIX `getcwd(3)` semantics.
149149
var currentWorkingDirectory: AbsolutePath? { get }
150150

151+
/// Change the current working directory.
152+
/// - Parameters:
153+
/// - path: The path to the directory to change the current working directory to.
154+
func changeCurrentWorkingDirectory(to path: AbsolutePath) throws
155+
151156
/// Get the home directory of current user
152157
var homeDirectory: AbsolutePath { get }
153158

@@ -279,6 +284,16 @@ private class LocalFileSystem: FileSystem {
279284
return try? AbsolutePath(validating: cwdStr)
280285
}
281286

287+
func changeCurrentWorkingDirectory(to path: AbsolutePath) throws {
288+
guard isDirectory(path) else {
289+
throw FileSystemError.notDirectory
290+
}
291+
292+
guard FileManager.default.changeCurrentDirectoryPath(path.pathString) else {
293+
throw FileSystemError.unknownOSError
294+
}
295+
}
296+
282297
var homeDirectory: AbsolutePath {
283298
return AbsolutePath(NSHomeDirectory())
284299
}
@@ -570,6 +585,10 @@ public class InMemoryFileSystem: FileSystem {
570585
return AbsolutePath("/")
571586
}
572587

588+
public func changeCurrentWorkingDirectory(to path: AbsolutePath) throws {
589+
fatalError("Unsupported")
590+
}
591+
573592
public var homeDirectory: AbsolutePath {
574593
// FIXME: Maybe we should allow setting this when creating the fs.
575594
return AbsolutePath("/home/user")
@@ -800,6 +819,10 @@ public class RerootedFileSystemView: FileSystem {
800819
return AbsolutePath("/")
801820
}
802821

822+
public func changeCurrentWorkingDirectory(to path: AbsolutePath) throws {
823+
fatalError("Unsupported")
824+
}
825+
803826
public var homeDirectory: AbsolutePath {
804827
fatalError("homeDirectory on RerootedFileSystemView is not supported.")
805828
}

Sources/TSCTestSupport/DiagnosticsEngine.swift

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,6 @@ import TSCUtility
1313

1414
import XCTest
1515

16-
public enum StringCheck: ExpressibleByStringLiteral {
17-
case equal(String)
18-
case contains(String)
19-
20-
func check(
21-
input: String,
22-
file: StaticString = #file,
23-
line: UInt = #line
24-
) {
25-
switch self {
26-
case .equal(let str):
27-
XCTAssertEqual(str, input, file: file, line: line)
28-
case .contains(let str):
29-
XCTAssert(input.contains(str), "\(input) does not contain \(str)", file: file, line: line)
30-
}
31-
}
32-
33-
public init(stringLiteral value: String) {
34-
self = .equal(value)
35-
}
36-
37-
public init(extendedGraphemeClusterLiteral value: String) {
38-
self.init(stringLiteral: value)
39-
}
40-
41-
public init(unicodeScalarLiteral value: String) {
42-
self.init(stringLiteral: value)
43-
}
44-
}
45-
4616
public func DiagnosticsEngineTester(
4717
_ engine: DiagnosticsEngine,
4818
ignoreNotes: Bool = false,
@@ -73,7 +43,7 @@ final public class DiagnosticsEngineResult {
7343
}
7444

7545
public func check(
76-
diagnostic: StringCheck,
46+
diagnostic: StringPattern,
7747
checkContains: Bool = false,
7848
behavior: Diagnostic.Behavior,
7949
location: String? = nil,
@@ -87,7 +57,7 @@ final public class DiagnosticsEngineResult {
8757
let location = location ?? UnknownLocation.location.description
8858
let theDiagnostic = uncheckedDiagnostics.removeFirst()
8959

90-
diagnostic.check(input: theDiagnostic.description, file: file, line: line)
60+
XCTAssertMatch(theDiagnostic.description, diagnostic, file: file, line: line)
9161
XCTAssertEqual(theDiagnostic.message.behavior, behavior, file: file, line: line)
9262
XCTAssertEqual(theDiagnostic.location.description, location, file: file, line: line)
9363
}

Sources/TSCUtility/Diagnostics.swift

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,28 @@ extension DiagnosticsEngine {
3535

3636
public func emit(
3737
error: String,
38-
location: DiagnosticLocation = UnknownLocation.location
38+
location: DiagnosticLocation? = nil
3939
) {
4040
emit(.error(error), location: location)
4141
}
4242

4343
public func emit(
4444
warning: String,
45-
location: DiagnosticLocation = UnknownLocation.location
45+
location: DiagnosticLocation? = nil
4646
) {
4747
emit(.warning(warning), location: location)
4848
}
4949

5050
public func emit(
5151
note: String,
52-
location: DiagnosticLocation = UnknownLocation.location
52+
location: DiagnosticLocation? = nil
5353
) {
5454
emit(.note(note), location: location)
5555
}
5656

5757
public func emit(
5858
remark: String,
59-
location: DiagnosticLocation = UnknownLocation.location
59+
location: DiagnosticLocation? = nil
6060
) {
6161
emit(.remark(remark), location: location)
6262
}
@@ -67,7 +67,7 @@ extension DiagnosticsEngine {
6767
/// Otherwise, they will be emitted as AnyDiagnostic.
6868
public func emit(
6969
_ error: Swift.Error,
70-
location: DiagnosticLocation = UnknownLocation.location
70+
location: DiagnosticLocation? = nil
7171
) {
7272
if let diagnosticData = error as? DiagnosticData {
7373
emit(.error(diagnosticData), location: location)
@@ -81,26 +81,31 @@ extension DiagnosticsEngine {
8181
/// Emit a diagnostic data convertible instance.
8282
public func emit(
8383
_ convertible: DiagnosticDataConvertible,
84-
location: DiagnosticLocation = UnknownLocation.location
84+
location: DiagnosticLocation? = nil
8585
) {
8686
emit(.error(convertible.diagnosticData), location: location)
8787
}
8888

89+
@discardableResult
90+
public func with<T>(location: DiagnosticLocation, _ closure: (DiagnosticsEngine) -> T) -> T {
91+
let innerDiagnostics = DiagnosticsEngine(handlers: [self.emit], defaultLocation: location)
92+
return closure(innerDiagnostics)
93+
}
94+
8995
/// Wrap a throwing closure, returning an optional value and
9096
/// emitting any thrown errors.
9197
///
9298
/// - Parameters:
9399
/// - closure: Closure to wrap.
94100
/// - Returns: Returns the return value of the closure wrapped
95101
/// into an optional. If the closure throws, nil is returned.
96-
public func wrap<T>(
97-
with constuctLocation: @autoclosure () -> (DiagnosticLocation) = UnknownLocation.location,
98-
_ closure: () throws -> T
99-
) -> T? {
102+
public func wrap<T>(_ closure: () throws -> T) -> T? {
100103
do {
101104
return try closure()
105+
} catch Diagnostics.fatalError {
106+
return nil
102107
} catch {
103-
emit(error, location: constuctLocation())
108+
emit(error)
104109
return nil
105110
}
106111
}
@@ -113,20 +118,65 @@ extension DiagnosticsEngine {
113118
/// - Returns: Returns true if the wrapped closure did not throw
114119
/// and false otherwise.
115120
@discardableResult
116-
public func wrap(
117-
with constuctLocation: @autoclosure () -> (DiagnosticLocation) = UnknownLocation.location,
118-
_ closure: () throws -> Void
119-
) -> Bool {
121+
public func wrap(_ closure: () throws -> Void) -> Bool {
120122
do {
121123
try closure()
122124
return true
125+
} catch Diagnostics.fatalError {
126+
return false
123127
} catch {
124-
emit(error, location: constuctLocation())
128+
emit(error)
125129
return false
126130
}
127131
}
128132
}
129133

134+
extension Optional where Wrapped == DiagnosticsEngine {
135+
public func emit(
136+
error: String,
137+
location: DiagnosticLocation? = nil
138+
) throws {
139+
if case let diagnostics? = self {
140+
diagnostics.emit(.error(error), location: location)
141+
} else {
142+
throw Diagnostics.fatalError
143+
}
144+
}
145+
146+
public func emit(
147+
_ error: Swift.Error,
148+
location: DiagnosticLocation? = nil
149+
) throws {
150+
if case let diagnostics? = self {
151+
diagnostics.emit(error, location: location)
152+
} else {
153+
throw Diagnostics.fatalError
154+
}
155+
}
156+
157+
public func emit(
158+
_ convertible: DiagnosticDataConvertible,
159+
location: DiagnosticLocation? = nil
160+
) throws {
161+
if case let diagnostics? = self {
162+
diagnostics.emit(.error(convertible.diagnosticData), location: location)
163+
} else {
164+
throw Diagnostics.fatalError
165+
}
166+
}
167+
168+
public func emit(
169+
_ message: Diagnostic.Message,
170+
location: DiagnosticLocation? = nil
171+
) throws {
172+
if case let diagnostics? = self {
173+
diagnostics.emit(message, location: location)
174+
} else if message.behavior == .error {
175+
throw Diagnostics.fatalError
176+
}
177+
}
178+
}
179+
130180
/// Namespace for representing diagnostic location of a package.
131181
public enum PackageLocation {
132182

Tests/TSCBasicTests/CollectionAlgorithmsTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import TSCBasic
1414

1515
class CollectionAlgorithmsTests: XCTestCase {
1616
func testFindDuplicates() {
17-
XCTAssertEqual([1, 2, 3, 2, 1].spm_findDuplicates(), [2, 1])
17+
XCTAssertEqual(Set([1, 2, 3, 2, 1].spm_findDuplicates()), [1, 2])
18+
XCTAssertEqual(Set([1, 2, 3, 2, 1, 2].spm_findDuplicates()), [1, 2])
1819
XCTAssertEqual(["foo", "bar"].spm_findDuplicates(), [])
1920
XCTAssertEqual(["foo", "Foo"].spm_findDuplicates(), [])
2021
}

Tests/TSCUtilityTests/DownloaderTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,10 @@ class FailingFileSystem: FileSystem {
320320
fatalError("unexpected call")
321321
}
322322

323+
func changeCurrentWorkingDirectory(to path: AbsolutePath) throws {
324+
fatalError("unexpected call")
325+
}
326+
323327
func exists(_ path: AbsolutePath, followSymlink: Bool) -> Bool {
324328
fatalError("unexpected call")
325329
}

0 commit comments

Comments
 (0)