Skip to content

Commit

Permalink
Fix infinite looping if swift-format is run in a directory that doesn…
Browse files Browse the repository at this point in the history
…'t contain a `.swift-format` file

#802 this sort of infinite looping issue on Windows but introduced it on Unix platforms where `URL.deletingLastPathComponent` on `/` returns `/..`.
  • Loading branch information
ahoppen committed Oct 10, 2024
1 parent d143a8a commit 231be3c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
19 changes: 13 additions & 6 deletions Sources/SwiftFormat/API/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -425,17 +425,12 @@ public struct Configuration: Codable, Equatable {
candidateDirectory.appendPathComponent("placeholder")
}
repeat {
let previousDirectory = candidateDirectory
candidateDirectory.deleteLastPathComponent()
// if deleting a path component resulted in no change, terminate the loop
if candidateDirectory == previousDirectory {
break
}
let candidateFile = candidateDirectory.appendingPathComponent(".swift-format")
if FileManager.default.isReadableFile(atPath: candidateFile.path) {
return candidateFile
}
} while true
} while !candidateDirectory.isRoot

return nil
}
Expand Down Expand Up @@ -477,3 +472,15 @@ public struct NoAssignmentInExpressionsConfiguration: Codable, Equatable {

public init() {}
}

fileprivate extension URL {
var isRoot: Bool {
#if os(Windows)
// 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.
// https://github.com/swiftlang/swift-format/issues/844
return self.pathComponents.count == 1
#else
return self.path == "/"
#endif
}
}
9 changes: 9 additions & 0 deletions Tests/SwiftFormatTests/API/ConfigurationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,13 @@ final class ConfigurationTests: XCTestCase {

XCTAssertEqual(defaultInitConfig, emptyJSONConfig)
}

func testMissingConfigurationFile() {
#if os(Windows)
let path = #"C:\test.swift"#
#else
let path = "/test.swift"
#endif
XCTAssertNil(Configuration.url(forConfigurationFileApplyingTo: URL(fileURLWithPath: path)))
}
}

0 comments on commit 231be3c

Please sign in to comment.