Compare commits

...

3 Commits

Author SHA1 Message Date
JP Simard 860814fe78
undo local development changes 2017-02-03 17:36:47 -08:00
JP Simard ee9ce4a3b6
move caches to ~/Library/Caches 2017-02-03 17:35:52 -08:00
JP Simard 327e98a86e
WIP: use modified time instead of file content hash for caching 2017-02-03 17:32:02 -08:00
5 changed files with 33 additions and 25 deletions

View File

@ -10,6 +10,7 @@ import Foundation
public protocol LintableFileManager {
func filesToLint(inPath: String, rootDirectory: String?) -> [String]
func modifiedDate(forFileAtPath: String) -> Date?
}
extension FileManager: LintableFileManager {
@ -31,4 +32,9 @@ extension FileManager: LintableFileManager {
return nil
} ?? []
}
public func modifiedDate(forFileAtPath path: String) -> Date? {
// swiftlint:disable:next force_cast
return try? attributesOfItem(atPath: path)[.modificationDate] as! Date
}
}

View File

@ -34,7 +34,7 @@ public struct Configuration: Equatable {
public let rules: [Rule]
public var rootPath: String? // the root path to search for nested configurations
public var configurationPath: String? // if successfully loaded from a path
public var hash: Int?
public var cacheDescription: String?
public let cachePath: String?
public init?(disabledRules: [String] = [],
@ -175,7 +175,7 @@ public struct Configuration: Equatable {
}
self.init(dict: dict, enableAllRules: enableAllRules)!
configurationPath = fullPath
hash = dict.description.hashValue
cacheDescription = dict.description
self.rootPath = rootPath
return
} catch YamlParserError.yamlParsing(let message) {

View File

@ -85,8 +85,7 @@ public struct Linter {
}
if let cache = cache, let path = file.path {
let hash = file.contents.hash
cache.cache(violations: violations, forFile: path, fileHash: hash)
cache.cache(violations: violations, forFile: path)
}
for (deprecatedIdentifier, identifier) in deprecatedToValidIdentifier {
@ -99,10 +98,7 @@ public struct Linter {
private func cachedStyleViolations(benchmark: Bool = false) -> ([StyleViolation], [(id: String, time: Double)])? {
let start: Date! = benchmark ? Date() : nil
guard let cache = cache,
let file = file.path,
case let hash = self.file.contents.hash,
let cachedViolations = cache.violations(forFile: file, hash: hash) else {
guard let cache = cache, let file = file.path, let cachedViolations = cache.violations(forFile: file) else {
return nil
}

View File

@ -19,24 +19,24 @@ public final class LinterCache {
private var cache: [String: Any]
private let lock = NSLock()
public init(currentVersion: Version = .current, configurationHash: Int? = nil) {
public init(currentVersion: Version = .current, configurationDescription: String? = nil) {
cache = [
"version": currentVersion.value,
"files": [:]
]
cache["configuration_hash"] = configurationHash
cache["configuration"] = configurationDescription
}
public init(cache: Any, currentVersion: Version = .current, configurationHash: Int? = nil) throws {
public init(cache: Any, currentVersion: Version = .current, configurationDescription: String? = nil) throws {
guard let dictionary = cache as? [String: Any] else {
throw LinterCacheError.invalidFormat
}
guard let version = dictionary["version"] as? String, version == currentVersion.value else {
guard dictionary["version"] as? String == currentVersion.value else {
throw LinterCacheError.differentVersion
}
if dictionary["configuration_hash"] as? Int != configurationHash {
guard dictionary["configuration"] as? String == configurationDescription else {
throw LinterCacheError.differentConfiguration
}
@ -44,31 +44,37 @@ public final class LinterCache {
}
public convenience init(contentsOf url: URL, currentVersion: Version = .current,
configurationHash: Int? = nil) throws {
configurationDescription: String? = nil) throws {
let data = try Data(contentsOf: url)
let json = try JSONSerialization.jsonObject(with: data, options: [])
try self.init(cache: json, currentVersion: currentVersion,
configurationHash: configurationHash)
configurationDescription: configurationDescription)
}
public func cache(violations: [StyleViolation], forFile file: String, fileHash: Int) {
public func cache(violations: [StyleViolation], forFile file: String) {
guard let lastModified = FileManager.default.modifiedDate(forFileAtPath: file) else {
return
}
lock.lock()
var filesCache = (cache["files"] as? [String: Any]) ?? [:]
filesCache[file] = [
"violations": violations.map(dictionary(for:)),
"hash": fileHash
"last_modified": Int(lastModified.timeIntervalSinceReferenceDate)
]
cache["files"] = filesCache
lock.unlock()
}
public func violations(forFile file: String, hash: Int) -> [StyleViolation]? {
public func violations(forFile file: String) -> [StyleViolation]? {
guard let lastModified = FileManager.default.modifiedDate(forFileAtPath: file) else {
return nil
}
lock.lock()
guard let filesCache = cache["files"] as? [String: Any],
let entry = filesCache[file] as? [String: Any],
let cacheHash = entry["hash"] as? Int,
cacheHash == hash,
let cacheLastModified = entry["last_modified"] as? Int,
cacheLastModified == Int(lastModified.timeIntervalSinceReferenceDate),
let violations = entry["violations"] as? [[String: Any]] else {
lock.unlock()
return nil

View File

@ -16,12 +16,12 @@ extension LinterCache {
return nil
}
let configurationHash = configuration.hash
let configurationDescription = configuration.cacheDescription
let cache: LinterCache
do {
cache = try LinterCache(contentsOf: url, configurationHash: configurationHash)
cache = try LinterCache(contentsOf: url, configurationDescription: configurationDescription)
} catch {
cache = LinterCache(configurationHash: configurationHash)
cache = LinterCache(configurationDescription: configurationDescription)
}
return cache
@ -50,7 +50,7 @@ private func defaultCacheURL(options: LintOptions) -> URL {
#if os(Linux)
let baseURL = URL(fileURLWithPath: "/var/tmp/")
#else
let baseURL = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
let baseURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
#endif
let fileName = String(rootPath.hash) + ".json"