Skip to content

Commit ba343ca

Browse files
committed
Added string constructor. Don't skip dir.
1 parent e9861ca commit ba343ca

File tree

2 files changed

+50
-33
lines changed

2 files changed

+50
-33
lines changed

Sources/SwiftFormat/Core/IgnoreFile.swift

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import Foundation
1515
/// A file that describes which files and directories should be ignored by the formatter.
1616
/// In the future, this file may contain complex rules for ignoring files, based
1717
/// on pattern matching file paths.
18-
///
18+
///
1919
/// Currently, the only valid content for an ignore file is a single asterisk "*",
2020
/// optionally surrounded by whitespace.
2121
public class IgnoreFile {
@@ -26,18 +26,30 @@ public class IgnoreFile {
2626

2727
/// Errors that can be thrown by the IgnoreFile initializer.
2828
public enum Error: Swift.Error {
29-
/// Error thrown when an ignore file has invalid content.
30-
case invalidContent(URL)
29+
/// Error thrown when initialising with invalid content.
30+
case invalidContent
31+
32+
/// Error thrown when we fail to initialise with the given URL.
33+
case invalidFile(URL, Swift.Error)
34+
}
35+
36+
/// Create an instance from a string.
37+
/// Returns nil if the content is not valid.
38+
public init(_ content: String) throws {
39+
guard content.trimmingCharacters(in: .whitespacesAndNewlines) == "*" else {
40+
throw Error.invalidContent
41+
}
3142
}
3243

3344
/// Create an instance from the contents of the file at the given URL.
3445
/// Throws an error if the file content can't be read, or is not valid.
35-
public init(contentsOf url: URL) throws {
36-
let content = try String(contentsOf: url, encoding: .utf8)
37-
guard content.trimmingCharacters(in: .whitespacesAndNewlines) == "*" else {
38-
throw Error.invalidContent(url)
39-
}
40-
}
46+
public convenience init(contentsOf url: URL) throws {
47+
do {
48+
try self.init(try String(contentsOf: url, encoding: .utf8))
49+
} catch {
50+
throw Error.invalidFile(url, error)
51+
}
52+
}
4153

4254
/// Create an instance for the given directory, if a valid
4355
/// ignore file with the standard name is found in that directory.
@@ -47,35 +59,41 @@ public class IgnoreFile {
4759
/// Note that this initializer does not search parent directories for ignore files.
4860
public convenience init?(forDirectory directory: URL) throws {
4961
let url = directory.appendingPathComponent(IgnoreFile.fileName)
50-
guard FileManager.default.isReadableFile(atPath: url.path) else {
51-
return nil
52-
}
5362

54-
try self.init(contentsOf: url)
63+
do {
64+
try self.init(contentsOf: url)
65+
} catch {
66+
if case let Error.invalidFile(_, underlying) = error, (underlying as NSError).domain == NSCocoaErrorDomain,
67+
(underlying as NSError).code == NSFileReadNoSuchFileError
68+
{
69+
return nil
70+
}
71+
throw error
72+
}
5573
}
5674

5775
/// Create an instance to use for the given URL.
5876
/// We search for an ignore file starting from the given URL's container,
5977
/// and moving up the directory tree, until we reach the root directory.
6078
/// Returns nil if no ignore file is found.
61-
/// Throws an error if an invalid ignore file is found somewhere
79+
/// Throws an error if an invalid ignore file is found somewhere
6280
/// in the directory tree.
6381
///
6482
/// Note that we start the search from the given URL's **container**,
6583
/// not the URL itself; the URL passed in is expected to be for a file.
6684
/// If you pass a directory URL, the search will not include the contents
6785
/// of that directory.
6886
public convenience init?(for url: URL) throws {
69-
var containingDirectory = url.absoluteURL.standardized
70-
repeat {
71-
containingDirectory.deleteLastPathComponent()
72-
let url = containingDirectory.appendingPathComponent(IgnoreFile.fileName)
73-
if FileManager.default.isReadableFile(atPath: url.path) {
74-
try self.init(contentsOf: url)
75-
return
76-
}
77-
} while !containingDirectory.isRoot
78-
return nil
87+
var containingDirectory = url.absoluteURL.standardized
88+
repeat {
89+
containingDirectory.deleteLastPathComponent()
90+
let url = containingDirectory.appendingPathComponent(IgnoreFile.fileName)
91+
if FileManager.default.isReadableFile(atPath: url.path) {
92+
try self.init(contentsOf: url)
93+
return
94+
}
95+
} while !containingDirectory.isRoot
96+
return nil
7997
}
8098

8199
/// Should the given URL be processed?
@@ -85,9 +103,9 @@ public class IgnoreFile {
85103
return false
86104
}
87105

88-
/// Returns true if the name of the given URL matches
106+
/// Returns true if the name of the given URL matches
89107
/// the standard ignore file name.
90108
public static func isStandardIgnoreFile(_ url: URL) -> Bool {
91109
return url.lastPathComponent == fileName
92110
}
93-
}
111+
}

Sources/SwiftFormat/Utilities/FileIterator.swift

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,13 @@ public struct FileIterator: Sequence, IteratorProtocol {
9797
// skip this directory and its subdirectories if it should be ignored
9898
continue
9999
}
100-
} catch IgnoreFile.Error.invalidContent(let url) {
100+
} catch IgnoreFile.Error.invalidFile(let url, _) {
101101
// we hit an invalid ignore file
102-
// we skip the directory, but return the path of the ignore file
103-
// so that we can report an error
102+
// we return the path of the ignore file so that we can report an error
103+
// and process the directory as normal
104104
output = url
105105
} catch {
106-
// we hit another unexpected error; just skip the directory
107-
continue
106+
// we hit another unexpected error; process the directory as normal
108107
}
109108

110109
dirIterator = FileManager.default.enumerator(
@@ -197,7 +196,7 @@ private func fileType(at url: URL) -> FileAttributeType? {
197196

198197
/// Returns true if the file should be processed.
199198
/// Directories are always processed.
200-
/// For other files, we look for an ignore file in the containing
199+
/// For other files, we look for an ignore file in the containing
201200
/// directory or any of its parents.
202201
/// If there is no ignore file, we process the file.
203202
/// If an ignore file is found, we consult it to see if the file should be processed.
@@ -207,7 +206,7 @@ private func inputShouldBeProcessed(at url: URL) -> Bool {
207206
guard fileType(at: url) != .typeDirectory else {
208207
return true
209208
}
210-
209+
211210
let ignoreFile = try? IgnoreFile(for: url)
212211
return ignoreFile?.shouldProcess(url) ?? true
213212
}

0 commit comments

Comments
 (0)