Skip to content

Commit 2e4e0a6

Browse files
ahoppenmacshome
authored andcommitted
WIP
1 parent da2f133 commit 2e4e0a6

File tree

5 files changed

+71
-52
lines changed

5 files changed

+71
-52
lines changed

Sources/SwiftFormat/API/Configuration.swift

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -472,17 +472,3 @@ public struct NoAssignmentInExpressionsConfiguration: Codable, Equatable {
472472

473473
public init() {}
474474
}
475-
476-
fileprivate extension URL {
477-
var isRoot: Bool {
478-
#if os(Windows)
479-
// FIXME: We should call into Windows' native check to check if this path is a root once https://github.com/swiftlang/swift-foundation/issues/976 is fixed.
480-
// https://github.com/swiftlang/swift-format/issues/844
481-
return self.pathComponents.count <= 1
482-
#else
483-
// On Linux, we may end up with an string for the path due to https://github.com/swiftlang/swift-foundation/issues/980
484-
// TODO: Remove the check for "" once https://github.com/swiftlang/swift-foundation/issues/980 is fixed.
485-
return self.path == "/" || self.path == ""
486-
#endif
487-
}
488-
}

Sources/SwiftFormat/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ add_library(SwiftFormat
9797
Rules/UseTripleSlashForDocumentationComments.swift
9898
Rules/UseWhereClausesInForLoops.swift
9999
Rules/ValidateDocumentationComments.swift
100-
Utilities/FileIterator.swift)
100+
Utilities/FileIterator.swift
101+
Utilities/URL+isRoot.swift)
101102
target_link_libraries(SwiftFormat PUBLIC
102103
SwiftMarkdown::Markdown
103104
SwiftSyntax::SwiftSyntax

Sources/SwiftFormat/Utilities/FileIterator.swift

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,12 @@ public struct FileIterator: Sequence, IteratorProtocol {
153153
// if the user passes paths that are relative to the current working directory, they will
154154
// be displayed as relative paths. Otherwise, they will still be displayed as absolute
155155
// paths.
156-
#if os(Windows)
157-
let relativePath = path
158-
#else
159156
let relativePath =
160-
path.hasPrefix(workingDirectory.path)
161-
&& !URL(fileURLWithPath: FileManager.default.currentDirectoryPath).isRoot
162-
? String(path.dropFirst(workingDirectory.path.count + 1))
163-
: path
164-
#endif
157+
if !workingDirectory.isRoot, path.hasPrefix(workingDirectory.path) {
158+
String(path.dropFirst(workingDirectory.path.count).drop(while: { $0 == "/" || $0 == #"\"# }))
159+
} else {
160+
path
161+
}
165162
output =
166163
URL(fileURLWithPath: relativePath, isDirectory: false, relativeTo: workingDirectory)
167164

@@ -183,16 +180,3 @@ private func fileType(at url: URL) -> FileAttributeType? {
183180
// Linux.
184181
return try? FileManager.default.attributesOfItem(atPath: url.path)[.type] as? FileAttributeType
185182
}
186-
187-
fileprivate extension URL {
188-
var isRoot: Bool {
189-
guard isFileURL else { return false }
190-
#if os(macOS)
191-
return self.path == NSOpenStepRootDirectory()
192-
#elseif os(Windows)
193-
return self.path.withCString(encodedAs: UTF16.self, PathCchIsRoot)
194-
#else
195-
return self.path == "/"
196-
#endif
197-
}
198-
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Foundation
14+
15+
extension URL {
16+
@_spi(Testing) public var isRoot: Bool {
17+
#if os(Windows)
18+
// FIXME: We should call into Windows' native check to check if this path is a root once https://github.com/swiftlang/swift-foundation/issues/976 is fixed.
19+
// https://github.com/swiftlang/swift-format/issues/844
20+
return self.pathComponents.count <= 1
21+
#else
22+
// On Linux, we may end up with an string for the path due to https://github.com/swiftlang/swift-foundation/issues/980
23+
// TODO: Remove the check for "" once https://github.com/swiftlang/swift-foundation/issues/980 is fixed.
24+
return self.path == "/" || self.path == ""
25+
#endif
26+
}
27+
}

Tests/SwiftFormatTests/Utilities/FileIteratorTests.swift

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,31 @@
1-
@_spi(Internal) import SwiftFormat
1+
@_spi(Internal) @_spi(Testing) import SwiftFormat
22
import XCTest
33

4+
extension URL {
5+
/// Assuming this is a file URL, resolves all symlinks in the path.
6+
///
7+
/// - Note: We need this because `URL.resolvingSymlinksInPath()` not only resolves symlinks but also standardizes the
8+
/// path by stripping away `private` prefixes. Since sourcekitd is not performing this standardization, using
9+
/// `resolvingSymlinksInPath` can lead to slightly mismatched URLs between the sourcekit-lsp response and the test
10+
/// assertion.
11+
var realpath: URL {
12+
#if canImport(Darwin)
13+
return self.path.withCString { path in
14+
guard let realpath = Darwin.realpath(path, nil) else {
15+
return self
16+
}
17+
let result = URL(fileURLWithPath: String(cString: realpath))
18+
free(realpath)
19+
return result
20+
}
21+
#else
22+
// Non-Darwin platforms don't have the `/private` stripping issue, so we can just use `self.resolvingSymlinksInPath`
23+
// here.
24+
return self.resolvingSymlinksInPath()
25+
#endif
26+
}
27+
}
28+
429
final class FileIteratorTests: XCTestCase {
530
private var tmpdir: URL!
631

@@ -10,7 +35,7 @@ final class FileIteratorTests: XCTestCase {
1035
in: .userDomainMask,
1136
appropriateFor: FileManager.default.temporaryDirectory,
1237
create: true
13-
)
38+
).realpath
1439

1540
// Create a simple file tree used by the tests below.
1641
try touch("project/real1.swift")
@@ -73,26 +98,22 @@ final class FileIteratorTests: XCTestCase {
7398
}
7499

75100
func testDoesNotTrimFirstCharacterOfPathIfRunningInRoot() throws {
76-
#if os(Windows) && compiler(<5.10)
77-
try XCTSkipIf(true, "Testing issues with Foundation inserting extra slashes.")
78-
#endif
79-
// Make sure that we don't drop the begining of the path if we are running in root.
101+
// Find the root of tmpdir. On Unix systems, this is always `/`. On Windows it is the drive.
102+
var root = tmpdir!
103+
while !root.isRoot {
104+
root.deleteLastPathComponent()
105+
}
106+
// Make sure that we don't drop the beginning of the path if we are running in root.
80107
// https://github.com/swiftlang/swift-format/issues/862
81-
FileManager.default.changeCurrentDirectoryPath("/")
82-
let seen = allFilesSeen(iteratingOver: [tmpdir], followSymlinks: false)
83-
XCTAssertEqual(seen.count, 2)
84-
XCTAssertTrue(seen.contains { $0.path.hasPrefix("/") })
85-
XCTAssertTrue(seen.contains { $0.path.hasPrefix("/") })
108+
let seen = allFilesSeen(iteratingOver: [tmpdir], followSymlinks: false, workingDirectory: root)
109+
XCTAssertTrue(seen.allSatisfy { $0.relativePath.hasPrefix(root.path) }, "\(seen) does not contain root directory")
86110
}
87111

88112
func testShowsRelativePaths() throws {
89113
// Make sure that we still show the relative path if using them.
90114
// https://github.com/swiftlang/swift-format/issues/862
91-
FileManager.default.changeCurrentDirectoryPath(tmpdir.path)
92-
let seen = allFilesSeen(iteratingOver: [URL(fileURLWithPath: ".")], followSymlinks: false)
93-
XCTAssertEqual(seen.count, 2)
94-
XCTAssertTrue(seen.contains { $0.relativePath == "project/real1.swift" })
95-
XCTAssertTrue(seen.contains { $0.relativePath == "project/real2.swift" })
115+
let seen = allFilesSeen(iteratingOver: [tmpdir], followSymlinks: false, workingDirectory: tmpdir)
116+
XCTAssertEqual(Set(seen.map(\.relativePath)), ["project/real1.swift", "project/real2.swift"])
96117
}
97118
}
98119

0 commit comments

Comments
 (0)