From e95625ee79cb2ec9ba61fb2e59a14e3d5bba8acb Mon Sep 17 00:00:00 2001 From: JP Simard Date: Sun, 23 Aug 2015 22:21:20 -0700 Subject: [PATCH 1/9] update for swift 2 --- .gitignore | 31 +++++++++++++++++-- .gitmodules | 3 ++ Cartfile | 2 +- Cartfile.private | 2 +- Cartfile.resolved | 12 +++---- Carthage/Checkouts/Commandant | 2 +- Carthage/Checkouts/Result | 1 + Carthage/Checkouts/SWXMLHash | 2 +- Carthage/Checkouts/SourceKitten | 2 +- Carthage/Checkouts/SwiftXPC | 2 +- Carthage/Checkouts/xcconfigs | 2 +- .../SwiftLintFramework/File+SwiftLint.swift | 29 ++++++++--------- Source/SwiftLintFramework/Info.plist | 2 +- Source/SwiftLintFramework/Linter.swift | 4 +-- Source/SwiftLintFramework/Location.swift | 6 ++-- .../NSFileManager+SwiftLint.swift | 11 +++---- .../Rules/ControlStatementRule.swift | 6 ++-- .../Rules/FileLengthRule.swift | 2 +- .../Rules/FunctionBodyLengthRule.swift | 19 ++++++------ .../Rules/LineLengthRule.swift | 10 +++--- .../Rules/NestingRule.swift | 28 ++++++++++------- .../Rules/ReturnArrowWhitespaceRule.swift | 1 + .../Rules/TrailingNewlineRule.swift | 4 +-- .../Rules/TypeBodyLengthRule.swift | 19 ++++++------ .../Rules/TypeNameRule.swift | 15 ++++----- .../Rules/VariableNameRule.swift | 15 ++++----- .../SwiftLintFramework/String+SwiftLint.swift | 9 ++---- .../SwiftLintFramework/StyleViolation.swift | 2 +- .../StyleViolationType.swift | 2 +- .../ViolationSeverity.swift | 2 +- .../ASTRuleTests.swift | 14 ++++----- Source/SwiftLintFrameworkTests/Info.plist | 2 +- .../IntegrationTests.swift | 12 ++++--- .../StringRuleTests.swift | 22 ++++++------- .../SwiftLintFrameworkTests/TestHelpers.swift | 2 +- Source/swiftlint/Info.plist | 2 +- Source/swiftlint/LintCommand.swift | 29 +++++++++-------- Source/swiftlint/RulesCommand.swift | 8 ++--- Source/swiftlint/StructuredText.swift | 4 +-- Source/swiftlint/VersionCommand.swift | 8 ++--- SwiftLint.xcodeproj/project.pbxproj | 28 ++++++++++++----- .../xcschemes/SwiftLintFramework.xcscheme | 13 +++++--- .../xcshareddata/xcschemes/swiftlint.xcscheme | 13 +++++--- .../contents.xcworkspacedata | 2 +- 44 files changed, 230 insertions(+), 176 deletions(-) create mode 160000 Carthage/Checkouts/Result diff --git a/.gitignore b/.gitignore index 2b9c66988..777cb057b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,12 @@ # Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore +## Build generated build/ +DerivedData + +## Various settings *.pbxuser !default.pbxuser *.mode1v3 @@ -10,11 +16,32 @@ build/ *.perspectivev3 !default.perspectivev3 xcuserdata + +## Other *.xccheckout *.moved-aside -DerivedData +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific *.hmap *.ipa -*.xcuserstate + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +#Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# SwiftLint SwiftLint.pkg diff --git a/.gitmodules b/.gitmodules index 32f887e87..5856b1c9d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "Carthage/Checkouts/SourceKitten"] path = Carthage/Checkouts/SourceKitten url = https://github.com/jpsim/SourceKitten.git +[submodule "Carthage/Checkouts/Result"] + path = Carthage/Checkouts/Result + url = https://github.com/antitypical/Result.git diff --git a/Cartfile b/Cartfile index 66306c6c2..658a6ce47 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "jpsim/SourceKitten" ~> 0.4 +github "jpsim/SourceKitten" "swift-2.0" diff --git a/Cartfile.private b/Cartfile.private index a99553424..92345d88d 100644 --- a/Cartfile.private +++ b/Cartfile.private @@ -1,2 +1,2 @@ -github "Carthage/Commandant" ~> 0.5 +github "Carthage/Commandant" "swift-2.0" github "jspahrsummers/xcconfigs" >= 0.8 diff --git a/Cartfile.resolved b/Cartfile.resolved index 8ed4b5a5a..bfe47bcd6 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,6 +1,6 @@ -github "LlamaKit/LlamaKit" "v0.6.0" -github "drmohundro/SWXMLHash" "1.0.0" -github "jpsim/SwiftXPC" "1.0.0" -github "jspahrsummers/xcconfigs" "0.8" -github "Carthage/Commandant" "0.5" -github "jpsim/SourceKitten" "0.4.5" +github "antitypical/Result" "0.6-beta.1" +github "drmohundro/SWXMLHash" "2203b05b1e093b1dc3e32114953f937a6e7aa5f5" +github "jpsim/SwiftXPC" "d32e70f1b35cfa833be85fd40e70401f4190f5b0" +github "jspahrsummers/xcconfigs" "0.8.1" +github "Carthage/Commandant" "cc47af4a9e7a7d56bd1202d52762c1c66184c936" +github "jpsim/SourceKitten" "4906120ed45b09d9720718bf666eab1e7ef30b31" diff --git a/Carthage/Checkouts/Commandant b/Carthage/Checkouts/Commandant index 3866cadd4..cc47af4a9 160000 --- a/Carthage/Checkouts/Commandant +++ b/Carthage/Checkouts/Commandant @@ -1 +1 @@ -Subproject commit 3866cadd431b1c3ba8091383b80ec023beb1897f +Subproject commit cc47af4a9e7a7d56bd1202d52762c1c66184c936 diff --git a/Carthage/Checkouts/Result b/Carthage/Checkouts/Result new file mode 160000 index 000000000..18a10d680 --- /dev/null +++ b/Carthage/Checkouts/Result @@ -0,0 +1 @@ +Subproject commit 18a10d680af395d93b47ff4a3d8b0af3b8cad094 diff --git a/Carthage/Checkouts/SWXMLHash b/Carthage/Checkouts/SWXMLHash index 3f64d009c..2203b05b1 160000 --- a/Carthage/Checkouts/SWXMLHash +++ b/Carthage/Checkouts/SWXMLHash @@ -1 +1 @@ -Subproject commit 3f64d009ca1e2b737bf93d22bcaa837d3be1d90c +Subproject commit 2203b05b1e093b1dc3e32114953f937a6e7aa5f5 diff --git a/Carthage/Checkouts/SourceKitten b/Carthage/Checkouts/SourceKitten index a9b100ab0..4906120ed 160000 --- a/Carthage/Checkouts/SourceKitten +++ b/Carthage/Checkouts/SourceKitten @@ -1 +1 @@ -Subproject commit a9b100ab0803d79ef42c775895a40726d3128f07 +Subproject commit 4906120ed45b09d9720718bf666eab1e7ef30b31 diff --git a/Carthage/Checkouts/SwiftXPC b/Carthage/Checkouts/SwiftXPC index bfc256492..d32e70f1b 160000 --- a/Carthage/Checkouts/SwiftXPC +++ b/Carthage/Checkouts/SwiftXPC @@ -1 +1 @@ -Subproject commit bfc256492840ff6e8d05b851cb57af38d83469bf +Subproject commit d32e70f1b35cfa833be85fd40e70401f4190f5b0 diff --git a/Carthage/Checkouts/xcconfigs b/Carthage/Checkouts/xcconfigs index 813127f87..99624a6af 160000 --- a/Carthage/Checkouts/xcconfigs +++ b/Carthage/Checkouts/xcconfigs @@ -1 +1 @@ -Subproject commit 813127f87f66fa14a7da03d3fa8410c02d2075d6 +Subproject commit 99624a6af366c015b678a1135e4c558776a59be6 diff --git a/Source/SwiftLintFramework/File+SwiftLint.swift b/Source/SwiftLintFramework/File+SwiftLint.swift index e3571877e..59dd517fd 100644 --- a/Source/SwiftLintFramework/File+SwiftLint.swift +++ b/Source/SwiftLintFramework/File+SwiftLint.swift @@ -16,26 +16,23 @@ extension File { withSyntaxKinds syntaxKinds: [SyntaxKind]) -> [NSRange] { return matchPattern(pattern).filter { _, kindsInRange in return kindsInRange.count == syntaxKinds.count && - filter(zip(kindsInRange, syntaxKinds), { $0.0 != $0.1 }).count == 0 + zip(kindsInRange, syntaxKinds).filter({ $0.0 != $0.1 }).count == 0 }.map { $0.0 } } public func matchPattern(pattern: String) -> [(NSRange, [SyntaxKind])] { - return flatMap(NSRegularExpression(pattern: pattern, options: nil, error: nil)) { regex in - let range = NSRange(location: 0, length: count(contents.utf16)) - let syntax = syntaxMap - let matches = regex.matchesInString(contents, options: nil, range: range) - return map(matches as? [NSTextCheckingResult]) { matches in - return matches.map { match in - let tokensInRange = syntax.tokens.filter { - NSLocationInRange($0.offset, match.range) - } - let kindsInRange = compact(map(tokensInRange) { - SyntaxKind(rawValue: $0.type) - }) - return (match.range, kindsInRange) - } + let regex = try! NSRegularExpression(pattern: pattern, options: []) + let range = NSRange(location: 0, length: contents.utf16.count) + let syntax = syntaxMap + let matches = regex.matchesInString(contents, options: [], range: range) + return matches.map { match in + let tokensInRange = syntax.tokens.filter { + NSLocationInRange($0.offset, match.range) } - } ?? [] + let kindsInRange = tokensInRange.flatMap { + SyntaxKind(rawValue: $0.type) + } + return (match.range, kindsInRange) + } } } diff --git a/Source/SwiftLintFramework/Info.plist b/Source/SwiftLintFramework/Info.plist index 8c798dbec..186eccf12 100644 --- a/Source/SwiftLintFramework/Info.plist +++ b/Source/SwiftLintFramework/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - io.realm.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Source/SwiftLintFramework/Linter.swift b/Source/SwiftLintFramework/Linter.swift index e04e60c53..772869808 100644 --- a/Source/SwiftLintFramework/Linter.swift +++ b/Source/SwiftLintFramework/Linter.swift @@ -33,11 +33,11 @@ public struct Linter { ] public var styleViolations: [StyleViolation] { - return rules.flatMap { $0.validateFile(file) } + return rules.flatMap { $0.validateFile(self.file) } } public var ruleExamples: [RuleExample] { - return compact(rules.map { $0.example }) + return rules.flatMap { $0.example } } /** diff --git a/Source/SwiftLintFramework/Location.swift b/Source/SwiftLintFramework/Location.swift index 9cb786dce..5c773d1ab 100644 --- a/Source/SwiftLintFramework/Location.swift +++ b/Source/SwiftLintFramework/Location.swift @@ -8,7 +8,7 @@ import SourceKittenFramework -public struct Location: Printable, Equatable { +public struct Location: CustomStringConvertible, Equatable { public let file: String? public let line: Int? public let character: Int? @@ -16,8 +16,8 @@ public struct Location: Printable, Equatable { // Xcode likes warnings and errors in the following format: // {full_path_to_file}{:line}{:character}: {error,warning}: {content} return (file ?? "") + - (map(line, { ":\($0)" }) ?? "") + - (map(character, { ":\($0)" }) ?? "") + (line.map({ ":\($0)" }) ?? "") + + (character.map({ ":\($0)" }) ?? "") } public init(file: String?, line: Int? = nil, character: Int? = nil) { diff --git a/Source/SwiftLintFramework/NSFileManager+SwiftLint.swift b/Source/SwiftLintFramework/NSFileManager+SwiftLint.swift index 44a3944da..cf5f656af 100644 --- a/Source/SwiftLintFramework/NSFileManager+SwiftLint.swift +++ b/Source/SwiftLintFramework/NSFileManager+SwiftLint.swift @@ -7,14 +7,11 @@ // import Foundation -import SourceKittenFramework extension NSFileManager { - public func allFilesRecursively(# directory: String) -> [String] { - let relativeFiles = (contentsOfDirectoryAtPath(directory, error: nil) as? [String] ?? []) + - (subpathsOfDirectoryAtPath(directory, error: nil) as? [String] ?? []) - return relativeFiles.map { - directory.stringByAppendingPathComponent($0) - } + public func allFilesRecursively(directory directory: String) -> [String] { + let relativeFiles = (try! contentsOfDirectoryAtPath(directory)) + + (try! subpathsOfDirectoryAtPath(directory)) + return relativeFiles.map((directory as NSString).stringByAppendingPathComponent) } } diff --git a/Source/SwiftLintFramework/Rules/ControlStatementRule.swift b/Source/SwiftLintFramework/Rules/ControlStatementRule.swift index 8c78c6fb7..7218c3f59 100644 --- a/Source/SwiftLintFramework/Rules/ControlStatementRule.swift +++ b/Source/SwiftLintFramework/Rules/ControlStatementRule.swift @@ -14,9 +14,9 @@ public struct ControlStatementRule: Rule { public let identifier = "control_statement" public func validateFile(file: File) -> [StyleViolation] { - return ["if", "for", "switch", "while"].flatMap { statementKind in + return ["if", "for", "switch", "while"].flatMap { statementKind -> [StyleViolation] in let pattern = "\(statementKind)\\s*\\([^,]*\\)\\s*\\{" - return compact(file.matchPattern(pattern).map { match, syntaxKinds in + return file.matchPattern(pattern).flatMap { match, syntaxKinds in if syntaxKinds.first != .Keyword { return nil } @@ -25,7 +25,7 @@ public struct ControlStatementRule: Rule { severity: .Low, reason: "\(statementKind) statements shouldn't wrap their conditionals in " + "parentheses.") - }) + } } } diff --git a/Source/SwiftLintFramework/Rules/FileLengthRule.swift b/Source/SwiftLintFramework/Rules/FileLengthRule.swift index 6b6088711..d7099a380 100644 --- a/Source/SwiftLintFramework/Rules/FileLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/FileLengthRule.swift @@ -23,7 +23,7 @@ public struct FileLengthRule: ParameterizedRule { public func validateFile(file: File) -> [StyleViolation] { let lines = file.contents.lines() - for parameter in reverse(parameters) { + for parameter in parameters.reverse() { if lines.count > parameter.value { return [StyleViolation(type: .Length, location: Location(file: file.path, line: lines.count), diff --git a/Source/SwiftLintFramework/Rules/FunctionBodyLengthRule.swift b/Source/SwiftLintFramework/Rules/FunctionBodyLengthRule.swift index 46e0991c3..d6d0b658d 100644 --- a/Source/SwiftLintFramework/Rules/FunctionBodyLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/FunctionBodyLengthRule.swift @@ -27,13 +27,14 @@ public struct FunctionBodyLengthRule: ASTRule, ParameterizedRule { } public func validateFile(file: File, dictionary: XPCDictionary) -> [StyleViolation] { - return (dictionary["key.substructure"] as? XPCArray ?? []).flatMap { subItem in + let substructure = dictionary["key.substructure"] as? XPCArray ?? [] + return substructure.flatMap { subItem -> [StyleViolation] in var violations = [StyleViolation]() if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, - let kind = flatMap(kindString, { SwiftDeclarationKind(rawValue: $0) }) { - violations.extend(validateFile(file, dictionary: subDict)) - violations.extend(validateFile(file, kind: kind, dictionary: subDict)) + let kind = SwiftDeclarationKind(rawValue: kindString) { + violations.extend(self.validateFile(file, dictionary: subDict)) + violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) } return violations } @@ -58,16 +59,16 @@ public struct FunctionBodyLengthRule: ASTRule, ParameterizedRule { .FunctionOperator, .FunctionSubscript ] - if !contains(functionKinds, kind) { + if !functionKinds.contains(kind) { return [] } - if let offset = flatMap(dictionary["key.offset"] as? Int64, { Int($0) }), - let bodyOffset = flatMap(dictionary["key.bodyoffset"] as? Int64, { Int($0) }), - let bodyLength = flatMap(dictionary["key.bodylength"] as? Int64, { Int($0) }) { + if let offset = (dictionary["key.offset"] as? Int64).flatMap({ Int($0) }), + let bodyOffset = (dictionary["key.bodyoffset"] as? Int64).flatMap({ Int($0) }), + let bodyLength = (dictionary["key.bodylength"] as? Int64).flatMap({ Int($0) }) { let location = Location(file: file, offset: offset) let startLine = file.contents.lineAndCharacterForByteOffset(bodyOffset) let endLine = file.contents.lineAndCharacterForByteOffset(bodyOffset + bodyLength) - for parameter in reverse(parameters) { + for parameter in parameters.reverse() { if let startLine = startLine?.line, let endLine = endLine?.line where endLine - startLine > parameter.value { return [StyleViolation(type: .Length, diff --git a/Source/SwiftLintFramework/Rules/LineLengthRule.swift b/Source/SwiftLintFramework/Rules/LineLengthRule.swift index fb0b9ef6e..017198523 100644 --- a/Source/SwiftLintFramework/Rules/LineLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/LineLengthRule.swift @@ -22,18 +22,18 @@ public struct LineLengthRule: ParameterizedRule { ] public func validateFile(file: File) -> [StyleViolation] { - return compact(file.contents.lines().map { line in - for parameter in reverse(self.parameters) { - if count(line.content) > parameter.value { + return file.contents.lines().flatMap { line in + for parameter in self.parameters.reverse() { + if line.content.characters.count > parameter.value { return StyleViolation(type: .Length, location: Location(file: file.path, line: line.index), severity: parameter.severity, reason: "Line should be 100 characters or less: currently " + - "\(count(line.content)) characters") + "\(line.content.characters.count) characters") } } return nil - }) + } } public let example = RuleExample( diff --git a/Source/SwiftLintFramework/Rules/NestingRule.swift b/Source/SwiftLintFramework/Rules/NestingRule.swift index ea792e135..0af55c31f 100644 --- a/Source/SwiftLintFramework/Rules/NestingRule.swift +++ b/Source/SwiftLintFramework/Rules/NestingRule.swift @@ -19,13 +19,14 @@ public struct NestingRule: ASTRule { } public func validateFile(file: File, dictionary: XPCDictionary) -> [StyleViolation] { - return (dictionary["key.substructure"] as? XPCArray ?? []).flatMap { subItem in + let substructure = dictionary["key.substructure"] as? XPCArray ?? [] + return substructure.flatMap { subItem -> [StyleViolation] in var violations = [StyleViolation]() if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, - let kind = flatMap(kindString, { SwiftDeclarationKind(rawValue: $0) }) { - violations.extend(validateFile(file, dictionary: subDict)) - violations.extend(validateFile(file, kind: kind, dictionary: subDict)) + let kind = SwiftDeclarationKind(rawValue: kindString) { + violations.extend(self.validateFile(file, dictionary: subDict)) + violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) } return violations } @@ -47,10 +48,15 @@ public struct NestingRule: ASTRule { .Struct, .Typealias, .Enum, - .Enumelement + .Enumcase ] - if let offset = flatMap(dictionary["key.offset"] as? Int64, { Int($0) }) { - if level > 1 && contains(typeKinds, kind) { + if let offset = (dictionary["key.offset"] as? Int64).flatMap({ Int($0) }) { + if level > 1 && typeKinds.contains(kind) { + violations.append(StyleViolation(type: .Nesting, + location: Location(file: file, offset: offset), + reason: "Types should be nested at most 1 level deep")) + } else if level > 2 && kind == .Enumelement { + // Enum elements are implicitly wrapped in an .Enumcase violations.append(StyleViolation(type: .Nesting, location: Location(file: file, offset: offset), reason: "Types should be nested at most 1 level deep")) @@ -61,18 +67,18 @@ public struct NestingRule: ASTRule { } } let substructure = dictionary["key.substructure"] as? XPCArray ?? [] - violations.extend(compact(substructure.map { subItem in + violations.extend(substructure.flatMap { subItem in let subDict = subItem as? XPCDictionary let kindString = subDict?["key.kind"] as? String - let kind = flatMap(kindString) { kindString in + let kind = kindString.flatMap { kindString in return SwiftDeclarationKind(rawValue: kindString) } if let kind = kind, subDict = subDict { return (kind, subDict) } return nil - } as [(SwiftDeclarationKind, XPCDictionary)?]).flatMap { (kind, dict) in - return validateFile(file, kind: kind, dictionary: dict, level: level + 1) + }.flatMap { (kind, dict) -> [StyleViolation] in + return self.validateFile(file, kind: kind, dictionary: dict, level: level + 1) }) return violations } diff --git a/Source/SwiftLintFramework/Rules/ReturnArrowWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/ReturnArrowWhitespaceRule.swift index e8d6a0fcb..a5003cd98 100644 --- a/Source/SwiftLintFramework/Rules/ReturnArrowWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/ReturnArrowWhitespaceRule.swift @@ -6,6 +6,7 @@ // Copyright (c) 2015 Realm. All rights reserved. // +import Foundation import SourceKittenFramework public struct ReturnArrowWhitespaceRule: Rule { diff --git a/Source/SwiftLintFramework/Rules/TrailingNewlineRule.swift b/Source/SwiftLintFramework/Rules/TrailingNewlineRule.swift index eccc53fc4..2673c82a5 100644 --- a/Source/SwiftLintFramework/Rules/TrailingNewlineRule.swift +++ b/Source/SwiftLintFramework/Rules/TrailingNewlineRule.swift @@ -19,9 +19,9 @@ public struct TrailingNewlineRule: Rule { let range = Range(start: start, end: string.endIndex) let substring = string[range].utf16 let newLineSet = NSCharacterSet.newlineCharacterSet() - let slices = split(substring, allowEmptySlices: true) { !newLineSet.characterIsMember($0) } + let slices = substring.split(allowEmptySlices: true) { !newLineSet.characterIsMember($0) } - if let slice = slices.last where count(slice) != 1 { + if let slice = slices.last where slice.count != 1 { return [StyleViolation(type: .TrailingNewline, location: Location(file: file.path, line: file.contents.lines().count + 1), severity: .Medium, diff --git a/Source/SwiftLintFramework/Rules/TypeBodyLengthRule.swift b/Source/SwiftLintFramework/Rules/TypeBodyLengthRule.swift index bf2f0fef2..42306fba2 100644 --- a/Source/SwiftLintFramework/Rules/TypeBodyLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/TypeBodyLengthRule.swift @@ -27,13 +27,14 @@ public struct TypeBodyLengthRule: ASTRule, ParameterizedRule { } public func validateFile(file: File, dictionary: XPCDictionary) -> [StyleViolation] { - return (dictionary["key.substructure"] as? XPCArray ?? []).flatMap { subItem in + let substructure = dictionary["key.substructure"] as? XPCArray ?? [] + return substructure.flatMap { subItem -> [StyleViolation] in var violations = [StyleViolation]() if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, - let kind = flatMap(kindString, { SwiftDeclarationKind(rawValue: $0) }) { - violations.extend(validateFile(file, dictionary: subDict)) - violations.extend(validateFile(file, kind: kind, dictionary: subDict)) + let kind = SwiftDeclarationKind(rawValue: kindString) { + violations.extend(self.validateFile(file, dictionary: subDict)) + violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) } return violations } @@ -47,16 +48,16 @@ public struct TypeBodyLengthRule: ASTRule, ParameterizedRule { .Struct, .Enum ] - if !contains(typeKinds, kind) { + if !typeKinds.contains(kind) { return [] } - if let offset = flatMap(dictionary["key.offset"] as? Int64, { Int($0) }), - let bodyOffset = flatMap(dictionary["key.bodyoffset"] as? Int64, { Int($0) }), - let bodyLength = flatMap(dictionary["key.bodylength"] as? Int64, { Int($0) }) { + if let offset = (dictionary["key.offset"] as? Int64).flatMap({ Int($0) }), + let bodyOffset = (dictionary["key.bodyoffset"] as? Int64).flatMap({ Int($0) }), + let bodyLength = (dictionary["key.bodylength"] as? Int64).flatMap({ Int($0) }) { let location = Location(file: file, offset: offset) let startLine = file.contents.lineAndCharacterForByteOffset(bodyOffset) let endLine = file.contents.lineAndCharacterForByteOffset(bodyOffset + bodyLength) - for parameter in reverse(parameters) { + for parameter in parameters.reverse() { if let startLine = startLine?.line, let endLine = endLine?.line where endLine - startLine > parameter.value { return [StyleViolation(type: .Length, diff --git a/Source/SwiftLintFramework/Rules/TypeNameRule.swift b/Source/SwiftLintFramework/Rules/TypeNameRule.swift index 510452101..19db0189c 100644 --- a/Source/SwiftLintFramework/Rules/TypeNameRule.swift +++ b/Source/SwiftLintFramework/Rules/TypeNameRule.swift @@ -19,13 +19,14 @@ public struct TypeNameRule: ASTRule { } public func validateFile(file: File, dictionary: XPCDictionary) -> [StyleViolation] { - return (dictionary["key.substructure"] as? XPCArray ?? []).flatMap { subItem in + let substructure = dictionary["key.substructure"] as? XPCArray ?? [] + return substructure.flatMap { subItem -> [StyleViolation] in var violations = [StyleViolation]() if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, - let kind = flatMap(kindString, { SwiftDeclarationKind(rawValue: $0) }) { - violations.extend(validateFile(file, dictionary: subDict)) - violations.extend(validateFile(file, kind: kind, dictionary: subDict)) + let kind = SwiftDeclarationKind(rawValue: kindString) { + violations.extend(self.validateFile(file, dictionary: subDict)) + violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) } return violations } @@ -41,12 +42,12 @@ public struct TypeNameRule: ASTRule { .Enum, .Enumelement ] - if !contains(typeKinds, kind) { + if !typeKinds.contains(kind) { return [] } var violations = [StyleViolation]() if let name = dictionary["key.name"] as? String, - let offset = flatMap(dictionary["key.offset"] as? Int64, { Int($0) }) { + let offset = (dictionary["key.offset"] as? Int64).flatMap({ Int($0) }) { let location = Location(file: file, offset: offset) let nameCharacterSet = NSCharacterSet(charactersInString: name) if !NSCharacterSet.alphanumericCharacterSet().isSupersetOfSet(nameCharacterSet) { @@ -59,7 +60,7 @@ public struct TypeNameRule: ASTRule { location: location, severity: .High, reason: "Type name should start with an uppercase character: '\(name)'")) - } else if count(name) < 3 || count(name) > 40 { + } else if name.characters.count < 3 || name.characters.count > 40 { violations.append(StyleViolation(type: .NameFormat, location: location, severity: .Medium, diff --git a/Source/SwiftLintFramework/Rules/VariableNameRule.swift b/Source/SwiftLintFramework/Rules/VariableNameRule.swift index 9e5a9a4d1..6eb71485a 100644 --- a/Source/SwiftLintFramework/Rules/VariableNameRule.swift +++ b/Source/SwiftLintFramework/Rules/VariableNameRule.swift @@ -19,13 +19,14 @@ public struct VariableNameRule: ASTRule { } public func validateFile(file: File, dictionary: XPCDictionary) -> [StyleViolation] { - return (dictionary["key.substructure"] as? XPCArray ?? []).flatMap { subItem in + let substructure = dictionary["key.substructure"] as? XPCArray ?? [] + return substructure.flatMap { subItem -> [StyleViolation] in var violations = [StyleViolation]() if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, - let kind = flatMap(kindString, { SwiftDeclarationKind(rawValue: $0) }) { - violations.extend(validateFile(file, dictionary: subDict)) - violations.extend(validateFile(file, kind: kind, dictionary: subDict)) + let kind = SwiftDeclarationKind(rawValue: kindString) { + violations.extend(self.validateFile(file, dictionary: subDict)) + violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) } return violations } @@ -42,12 +43,12 @@ public struct VariableNameRule: ASTRule { .VarParameter, .VarStatic ] - if !contains(variableKinds, kind) { + if !variableKinds.contains(kind) { return [] } var violations = [StyleViolation]() if let name = dictionary["key.name"] as? String, - let offset = flatMap(dictionary["key.offset"] as? Int64, { Int($0) }) { + let offset = (dictionary["key.offset"] as? Int64).flatMap({ Int($0) }) { let location = Location(file: file, offset: offset) let nameCharacterSet = NSCharacterSet(charactersInString: name) if !NSCharacterSet.alphanumericCharacterSet().isSupersetOfSet(nameCharacterSet) { @@ -60,7 +61,7 @@ public struct VariableNameRule: ASTRule { location: location, severity: .High, reason: "Variable name should start with a lowercase character: '\(name)'")) - } else if count(name) < 3 || count(name) > 40 { + } else if name.characters.count < 3 || name.characters.count > 40 { violations.append(StyleViolation(type: .NameFormat, location: location, severity: .Medium, diff --git a/Source/SwiftLintFramework/String+SwiftLint.swift b/Source/SwiftLintFramework/String+SwiftLint.swift index 4bf232773..89c3094da 100644 --- a/Source/SwiftLintFramework/String+SwiftLint.swift +++ b/Source/SwiftLintFramework/String+SwiftLint.swift @@ -24,7 +24,7 @@ extension String { } func countOfTailingCharactersInSet(characterSet: NSCharacterSet) -> Int { - return String(reverse(self)).countOfLeadingCharactersInSet(characterSet) + return String(self.characters.reverse()).countOfLeadingCharactersInSet(characterSet) } public var chomped: String { @@ -34,11 +34,8 @@ extension String { extension NSString { public func lineAndCharacterForByteOffset(offset: Int) -> (line: Int, character: Int)? { - return flatMap(byteRangeToNSRange(start: offset, length: 0)) { range in - var numberOfLines = 0 - var index = 0 - var lineRangeStart = 0 - var previousIndex = 0 + return byteRangeToNSRange(start: offset, length: 0).flatMap { range in + var numberOfLines = 0, index = 0, lineRangeStart = 0, previousIndex = 0 while index < length { numberOfLines++ if index <= range.location { diff --git a/Source/SwiftLintFramework/StyleViolation.swift b/Source/SwiftLintFramework/StyleViolation.swift index 1fe1dfb08..8a1795f17 100644 --- a/Source/SwiftLintFramework/StyleViolation.swift +++ b/Source/SwiftLintFramework/StyleViolation.swift @@ -6,7 +6,7 @@ // Copyright (c) 2015 Realm. All rights reserved. // -public struct StyleViolation: Printable, Equatable { +public struct StyleViolation: CustomStringConvertible, Equatable { public let type: StyleViolationType public let severity: ViolationSeverity public let location: Location diff --git a/Source/SwiftLintFramework/StyleViolationType.swift b/Source/SwiftLintFramework/StyleViolationType.swift index 0d7036e8e..6dd2a5445 100644 --- a/Source/SwiftLintFramework/StyleViolationType.swift +++ b/Source/SwiftLintFramework/StyleViolationType.swift @@ -6,7 +6,7 @@ // Copyright (c) 2015 Realm. All rights reserved. // -public enum StyleViolationType: String, Printable { +public enum StyleViolationType: String, CustomStringConvertible { case NameFormat = "Name Format" case Length = "Length" case TrailingNewline = "Trailing Newline" diff --git a/Source/SwiftLintFramework/ViolationSeverity.swift b/Source/SwiftLintFramework/ViolationSeverity.swift index 823e21f45..6cb15a0ee 100644 --- a/Source/SwiftLintFramework/ViolationSeverity.swift +++ b/Source/SwiftLintFramework/ViolationSeverity.swift @@ -6,7 +6,7 @@ // Copyright (c) 2015 Realm. All rights reserved. // -public enum ViolationSeverity: Int, Printable, Comparable { +public enum ViolationSeverity: Int, CustomStringConvertible, Comparable { case VeryLow case Low case Medium diff --git a/Source/SwiftLintFrameworkTests/ASTRuleTests.swift b/Source/SwiftLintFrameworkTests/ASTRuleTests.swift index 3c6eb9f15..f01530e45 100644 --- a/Source/SwiftLintFrameworkTests/ASTRuleTests.swift +++ b/Source/SwiftLintFrameworkTests/ASTRuleTests.swift @@ -29,7 +29,7 @@ class ASTRuleTests: XCTestCase { severity: .Medium, reason: "Type name should be between 3 and 40 characters in length: 'Ab'")]) - let longName = join("", Array(count: 40, repeatedValue: "A")) + let longName = "".join(Array(count: 40, repeatedValue: "A")) XCTAssertEqual(violations("\(kind) \(longName) {}\n"), []) let longerName = longName + "A" XCTAssertEqual(violations("\(kind) \(longerName) {}\n"), [ @@ -57,7 +57,7 @@ class ASTRuleTests: XCTestCase { func testVariableNames() { for kind in ["class", "struct"] { for varType in ["var", "let"] { - let characterOffset = 8 + count(kind) + let characterOffset = 8 + kind.characters.count XCTAssertEqual(violations("\(kind) Abc { \(varType) def: Void }\n"), []) XCTAssertEqual(violations("\(kind) Abc { \(varType) de_: Void }\n"), [ @@ -82,7 +82,7 @@ class ASTRuleTests: XCTestCase { "'de'") ]) - let longName = join("", Array(count: 40, repeatedValue: "d")) + let longName = "".join(Array(count: 40, repeatedValue: "d")) XCTAssertEqual(violations("\(kind) Abc { \(varType) \(longName): Void }\n"), []) let longerName = longName + "d" XCTAssertEqual(violations("\(kind) Abc { \(varType) \(longerName): Void }\n"), [ @@ -98,11 +98,11 @@ class ASTRuleTests: XCTestCase { func testFunctionBodyLengths() { let longFunctionBody = "func abc() {" + - join("", Array(count: 40, repeatedValue: "\n")) + + "".join(Array(count: 40, repeatedValue: "\n")) + "}\n" XCTAssertEqual(violations(longFunctionBody), []) let longerFunctionBody = "func abc() {" + - join("", Array(count: 41, repeatedValue: "\n")) + + "".join(Array(count: 41, repeatedValue: "\n")) + "}\n" XCTAssertEqual(violations(longerFunctionBody), [StyleViolation(type: .Length, location: Location(file: nil, line: 1, character: 1), @@ -113,11 +113,11 @@ class ASTRuleTests: XCTestCase { func testTypeBodyLengths() { for kind in ["class", "struct", "enum"] { let longTypeBody = "\(kind) Abc {" + - join("", Array(count: 200, repeatedValue: "\n")) + + "".join(Array(count: 200, repeatedValue: "\n")) + "}\n" XCTAssertEqual(violations(longTypeBody), []) let longerTypeBody = "\(kind) Abc {" + - join("", Array(count: 201, repeatedValue: "\n")) + + "".join(Array(count: 201, repeatedValue: "\n")) + "}\n" XCTAssertEqual(violations(longerTypeBody), [StyleViolation(type: .Length, location: Location(file: nil, line: 1, character: 1), diff --git a/Source/SwiftLintFrameworkTests/Info.plist b/Source/SwiftLintFrameworkTests/Info.plist index 3e5a88fb0..e90c12e6a 100644 --- a/Source/SwiftLintFrameworkTests/Info.plist +++ b/Source/SwiftLintFrameworkTests/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - io.realm.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Source/SwiftLintFrameworkTests/IntegrationTests.swift b/Source/SwiftLintFrameworkTests/IntegrationTests.swift index 704f1c7c6..c66c9e90c 100644 --- a/Source/SwiftLintFrameworkTests/IntegrationTests.swift +++ b/Source/SwiftLintFrameworkTests/IntegrationTests.swift @@ -15,12 +15,14 @@ class IntegrationTests: XCTestCase { func testSwiftLintLints() { // This is as close as we're ever going to get to a self-hosting linter. let fileManager = NSFileManager.defaultManager() - let directory = fileManager.currentDirectoryPath.stringByAppendingPathComponent("Source") + let directory = ((((__FILE__ as NSString) + .stringByDeletingLastPathComponent as NSString) + .stringByDeletingLastPathComponent as NSString) + .stringByDeletingLastPathComponent as NSString) + .stringByAppendingPathComponent("Source") let allFiles = fileManager.allFilesRecursively(directory: directory) - let swiftFiles = allFiles.filter { - $0.isSwiftFile() - } - XCTAssert(contains(swiftFiles, __FILE__), "current file should be included") + let swiftFiles = allFiles.filter { $0.isSwiftFile() } + XCTAssert(swiftFiles.contains(__FILE__), "current file should be included") XCTAssertEqual(swiftFiles.flatMap({Linter(file: File(path: $0)!).styleViolations}), []) } } diff --git a/Source/SwiftLintFrameworkTests/StringRuleTests.swift b/Source/SwiftLintFrameworkTests/StringRuleTests.swift index eac23b0db..c4bbd4de9 100644 --- a/Source/SwiftLintFrameworkTests/StringRuleTests.swift +++ b/Source/SwiftLintFrameworkTests/StringRuleTests.swift @@ -11,14 +11,14 @@ import XCTest class StringRuleTests: XCTestCase { func testLineLengths() { - let longLine = join("", Array(count: 100, repeatedValue: "/")) + "\n" + let longLine = "".join(Array(count: 100, repeatedValue: "/")) + "\n" XCTAssertEqual(violations(longLine), []) let testCases: [(String, Int, ViolationSeverity)] = [ ("/", 101, .VeryLow), - (join("", Array(count: 21, repeatedValue: "/")), 121, .Low), - (join("", Array(count: 51, repeatedValue: "/")), 151, .Medium), - (join("", Array(count: 101, repeatedValue: "/")), 201, .High), - (join("", Array(count: 151, repeatedValue: "/")), 251, .VeryHigh) + ("".join(Array(count: 21, repeatedValue: "/")), 121, .Low), + ("".join(Array(count: 51, repeatedValue: "/")), 151, .Medium), + ("".join(Array(count: 101, repeatedValue: "/")), 201, .High), + ("".join(Array(count: 151, repeatedValue: "/")), 251, .VeryHigh) ] for testCase in testCases { XCTAssertEqual(violations(testCase.0 + longLine), [StyleViolation(type: .Length, @@ -42,13 +42,13 @@ class StringRuleTests: XCTestCase { } func testFileLengths() { - XCTAssertEqual(violations(join("", Array(count: 400, repeatedValue: "//\n"))), []) + XCTAssertEqual(violations("".join(Array(count: 400, repeatedValue: "//\n"))), []) let testCases: [(String, Int, ViolationSeverity)] = [ - (join("", Array(count: 401, repeatedValue: "//\n")), 401, .VeryLow), - (join("", Array(count: 501, repeatedValue: "//\n")), 501, .Low), - (join("", Array(count: 751, repeatedValue: "//\n")), 751, .Medium), - (join("", Array(count: 1001, repeatedValue: "//\n")), 1001, .High), - (join("", Array(count: 2001, repeatedValue: "//\n")), 2001, .VeryHigh) + ("".join(Array(count: 401, repeatedValue: "//\n")), 401, .VeryLow), + ("".join(Array(count: 501, repeatedValue: "//\n")), 501, .Low), + ("".join(Array(count: 751, repeatedValue: "//\n")), 751, .Medium), + ("".join(Array(count: 1001, repeatedValue: "//\n")), 1001, .High), + ("".join(Array(count: 2001, repeatedValue: "//\n")), 2001, .VeryHigh) ] for testCase in testCases { XCTAssertEqual(violations(testCase.0), [StyleViolation(type: .Length, diff --git a/Source/SwiftLintFrameworkTests/TestHelpers.swift b/Source/SwiftLintFrameworkTests/TestHelpers.swift index fdd1182bd..837524da5 100644 --- a/Source/SwiftLintFrameworkTests/TestHelpers.swift +++ b/Source/SwiftLintFrameworkTests/TestHelpers.swift @@ -14,7 +14,7 @@ func violations(string: String) -> [StyleViolation] { return Linter(file: File(contents: string)).styleViolations } -private func violations(string: String, type: StyleViolationType) -> [StyleViolation] { +private func violations(string: String, _ type: StyleViolationType) -> [StyleViolation] { return violations(string).filter { $0.type == type } } diff --git a/Source/swiftlint/Info.plist b/Source/swiftlint/Info.plist index 52ede2e8a..afdd63f3c 100644 --- a/Source/swiftlint/Info.plist +++ b/Source/swiftlint/Info.plist @@ -9,7 +9,7 @@ CFBundleIconFile CFBundleIdentifier - io.realm.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Source/swiftlint/LintCommand.swift b/Source/swiftlint/LintCommand.swift index 34820d349..469c58b03 100644 --- a/Source/swiftlint/LintCommand.swift +++ b/Source/swiftlint/LintCommand.swift @@ -8,7 +8,7 @@ import Commandant import Foundation -import LlamaKit +import Result import SourceKittenFramework import SwiftLintFramework @@ -27,10 +27,10 @@ struct LintCommand: CommandType { let stdinNSString = NSString(data: stdinData, encoding: NSUTF8StringEncoding) if let stdinString = stdinNSString as? String { let violations = Linter(file: File(contents: stdinString)).styleViolations - println(join("\n", violations.map { $0.description })) - return success() + print("\n".join(violations.map { $0.description })) + return .Success() } - return failure(CommandantError<()>.CommandError(Box())) + return .Failure(CommandantError<()>.CommandError()) } // Otherwise parse path. @@ -41,18 +41,17 @@ struct LintCommand: CommandType { private func lint(path: String) -> Result<(), CommandantError<()>> { let filesToLint = filesToLintAtPath(path) if filesToLint.count > 0 { - if path == "" { - println("Linting Swift files in current working directory") + print("Linting Swift files in current working directory") } else { - println("Linting Swift files at path \(path)") + print("Linting Swift files at path \(path)") } - var numberOfViolations = 0, numberOfSeriousViolations = 0 - for (index, file) in enumerate(filesToLint) { - println("Linting '\(file.lastPathComponent)' (\(index + 1)/\(filesToLint.count))") + for (index, file) in filesToLint.enumerate() { + let filename = (file as NSString).lastPathComponent + print("Linting '\(filename)' (\(index + 1)/\(filesToLint.count))") for violation in Linter(file: File(path: file)!).styleViolations { - println(violation) + print(violation) numberOfViolations++ if violation.severity.isError { numberOfSeriousViolations++ @@ -61,22 +60,22 @@ struct LintCommand: CommandType { } let violationSuffix = (numberOfViolations != 1 ? "s" : "") let filesSuffix = (filesToLint.count != 1 ? "s." : ".") - println( + print( "Done linting!" + " Found \(numberOfViolations) violation\(violationSuffix)," + " \(numberOfSeriousViolations) serious" + " in \(filesToLint.count) file\(filesSuffix)" ) if numberOfSeriousViolations <= 0 { - return success() + return .Success() } else { // This represents failure of the content (i.e. violations in the files linted) // and not failure of the scanning process itself. The current command architecture // doesn't discriminate between these types. - return failure(CommandantError<()>.CommandError(Box())) + return .Failure(CommandantError<()>.CommandError()) } } - return failure(CommandantError<()>.UsageError(description: "No lintable files found at" + + return .Failure(CommandantError<()>.UsageError(description: "No lintable files found at" + " path \(path)")) } diff --git a/Source/swiftlint/RulesCommand.swift b/Source/swiftlint/RulesCommand.swift index f9323061a..ff46a2373 100644 --- a/Source/swiftlint/RulesCommand.swift +++ b/Source/swiftlint/RulesCommand.swift @@ -8,7 +8,7 @@ import Foundation import Commandant -import LlamaKit +import Result import SwiftLintFramework import SourceKittenFramework @@ -34,15 +34,15 @@ struct RulesCommand: CommandType { func run(mode: CommandMode) -> Result<(), CommandantError<()>> { switch mode { - case let .Arguments: + case .Arguments: let ruleExamples = Linter(file: File(contents: "")).ruleExamples let text = StructuredText.Joined(ruleExamples.map(describeExample)) - println(text.ansi) + print(text.ansi) default: break } - return success() + return .Success() } } diff --git a/Source/swiftlint/StructuredText.swift b/Source/swiftlint/StructuredText.swift index c3dcb15ac..237640701 100644 --- a/Source/swiftlint/StructuredText.swift +++ b/Source/swiftlint/StructuredText.swift @@ -19,7 +19,7 @@ enum StructuredText { var markdown: String { switch self { case let .Header(level, t): - return join("", Array(count: level, repeatedValue: "#")) + " \(t)" + return "".join(Array(count: level, repeatedValue: "#")) + " \(t)" case .Paragraph(let t): return t case .List(let items): @@ -32,7 +32,7 @@ enum StructuredText { var ansi: String { switch self { case .Header(1, let t): return t.uppercaseString - case let .Header(other, t): return t + case .Header(_, let t): return t case .Paragraph(let t): return t case .List(let items): return "\n".join(items.map { "* " + $0.ansi }) case .Joined(let items): return "\n\n".join(items.map { $0.ansi } ) diff --git a/Source/swiftlint/VersionCommand.swift b/Source/swiftlint/VersionCommand.swift index 5a5df025d..21bdf2333 100644 --- a/Source/swiftlint/VersionCommand.swift +++ b/Source/swiftlint/VersionCommand.swift @@ -7,7 +7,7 @@ // import Commandant -import LlamaKit +import Result private let version = "0.1.2" @@ -17,12 +17,12 @@ struct VersionCommand: CommandType { func run(mode: CommandMode) -> Result<(), CommandantError<()>> { switch mode { - case let .Arguments: - println(version) + case .Arguments: + print(version) default: break } - return success() + return .Success() } } diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj index 1d1605e6a..31098803f 100644 --- a/SwiftLint.xcodeproj/project.pbxproj +++ b/SwiftLint.xcodeproj/project.pbxproj @@ -54,8 +54,8 @@ E88DEA961B099CF200A66CB0 /* NestingRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA951B099CF200A66CB0 /* NestingRule.swift */; }; E8AB1A2E1A649F2100452012 /* libclang.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E8AB1A2D1A649F2100452012 /* libclang.dylib */; }; E8BA7E111B07A3EC003E02D0 /* Commandant.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E101B07A3EC003E02D0 /* Commandant.framework */; }; - E8BA7E131B07A3F3003E02D0 /* LlamaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E121B07A3F3003E02D0 /* LlamaKit.framework */; }; - E8BA7E141B07A400003E02D0 /* LlamaKit.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E121B07A3F3003E02D0 /* LlamaKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + E8BA7E131B07A3F3003E02D0 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E121B07A3F3003E02D0 /* Result.framework */; }; + E8BA7E141B07A400003E02D0 /* Result.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E121B07A3F3003E02D0 /* Result.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; E8BA7E151B07A400003E02D0 /* Commandant.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E101B07A3EC003E02D0 /* Commandant.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; E8BB8F9A1B17DDB200199606 /* ASTRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8BB8F991B17DDB200199606 /* ASTRuleTests.swift */; }; E8BB8F9C1B17DE3B00199606 /* StringRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8BB8F9B1B17DE3B00199606 /* StringRuleTests.swift */; }; @@ -87,7 +87,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - E8BA7E141B07A400003E02D0 /* LlamaKit.framework in Copy Frameworks */, + E8BA7E141B07A400003E02D0 /* Result.framework in Copy Frameworks */, E8BA7E151B07A400003E02D0 /* Commandant.framework in Copy Frameworks */, E876BFBF1B0782AA00114ED5 /* SourceKittenFramework.framework in Copy Frameworks */, E8C0DFCE1AD349E5007EE3D4 /* SWXMLHash.framework in Copy Frameworks */, @@ -178,7 +178,7 @@ E88DEA951B099CF200A66CB0 /* NestingRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NestingRule.swift; sourceTree = ""; }; E8AB1A2D1A649F2100452012 /* libclang.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libclang.dylib; path = Toolchains/XcodeDefault.xctoolchain/usr/lib/libclang.dylib; sourceTree = DEVELOPER_DIR; }; E8BA7E101B07A3EC003E02D0 /* Commandant.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Commandant.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - E8BA7E121B07A3F3003E02D0 /* LlamaKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = LlamaKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E8BA7E121B07A3F3003E02D0 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E8BB8F991B17DDB200199606 /* ASTRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASTRuleTests.swift; sourceTree = ""; }; E8BB8F9B1B17DE3B00199606 /* StringRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringRuleTests.swift; sourceTree = ""; }; E8C0DFCC1AD349DB007EE3D4 /* SWXMLHash.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SWXMLHash.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -189,7 +189,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E8BA7E131B07A3F3003E02D0 /* LlamaKit.framework in Frameworks */, + E8BA7E131B07A3F3003E02D0 /* Result.framework in Frameworks */, E8BA7E111B07A3EC003E02D0 /* Commandant.framework in Frameworks */, E876BFBE1B07828500114ED5 /* SourceKittenFramework.framework in Frameworks */, E8AB1A2E1A649F2100452012 /* libclang.dylib in Frameworks */, @@ -365,7 +365,7 @@ D0D1216F19E87B05005E4BAA /* Supporting Files */ = { isa = PBXGroup; children = ( - E8BA7E121B07A3F3003E02D0 /* LlamaKit.framework */, + E8BA7E121B07A3F3003E02D0 /* Result.framework */, E8BA7E101B07A3EC003E02D0 /* Commandant.framework */, E876BFBD1B07828500114ED5 /* SourceKittenFramework.framework */, E8AB1A2D1A649F2100452012 /* libclang.dylib */, @@ -497,7 +497,8 @@ D0D1211019E87861005E4BAA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0630; + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 0700; ORGANIZATIONNAME = Realm; TargetAttributes = { D0D1216C19E87B05005E4BAA = { @@ -659,6 +660,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = D0D1212619E878CC005E4BAA /* Debug.xcconfig */; buildSettings = { + ENABLE_TESTABILITY = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; MACOSX_DEPLOYMENT_TARGET = 10.10; @@ -697,6 +699,7 @@ "$(inherited)", "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", ); + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SwiftLintFramework; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -729,6 +732,7 @@ "$(inherited)", "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", ); + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SwiftLintFramework; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -749,6 +753,7 @@ "$(inherited)", ); INFOPLIST_FILE = Source/SwiftLintFrameworkTests/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SwiftLintFrameworkTests; }; name = Debug; @@ -762,6 +767,7 @@ "$(inherited)", ); INFOPLIST_FILE = Source/SwiftLintFrameworkTests/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SwiftLintFrameworkTests; }; name = Release; @@ -797,6 +803,7 @@ "$(inherited)", "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", ); + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SwiftLintFramework; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -817,6 +824,7 @@ "$(inherited)", ); INFOPLIST_FILE = Source/SwiftLintFrameworkTests/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SwiftLintFrameworkTests; }; name = Profile; @@ -852,6 +860,7 @@ "$(inherited)", "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", ); + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SwiftLintFramework; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -872,6 +881,7 @@ "$(inherited)", ); INFOPLIST_FILE = Source/SwiftLintFrameworkTests/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SwiftLintFrameworkTests; }; name = Test; @@ -883,6 +893,7 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Source/swiftlint/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@executable_path/. @executable_path/../Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks /Library/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -894,6 +905,7 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Source/swiftlint/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@executable_path/. @executable_path/../Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks /Library/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Test; @@ -905,6 +917,7 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Source/swiftlint/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@executable_path/. @executable_path/../Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks /Library/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -916,6 +929,7 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Source/swiftlint/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@executable_path/. @executable_path/../Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks /Library/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Profile; diff --git a/SwiftLint.xcodeproj/xcshareddata/xcschemes/SwiftLintFramework.xcscheme b/SwiftLint.xcodeproj/xcshareddata/xcschemes/SwiftLintFramework.xcscheme index b1868e335..8a181e818 100644 --- a/SwiftLint.xcodeproj/xcshareddata/xcschemes/SwiftLintFramework.xcscheme +++ b/SwiftLint.xcodeproj/xcshareddata/xcschemes/SwiftLintFramework.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -62,15 +62,18 @@ ReferencedContainer = "container:SwiftLint.xcodeproj"> + + + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -48,16 +48,19 @@ ReferencedContainer = "container:SwiftLint.xcodeproj"> + + diff --git a/SwiftLint.xcworkspace/contents.xcworkspacedata b/SwiftLint.xcworkspace/contents.xcworkspacedata index 36f152236..8d44739d9 100644 --- a/SwiftLint.xcworkspace/contents.xcworkspacedata +++ b/SwiftLint.xcworkspace/contents.xcworkspacedata @@ -14,7 +14,7 @@ location = "group:Carthage/Checkouts/Commandant/Commandant.xcodeproj"> + location = "group:Carthage/Checkouts/Commandant/Carthage/Checkouts/Result/Result.xcodeproj"> From 29536759d1dbafd1402302e937af636a579c5279 Mon Sep 17 00:00:00 2001 From: JP Simard Date: Tue, 25 Aug 2015 15:45:10 -0700 Subject: [PATCH 2/9] update for Xcode 7 Beta 6 --- .gitmodules | 2 +- Cartfile | 2 +- Cartfile.resolved | 6 ++--- Carthage/Checkouts/Commandant | 2 +- Carthage/Checkouts/LlamaKit | 1 - Carthage/Checkouts/SWXMLHash | 2 +- Carthage/Checkouts/SourceKitten | 2 +- .../Rules/FunctionBodyLengthRule.swift | 6 +++-- .../Rules/NestingRule.swift | 8 +++--- .../OperatorFunctionWhitespaceRule.swift | 8 ++++-- .../Rules/TrailingNewlineRule.swift | 2 +- .../Rules/TypeBodyLengthRule.swift | 6 +++-- .../Rules/TypeNameRule.swift | 6 +++-- .../Rules/VariableNameRule.swift | 6 +++-- .../ASTRuleTests.swift | 12 ++++----- .../StringRuleTests.swift | 25 +++++++++++-------- Source/swiftlint/LintCommand.swift | 2 +- Source/swiftlint/StructuredText.swift | 10 ++++---- 18 files changed, 62 insertions(+), 46 deletions(-) delete mode 160000 Carthage/Checkouts/LlamaKit diff --git a/.gitmodules b/.gitmodules index 5856b1c9d..b4b1f8fd9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,7 @@ url = https://github.com/Carthage/Commandant.git [submodule "Carthage/Checkouts/SWXMLHash"] path = Carthage/Checkouts/SWXMLHash - url = https://github.com/drmohundro/SWXMLHash.git + url = https://github.com/jpsim/SWXMLHash.git [submodule "Carthage/Checkouts/SourceKitten"] path = Carthage/Checkouts/SourceKitten url = https://github.com/jpsim/SourceKitten.git diff --git a/Cartfile b/Cartfile index 658a6ce47..346878590 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "jpsim/SourceKitten" "swift-2.0" +github "jpsim/SourceKitten" "master" diff --git a/Cartfile.resolved b/Cartfile.resolved index bfe47bcd6..565f71405 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,6 +1,6 @@ github "antitypical/Result" "0.6-beta.1" -github "drmohundro/SWXMLHash" "2203b05b1e093b1dc3e32114953f937a6e7aa5f5" +github "drmohundro/SWXMLHash" "050154bfc56032f04fcca37464693a17f897200a" github "jpsim/SwiftXPC" "d32e70f1b35cfa833be85fd40e70401f4190f5b0" github "jspahrsummers/xcconfigs" "0.8.1" -github "Carthage/Commandant" "cc47af4a9e7a7d56bd1202d52762c1c66184c936" -github "jpsim/SourceKitten" "4906120ed45b09d9720718bf666eab1e7ef30b31" +github "Carthage/Commandant" "40f503c33121431dc098adb7c44d9496e3a1de2f" +github "jpsim/SourceKitten" "ace729472170a4ec2996b8f921fc66784e5ef4fe" diff --git a/Carthage/Checkouts/Commandant b/Carthage/Checkouts/Commandant index cc47af4a9..40f503c33 160000 --- a/Carthage/Checkouts/Commandant +++ b/Carthage/Checkouts/Commandant @@ -1 +1 @@ -Subproject commit cc47af4a9e7a7d56bd1202d52762c1c66184c936 +Subproject commit 40f503c33121431dc098adb7c44d9496e3a1de2f diff --git a/Carthage/Checkouts/LlamaKit b/Carthage/Checkouts/LlamaKit deleted file mode 160000 index e28d7f6e8..000000000 --- a/Carthage/Checkouts/LlamaKit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e28d7f6e82fbd5dcd5388b36e2acf4eedb44b4e8 diff --git a/Carthage/Checkouts/SWXMLHash b/Carthage/Checkouts/SWXMLHash index 2203b05b1..050154bfc 160000 --- a/Carthage/Checkouts/SWXMLHash +++ b/Carthage/Checkouts/SWXMLHash @@ -1 +1 @@ -Subproject commit 2203b05b1e093b1dc3e32114953f937a6e7aa5f5 +Subproject commit 050154bfc56032f04fcca37464693a17f897200a diff --git a/Carthage/Checkouts/SourceKitten b/Carthage/Checkouts/SourceKitten index 4906120ed..ace729472 160000 --- a/Carthage/Checkouts/SourceKitten +++ b/Carthage/Checkouts/SourceKitten @@ -1 +1 @@ -Subproject commit 4906120ed45b09d9720718bf666eab1e7ef30b31 +Subproject commit ace729472170a4ec2996b8f921fc66784e5ef4fe diff --git a/Source/SwiftLintFramework/Rules/FunctionBodyLengthRule.swift b/Source/SwiftLintFramework/Rules/FunctionBodyLengthRule.swift index d6d0b658d..8fb60d37d 100644 --- a/Source/SwiftLintFramework/Rules/FunctionBodyLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/FunctionBodyLengthRule.swift @@ -33,8 +33,10 @@ public struct FunctionBodyLengthRule: ASTRule, ParameterizedRule { if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, let kind = SwiftDeclarationKind(rawValue: kindString) { - violations.extend(self.validateFile(file, dictionary: subDict)) - violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) + violations.appendContentsOf( + self.validateFile(file, dictionary: subDict) + + self.validateFile(file, kind: kind, dictionary: subDict) + ) } return violations } diff --git a/Source/SwiftLintFramework/Rules/NestingRule.swift b/Source/SwiftLintFramework/Rules/NestingRule.swift index 0af55c31f..e6d1b8daa 100644 --- a/Source/SwiftLintFramework/Rules/NestingRule.swift +++ b/Source/SwiftLintFramework/Rules/NestingRule.swift @@ -25,8 +25,10 @@ public struct NestingRule: ASTRule { if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, let kind = SwiftDeclarationKind(rawValue: kindString) { - violations.extend(self.validateFile(file, dictionary: subDict)) - violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) + violations.appendContentsOf( + self.validateFile(file, dictionary: subDict) + + self.validateFile(file, kind: kind, dictionary: subDict) + ) } return violations } @@ -67,7 +69,7 @@ public struct NestingRule: ASTRule { } } let substructure = dictionary["key.substructure"] as? XPCArray ?? [] - violations.extend(substructure.flatMap { subItem in + violations.appendContentsOf(substructure.flatMap { subItem in let subDict = subItem as? XPCDictionary let kindString = subDict?["key.kind"] as? String let kind = kindString.flatMap { kindString in diff --git a/Source/SwiftLintFramework/Rules/OperatorFunctionWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/OperatorFunctionWhitespaceRule.swift index 1e87f166c..e8fd1a845 100644 --- a/Source/SwiftLintFramework/Rules/OperatorFunctionWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/OperatorFunctionWhitespaceRule.swift @@ -17,8 +17,12 @@ public struct OperatorFunctionWhitespaceRule: Rule { let operators = ["/", "=", "-", "+", "!", "*", "|", "^", "~", "?", "."].map({"\\\($0)"}) + ["%", "<", ">", "&"] let zeroOrManySpaces = "(\\s{0}|\\s{2,})" - let pattern1 = "func\\s+[" + "".join(operators) + "]+\(zeroOrManySpaces)(<[A-Z]+>)?\\(" - let pattern2 = "func\(zeroOrManySpaces)[" + "".join(operators) + "]+\\s+(<[A-Z]+>)?\\(" + let pattern1 = "func\\s+[" + + operators.joinWithSeparator("") + + "]+\(zeroOrManySpaces)(<[A-Z]+>)?\\(" + let pattern2 = "func\(zeroOrManySpaces)[" + + operators.joinWithSeparator("") + + "]+\\s+(<[A-Z]+>)?\\(" return file.matchPattern("(\(pattern1)|\(pattern2))").filter { _, syntaxKinds in return syntaxKinds.first == .Keyword }.map { range, _ in diff --git a/Source/SwiftLintFramework/Rules/TrailingNewlineRule.swift b/Source/SwiftLintFramework/Rules/TrailingNewlineRule.swift index 2673c82a5..e8751c247 100644 --- a/Source/SwiftLintFramework/Rules/TrailingNewlineRule.swift +++ b/Source/SwiftLintFramework/Rules/TrailingNewlineRule.swift @@ -15,7 +15,7 @@ public struct TrailingNewlineRule: Rule { public func validateFile(file: File) -> [StyleViolation] { let string = file.contents - let start = advance(string.endIndex, -2, string.startIndex) + let start = string.endIndex.advancedBy(-2, limit: string.startIndex) let range = Range(start: start, end: string.endIndex) let substring = string[range].utf16 let newLineSet = NSCharacterSet.newlineCharacterSet() diff --git a/Source/SwiftLintFramework/Rules/TypeBodyLengthRule.swift b/Source/SwiftLintFramework/Rules/TypeBodyLengthRule.swift index 42306fba2..5a2d12613 100644 --- a/Source/SwiftLintFramework/Rules/TypeBodyLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/TypeBodyLengthRule.swift @@ -33,8 +33,10 @@ public struct TypeBodyLengthRule: ASTRule, ParameterizedRule { if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, let kind = SwiftDeclarationKind(rawValue: kindString) { - violations.extend(self.validateFile(file, dictionary: subDict)) - violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) + violations.appendContentsOf( + self.validateFile(file, dictionary: subDict) + + self.validateFile(file, kind: kind, dictionary: subDict) + ) } return violations } diff --git a/Source/SwiftLintFramework/Rules/TypeNameRule.swift b/Source/SwiftLintFramework/Rules/TypeNameRule.swift index 19db0189c..a3af178b3 100644 --- a/Source/SwiftLintFramework/Rules/TypeNameRule.swift +++ b/Source/SwiftLintFramework/Rules/TypeNameRule.swift @@ -25,8 +25,10 @@ public struct TypeNameRule: ASTRule { if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, let kind = SwiftDeclarationKind(rawValue: kindString) { - violations.extend(self.validateFile(file, dictionary: subDict)) - violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) + violations.appendContentsOf( + self.validateFile(file, dictionary: subDict) + + self.validateFile(file, kind: kind, dictionary: subDict) + ) } return violations } diff --git a/Source/SwiftLintFramework/Rules/VariableNameRule.swift b/Source/SwiftLintFramework/Rules/VariableNameRule.swift index 6eb71485a..5ebea50ac 100644 --- a/Source/SwiftLintFramework/Rules/VariableNameRule.swift +++ b/Source/SwiftLintFramework/Rules/VariableNameRule.swift @@ -25,8 +25,10 @@ public struct VariableNameRule: ASTRule { if let subDict = subItem as? XPCDictionary, let kindString = subDict["key.kind"] as? String, let kind = SwiftDeclarationKind(rawValue: kindString) { - violations.extend(self.validateFile(file, dictionary: subDict)) - violations.extend(self.validateFile(file, kind: kind, dictionary: subDict)) + violations.appendContentsOf( + self.validateFile(file, dictionary: subDict) + + self.validateFile(file, kind: kind, dictionary: subDict) + ) } return violations } diff --git a/Source/SwiftLintFrameworkTests/ASTRuleTests.swift b/Source/SwiftLintFrameworkTests/ASTRuleTests.swift index f01530e45..82000f13d 100644 --- a/Source/SwiftLintFrameworkTests/ASTRuleTests.swift +++ b/Source/SwiftLintFrameworkTests/ASTRuleTests.swift @@ -29,7 +29,7 @@ class ASTRuleTests: XCTestCase { severity: .Medium, reason: "Type name should be between 3 and 40 characters in length: 'Ab'")]) - let longName = "".join(Array(count: 40, repeatedValue: "A")) + let longName = Repeat(count: 40, repeatedValue: "A").joinWithSeparator("") XCTAssertEqual(violations("\(kind) \(longName) {}\n"), []) let longerName = longName + "A" XCTAssertEqual(violations("\(kind) \(longerName) {}\n"), [ @@ -82,7 +82,7 @@ class ASTRuleTests: XCTestCase { "'de'") ]) - let longName = "".join(Array(count: 40, repeatedValue: "d")) + let longName = Repeat(count: 40, repeatedValue: "d").joinWithSeparator("") XCTAssertEqual(violations("\(kind) Abc { \(varType) \(longName): Void }\n"), []) let longerName = longName + "d" XCTAssertEqual(violations("\(kind) Abc { \(varType) \(longerName): Void }\n"), [ @@ -98,11 +98,11 @@ class ASTRuleTests: XCTestCase { func testFunctionBodyLengths() { let longFunctionBody = "func abc() {" + - "".join(Array(count: 40, repeatedValue: "\n")) + + Repeat(count: 40, repeatedValue: "\n").joinWithSeparator("") + "}\n" XCTAssertEqual(violations(longFunctionBody), []) let longerFunctionBody = "func abc() {" + - "".join(Array(count: 41, repeatedValue: "\n")) + + Repeat(count: 41, repeatedValue: "\n").joinWithSeparator("") + "}\n" XCTAssertEqual(violations(longerFunctionBody), [StyleViolation(type: .Length, location: Location(file: nil, line: 1, character: 1), @@ -113,11 +113,11 @@ class ASTRuleTests: XCTestCase { func testTypeBodyLengths() { for kind in ["class", "struct", "enum"] { let longTypeBody = "\(kind) Abc {" + - "".join(Array(count: 200, repeatedValue: "\n")) + + Repeat(count: 200, repeatedValue: "\n").joinWithSeparator("") + "}\n" XCTAssertEqual(violations(longTypeBody), []) let longerTypeBody = "\(kind) Abc {" + - "".join(Array(count: 201, repeatedValue: "\n")) + + Repeat(count: 201, repeatedValue: "\n").joinWithSeparator("") + "}\n" XCTAssertEqual(violations(longerTypeBody), [StyleViolation(type: .Length, location: Location(file: nil, line: 1, character: 1), diff --git a/Source/SwiftLintFrameworkTests/StringRuleTests.swift b/Source/SwiftLintFrameworkTests/StringRuleTests.swift index c4bbd4de9..20476fbdc 100644 --- a/Source/SwiftLintFrameworkTests/StringRuleTests.swift +++ b/Source/SwiftLintFrameworkTests/StringRuleTests.swift @@ -11,14 +11,14 @@ import XCTest class StringRuleTests: XCTestCase { func testLineLengths() { - let longLine = "".join(Array(count: 100, repeatedValue: "/")) + "\n" + let longLine = Repeat(count: 100, repeatedValue: "/").joinWithSeparator("") + "\n" XCTAssertEqual(violations(longLine), []) let testCases: [(String, Int, ViolationSeverity)] = [ ("/", 101, .VeryLow), - ("".join(Array(count: 21, repeatedValue: "/")), 121, .Low), - ("".join(Array(count: 51, repeatedValue: "/")), 151, .Medium), - ("".join(Array(count: 101, repeatedValue: "/")), 201, .High), - ("".join(Array(count: 151, repeatedValue: "/")), 251, .VeryHigh) + (Repeat(count: 21, repeatedValue: "/").joinWithSeparator(""), 121, .Low), + (Repeat(count: 51, repeatedValue: "/").joinWithSeparator(""), 151, .Medium), + (Repeat(count: 101, repeatedValue: "/").joinWithSeparator(""), 201, .High), + (Repeat(count: 151, repeatedValue: "/").joinWithSeparator(""), 251, .VeryHigh) ] for testCase in testCases { XCTAssertEqual(violations(testCase.0 + longLine), [StyleViolation(type: .Length, @@ -42,13 +42,16 @@ class StringRuleTests: XCTestCase { } func testFileLengths() { - XCTAssertEqual(violations("".join(Array(count: 400, repeatedValue: "//\n"))), []) + XCTAssertEqual( + violations(Repeat(count: 400, repeatedValue: "//\n").joinWithSeparator("")), + [] + ) let testCases: [(String, Int, ViolationSeverity)] = [ - ("".join(Array(count: 401, repeatedValue: "//\n")), 401, .VeryLow), - ("".join(Array(count: 501, repeatedValue: "//\n")), 501, .Low), - ("".join(Array(count: 751, repeatedValue: "//\n")), 751, .Medium), - ("".join(Array(count: 1001, repeatedValue: "//\n")), 1001, .High), - ("".join(Array(count: 2001, repeatedValue: "//\n")), 2001, .VeryHigh) + (Repeat(count: 401, repeatedValue: "//\n").joinWithSeparator(""), 401, .VeryLow), + (Repeat(count: 501, repeatedValue: "//\n").joinWithSeparator(""), 501, .Low), + (Repeat(count: 751, repeatedValue: "//\n").joinWithSeparator(""), 751, .Medium), + (Repeat(count: 1001, repeatedValue: "//\n").joinWithSeparator(""), 1001, .High), + (Repeat(count: 2001, repeatedValue: "//\n").joinWithSeparator(""), 2001, .VeryHigh) ] for testCase in testCases { XCTAssertEqual(violations(testCase.0), [StyleViolation(type: .Length, diff --git a/Source/swiftlint/LintCommand.swift b/Source/swiftlint/LintCommand.swift index 469c58b03..937c62ecc 100644 --- a/Source/swiftlint/LintCommand.swift +++ b/Source/swiftlint/LintCommand.swift @@ -27,7 +27,7 @@ struct LintCommand: CommandType { let stdinNSString = NSString(data: stdinData, encoding: NSUTF8StringEncoding) if let stdinString = stdinNSString as? String { let violations = Linter(file: File(contents: stdinString)).styleViolations - print("\n".join(violations.map { $0.description })) + print(violations.map({ $0.description }).joinWithSeparator("\n")) return .Success() } return .Failure(CommandantError<()>.CommandError()) diff --git a/Source/swiftlint/StructuredText.swift b/Source/swiftlint/StructuredText.swift index 237640701..289170219 100644 --- a/Source/swiftlint/StructuredText.swift +++ b/Source/swiftlint/StructuredText.swift @@ -19,13 +19,13 @@ enum StructuredText { var markdown: String { switch self { case let .Header(level, t): - return "".join(Array(count: level, repeatedValue: "#")) + " \(t)" + return String(Repeat(count: level, repeatedValue: "#")) + " \(t)" case .Paragraph(let t): return t case .List(let items): - return "\n".join(items.map { "* " + $0.markdown }) + return items.map({ "* " + $0.markdown }).joinWithSeparator("\n") case .Joined(let items): - return "\n\n".join(items.map { $0.markdown } ) + return items.map({ $0.markdown }).joinWithSeparator("\n\n") } } @@ -34,8 +34,8 @@ enum StructuredText { case .Header(1, let t): return t.uppercaseString case .Header(_, let t): return t case .Paragraph(let t): return t - case .List(let items): return "\n".join(items.map { "* " + $0.ansi }) - case .Joined(let items): return "\n\n".join(items.map { $0.ansi } ) + case .List(let items): return items.map({ "* " + $0.ansi }).joinWithSeparator("\n") + case .Joined(let items): return items.map({ $0.ansi } ).joinWithSeparator("\n\n") } } } From 66943c11fdba44d3a11960870a9531691d54bf9b Mon Sep 17 00:00:00 2001 From: JP Simard Date: Thu, 27 Aug 2015 14:20:41 -0700 Subject: [PATCH 3/9] update travis to Xcode 7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 065327299..4be693b54 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: beta-xcode6.3 +osx_image: xcode7 git: submodules: false branches: From f7891827e4a2a7422856f59cb260e80ca7c7a073 Mon Sep 17 00:00:00 2001 From: JP Simard Date: Sun, 23 Aug 2015 14:22:19 -0700 Subject: [PATCH 4/9] added YamlSwift dependency --- .gitmodules | 3 +++ Cartfile.private | 1 + Cartfile.resolved | 1 + Carthage/Checkouts/YamlSwift | 1 + SwiftLint.xcodeproj/project.pbxproj | 12 ++++++------ SwiftLint.xcworkspace/contents.xcworkspacedata | 3 +++ 6 files changed, 15 insertions(+), 6 deletions(-) create mode 160000 Carthage/Checkouts/YamlSwift diff --git a/.gitmodules b/.gitmodules index b4b1f8fd9..913332702 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "Carthage/Checkouts/Result"] path = Carthage/Checkouts/Result url = https://github.com/antitypical/Result.git +[submodule "Carthage/Checkouts/YamlSwift"] + path = Carthage/Checkouts/YamlSwift + url = https://github.com/behrang/YamlSwift.git diff --git a/Cartfile.private b/Cartfile.private index 92345d88d..14cb9c919 100644 --- a/Cartfile.private +++ b/Cartfile.private @@ -1,2 +1,3 @@ github "Carthage/Commandant" "swift-2.0" github "jspahrsummers/xcconfigs" >= 0.8 +github "behrang/YamlSwift" ~> 1.2 diff --git a/Cartfile.resolved b/Cartfile.resolved index 565f71405..008bdb5ab 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,6 +1,7 @@ github "antitypical/Result" "0.6-beta.1" github "drmohundro/SWXMLHash" "050154bfc56032f04fcca37464693a17f897200a" github "jpsim/SwiftXPC" "d32e70f1b35cfa833be85fd40e70401f4190f5b0" +github "behrang/YamlSwift" "v1.2.0" github "jspahrsummers/xcconfigs" "0.8.1" github "Carthage/Commandant" "40f503c33121431dc098adb7c44d9496e3a1de2f" github "jpsim/SourceKitten" "ace729472170a4ec2996b8f921fc66784e5ef4fe" diff --git a/Carthage/Checkouts/YamlSwift b/Carthage/Checkouts/YamlSwift new file mode 160000 index 000000000..5b6a706c8 --- /dev/null +++ b/Carthage/Checkouts/YamlSwift @@ -0,0 +1 @@ +Subproject commit 5b6a706c8207eda937a2c640ceb358d8fc5eb337 diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj index 31098803f..360b7c4db 100644 --- a/SwiftLint.xcodeproj/project.pbxproj +++ b/SwiftLint.xcodeproj/project.pbxproj @@ -52,6 +52,8 @@ E88DEA921B099B1F00A66CB0 /* TypeNameRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA911B099B1F00A66CB0 /* TypeNameRule.swift */; }; E88DEA941B099C0900A66CB0 /* VariableNameRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA931B099C0900A66CB0 /* VariableNameRule.swift */; }; E88DEA961B099CF200A66CB0 /* NestingRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88DEA951B099CF200A66CB0 /* NestingRule.swift */; }; + E89376AD1B8A701E0025708E /* Yaml.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E89376AC1B8A701E0025708E /* Yaml.framework */; }; + E89376AE1B8A70400025708E /* Yaml.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = E89376AC1B8A701E0025708E /* Yaml.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; E8AB1A2E1A649F2100452012 /* libclang.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E8AB1A2D1A649F2100452012 /* libclang.dylib */; }; E8BA7E111B07A3EC003E02D0 /* Commandant.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E101B07A3EC003E02D0 /* Commandant.framework */; }; E8BA7E131B07A3F3003E02D0 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8BA7E121B07A3F3003E02D0 /* Result.framework */; }; @@ -87,6 +89,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + E89376AE1B8A70400025708E /* Yaml.framework in Copy Frameworks */, E8BA7E141B07A400003E02D0 /* Result.framework in Copy Frameworks */, E8BA7E151B07A400003E02D0 /* Commandant.framework in Copy Frameworks */, E876BFBF1B0782AA00114ED5 /* SourceKittenFramework.framework in Copy Frameworks */, @@ -142,7 +145,6 @@ D0D1217719E87B05005E4BAA /* SwiftLintFrameworkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftLintFrameworkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D0D1217D19E87B05005E4BAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D0E7B63219E9C64500EDBA4D /* swiftlint.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = swiftlint.app; sourceTree = BUILT_PRODUCTS_DIR; }; - D0E7B65819E9CA0800EDBA4D /* swiftlint */ = {isa = PBXFileReference; lastKnownFileType = text; path = swiftlint; sourceTree = BUILT_PRODUCTS_DIR; }; E57B23C01B1D8BF000DEA512 /* ReturnArrowWhitespaceRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReturnArrowWhitespaceRule.swift; sourceTree = ""; }; E5A167C81B25A0B000CF2D03 /* OperatorFunctionWhitespaceRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperatorFunctionWhitespaceRule.swift; sourceTree = ""; }; E81224991B04F85B001783D2 /* TestHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestHelpers.swift; sourceTree = ""; }; @@ -176,6 +178,7 @@ E88DEA911B099B1F00A66CB0 /* TypeNameRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeNameRule.swift; sourceTree = ""; }; E88DEA931B099C0900A66CB0 /* VariableNameRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VariableNameRule.swift; sourceTree = ""; }; E88DEA951B099CF200A66CB0 /* NestingRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NestingRule.swift; sourceTree = ""; }; + E89376AC1B8A701E0025708E /* Yaml.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Yaml.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E8AB1A2D1A649F2100452012 /* libclang.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libclang.dylib; path = Toolchains/XcodeDefault.xctoolchain/usr/lib/libclang.dylib; sourceTree = DEVELOPER_DIR; }; 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; }; @@ -189,6 +192,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E89376AD1B8A701E0025708E /* Yaml.framework in Frameworks */, E8BA7E131B07A3F3003E02D0 /* Result.framework in Frameworks */, E8BA7E111B07A3EC003E02D0 /* Commandant.framework in Frameworks */, E876BFBE1B07828500114ED5 /* SourceKittenFramework.framework in Frameworks */, @@ -244,7 +248,6 @@ D0D1216E19E87B05005E4BAA /* SwiftLintFramework */, D0D1217B19E87B05005E4BAA /* SwiftLintFrameworkTests */, D0D1211919E87861005E4BAA /* Products */, - D0E7B65819E9CA0800EDBA4D /* swiftlint */, ); sourceTree = ""; usesTabs = 0; @@ -365,6 +368,7 @@ D0D1216F19E87B05005E4BAA /* Supporting Files */ = { isa = PBXGroup; children = ( + E89376AC1B8A701E0025708E /* Yaml.framework */, E8BA7E121B07A3F3003E02D0 /* Result.framework */, E8BA7E101B07A3EC003E02D0 /* Commandant.framework */, E876BFBD1B07828500114ED5 /* SourceKittenFramework.framework */, @@ -690,7 +694,6 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", - "$(PROJECT_DIR)/build/DerivedData/SwiftLint/Build/Products/Debug", ); FRAMEWORK_VERSION = A; INFOPLIST_FILE = "$(SRCROOT)/Source/SwiftLintFramework/Info.plist"; @@ -723,7 +726,6 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", - "$(PROJECT_DIR)/build/DerivedData/SwiftLint/Build/Products/Debug", ); FRAMEWORK_VERSION = A; INFOPLIST_FILE = "$(SRCROOT)/Source/SwiftLintFramework/Info.plist"; @@ -794,7 +796,6 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", - "$(PROJECT_DIR)/build/DerivedData/SwiftLint/Build/Products/Debug", ); FRAMEWORK_VERSION = A; INFOPLIST_FILE = "$(SRCROOT)/Source/SwiftLintFramework/Info.plist"; @@ -851,7 +852,6 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", - "$(PROJECT_DIR)/build/DerivedData/SwiftLint/Build/Products/Debug", ); FRAMEWORK_VERSION = A; INFOPLIST_FILE = "$(SRCROOT)/Source/SwiftLintFramework/Info.plist"; diff --git a/SwiftLint.xcworkspace/contents.xcworkspacedata b/SwiftLint.xcworkspace/contents.xcworkspacedata index 8d44739d9..84b11a5ed 100644 --- a/SwiftLint.xcworkspace/contents.xcworkspacedata +++ b/SwiftLint.xcworkspace/contents.xcworkspacedata @@ -19,4 +19,7 @@ + + From 19cc87a4044a5cdd7a15f24da51d812dc193f430 Mon Sep 17 00:00:00 2001 From: JP Simard Date: Sun, 23 Aug 2015 21:54:34 -0700 Subject: [PATCH 5/9] Configure SwiftLint via a YAML file. Fixes #1 and #3. --- .swiftlint.yml | 2 + CHANGELOG.md | 19 ++++ README.md | 29 ++++- Source/SwiftLintFramework/Configuration.swift | 103 ++++++++++++++++++ Source/SwiftLintFramework/Linter.swift | 22 +--- Source/SwiftLintFramework/Rule.swift | 19 ++++ .../Rules/LineLengthRule.swift | 2 +- .../Rules/NestingRule.swift | 2 +- .../OperatorFunctionWhitespaceRule.swift | 2 +- .../SwiftLintFramework/String+SwiftLint.swift | 11 +- .../ConfigurationTests.swift | 50 +++++++++ Source/swiftlint/Components.plist | 21 ---- Source/swiftlint/LintCommand.swift | 50 +++++---- SwiftLint.xcodeproj/project.pbxproj | 26 +++-- 14 files changed, 275 insertions(+), 83 deletions(-) create mode 100644 .swiftlint.yml create mode 100644 Source/SwiftLintFramework/Configuration.swift create mode 100644 Source/SwiftLintFrameworkTests/ConfigurationTests.swift diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 000000000..4e8698361 --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,2 @@ +included: + - Source diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dabda01b..bbc37644c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## Master + +##### Breaking + +* None. + +##### Enhancements + +* Configure SwiftLint via a YAML file: + Supports `disabled_rules`, `included` and `excluded`. + Pass a configuration file path to `--config`, defaults to `.swiftlint.yml`. + [JP Simard](https://github.com/jpsim) + [#3](https://github.com/realm/SwiftLint/issues/3) + +##### Bug Fixes + +* None. + + ## 0.1.2: FabricSoftenerRule ##### Breaking diff --git a/README.md b/README.md index 2f347bc4d..41e5f857d 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,12 @@ Using [Homebrew](http://brew.sh/) brew install swiftlint ``` -You can also install SwiftLint by downloading `SwiftLint.pkg` from the [latest GitHub release](https://github.com/realm/SwiftLint/releases/latest) and running it. +You can also install SwiftLint by downloading `SwiftLint.pkg` from the +[latest GitHub release](https://github.com/realm/SwiftLint/releases/latest) and +running it. -You can also build from source by cloning this project and running `make install`. +You can also build from source by cloning this project and running +`make install`. ## Usage @@ -36,7 +39,8 @@ as its contents. Like this: ### Atom To integrate SwiftLint with [Atom](https://atom.io/) install the -[`linter-swiftlint`](https://atom.io/packages/linter-swiftlint) package from APM. +[`linter-swiftlint`](https://atom.io/packages/linter-swiftlint) package from +APM. ### Command Line @@ -62,8 +66,23 @@ encouraged. The rules that *are* currently implemented are mostly there as a starting point and are subject to change. -See the [Source/SwiftLintFramework/Rules](Source/SwiftLintFramework/Rules) directory to see the currently -implemented rules. +See the [Source/SwiftLintFramework/Rules](Source/SwiftLintFramework/Rules) +directory to see the currently implemented rules. + +### Configuration + +Configure SwiftLint by adding a `.swiftlint.yml` file from the directory you'll +run SwiftLint from. The following parameters can be configured: + +```yaml +disabled_rules: # rule identifiers to exclude from running + - todo +included: # paths to include during linting. `--path` is ignored if present. takes precendence over `excluded`. + - Source +excluded: # paths to ignore during linting. overridden by `included`. + - Carthage + - Pods +``` ## License diff --git a/Source/SwiftLintFramework/Configuration.swift b/Source/SwiftLintFramework/Configuration.swift new file mode 100644 index 000000000..2e33bd786 --- /dev/null +++ b/Source/SwiftLintFramework/Configuration.swift @@ -0,0 +1,103 @@ +// +// Configuration.swift +// SwiftLint +// +// Created by JP Simard on 2015-08-23. +// Copyright (c) 2015 Realm. All rights reserved. +// + +import Yaml + +extension Yaml { + var arrayOfStrings: [Swift.String]? { + return array?.flatMap { $0.string } + } +} + +public struct Configuration { + public let disabledRules: [String] // disabled_rules + public let included: [String] // included + public let excluded: [String] // excluded + + public var rules: [Rule] { + return allRules.filter { !disabledRules.contains($0.identifier) } + } + + public init?(disabledRules: [String] = [], included: [String] = [], excluded: [String] = []) { + self.disabledRules = disabledRules + self.included = included + self.excluded = excluded + + // Validate that all rule identifiers map to a defined rule + + let validRuleIdentifiers = allRules.map { $0.identifier } + + let ruleSet = Set(disabledRules) + let invalidRules = ruleSet.filter({ !validRuleIdentifiers.contains($0) }) + if invalidRules.count > 0 { + for invalidRule in invalidRules { + fputs("config error: '\(invalidRule)' is not a valid rule identifier\n", stderr) + let listOfValidRuleIdentifiers = "\n".join(validRuleIdentifiers) + fputs("Valid rule identifiers:\n\(listOfValidRuleIdentifiers)\n", stderr) + } + return nil + } + + // Validate that rule identifiers aren't listed multiple times + + if ruleSet.count != disabledRules.count { + let duplicateRules = disabledRules.reduce([String: Int]()) { (var accu, element) in + 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) + } + return nil + } + } + + public init?(yaml: String) { + guard let yamlConfig = Yaml.load(yaml).value else { + return nil + } + self.init( + disabledRules: yamlConfig["disabled_rules"].arrayOfStrings ?? [], + included: yamlConfig["included"].arrayOfStrings ?? [], + excluded: yamlConfig["excluded"].arrayOfStrings ?? [] + ) + } + + public init(path: String = ".swiftlint.yml", optional: Bool = true) { + let fullPath = (path as NSString).absolutePathRepresentation() + let failIfRequired = { + if !optional { fatalError("Could not read configuration file at path '\(fullPath)'") } + } + if path.isEmpty { + failIfRequired() + self.init()! + } else { + if !NSFileManager.defaultManager().fileExistsAtPath(fullPath) { + failIfRequired() + self.init()! + return + } + do { + let yamlContents = try NSString(contentsOfFile: fullPath, + encoding: NSUTF8StringEncoding) as String + if let _ = Configuration(yaml: yamlContents) { + print("Loading configuration from '\(path)'") + self.init(yaml: yamlContents)! + } else { + self.init()! + } + } catch { + failIfRequired() + self.init()! + } + } + } +} diff --git a/Source/SwiftLintFramework/Linter.swift b/Source/SwiftLintFramework/Linter.swift index 772869808..fcafcc94e 100644 --- a/Source/SwiftLintFramework/Linter.swift +++ b/Source/SwiftLintFramework/Linter.swift @@ -13,24 +13,7 @@ import SourceKittenFramework public struct Linter { private let file: File - private let rules: [Rule] = [ - LineLengthRule(), - LeadingWhitespaceRule(), - TrailingWhitespaceRule(), - ReturnArrowWhitespaceRule(), - TrailingNewlineRule(), - OperatorFunctionWhitespaceRule(), - ForceCastRule(), - FileLengthRule(), - TodoRule(), - ColonRule(), - TypeNameRule(), - VariableNameRule(), - TypeBodyLengthRule(), - FunctionBodyLengthRule(), - NestingRule(), - ControlStatementRule() - ] + private let rules: [Rule] public var styleViolations: [StyleViolation] { return rules.flatMap { $0.validateFile(self.file) } @@ -45,7 +28,8 @@ public struct Linter { :param: file File to lint. */ - public init(file: File) { + public init(file: File, configuration: Configuration = Configuration()!) { self.file = file + rules = configuration.rules } } diff --git a/Source/SwiftLintFramework/Rule.swift b/Source/SwiftLintFramework/Rule.swift index 5f5534e14..8a73f30ec 100644 --- a/Source/SwiftLintFramework/Rule.swift +++ b/Source/SwiftLintFramework/Rule.swift @@ -18,3 +18,22 @@ public protocol ParameterizedRule: Rule { typealias ParameterType var parameters: [RuleParameter] { get } } + +public let allRules: [Rule] = [ + LineLengthRule(), + LeadingWhitespaceRule(), + TrailingWhitespaceRule(), + ReturnArrowWhitespaceRule(), + TrailingNewlineRule(), + OperatorFunctionWhitespaceRule(), + ForceCastRule(), + FileLengthRule(), + TodoRule(), + ColonRule(), + TypeNameRule(), + VariableNameRule(), + TypeBodyLengthRule(), + FunctionBodyLengthRule(), + NestingRule(), + ControlStatementRule() +] diff --git a/Source/SwiftLintFramework/Rules/LineLengthRule.swift b/Source/SwiftLintFramework/Rules/LineLengthRule.swift index 017198523..26549e76d 100644 --- a/Source/SwiftLintFramework/Rules/LineLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/LineLengthRule.swift @@ -23,7 +23,7 @@ public struct LineLengthRule: ParameterizedRule { public func validateFile(file: File) -> [StyleViolation] { return file.contents.lines().flatMap { line in - for parameter in self.parameters.reverse() { + for parameter in parameters.reverse() { if line.content.characters.count > parameter.value { return StyleViolation(type: .Length, location: Location(file: file.path, line: line.index), diff --git a/Source/SwiftLintFramework/Rules/NestingRule.swift b/Source/SwiftLintFramework/Rules/NestingRule.swift index e6d1b8daa..04c759530 100644 --- a/Source/SwiftLintFramework/Rules/NestingRule.swift +++ b/Source/SwiftLintFramework/Rules/NestingRule.swift @@ -37,7 +37,7 @@ public struct NestingRule: ASTRule { public func validateFile(file: File, kind: SwiftDeclarationKind, dictionary: XPCDictionary) -> [StyleViolation] { - return self.validateFile(file, kind: kind, dictionary: dictionary, level: 0) + return validateFile(file, kind: kind, dictionary: dictionary, level: 0) } func validateFile(file: File, diff --git a/Source/SwiftLintFramework/Rules/OperatorFunctionWhitespaceRule.swift b/Source/SwiftLintFramework/Rules/OperatorFunctionWhitespaceRule.swift index e8fd1a845..95aae2bb7 100644 --- a/Source/SwiftLintFramework/Rules/OperatorFunctionWhitespaceRule.swift +++ b/Source/SwiftLintFramework/Rules/OperatorFunctionWhitespaceRule.swift @@ -29,7 +29,7 @@ public struct OperatorFunctionWhitespaceRule: Rule { return StyleViolation(type: .OperatorFunctionWhitespace, location: Location(file: file, offset: range.location), severity: .Medium, - reason: self.example.ruleDescription) + reason: example.ruleDescription) } } diff --git a/Source/SwiftLintFramework/String+SwiftLint.swift b/Source/SwiftLintFramework/String+SwiftLint.swift index 89c3094da..7ce54bd76 100644 --- a/Source/SwiftLintFramework/String+SwiftLint.swift +++ b/Source/SwiftLintFramework/String+SwiftLint.swift @@ -24,7 +24,7 @@ extension String { } func countOfTailingCharactersInSet(characterSet: NSCharacterSet) -> Int { - return String(self.characters.reverse()).countOfLeadingCharactersInSet(characterSet) + return String(characters.reverse()).countOfLeadingCharactersInSet(characterSet) } public var chomped: String { @@ -38,13 +38,12 @@ extension NSString { var numberOfLines = 0, index = 0, lineRangeStart = 0, previousIndex = 0 while index < length { numberOfLines++ - if index <= range.location { - lineRangeStart = numberOfLines - previousIndex = index - index = NSMaxRange(self.lineRangeForRange(NSRange(location: index, length: 1))) - } else { + if index > range.location { break } + lineRangeStart = numberOfLines + previousIndex = index + index = NSMaxRange(lineRangeForRange(NSRange(location: index, length: 1))) } return (lineRangeStart, range.location - previousIndex + 1) } diff --git a/Source/SwiftLintFrameworkTests/ConfigurationTests.swift b/Source/SwiftLintFrameworkTests/ConfigurationTests.swift new file mode 100644 index 000000000..0af7e51e0 --- /dev/null +++ b/Source/SwiftLintFrameworkTests/ConfigurationTests.swift @@ -0,0 +1,50 @@ +// +// ConfigurationTests.swift +// SwiftLint +// +// Created by JP Simard on 8/23/15. +// Copyright © 2015 Realm. All rights reserved. +// + +import SwiftLintFramework +import XCTest + +class ConfigurationTests: XCTestCase { + func testInit() { + XCTAssert(Configuration(yaml: "") != nil, + "initializing Configuration with empty YAML string should succeed") + XCTAssert(Configuration(yaml: "a: 1\nb: 2") != nil, + "initializing Configuration with valid YAML string should succeed") + XCTAssert(Configuration(yaml: "|\na") == nil, + "initializing Configuration with invalid YAML string should fail") + } + + func testEmptyConfiguration() { + guard let config = Configuration(yaml: "") else { + XCTFail("empty YAML string should yield non-nil Configuration") + return + } + XCTAssertEqual(config.disabledRules, []) + XCTAssertEqual(config.included, []) + XCTAssertEqual(config.excluded, []) + } + + func testDisabledRules() { + XCTAssert(Configuration(yaml: "disabled_rules:\n - a") == nil, + "initializing Configuration with invalid rules in YAML string should fail") + let disabledConfig = Configuration(yaml: "disabled_rules:\n - nesting\n - todo")! + XCTAssertEqual(disabledConfig.disabledRules, + ["nesting", "todo"], + "initializing Configuration with valid rules in YAML string should succeed") + let expectedIdentifiers = allRules + .map({ $0.identifier }) + .filter({ !["nesting", "todo"].contains($0) }) + let configuredIdentifiers = disabledConfig.rules.map({ $0.identifier }) + XCTAssertEqual(expectedIdentifiers, configuredIdentifiers) + + // Duplicate + let duplicateConfig = Configuration( yaml: "disabled_rules:\n - todo\n - todo") + XCTAssert(duplicateConfig == nil, "initializing Configuration with duplicate rules in " + + " YAML string should fail") + } +} diff --git a/Source/swiftlint/Components.plist b/Source/swiftlint/Components.plist index 6c7141e76..8d3a3a1b0 100644 --- a/Source/swiftlint/Components.plist +++ b/Source/swiftlint/Components.plist @@ -7,27 +7,6 @@ BundleOverwriteAction upgrade - ChildBundles - - - BundleOverwriteAction - - RootRelativeBundlePath - Library/Frameworks/SwiftLintFramework.framework/Versions/A/Frameworks/SourceKittenFramework.framework - - - BundleOverwriteAction - - RootRelativeBundlePath - Library/Frameworks/SwiftLintFramework.framework/Versions/A/Frameworks/LlamaKit.framework - - - BundleOverwriteAction - - RootRelativeBundlePath - Library/Frameworks/SwiftLintFramework.framework/Versions/A/Frameworks/Commandant.framework - - RootRelativeBundlePath Library/Frameworks/SwiftLintFramework.framework diff --git a/Source/swiftlint/LintCommand.swift b/Source/swiftlint/LintCommand.swift index 937c62ecc..63ea59ec1 100644 --- a/Source/swiftlint/LintCommand.swift +++ b/Source/swiftlint/LintCommand.swift @@ -21,36 +21,43 @@ struct LintCommand: CommandType { func run(mode: CommandMode) -> Result<(), CommandantError<()>> { return LintOptions.evaluate(mode).flatMap { options in + let configuration = Configuration(path: options.configurationFile, + optional: !Process.arguments.contains("--config")) if options.useSTDIN { let standardInput = NSFileHandle.fileHandleWithStandardInput() let stdinData = standardInput.readDataToEndOfFile() let stdinNSString = NSString(data: stdinData, encoding: NSUTF8StringEncoding) if let stdinString = stdinNSString as? String { - let violations = Linter(file: File(contents: stdinString)).styleViolations - print(violations.map({ $0.description }).joinWithSeparator("\n")) + let file = File(contents: stdinString) + let linter = Linter(file: file, configuration: configuration) + print(linter.styleViolations.map({ $0.description }).joinWithSeparator("\n")) return .Success() } return .Failure(CommandantError<()>.CommandError()) } // Otherwise parse path. - return self.lint(options.path) + return lint(options.path, configuration: configuration) } } - private func lint(path: String) -> Result<(), CommandantError<()>> { - let filesToLint = filesToLintAtPath(path) + private func lint(path: String, + configuration: Configuration) -> Result<(), CommandantError<()>> { + let filesToLint = (configuration.included.count == 0 ? filesToLintAtPath(path) : []) + .filter({ !configuration.excluded.flatMap(filesToLintAtPath).contains($0) }) + + configuration.included.flatMap(filesToLintAtPath) if filesToLint.count > 0 { - if path == "" { + if path.isEmpty { print("Linting Swift files in current working directory") } else { print("Linting Swift files at path \(path)") } var numberOfViolations = 0, numberOfSeriousViolations = 0 - for (index, file) in filesToLint.enumerate() { - let filename = (file as NSString).lastPathComponent + for (index, path) in filesToLint.enumerate() { + let filename = (path as NSString).lastPathComponent print("Linting '\(filename)' (\(index + 1)/\(filesToLint.count))") - for violation in Linter(file: File(path: file)!).styleViolations { + let file = File(path: path)! + for violation in Linter(file: file, configuration: configuration).styleViolations { print(violation) numberOfViolations++ if violation.severity.isError { @@ -68,19 +75,15 @@ struct LintCommand: CommandType { ) if numberOfSeriousViolations <= 0 { return .Success() - } else { - // This represents failure of the content (i.e. violations in the files linted) - // and not failure of the scanning process itself. The current command architecture - // doesn't discriminate between these types. - return .Failure(CommandantError<()>.CommandError()) } + return .Failure(CommandantError<()>.CommandError()) } return .Failure(CommandantError<()>.UsageError(description: "No lintable files found at" + " path \(path)")) } private func filesToLintAtPath(path: String) -> [String] { - let absolutePath = path.absolutePathRepresentation() + let absolutePath = (path.absolutePathRepresentation() as NSString).stringByStandardizingPath var isDirectory: ObjCBool = false if fileManager.fileExistsAtPath(absolutePath, isDirectory: &isDirectory) { if isDirectory { @@ -98,15 +101,22 @@ struct LintCommand: CommandType { struct LintOptions: OptionsType { let path: String let useSTDIN: Bool + let configurationFile: String - static func create(path: String)(useSTDIN: Bool) -> LintOptions { - return LintOptions(path: path, useSTDIN: useSTDIN) + static func create(path: String)(useSTDIN: Bool)(configurationFile: String) -> LintOptions { + return LintOptions(path: path, useSTDIN: useSTDIN, configurationFile: configurationFile) } static func evaluate(m: CommandMode) -> Result> { return create - <*> m <| Option(key: "path", defaultValue: "", usage: "the path to the file or" + - " directory to lint") - <*> m <| Option(key: "use-stdin", defaultValue: false, usage: "lint standard input") + <*> m <| Option(key: "path", + defaultValue: "", + usage: "the path to the file or directory to lint") + <*> m <| Option(key: "use-stdin", + defaultValue: false, + usage: "lint standard input") + <*> m <| Option(key: "config", + defaultValue: ".swiftlint.yml", + usage: "the path to SwiftLint's configuration file") } } diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj index 360b7c4db..15dd91249 100644 --- a/SwiftLint.xcodeproj/project.pbxproj +++ b/SwiftLint.xcodeproj/project.pbxproj @@ -19,6 +19,8 @@ D0E7B65619E9C76900EDBA4D /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D1211B19E87861005E4BAA /* main.swift */; }; E57B23C11B1D8BF000DEA512 /* ReturnArrowWhitespaceRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E57B23C01B1D8BF000DEA512 /* ReturnArrowWhitespaceRule.swift */; }; E5A167C91B25A0B000CF2D03 /* OperatorFunctionWhitespaceRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5A167C81B25A0B000CF2D03 /* OperatorFunctionWhitespaceRule.swift */; }; + E809EDA11B8A71DF00399043 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E809EDA01B8A71DF00399043 /* Configuration.swift */; }; + E809EDA31B8A73FB00399043 /* ConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E809EDA21B8A73FB00399043 /* ConfigurationTests.swift */; }; E812249A1B04F85B001783D2 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81224991B04F85B001783D2 /* TestHelpers.swift */; }; E812249C1B04FADC001783D2 /* Linter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E812249B1B04FADC001783D2 /* Linter.swift */; }; E832F10B1B17E2F5003F265F /* NSFileManager+SwiftLint.swift in Sources */ = {isa = PBXBuildFile; fileRef = E832F10A1B17E2F5003F265F /* NSFileManager+SwiftLint.swift */; }; @@ -147,6 +149,8 @@ D0E7B63219E9C64500EDBA4D /* swiftlint.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = swiftlint.app; sourceTree = BUILT_PRODUCTS_DIR; }; E57B23C01B1D8BF000DEA512 /* ReturnArrowWhitespaceRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReturnArrowWhitespaceRule.swift; sourceTree = ""; }; E5A167C81B25A0B000CF2D03 /* OperatorFunctionWhitespaceRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperatorFunctionWhitespaceRule.swift; sourceTree = ""; }; + E809EDA01B8A71DF00399043 /* Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; + E809EDA21B8A73FB00399043 /* ConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurationTests.swift; sourceTree = ""; }; E81224991B04F85B001783D2 /* TestHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestHelpers.swift; sourceTree = ""; }; E812249B1B04FADC001783D2 /* Linter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Linter.swift; sourceTree = ""; }; E832F10A1B17E2F5003F265F /* NSFileManager+SwiftLint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFileManager+SwiftLint.swift"; sourceTree = ""; }; @@ -346,6 +350,7 @@ isa = PBXGroup; children = ( E88DEA8B1B0999A000A66CB0 /* ASTRule.swift */, + E809EDA01B8A71DF00399043 /* Configuration.swift */, 24E17F701B1481FF008195BE /* File+Cache.swift */, E88DEA741B09852000A66CB0 /* File+SwiftLint.swift */, E812249B1B04FADC001783D2 /* Linter.swift */, @@ -385,6 +390,7 @@ isa = PBXGroup; children = ( E8BB8F991B17DDB200199606 /* ASTRuleTests.swift */, + E809EDA21B8A73FB00399043 /* ConfigurationTests.swift */, E832F10C1B17E725003F265F /* IntegrationTests.swift */, E8BB8F9B1B17DE3B00199606 /* StringRuleTests.swift */, E81224991B04F85B001783D2 /* TestHelpers.swift */, @@ -579,7 +585,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\n cd Source && swiftlint\nelse\n echo \"SwiftLint not installed. Skipping lint.\"\nfi"; + shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"SwiftLint not installed. Skipping lint.\"\nfi"; }; /* End PBXShellScriptBuildPhase section */ @@ -594,6 +600,7 @@ E57B23C11B1D8BF000DEA512 /* ReturnArrowWhitespaceRule.swift in Sources */, E88DEA841B0990F500A66CB0 /* ColonRule.swift in Sources */, E88DEA791B098D4400A66CB0 /* RuleParameter.swift in Sources */, + E809EDA11B8A71DF00399043 /* Configuration.swift in Sources */, E88DEA731B0984C400A66CB0 /* String+SwiftLint.swift in Sources */, 24E17F721B14BB3F008195BE /* File+Cache.swift in Sources */, E88DEA6D1B09842200A66CB0 /* StyleViolationType.swift in Sources */, @@ -628,6 +635,7 @@ E812249A1B04F85B001783D2 /* TestHelpers.swift in Sources */, E8BB8F9C1B17DE3B00199606 /* StringRuleTests.swift in Sources */, E8BB8F9A1B17DDB200199606 /* ASTRuleTests.swift in Sources */, + E809EDA31B8A73FB00399043 /* ConfigurationTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -696,7 +704,7 @@ "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", ); FRAMEWORK_VERSION = A; - INFOPLIST_FILE = "$(SRCROOT)/Source/SwiftLintFramework/Info.plist"; + INFOPLIST_FILE = "Source/SwiftLintFramework/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks $(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -728,7 +736,7 @@ "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", ); FRAMEWORK_VERSION = A; - INFOPLIST_FILE = "$(SRCROOT)/Source/SwiftLintFramework/Info.plist"; + INFOPLIST_FILE = "Source/SwiftLintFramework/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks $(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -798,7 +806,7 @@ "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", ); FRAMEWORK_VERSION = A; - INFOPLIST_FILE = "$(SRCROOT)/Source/SwiftLintFramework/Info.plist"; + INFOPLIST_FILE = "Source/SwiftLintFramework/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks $(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -854,7 +862,7 @@ "$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib", ); FRAMEWORK_VERSION = A; - INFOPLIST_FILE = "$(SRCROOT)/Source/SwiftLintFramework/Info.plist"; + INFOPLIST_FILE = "Source/SwiftLintFramework/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks $(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -891,7 +899,7 @@ baseConfigurationReference = D0D1213419E878CC005E4BAA /* Mac-Application.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = "$(SRCROOT)/Source/swiftlint/Info.plist"; + INFOPLIST_FILE = "Source/swiftlint/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@executable_path/. @executable_path/../Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks /Library/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -903,7 +911,7 @@ baseConfigurationReference = D0D1213419E878CC005E4BAA /* Mac-Application.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = "$(SRCROOT)/Source/swiftlint/Info.plist"; + INFOPLIST_FILE = "Source/swiftlint/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@executable_path/. @executable_path/../Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks /Library/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -915,7 +923,7 @@ baseConfigurationReference = D0D1213419E878CC005E4BAA /* Mac-Application.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = "$(SRCROOT)/Source/swiftlint/Info.plist"; + INFOPLIST_FILE = "Source/swiftlint/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@executable_path/. @executable_path/../Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks /Library/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -927,7 +935,7 @@ baseConfigurationReference = D0D1213419E878CC005E4BAA /* Mac-Application.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = "$(SRCROOT)/Source/swiftlint/Info.plist"; + INFOPLIST_FILE = "Source/swiftlint/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@executable_path/. @executable_path/../Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks @executable_path/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks /Library/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks /Library/Frameworks/SwiftLintFramework.framework/Versions/Current/Frameworks/SourceKittenFramework.framework/Versions/Current/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "io.realm.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; From 57a8abb5140031183f7f65bd685e8ffc5a39ffa1 Mon Sep 17 00:00:00 2001 From: JP Simard Date: Tue, 25 Aug 2015 16:04:58 -0700 Subject: [PATCH 6/9] update for Xcode 7 Beta 6 --- .gitmodules | 2 +- Cartfile.private | 2 +- Cartfile.resolved | 2 +- Carthage/Checkouts/YamlSwift | 2 +- Source/SwiftLintFramework/Configuration.swift | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index 913332702..c8a728afb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -21,4 +21,4 @@ url = https://github.com/antitypical/Result.git [submodule "Carthage/Checkouts/YamlSwift"] path = Carthage/Checkouts/YamlSwift - url = https://github.com/behrang/YamlSwift.git + url = https://github.com/jpsim/YamlSwift.git diff --git a/Cartfile.private b/Cartfile.private index 14cb9c919..3c3f0fedf 100644 --- a/Cartfile.private +++ b/Cartfile.private @@ -1,3 +1,3 @@ github "Carthage/Commandant" "swift-2.0" github "jspahrsummers/xcconfigs" >= 0.8 -github "behrang/YamlSwift" ~> 1.2 +github "jpsim/YamlSwift" "master" diff --git a/Cartfile.resolved b/Cartfile.resolved index 008bdb5ab..71f224617 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,7 +1,7 @@ github "antitypical/Result" "0.6-beta.1" github "drmohundro/SWXMLHash" "050154bfc56032f04fcca37464693a17f897200a" github "jpsim/SwiftXPC" "d32e70f1b35cfa833be85fd40e70401f4190f5b0" -github "behrang/YamlSwift" "v1.2.0" +github "jpsim/YamlSwift" "ed060df018b5693a045f207088b95ce15f433065" github "jspahrsummers/xcconfigs" "0.8.1" github "Carthage/Commandant" "40f503c33121431dc098adb7c44d9496e3a1de2f" github "jpsim/SourceKitten" "ace729472170a4ec2996b8f921fc66784e5ef4fe" diff --git a/Carthage/Checkouts/YamlSwift b/Carthage/Checkouts/YamlSwift index 5b6a706c8..ed060df01 160000 --- a/Carthage/Checkouts/YamlSwift +++ b/Carthage/Checkouts/YamlSwift @@ -1 +1 @@ -Subproject commit 5b6a706c8207eda937a2c640ceb358d8fc5eb337 +Subproject commit ed060df018b5693a045f207088b95ce15f433065 diff --git a/Source/SwiftLintFramework/Configuration.swift b/Source/SwiftLintFramework/Configuration.swift index 2e33bd786..3804bd4d7 100644 --- a/Source/SwiftLintFramework/Configuration.swift +++ b/Source/SwiftLintFramework/Configuration.swift @@ -37,7 +37,7 @@ public struct Configuration { if invalidRules.count > 0 { for invalidRule in invalidRules { fputs("config error: '\(invalidRule)' is not a valid rule identifier\n", stderr) - let listOfValidRuleIdentifiers = "\n".join(validRuleIdentifiers) + let listOfValidRuleIdentifiers = validRuleIdentifiers.joinWithSeparator("\n") fputs("Valid rule identifiers:\n\(listOfValidRuleIdentifiers)\n", stderr) } return nil From 3ac2fa2ce65c5f2a3107c311238b8435d9c6210b Mon Sep 17 00:00:00 2001 From: JP Simard Date: Fri, 28 Aug 2015 11:54:32 -0700 Subject: [PATCH 7/9] behrang/YamlSwift --- .gitmodules | 4 ++-- Cartfile.private | 2 +- Cartfile.resolved | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index c8a728afb..5afa9b035 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,7 @@ url = https://github.com/Carthage/Commandant.git [submodule "Carthage/Checkouts/SWXMLHash"] path = Carthage/Checkouts/SWXMLHash - url = https://github.com/jpsim/SWXMLHash.git + url = https://github.com/drmohundro/SWXMLHash.git [submodule "Carthage/Checkouts/SourceKitten"] path = Carthage/Checkouts/SourceKitten url = https://github.com/jpsim/SourceKitten.git @@ -21,4 +21,4 @@ url = https://github.com/antitypical/Result.git [submodule "Carthage/Checkouts/YamlSwift"] path = Carthage/Checkouts/YamlSwift - url = https://github.com/jpsim/YamlSwift.git + url = https://github.com/behrang/YamlSwift.git diff --git a/Cartfile.private b/Cartfile.private index 3c3f0fedf..e5831ffc3 100644 --- a/Cartfile.private +++ b/Cartfile.private @@ -1,3 +1,3 @@ github "Carthage/Commandant" "swift-2.0" github "jspahrsummers/xcconfigs" >= 0.8 -github "jpsim/YamlSwift" "master" +github "behrang/YamlSwift" "master" diff --git a/Cartfile.resolved b/Cartfile.resolved index 71f224617..1efd11e1f 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,7 +1,7 @@ github "antitypical/Result" "0.6-beta.1" github "drmohundro/SWXMLHash" "050154bfc56032f04fcca37464693a17f897200a" github "jpsim/SwiftXPC" "d32e70f1b35cfa833be85fd40e70401f4190f5b0" -github "jpsim/YamlSwift" "ed060df018b5693a045f207088b95ce15f433065" +github "behrang/YamlSwift" "243ebbafb8ed60f57f9d5a7c2a4ff8099824644a" github "jspahrsummers/xcconfigs" "0.8.1" github "Carthage/Commandant" "40f503c33121431dc098adb7c44d9496e3a1de2f" github "jpsim/SourceKitten" "ace729472170a4ec2996b8f921fc66784e5ef4fe" From 7b9ac810a8be99d15156dfe2f3e643861950a53c Mon Sep 17 00:00:00 2001 From: JP Simard Date: Fri, 28 Aug 2015 13:11:26 -0700 Subject: [PATCH 8/9] [CHANGELOG] added Swift 2 entry --- CHANGELOG.md | 4 +++- README.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbc37644c..28a633632 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ ##### Breaking -* None. +* SwiftLint now exclusively supports Swift 2.0. + [JP Simard](https://github.com/jpsim) + [#77](https://github.com/realm/SwiftLint/issues/77) ##### Enhancements diff --git a/README.md b/README.md index 41e5f857d..307f0e5b4 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ You can also install SwiftLint by downloading `SwiftLint.pkg` from the running it. You can also build from source by cloning this project and running -`make install`. +`make install` (Xcode 7 Beta 6 required). ## Usage From 9a65c5bdb858e3eab34a65e9bdeb6afd12282b0b Mon Sep 17 00:00:00 2001 From: JP Simard Date: Fri, 28 Aug 2015 13:17:16 -0700 Subject: [PATCH 9/9] extra space --- Source/swiftlint/StructuredText.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/swiftlint/StructuredText.swift b/Source/swiftlint/StructuredText.swift index 289170219..7423f3740 100644 --- a/Source/swiftlint/StructuredText.swift +++ b/Source/swiftlint/StructuredText.swift @@ -35,7 +35,7 @@ enum StructuredText { case .Header(_, let t): return t case .Paragraph(let t): return t case .List(let items): return items.map({ "* " + $0.ansi }).joinWithSeparator("\n") - case .Joined(let items): return items.map({ $0.ansi } ).joinWithSeparator("\n\n") + case .Joined(let items): return items.map({ $0.ansi }).joinWithSeparator("\n\n") } } }