Skip to content

Commit

Permalink
use Sourcery to generate MasterRuleList.swift
Browse files Browse the repository at this point in the history
  • Loading branch information
jpsim committed Jun 2, 2017
1 parent 25a92c4 commit 9a81734
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 77 deletions.
11 changes: 11 additions & 0 deletions .sourcery/MasterRuleList.stencil
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// MasterRuleList.swift
// SwiftLint
//
// Created by Scott Hoyt on 12/28/15.
// Copyright © 2015 Realm. All rights reserved.
//

public let masterRuleList = RuleList(rules:
{% for rule in types.structs where rule.name|hasSuffix:"Rule" or rule.name|hasSuffix:"Rules" %} {{ rule.name }}.self{% if not forloop.last %},{% endif %}
{% endfor %})
13 changes: 7 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ don't forget to checkout the submodules as well when cloning, by running

See more info [in the README](https://github.com/realm/SwiftLint#installation).

### Code Generation

If XCTest cases or functions are added/removed/renamed, or if rules are
added/removed/renamed, you'll need to run `make sourcery`, which requires that
[Sourcery](https://github.com/krzysztofzablocki/Sourcery) be installed on your
machine. This will update source files to reflect these changes.

### Tests

SwiftLint supports building via Xcode and Swift Package Manager on macOS, and
Expand All @@ -28,17 +35,11 @@ $ swift test
$ make docker_test
```

If XCTest cases or functions are added/removed/renamed, you'll need to run
`make update_linux_tests`, which requires that
[Sourcery](https://github.com/krzysztofzablocki/Sourcery) be installed on your
machine.

## Rules

New rules should be added in the `Source/SwiftLintFramework/Rules` directory.

Rules should conform to either the `Rule` or `ASTRule` protocols.
To activate a rule, add the rule to `masterRuleList` in `MasterRuleList.swift`.

All new rules or changes to existing rules should be accompanied by unit tests.

Expand Down
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ VERSION_STRING=$(shell /usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionSt
all: bootstrap
$(BUILD_TOOL) $(XCODEFLAGS) build

update_linux_tests:
sourcery --sources Tests --templates .sourcery --output .sourcery
sourcery:
sourcery --sources Tests --templates .sourcery/LinuxMain.stencil --output .sourcery
tail -n +4 .sourcery/LinuxMain.generated.swift > Tests/LinuxMain.swift
rm .sourcery/LinuxMain.generated.swift
sourcery --sources Source/SwiftLintFramework/Rules --templates .sourcery/MasterRuleList.stencil --output .sourcery
tail -n +4 .sourcery/MasterRuleList.generated.swift > Source/SwiftLintFramework/Models/MasterRuleList.swift
rm .sourcery/MasterRuleList.generated.swift

bootstrap:
script/bootstrap
Expand Down
71 changes: 2 additions & 69 deletions Source/SwiftLintFramework/Models/MasterRuleList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,73 +6,6 @@
// Copyright © 2015 Realm. All rights reserved.
//

import Foundation

public enum RuleListError: Error {
case duplicatedConfigurations(rule: Rule.Type)
}

public struct RuleList {
public let list: [String: Rule.Type]
private let aliases: [String: String]

public init(rules: Rule.Type...) {
self.init(rules: rules)
}

public init(rules: [Rule.Type]) {
var tmpList = [String: Rule.Type]()
var tmpAliases = [String: String]()

for rule in rules {
let identifier = rule.description.identifier
tmpList[identifier] = rule
for alias in rule.description.deprecatedAliases {
tmpAliases[alias] = identifier
}
tmpAliases[identifier] = identifier
}
list = tmpList
aliases = tmpAliases
}

internal func configuredRules(with dictionary: [String: Any]) throws -> [Rule] {
var rules = [String: Rule]()

for (key, configuration) in dictionary {
guard let identifier = identifier(for: key), let ruleType = list[identifier] else {
continue
}
guard rules[identifier] == nil else {
throw RuleListError.duplicatedConfigurations(rule: ruleType)
}
do {
let configuredRule = try ruleType.init(configuration: configuration)
rules[identifier] = configuredRule
} catch {
queuedPrintError("Invalid configuration for '\(identifier)'. Falling back to default.")
rules[identifier] = ruleType.init()
}
}

for (identifier, ruleType) in list where rules[identifier] == nil {
rules[identifier] = ruleType.init()
}

return Array(rules.values)
}

internal func identifier(for alias: String) -> String? {
return aliases[alias]
}

internal func allValidIdentifiers() -> [String] {
return list.flatMap { (_, rule) -> [String] in
rule.description.allIdentifiers
}
}
}

public let masterRuleList = RuleList(rules:
AttributesRule.self,
ClassDelegateProtocolRule.self,
Expand Down Expand Up @@ -101,17 +34,17 @@ public let masterRuleList = RuleList(rules:
FileHeaderRule.self,
FileLengthRule.self,
FirstWhereRule.self,
ForWhereRule.self,
ForceCastRule.self,
ForceTryRule.self,
ForceUnwrappingRule.self,
ForWhereRule.self,
FunctionBodyLengthRule.self,
FunctionParameterCountRule.self,
GenericTypeNameRule.self,
IdentifierNameRule.self,
ImplicitGetterRule.self,
ImplicitlyUnwrappedOptionalRule.self,
ImplicitReturnRule.self,
ImplicitlyUnwrappedOptionalRule.self,
LargeTupleRule.self,
LeadingWhitespaceRule.self,
LegacyCGGeometryFunctionsRule.self,
Expand Down
74 changes: 74 additions & 0 deletions Source/SwiftLintFramework/Models/RuleList.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// RuleList.swift
// SwiftLint
//
// Created by JP Simard on 5/31/17.
// Copyright © 2017 Realm. All rights reserved.
//

import Foundation

public enum RuleListError: Error {
case duplicatedConfigurations(rule: Rule.Type)
}

public struct RuleList {
public let list: [String: Rule.Type]
private let aliases: [String: String]

public init(rules: Rule.Type...) {
self.init(rules: rules)
}

public init(rules: [Rule.Type]) {
var tmpList = [String: Rule.Type]()
var tmpAliases = [String: String]()

for rule in rules {
let identifier = rule.description.identifier
tmpList[identifier] = rule
for alias in rule.description.deprecatedAliases {
tmpAliases[alias] = identifier
}
tmpAliases[identifier] = identifier
}
list = tmpList
aliases = tmpAliases
}

internal func configuredRules(with dictionary: [String: Any]) throws -> [Rule] {
var rules = [String: Rule]()

for (key, configuration) in dictionary {
guard let identifier = identifier(for: key), let ruleType = list[identifier] else {
continue
}
guard rules[identifier] == nil else {
throw RuleListError.duplicatedConfigurations(rule: ruleType)
}
do {
let configuredRule = try ruleType.init(configuration: configuration)
rules[identifier] = configuredRule
} catch {
queuedPrintError("Invalid configuration for '\(identifier)'. Falling back to default.")
rules[identifier] = ruleType.init()
}
}

for (identifier, ruleType) in list where rules[identifier] == nil {
rules[identifier] = ruleType.init()
}

return Array(rules.values)
}

internal func identifier(for alias: String) -> String? {
return aliases[alias]
}

internal func allValidIdentifiers() -> [String] {
return list.flatMap { (_, rule) -> [String] in
rule.description.allIdentifiers
}
}
}
4 changes: 4 additions & 0 deletions SwiftLint.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@
E88DEA8C1B0999A000A66CB0 /* ASTRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA8B1B0999A000A66CB0 /* ASTRule.swift */; };
E8B067811C13E49600E9E13F /* Configuration+CommandLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B067801C13E49600E9E13F /* Configuration+CommandLine.swift */; };
E8B67C3E1C095E6300FDED8E /* Correction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B67C3D1C095E6300FDED8E /* Correction.swift */; };
E8BDE3FF1EDF91B6002EC12F /* RuleList.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8BDE3FE1EDF91B6002EC12F /* RuleList.swift */; };
E8BE1FCC1E07687400F781C7 /* Yams.framework in Embed Frameworks into SwiftLintFramework.framework */ = {isa = PBXBuildFile; fileRef = E8BE1FCB1E07687400F781C7 /* Yams.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
E8C0DFCD1AD349DB007EE3D4 /* SWXMLHash.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8C0DFCC1AD349DB007EE3D4 /* SWXMLHash.framework */; };
E8EA41171C2D1DBE004F9930 /* CheckstyleReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8EA41161C2D1DBE004F9930 /* CheckstyleReporter.swift */; };
Expand Down Expand Up @@ -530,6 +531,7 @@
E8BA7E101B07A3EC003E02D0 /* Commandant.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Commandant.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E8BA7E121B07A3F3003E02D0 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E8BB8F9B1B17DE3B00199606 /* RulesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RulesTests.swift; sourceTree = "<group>"; };
E8BDE3FE1EDF91B6002EC12F /* RuleList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuleList.swift; sourceTree = "<group>"; };
E8BE1FCB1E07687400F781C7 /* Yams.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Yams.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E8C0DFCC1AD349DB007EE3D4 /* SWXMLHash.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SWXMLHash.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E8EA41161C2D1DBE004F9930 /* CheckstyleReporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckstyleReporter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -981,6 +983,7 @@
3B12C9C41C322032000B423F /* MasterRuleList.swift */,
E80E018E1B92C1350078EB70 /* Region.swift */,
83D71E261B131EB5000395DE /* RuleDescription.swift */,
E8BDE3FE1EDF91B6002EC12F /* RuleList.swift */,
E88DEA781B098D4400A66CB0 /* RuleParameter.swift */,
E88DEA6A1B0983FE00A66CB0 /* StyleViolation.swift */,
D4A893341E15824100BF954D /* SwiftVersion.swift */,
Expand Down Expand Up @@ -1284,6 +1287,7 @@
1E18574B1EADBA51004F89F7 /* NoExtensionAccessModifier.swift in Sources */,
D42D2B381E09CC0D00CD7A2E /* FirstWhereRule.swift in Sources */,
D4B0226F1E0C75F9007E5297 /* VerticalParameterAlignmentRule.swift in Sources */,
E8BDE3FF1EDF91B6002EC12F /* RuleList.swift in Sources */,
D44254271DB9C15C00492EA4 /* SyntacticSugarRule.swift in Sources */,
006204DC1E1E492F00FFFBE1 /* VerticalWhitespaceConfiguration.swift in Sources */,
E88198441BEA93D200333A11 /* ColonRule.swift in Sources */,
Expand Down

0 comments on commit 9a81734

Please sign in to comment.