mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
Fix an issue where logs would be printed asynchronously. Fixes #200.
This commit is contained in:
@@ -48,6 +48,10 @@
|
||||
[Mickael Morier](https://github.com/mmorier)
|
||||
[#135](https://github.com/realm/SwiftLint/issues/135)
|
||||
|
||||
* Fix an issue where logs would be printed asynchronously over each other.
|
||||
[JP Simard](https://github.com/jpsim)
|
||||
[#200](https://github.com/realm/SwiftLint/issues/200)
|
||||
|
||||
|
||||
## 0.3.0: Wrinkly Rules
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// QueuedPrint.swift
|
||||
// SwiftLint
|
||||
//
|
||||
// Created by JP Simard on 2015-11-17.
|
||||
// Copyright © 2015 Realm. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
private let outputQueue: dispatch_queue_t = {
|
||||
let queue = dispatch_queue_create("io.realm.swiftlint.outputQueue", DISPATCH_QUEUE_SERIAL)
|
||||
dispatch_set_target_queue(queue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0))
|
||||
|
||||
atexit_b {
|
||||
dispatch_barrier_sync(queue) {}
|
||||
}
|
||||
|
||||
return queue
|
||||
}()
|
||||
|
||||
/// A thread-safe version of Swift's standard print().
|
||||
public func queuedPrint<T>(object: T) {
|
||||
dispatch_async(outputQueue) {
|
||||
print(object, terminator: "")
|
||||
}
|
||||
}
|
||||
|
||||
/// A thread-safe, newline-terminated version of fputs(..., stderr).
|
||||
public func queuedPrintError(string: String) {
|
||||
dispatch_async(outputQueue) {
|
||||
fputs(string + "\n", stderr)
|
||||
}
|
||||
}
|
||||
@@ -57,10 +57,10 @@ public struct Configuration {
|
||||
let invalidRules = disabledRules.filter({ !validRuleIdentifiers.contains($0) })
|
||||
if !invalidRules.isEmpty {
|
||||
for invalidRule in invalidRules {
|
||||
fputs("config error: '\(invalidRule)' is not a valid rule identifier\n", stderr)
|
||||
queuedPrintError("config error: '\(invalidRule)' is not a valid rule identifier")
|
||||
}
|
||||
let listOfValidRuleIdentifiers = validRuleIdentifiers.joinWithSeparator("\n")
|
||||
fputs("Valid rule identifiers:\n\(listOfValidRuleIdentifiers)\n", stderr)
|
||||
queuedPrintError("Valid rule identifiers:\n\(listOfValidRuleIdentifiers)")
|
||||
}
|
||||
|
||||
// Validate that rule identifiers aren't listed multiple times
|
||||
@@ -71,10 +71,9 @@ public struct Configuration {
|
||||
accu[element] = accu[element]?.successor() ?? 1
|
||||
return accu
|
||||
}.filter { $0.1 > 1 }
|
||||
for duplicateRule in duplicateRules {
|
||||
fputs("config error: '\(duplicateRule.0)' is listed \(duplicateRule.1) times\n",
|
||||
stderr)
|
||||
}
|
||||
queuedPrintError(duplicateRules.map { rule in
|
||||
"config error: '\(rule.0)' is listed \(rule.1) times"
|
||||
}.joinWithSeparator("\n"))
|
||||
return nil
|
||||
}
|
||||
self.disabledRules = validDisabledRules
|
||||
@@ -111,7 +110,7 @@ public struct Configuration {
|
||||
let yamlContents = try NSString(contentsOfFile: fullPath,
|
||||
encoding: NSUTF8StringEncoding) as String
|
||||
if let _ = Configuration(yaml: yamlContents) {
|
||||
fputs("Loading configuration from '\(path)'\n", stderr)
|
||||
queuedPrintError("Loading configuration from '\(path)'")
|
||||
self.init(yaml: yamlContents)!
|
||||
return
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ struct LintCommand: CommandType {
|
||||
.filter({ !configuration.excluded.flatMap(filesToLintAtPath).contains($0) }) +
|
||||
configuration.included.flatMap(filesToLintAtPath)
|
||||
if path.isEmpty {
|
||||
fputs("Linting Swift files in current working directory\n", stderr)
|
||||
queuedPrintError("Linting Swift files in current working directory")
|
||||
} else {
|
||||
fputs("Linting Swift files at path \(path)\n", stderr)
|
||||
queuedPrintError("Linting Swift files at path \(path)")
|
||||
}
|
||||
let files = filesToLint.flatMap(File.init)
|
||||
if !files.isEmpty {
|
||||
@@ -70,7 +70,7 @@ struct LintCommand: CommandType {
|
||||
for (index, file) in files.enumerate() {
|
||||
if let path = file.path {
|
||||
let filename = (path as NSString).lastPathComponent
|
||||
fputs("Linting '\(filename)' (\(index + 1)/\(files.count))\n", stderr)
|
||||
queuedPrintError("Linting '\(filename)' (\(index + 1)/\(files.count))")
|
||||
}
|
||||
let linter = Linter(file: file, configuration: configuration)
|
||||
let currentViolations = linter.styleViolations
|
||||
@@ -79,22 +79,21 @@ struct LintCommand: CommandType {
|
||||
if reporter.isRealtime {
|
||||
let report = reporter.generateReport(currentViolations)
|
||||
if !report.isEmpty {
|
||||
print(report)
|
||||
queuedPrint(report)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !reporter.isRealtime {
|
||||
print(reporter.generateReport(violations))
|
||||
queuedPrint(reporter.generateReport(violations))
|
||||
}
|
||||
let numberOfSeriousViolations = violations.filter({ $0.severity == .Error }).count
|
||||
let violationSuffix = (violations.count != 1 ? "s" : "")
|
||||
let filesSuffix = (files.count != 1 ? "s." : ".")
|
||||
fputs(
|
||||
queuedPrintError(
|
||||
"Done linting!" +
|
||||
" Found \(violations.count) violation\(violationSuffix)," +
|
||||
" \(numberOfSeriousViolations) serious" +
|
||||
" in \(files.count) file\(filesSuffix)\n",
|
||||
stderr
|
||||
" in \(files.count) file\(filesSuffix)"
|
||||
)
|
||||
if strict && !violations.isEmpty {
|
||||
return .Failure(CommandantError<()>.CommandError())
|
||||
@@ -152,7 +151,7 @@ struct LintCommand: CommandType {
|
||||
case let .Success(path):
|
||||
return path
|
||||
case let .Failure(error):
|
||||
fputs("\(error)\n", stderr)
|
||||
queuedPrintError(String(error))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import Commandant
|
||||
import SwiftLintFramework
|
||||
|
||||
let registry = CommandRegistry<()>()
|
||||
registry.register(LintCommand())
|
||||
@@ -15,5 +16,5 @@ registry.register(HelpCommand(registry: registry))
|
||||
registry.register(RulesCommand())
|
||||
|
||||
registry.main(defaultVerb: LintCommand().verb) { error in
|
||||
fputs("\(error)\n", stderr)
|
||||
queuedPrintError(String(error))
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
E812249C1B04FADC001783D2 /* Linter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E812249B1B04FADC001783D2 /* Linter.swift */; };
|
||||
E816194C1BFBF35D00946723 /* SwiftDeclarationKind+SwiftLint.swift in Sources */ = {isa = PBXBuildFile; fileRef = E816194B1BFBF35D00946723 /* SwiftDeclarationKind+SwiftLint.swift */; };
|
||||
E816194E1BFBFEAB00946723 /* ForceTryRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E816194D1BFBFEAB00946723 /* ForceTryRule.swift */; };
|
||||
E81619531BFC162C00946723 /* QueuedPrint.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81619521BFC162C00946723 /* QueuedPrint.swift */; };
|
||||
E832F10B1B17E2F5003F265F /* NSFileManager+SwiftLint.swift in Sources */ = {isa = PBXBuildFile; fileRef = E832F10A1B17E2F5003F265F /* NSFileManager+SwiftLint.swift */; };
|
||||
E832F10D1B17E725003F265F /* IntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E832F10C1B17E725003F265F /* IntegrationTests.swift */; };
|
||||
E83A0B351A5D382B0041A60A /* VersionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = E83A0B341A5D382B0041A60A /* VersionCommand.swift */; };
|
||||
@@ -173,6 +174,7 @@
|
||||
E812249B1B04FADC001783D2 /* Linter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Linter.swift; sourceTree = "<group>"; };
|
||||
E816194B1BFBF35D00946723 /* SwiftDeclarationKind+SwiftLint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftDeclarationKind+SwiftLint.swift"; sourceTree = "<group>"; };
|
||||
E816194D1BFBFEAB00946723 /* ForceTryRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForceTryRule.swift; sourceTree = "<group>"; };
|
||||
E81619521BFC162C00946723 /* QueuedPrint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueuedPrint.swift; sourceTree = "<group>"; };
|
||||
E832F10A1B17E2F5003F265F /* NSFileManager+SwiftLint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFileManager+SwiftLint.swift"; sourceTree = "<group>"; };
|
||||
E832F10C1B17E725003F265F /* IntegrationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntegrationTests.swift; sourceTree = "<group>"; };
|
||||
E83A0B341A5D382B0041A60A /* VersionCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionCommand.swift; sourceTree = "<group>"; };
|
||||
@@ -487,6 +489,7 @@
|
||||
24E17F701B1481FF008195BE /* File+Cache.swift */,
|
||||
E88DEA741B09852000A66CB0 /* File+SwiftLint.swift */,
|
||||
E832F10A1B17E2F5003F265F /* NSFileManager+SwiftLint.swift */,
|
||||
E81619521BFC162C00946723 /* QueuedPrint.swift */,
|
||||
E88DEA721B0984C400A66CB0 /* String+SwiftLint.swift */,
|
||||
E816194B1BFBF35D00946723 /* SwiftDeclarationKind+SwiftLint.swift */,
|
||||
E87E4A081BFB9CAE00FCFE46 /* SyntaxKind+SwiftLint.swift */,
|
||||
@@ -688,6 +691,7 @@
|
||||
E88DEA6F1B09843F00A66CB0 /* Location.swift in Sources */,
|
||||
E88DEA771B098D0C00A66CB0 /* Rule.swift in Sources */,
|
||||
CAF900141BED8B17006A371D /* VariableNameMaxLengthRule.swift in Sources */,
|
||||
E81619531BFC162C00946723 /* QueuedPrint.swift in Sources */,
|
||||
E87E4A051BFB927C00FCFE46 /* TrailingSemicolonRule.swift in Sources */,
|
||||
E88198421BEA929F00333A11 /* NestingRule.swift in Sources */,
|
||||
E881985B1BEA974E00333A11 /* StatementPositionRule.swift in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user