Skip to content

Commit

Permalink
Merge branch 'realm/master' into sh-recursive-configs
Browse files Browse the repository at this point in the history
* realm/master:
  use SourceKitten 0.7.3 release
  [README] `excluded` overrides `included`
  only generate violations once for triggering examples in verifyRule()
  Support command comment modifiers
  [CHANGELOG] Fix entry
  [CHANGELOG] add entry
  Fix realm#295
  Add failing test to ValidDocsRule.swift
  [CHANGELOG] Fix entry
  test violation locations
  [CHANGELOG] add entry
  Fix realm#294

# Conflicts:
#	CHANGELOG.md
#	README.md
  • Loading branch information
scottrhoyt committed Dec 31, 2015
2 parents 37b462d + 029a5eb commit 089d89e
Show file tree
Hide file tree
Showing 26 changed files with 244 additions and 142 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
[JP Simard](https://github.com/jpsim)
[#277](https://github.com/realm/SwiftLint/issues/277)

* Support command comment modifiers (`previous`, `this` & `next`) to limit the
command's scope to a single line.
[JP Simard](https://github.com/jpsim)
[#222](https://github.com/realm/SwiftLint/issues/222)

* Add nested `.swiftlint.yml` configuration support.
[Scott Hoyt](https://github.com/scottrhoyt)
[#299](https://github.com/realm/SwiftLint/issues/299)
Expand All @@ -23,6 +28,14 @@
[JP Simard](https://github.com/jpsim)
[#279](https://github.com/realm/SwiftLint/issues/279)

* Fix an `NSRangeException` crash.
[Norio Nomura](https://github.com/norio-nomura)
[#294](https://github.com/realm/SwiftLint/issues/294)

* The `valid_docs` rule now handles multibyte characters.
[Norio Nomura](https://github.com/norio-nomura)
[#295](https://github.com/realm/SwiftLint/issues/295)

## 0.5.3: Mountain Scent

##### Breaking
Expand Down
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "jpsim/SourceKitten" "master"
github "jpsim/SourceKitten" ~> 0.7
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ github "jpsim/SwiftXPC" "1.1.0"
github "behrang/YamlSwift" "1.2.4"
github "jspahrsummers/xcconfigs" "0.8.1"
github "Carthage/Commandant" "0.7.0"
github "jpsim/SourceKitten" "d6b832d4e60c2606bde979eb1137d44e28cbe08b"
github "jpsim/SourceKitten" "0.7.3"
38 changes: 24 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,13 @@ directory to see the currently implemented rules.

### Disable a rule in code

Rules can be disabled with a comment inside a source file with the following format:
Rules can be disabled with a comment inside a source file with the following
format:

`// swiftlint:disable <rule>`

The rule will be disabled until the end of the file or until the linter sees a matching enable comment:
The rule will be disabled until the end of the file or until the linter sees a
matching enable comment:

`// swiftlint:enable <rule>`

Expand All @@ -93,10 +95,26 @@ For example:
// swiftlint:disable colon
let noWarning :String = "" // No warning about colons immediately after variable names!
// swiftlint:enable colon
let yesWarning :String = "" // Warning generated about colons immediately after variable names
let hasWarning :String = "" // Warning generated about colons immediately after variable names
```

Run `swiftlint rules` to print a list of all available rules and their identifiers.
It's also possible to modify a disable or enable command by appending
`:previous`, `:this` or `:next` for only applying the command to the previous,
this (current) or next line respectively.

For example:

```swift
// swiftlint:disable:next force_cast
let noWarning = NSNumber() as! Int
let hasWarning = NSNumber() as! Int
let noWarning2 = NSNumber() as! Int // swiftlint:disable:this force_cast
let noWarning3 = NSNumber() as! Int
// swiftlint:disable:previous force_cast
```

Run `swiftlint rules` to print a list of all available rules and their
identifiers.

### Configuration

Expand All @@ -114,7 +132,7 @@ disabled_rules: # rule identifiers to exclude from running
# swiftlint rules
included: # paths to include during linting. `--path` is ignored if present.
- Source
excluded: # paths to ignore during linting.
excluded: # paths to ignore during linting. Takes precedence over `included`.
- Carthage
- Pods
- Source/ExcludedFolder
Expand All @@ -125,14 +143,6 @@ line_length: 110
type_body_length:
- 300 # warning
- 400 # error
# parameterized rules are first parameterized as a warning level, then error level.
variable_name_max_length:
- 40 # warning
- 60 # error
# parameterized rules are first parameterized as a warning level, then error level.
variable_name_min_length:
- 3 # warning
- 2 # error
reporter: "csv" # reporter type (xcode, json, csv, checkstyle)
```
Expand All @@ -141,7 +151,7 @@ reporter: "csv" # reporter type (xcode, json, csv, checkstyle)
SwiftLint supports nesting configuration files for more granular control over
the linting process.
* Set the `use_nested_configs: true` value in your root `.swiftlint.yml` file
* Set the `use_nested_configs: true` value in your root `.swiftlint.yml` file
* Include additional `.swiftlint.yml` files where necessary in your directory
structure.
* Each file will be linted using the configuration file that is in it's
Expand Down
22 changes: 13 additions & 9 deletions Source/SwiftLintFramework/Extensions/File+SwiftLint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@ import SourceKittenFramework
import SwiftXPC

internal func regex(pattern: String) -> NSRegularExpression {
// all patterns used for regular expressions in SwiftLint are string literals which have
// been confirmed to work, so it's ok to force-try here.
// swiftlint:disable force_try
// all patterns used for regular expressions in SwiftLint are string literals which have been
// confirmed to work, so it's ok to force-try here.

// swiftlint:disable:next force_try
return try! NSRegularExpression(pattern: pattern, options: [.AnchorsMatchLines])
// swiftlint:enable force_try
}

extension File {
public func regions() -> [Region] {
let contents = self.contents as NSString
let commands = matchPattern("swiftlint:(enable|disable)\\ [^\\s]+",
withSyntaxKinds: [.Comment]).flatMap { Command(string: contents, range: $0) }
let commands = matchPattern("swiftlint:(enable|disable)(:previous|:this|:next)?\\ [^\\s]+",
withSyntaxKinds: [.Comment]).flatMap { range in
return Command(string: contents, range: range)
}.flatMap { command in
return command.expand()
}
let totalNumberOfLines = lines.count
let numberOfCharactersInLastLine = lines.last?.content.characters.count
var regions = [Region]()
Expand Down Expand Up @@ -115,12 +119,12 @@ extension File {
}

public func write(string: String) {
guard let stringData = string.dataUsingEncoding(NSUTF8StringEncoding) else {
fatalError("can't encode '\(string)' with UTF8")
}
guard let path = path else {
fatalError("file needs a path to call write(_:)")
}
guard let stringData = string.dataUsingEncoding(NSUTF8StringEncoding) else {
fatalError("can't encode '\(string)' with UTF8")
}
stringData.writeToFile(path, atomically: true)
contents = string
lines = contents.lines()
Expand Down
64 changes: 60 additions & 4 deletions Source/SwiftLintFramework/Models/Command.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,91 @@ import Foundation
public enum CommandAction: String {
case Enable = "enable"
case Disable = "disable"

private func inverse() -> CommandAction {
switch self {
case .Enable: return .Disable
case .Disable: return .Enable
}
}
}

public enum CommandModifier: String {
case Previous = "previous"
case This = "this"
case Next = "next"
}

public struct Command {
let action: CommandAction
let ruleIdentifier: String
let line: Int
let character: Int
let modifier: CommandModifier?

public init(action: CommandAction, ruleIdentifier: String, line: Int, character: Int) {
public init(action: CommandAction, ruleIdentifier: String, line: Int = 0, character: Int = 0,
modifier: CommandModifier? = nil) {
self.action = action
self.ruleIdentifier = ruleIdentifier
self.line = line
self.character = character
self.modifier = modifier
}

public init?(string: NSString, range: NSRange) {
let scanner = NSScanner(string: string.substringWithRange(range))
scanner.scanString("swiftlint:", intoString: nil)
var optionalActionAndModifierNSString: NSString? = nil
scanner.scanUpToString(" ", intoString: &optionalActionAndModifierNSString)
guard let actionAndModifierString = optionalActionAndModifierNSString as String? else {
return nil
}
let actionAndModifierScanner = NSScanner(string: actionAndModifierString)
var actionNSString: NSString? = nil
scanner.scanUpToString(" ", intoString: &actionNSString)
actionAndModifierScanner.scanUpToString(":",
intoString: &actionNSString)
guard let actionString = actionNSString as String?,
action = CommandAction(rawValue: actionString),
lineAndCharacter = string.lineAndCharacterForCharacterOffset(NSMaxRange(range)) else {
return nil
}
self.action = action
let ruleStart = scanner.string.startIndex.advancedBy(scanner.scanLocation + 1)
ruleIdentifier = scanner.string.substringFromIndex(ruleStart)
ruleIdentifier = (scanner.string as NSString).substringFromIndex(scanner.scanLocation + 1)
line = lineAndCharacter.line
character = lineAndCharacter.character

let hasModifier = actionAndModifierScanner.scanString(":", intoString: nil)

// Modifier
if hasModifier {
let modifierString = (actionAndModifierScanner.string as NSString)
.substringFromIndex(actionAndModifierScanner.scanLocation)
modifier = CommandModifier(rawValue: modifierString)
} else {
modifier = nil
}
}

internal func expand() -> [Command] {
guard let modifier = modifier else {
return [self]
}
switch modifier {
case .Previous:
return [
Command(action: action, ruleIdentifier: ruleIdentifier, line: line - 1),
Command(action: action.inverse(), ruleIdentifier: ruleIdentifier, line: line)
]
case .This:
return [
Command(action: action, ruleIdentifier: ruleIdentifier, line: line),
Command(action: action.inverse(), ruleIdentifier: ruleIdentifier, line: line + 1)
]
case .Next:
return [
Command(action: action, ruleIdentifier: ruleIdentifier, line: line + 1),
Command(action: action.inverse(), ruleIdentifier: ruleIdentifier, line: line + 2)
]
}
}
}
2 changes: 1 addition & 1 deletion Source/SwiftLintFramework/Rules/ClosingBraceRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public struct ClosingBraceRule: CorrectableRule {
"[].map({ })"
],
triggeringExamples: [
"[].map({ } )"
"[].map({ } )"
],
corrections: [
"[].map({ } )\n": "[].map({ })\n"
Expand Down
44 changes: 22 additions & 22 deletions Source/SwiftLintFramework/Rules/ColonRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,28 @@ public struct ColonRule: CorrectableRule {
"// 周斌佳年周斌佳\nlet abc: String = \"abc:\""
],
triggeringExamples: [
"let abc:Void\n",
"let abc: Void\n",
"let abc :Void\n",
"let abc : Void\n",
"let abc : [Void: Void]\n",
"let abc : (Void, String, Int)\n",
"let abc : ([Void], String, Int)\n",
"let abc : [([Void], String, Int)]\n",
"let abc: (Void, String, Int)\n",
"let abc: ([Void], String, Int)\n",
"let abc: [([Void], String, Int)]\n",
"let abc :String=\"def\"\n",
"let abc :Int=0\n",
"let abc :Int = 0\n",
"let abc:Int=0\n",
"let abc:Int = 0\n",
"let abc:Enum=Enum.Value\n",
"func abc(def:Void) {}\n",
"func abc(def: Void) {}\n",
"func abc(def :Void) {}\n",
"func abc(def : Void) {}\n",
"func abc(def: Void, ghi :Void) {}\n"
"let abc:Void\n",
"let abc: Void\n",
"let abc :Void\n",
"let abc : Void\n",
"let abc : [Void: Void]\n",
"let abc : (Void, String, Int)\n",
"let abc : ([Void], String, Int)\n",
"let abc : [([Void], String, Int)]\n",
"let abc: (Void, String, Int)\n",
"let abc: ([Void], String, Int)\n",
"let abc: [([Void], String, Int)]\n",
"let abc :String=\"def\"\n",
"let abc :Int=0\n",
"let abc :Int = 0\n",
"let abc:Int=0\n",
"let abc:Int = 0\n",
"let abc:Enum=Enum.Value\n",
"func abc(def:Void) {}\n",
"func abc(def: Void) {}\n",
"func abc(def :Void) {}\n",
"func abc(def : Void) {}\n",
"func abc(def: Void, ghi :Void) {}\n"
],
corrections: [
"let abc:Void\n": "let abc: Void\n",
Expand Down
6 changes: 3 additions & 3 deletions Source/SwiftLintFramework/Rules/CommaRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public struct CommaRule: Rule {
"enum a { case a, b, c }"
],
triggeringExamples: [
"func abc(a: String ,b: String) { }",
"abc(a: \"string\",b: \"string\"",
"enum a { case a ,b }"
"func abc(a: String ,b: String) { }",
"abc(a: \"string\",b: \"string\"",
"enum a { case a ,b }"
]
)

Expand Down
32 changes: 16 additions & 16 deletions Source/SwiftLintFramework/Rules/ControlStatementRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,22 @@ public struct ControlStatementRule: Rule {
"switch foo {\n"
],
triggeringExamples: [
"if (condition) {\n",
"if(condition) {\n",
"if ((a || b) && (c || d)) {\n",
"if ((min...max).contains(value)) {\n",
"for (item in collection) {\n",
"for (var index = 0; index < 42; index++) {\n",
"for(item in collection) {\n",
"for(var index = 0; index < 42; index++) {\n",
"guard (condition) else {\n",
"while (condition) {\n",
"while(condition) {\n",
"} while (condition) {\n",
"} while(condition) {\n",
"do { ; } while(condition) {\n",
"do { ; } while (condition) {\n",
"switch (foo) {\n"
"if (condition) {\n",
"if(condition) {\n",
"if ((a || b) && (c || d)) {\n",
"if ((min...max).contains(value)) {\n",
"for (item in collection) {\n",
"for (var index = 0; index < 42; index++) {\n",
"for(item in collection) {\n",
"for(var index = 0; index < 42; index++) {\n",
"guard (condition) else {\n",
"while (condition) {\n",
"while(condition) {\n",
"} while (condition) {\n",
"} while(condition) {\n",
"do { ; } while(condition) {\n",
"do { ; } while (condition) {\n",
"switch (foo) {\n"
]
)

Expand Down
2 changes: 1 addition & 1 deletion Source/SwiftLintFramework/Rules/ForceCastRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public struct ForceCastRule: Rule {
nonTriggeringExamples: [
"NSNumber() as? Int\n"
],
triggeringExamples: [ "NSNumber() as! Int\n" ]
triggeringExamples: [ "NSNumber() as! Int\n" ]
)

public func validateFile(file: File) -> [StyleViolation] {
Expand Down
2 changes: 1 addition & 1 deletion Source/SwiftLintFramework/Rules/ForceTryRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public struct ForceTryRule: Rule {
"func a() throws {}; do { try a() } catch {}"
],
triggeringExamples: [
"func a() throws {}; try! a()"
"func a() throws {}; try! a()"
]
)

Expand Down
Loading

0 comments on commit 089d89e

Please sign in to comment.