-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathPartialRule.swift
More file actions
95 lines (76 loc) · 3.21 KB
/
PartialRule.swift
File metadata and controls
95 lines (76 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//
// PartialRule.swift
// StringsLintFramework
//
// Created by Alessandro "Sandro" Calzavara on 11/09/2018.
//
import Foundation
public class PartialRule: LintRule {
public static var description = RuleDescription(
identifier: "partial",
name: "Partial",
description: "String has not been localized on all supported locales"
)
private let parser: LocalizableParser
var severity: ViolationSeverity
private var locales = [Locale]()
private var declaredStrings = [Locale: [LocalizedString]]()
public required convenience init() {
let config = PartialRuleConfiguration()
self.init(parser: ComposedParser(parsers: [ StringsParser(), StringsdictParser() ]),
severity: config.severity)
}
public required convenience init(configuration: Any) throws {
var config = PartialRuleConfiguration()
do {
try config.apply(defaultDictionaryValue(configuration, for: PartialRule.self.description.identifier))
} catch {}
self.init(parser: ComposedParser(parsers: [
try StringsParser.self.init(configuration: configuration),
try StringsdictParser.self.init(configuration: configuration)
]), severity: config.severity)
}
public init(parser: LocalizableParser, severity: ViolationSeverity) {
self.parser = parser
self.severity = severity
}
public func processFile(_ file: File) {
guard self.parser.support(file: file) else {
return
}
let locale = Locale(url: file.url)
if !self.locales.contains(locale) {
self.locales.append(locale)
}
let strings = self.processDeclarationFile(file)
if let knownStrings = self.declaredStrings[locale] {
self.declaredStrings[locale] = (knownStrings + strings)
} else {
self.declaredStrings[locale] = strings
}
}
public var violations: [Violation] {
var violations = [Violation]()
for baseLocale in self.locales {
let baseStrings = self.declaredStrings[baseLocale] ?? []
for otherLocale in self.locales where baseLocale != otherLocale {
let otherStrings = self.declaredStrings[otherLocale] ?? []
violations += baseStrings.difference(from: otherStrings).compactMap({ (string) -> Violation? in
return self.buildViolation(key: string.key, location: string.location, locale: otherLocale)
})
}
}
return violations
}
private func processDeclarationFile(_ file: File) -> [LocalizedString] {
do {
return try self.parser.parse(file: file)
} catch let error {
print("Unable to parse file \(file): \(error)")
return []
}
}
private func buildViolation(key: String, location: Location, locale: Locale) -> Violation {
return Violation(ruleDescription: PartialRule.description, severity: self.severity, location: location, reason: "Localized string \"\(key)\" is missing in locale \"\(locale)\"")
}
}