mirror of
https://github.com/nicklockwood/SwiftFormat.git
synced 2026-06-16 10:34:34 +00:00
More error reporting improvements
This commit is contained in:
+30
-20
@@ -92,14 +92,15 @@ extension FileHandle: TextOutputStream {
|
||||
}
|
||||
}
|
||||
|
||||
func printErrors(_ errors: [FormatError]) {
|
||||
func printWarnings(_ errors: [Error]) {
|
||||
var stderr = FileHandle.standardError
|
||||
for error in errors {
|
||||
print("error: \(error)", to: &stderr)
|
||||
print("warning: \(error)", to: &stderr)
|
||||
}
|
||||
}
|
||||
|
||||
func processArguments(_ args: [String]) {
|
||||
var errors = [Error]()
|
||||
do {
|
||||
// Get options
|
||||
let args = try preprocessArguments(args, commandLineArguments)
|
||||
@@ -149,15 +150,18 @@ func processArguments(_ args: [String]) {
|
||||
let time = timeEvent {
|
||||
(filesParsed, filesChecked, options, errors) = inferOptions(from: inferURL)
|
||||
}
|
||||
printErrors(errors)
|
||||
printWarnings(errors)
|
||||
if filesParsed == 0 {
|
||||
throw FormatError.parsing("failed to to infer options")
|
||||
}
|
||||
print("options inferred from \(filesParsed)/\(filesChecked) files in \(time)")
|
||||
print("")
|
||||
print(commandLineArguments(for: options).map({ "--\($0) \($1)" }).joined(separator: " "))
|
||||
print("")
|
||||
return
|
||||
} else {
|
||||
throw FormatError.options("--inferoptions argument was not a valid path")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Get input path(s)
|
||||
@@ -174,7 +178,6 @@ func processArguments(_ args: [String]) {
|
||||
|
||||
// Get cache path
|
||||
var cacheURL: URL?
|
||||
var errors = [FormatError]()
|
||||
let defaultCacheFileName = "swiftformat.cache"
|
||||
let manager = FileManager.default
|
||||
func setDefaultCacheURL() {
|
||||
@@ -185,7 +188,7 @@ func processArguments(_ args: [String]) {
|
||||
try manager.createDirectory(at: cacheDirectory, withIntermediateDirectories: true, attributes: nil)
|
||||
cacheURL = cacheDirectory.appendingPathComponent(defaultCacheFileName)
|
||||
} catch {
|
||||
errors.append(FormatError.writing("failed to create cache directory at: \(cacheDirectory.path)"))
|
||||
errors.append(FormatError.writing("failed to create cache directory at \(cacheDirectory.path)"))
|
||||
}
|
||||
} else {
|
||||
errors.append(FormatError.reading("failed to find cache directory at ~/Library/Caches"))
|
||||
@@ -194,7 +197,7 @@ func processArguments(_ args: [String]) {
|
||||
if let cache = args["cache"] {
|
||||
switch cache {
|
||||
case "":
|
||||
throw FormatError.options("--cache option expects a value.")
|
||||
throw FormatError.options("--cache option expects a value")
|
||||
case "ignore":
|
||||
break
|
||||
case "clear":
|
||||
@@ -203,13 +206,13 @@ func processArguments(_ args: [String]) {
|
||||
do {
|
||||
try manager.removeItem(at: cacheURL)
|
||||
} catch {
|
||||
errors.append(FormatError.writing("failed to delete cache file at: \(cacheURL.path)"))
|
||||
errors.append(FormatError.writing("failed to delete cache file at \(cacheURL.path)"))
|
||||
}
|
||||
}
|
||||
default:
|
||||
cacheURL = expandPath(cache)
|
||||
guard cacheURL != nil else {
|
||||
throw FormatError.options("unsupported --cache value: \(cache).")
|
||||
throw FormatError.options("unsupported --cache value `\(cache)`")
|
||||
}
|
||||
var isDirectory: ObjCBool = false
|
||||
if manager.fileExists(atPath: cacheURL!.path, isDirectory: &isDirectory) && isDirectory.boolValue {
|
||||
@@ -224,6 +227,7 @@ func processArguments(_ args: [String]) {
|
||||
if inputURLs.count == 0 {
|
||||
var input: String?
|
||||
var finished = false
|
||||
var fatalError: Error?
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
while let line = readLine(strippingNewline: false) {
|
||||
input = (input ?? "") + line
|
||||
@@ -236,16 +240,14 @@ func processArguments(_ args: [String]) {
|
||||
try output.write(to: outputURL, atomically: true, encoding: String.Encoding.utf8)
|
||||
print("swiftformat completed successfully")
|
||||
} catch {
|
||||
throw FormatError.writing("failed to write file: \(outputURL.path)")
|
||||
throw FormatError.writing("failed to write file \(outputURL.path)")
|
||||
}
|
||||
} else {
|
||||
// Write to stdout
|
||||
print(output)
|
||||
}
|
||||
} catch let error as FormatError {
|
||||
errors.append(error)
|
||||
} catch {
|
||||
errors.append(FormatError.writing("unknown error: \(error)"))
|
||||
fatalError = error
|
||||
}
|
||||
}
|
||||
finished = true
|
||||
@@ -255,8 +257,11 @@ func processArguments(_ args: [String]) {
|
||||
while start.timeIntervalSinceNow > -0.01 {}
|
||||
// If no input received by now, assume none is coming
|
||||
if input != nil {
|
||||
while !finished && start.timeIntervalSinceNow > -30 {}
|
||||
printErrors(errors)
|
||||
while !finished && start.timeIntervalSinceNow > -30 {
|
||||
if let fatalError = fatalError {
|
||||
throw fatalError
|
||||
}
|
||||
}
|
||||
} else {
|
||||
showHelp()
|
||||
}
|
||||
@@ -277,15 +282,20 @@ func processArguments(_ args: [String]) {
|
||||
fileOptions: fileOptions,
|
||||
cacheURL: cacheURL
|
||||
)
|
||||
errors += _errors
|
||||
errors += _errors as [Error]
|
||||
}
|
||||
printWarnings(errors)
|
||||
if filesChecked == 0 {
|
||||
let inputPaths = inputURLs.map({ $0.path }).joined(separator: ", ")
|
||||
throw FormatError.options("no eligible files found at \(inputPaths)")
|
||||
}
|
||||
printErrors(errors)
|
||||
print("swiftformat completed. \(filesWritten)/\(filesChecked) files updated in \(time)")
|
||||
|
||||
} catch let error as FormatError {
|
||||
printErrors([error])
|
||||
} catch {
|
||||
printErrors([FormatError.options("unknown error: \(error)")])
|
||||
printWarnings(errors)
|
||||
// Fatal error
|
||||
var stderr = FileHandle.standardError
|
||||
print("error: \(error)", to: &stderr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -91,9 +91,9 @@ public func enumerateSwiftFiles(withInputURL inputURL: URL,
|
||||
|
||||
guard let resourceValues = try? inputURL.resourceValues(forKeys: Set(keys)) else {
|
||||
if manager.fileExists(atPath: inputURL.path) {
|
||||
onComplete { throw FormatError.reading("failed to read attributes for: \(inputURL.path)") }
|
||||
onComplete { throw FormatError.reading("failed to read attributes for \(inputURL.path)") }
|
||||
} else {
|
||||
onComplete { throw FormatError.reading("file not found: \(inputURL.path)") }
|
||||
onComplete { throw FormatError.reading("file not found at \(inputURL.path)") }
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -104,7 +104,7 @@ public func enumerateSwiftFiles(withInputURL inputURL: URL,
|
||||
} else if resourceValues.isDirectory == true {
|
||||
guard let files = try? manager.contentsOfDirectory(
|
||||
at: inputURL, includingPropertiesForKeys: keys, options: .skipsHiddenFiles) else {
|
||||
onComplete { throw FormatError.reading("failed to read contents of directory at: \(inputURL.path)") }
|
||||
onComplete { throw FormatError.reading("failed to read contents of directory at \(inputURL.path)") }
|
||||
return
|
||||
}
|
||||
for url in files {
|
||||
@@ -200,14 +200,14 @@ func inferOptions(from inputURL: URL) -> (Int, Int, FormatOptions, [FormatError]
|
||||
guard let input = try? String(contentsOf: inputURL) else {
|
||||
return {
|
||||
filesChecked += 1
|
||||
errors.append(FormatError.reading("failed to read file: \(inputURL.path)"))
|
||||
errors.append(FormatError.reading("failed to read file \(inputURL.path)"))
|
||||
}
|
||||
}
|
||||
let _tokens = tokenize(input)
|
||||
if let error = parsingError(for: _tokens), case .parsing(let string) = error {
|
||||
return {
|
||||
filesChecked += 1
|
||||
errors.append(FormatError.parsing("\(string) in file: \(inputURL.path)"))
|
||||
errors.append(FormatError.parsing("\(string) in \(inputURL.path)"))
|
||||
}
|
||||
}
|
||||
return {
|
||||
@@ -239,7 +239,11 @@ func processInput(_ inputURLs: [URL],
|
||||
for inputURL in inputURLs {
|
||||
guard let resourceValues = try? inputURL.resourceValues(
|
||||
forKeys: Set([.isDirectoryKey, .isAliasFileKey, .isSymbolicLinkKey])) else {
|
||||
errors.append(FormatError.reading("failed to read attributes for: \(inputURL.path)"))
|
||||
if FileManager.default.fileExists(atPath: inputURL.path) {
|
||||
errors.append(FormatError.reading("failed to read attributes for \(inputURL.path)"))
|
||||
} else {
|
||||
errors.append(FormatError.reading("file not found at \(inputURL.path)"))
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !fileOptions.followSymlinks &&
|
||||
@@ -256,7 +260,7 @@ func processInput(_ inputURLs: [URL],
|
||||
guard let input = try? String(contentsOf: inputURL) else {
|
||||
return {
|
||||
filesChecked += 1 // TODO: should this count?
|
||||
throw FormatError.reading("failed to read file: \(inputURL.path)")
|
||||
throw FormatError.reading("failed to read file \(inputURL.path)")
|
||||
}
|
||||
}
|
||||
let cacheKey: String = {
|
||||
@@ -282,7 +286,7 @@ func processInput(_ inputURLs: [URL],
|
||||
} catch {
|
||||
return {
|
||||
filesChecked += 1
|
||||
throw FormatError.writing("failed to create directory at: \(outputURL.path), \(error)")
|
||||
throw FormatError.writing("failed to create directory at \(outputURL.path), \(error)")
|
||||
}
|
||||
}
|
||||
} else if output == input {
|
||||
@@ -302,13 +306,13 @@ func processInput(_ inputURLs: [URL],
|
||||
} catch {
|
||||
return {
|
||||
filesChecked += 1
|
||||
throw FormatError.writing("failed to write file: \(outputURL.path), \(error)")
|
||||
throw FormatError.writing("failed to write file \(outputURL.path), \(error)")
|
||||
}
|
||||
}
|
||||
} catch FormatError.parsing(let string) {
|
||||
return {
|
||||
filesChecked += 1
|
||||
throw FormatError.parsing("\(string) in file: \(inputURL.path)")
|
||||
throw FormatError.parsing("\(string) in \(inputURL.path)")
|
||||
}
|
||||
} catch {
|
||||
return {
|
||||
@@ -318,15 +322,12 @@ func processInput(_ inputURLs: [URL],
|
||||
}
|
||||
}
|
||||
}
|
||||
if filesChecked == 0 {
|
||||
let inputPaths = inputURLs.map({ $0.path }).joined(separator: ", ")
|
||||
errors.append(FormatError.options("no eligible files found at: \(inputPaths)"))
|
||||
} else {
|
||||
if filesChecked > 0 {
|
||||
// Save cache
|
||||
if let cache = cache, let cacheURL = cacheURL, let cacheDirectory = cacheDirectory {
|
||||
if !(cache as NSDictionary).write(to: cacheURL, atomically: true) {
|
||||
if FileManager.default.fileExists(atPath: cacheDirectory.path) {
|
||||
errors.append(FormatError.writing("failed to write cache file at: \(cacheURL.path)"))
|
||||
errors.append(FormatError.writing("failed to write cache file at \(cacheURL.path)"))
|
||||
} else {
|
||||
errors.append(FormatError.reading("specified cache file directory does not exist: \(cacheDirectory.path)"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user