├── .circleci └── config.yml ├── .gitignore ├── .swiftlint.yml ├── CHANGELOG.md ├── LICENSE ├── Package.resolved ├── Package.swift ├── README.md ├── Sources └── DangerSwiftLint │ ├── CurrentPathProvider.swift │ ├── DangerSwiftLint.swift │ ├── ShellExecutor.swift │ └── Violation.swift ├── Tests ├── DangerSwiftLintTests │ ├── DangerSwiftLintTests.swift │ ├── FakeCurrentPathProvider.swift │ ├── FakeShellExecutor.swift │ ├── URL+Utils.swift │ └── ViolationTests.swift ├── Fixtures │ ├── harness.json │ └── harness_directories.json └── LinuxMain.swift └── docs └── Deploy.md /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: ~/ashfurrow/danger-swiftlint 5 | parallelism: 1 6 | shell: /bin/bash --login 7 | environment: 8 | LANG: en_US.UTF-8 9 | macos: 10 | xcode: '9.3.0' 11 | steps: 12 | - checkout 13 | - restore_cache: 14 | keys: 15 | - v1-build-{{ .Branch }}- 16 | - run: 17 | name: swift package update 18 | command: swift package update 19 | - run: 20 | name: swift build 21 | command: swift build 22 | - run: 23 | name: swift test 24 | command: swift test 25 | - save_cache: 26 | key: v1-build-{{ .Branch }}-{{ epoch }} 27 | paths: 28 | - .build 29 | - store_test_results: 30 | path: test_output/report.xml 31 | - store_artifacts: 32 | path: /tmp/test-results 33 | destination: scan-test-results 34 | - store_artifacts: 35 | path: ~/Library/Logs/scan 36 | destination: scan-logs -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | DangerSwiftLint.xcodeproj/ 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | excluded: 2 | - .build/ 3 | 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Next 2 | 3 | - Added `swiftlintPath` option to `SwiftLint.lint()`. This allows providing a custom path if you want to use a specific binary instead of the global one (e.g. when using CocoaPods). 4 | 5 | ## 0.4.0 6 | 7 | - Added `lintAllFiles` option to `SwiftLint.lint()`. This will lint all existing files (instead of just the added/modified ones). However, nested configurations works when this option is enabled. 8 | 9 | ## 0.3.0 10 | 11 | - Added `inline` option to `SwiftLint.lint()`. This will trigger an inline comment instead of gathering all violations in a big main comment. For more details about inline mode, see [this docs in Danger JS](https://github.com/danger/danger-js/blob/master/CHANGELOG.md#340). 12 | 13 | ## 0.2.1 14 | 15 | - Fixed bug where source and config file paths that contain spaces would trigger erronuous failure messages. 16 | 17 | ## 0.2.0 18 | 19 | - Added `directory` & `configFile` options to `SwiftLint.lint()` function. 20 | 21 | ## 0.1.0 22 | 23 | - This is the initial public relase. 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ash Furrow 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "danger-swift", 6 | "repositoryURL": "https://github.com/danger/danger-swift.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "dd0d6457adf72eedeb10076e1887d49431fd56a6", 10 | "version": "0.4.0" 11 | } 12 | }, 13 | { 14 | "package": "Files", 15 | "repositoryURL": "https://github.com/JohnSundell/Files.git", 16 | "state": { 17 | "branch": null, 18 | "revision": "06f95bd1bf4f8d5f50bc6bb30b808c253acd4c88", 19 | "version": "2.2.1" 20 | } 21 | }, 22 | { 23 | "package": "Marathon", 24 | "repositoryURL": "https://github.com/JohnSundell/Marathon.git", 25 | "state": { 26 | "branch": null, 27 | "revision": "959e82b044f7dbb2680c6e7cdaa80d70e9dfa4ca", 28 | "version": "3.0.0" 29 | } 30 | }, 31 | { 32 | "package": "Releases", 33 | "repositoryURL": "https://github.com/JohnSundell/Releases.git", 34 | "state": { 35 | "branch": null, 36 | "revision": "e74f0895855b56147cb96f2d45aba3ec37da64fb", 37 | "version": "3.0.0" 38 | } 39 | }, 40 | { 41 | "package": "Require", 42 | "repositoryURL": "https://github.com/JohnSundell/Require.git", 43 | "state": { 44 | "branch": null, 45 | "revision": "7cfbd0d8a2dede0e01f6f0d8ab2c7acef1df112e", 46 | "version": "2.0.1" 47 | } 48 | }, 49 | { 50 | "package": "ShellOut", 51 | "repositoryURL": "https://github.com/JohnSundell/ShellOut.git", 52 | "state": { 53 | "branch": null, 54 | "revision": "f1c253a34a40df4bfd268b09fdb101b059f6d52d", 55 | "version": "2.1.0" 56 | } 57 | }, 58 | { 59 | "package": "Unbox", 60 | "repositoryURL": "https://github.com/JohnSundell/Unbox.git", 61 | "state": { 62 | "branch": null, 63 | "revision": "17ad6aa1cc2f1efa27a0bbbdb66f79796708aa95", 64 | "version": "2.5.0" 65 | } 66 | }, 67 | { 68 | "package": "Wrap", 69 | "repositoryURL": "https://github.com/JohnSundell/Wrap.git", 70 | "state": { 71 | "branch": null, 72 | "revision": "8085c925060b84a1fc0caef444c130da2c8154c3", 73 | "version": "3.0.1" 74 | } 75 | } 76 | ] 77 | }, 78 | "version": 1 79 | } 80 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.0 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "DangerSwiftLint", 7 | products: [ 8 | .library( 9 | name: "DangerSwiftLint", 10 | targets: ["DangerSwiftLint"]), 11 | ], 12 | dependencies: [ 13 | .package(url: "https://github.com/danger/danger-swift.git", from: "0.3.0") 14 | ], 15 | targets: [ 16 | .target( 17 | name: "DangerSwiftLint", 18 | dependencies: ["Danger"]), 19 | .testTarget( 20 | name: "DangerSwiftLintTests", 21 | dependencies: ["DangerSwiftLint"]), 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Deprecation Notice**: This repo has been deprecated, since SwiftLint integration is now a part of [Danger Swift](https://github.com/danger/swift) as a first-class feature. You can read [this issue](https://github.com/ashfurrow/danger-swiftlint/issues/17) for context. This repo will remain available for legacy use, but **new projects should _not_ use this repo**. 2 | 3 | --- 4 | 5 | [![CircleCI](https://circleci.com/gh/ashfurrow/danger-swiftlint.svg?style=svg)](https://circleci.com/gh/ashfurrow/danger-swiftlint) 6 | 7 | # Danger SwiftLint 8 | 9 | [Danger Swift](https://github.com/danger/danger-swift) plugin for [SwiftLint](https://github.com/realm/SwiftLint/). So you can get SwiftLint warnings on your pull requests! 10 | 11 | (**Note**: If you're looking for the _Ruby_ version of this Danger plugin, it has been moved [here](https://github.com/ashfurrow/danger-ruby-swiftlint).) 12 | 13 | ## Usage 14 | 15 | [Install and run](https://github.com/danger/danger-swift#ci-configuration) Danger Swift as normal and install SwiftLint in your CI's config file. Something like: 16 | 17 | ```yaml 18 | dependencies: 19 | override: 20 | - npm install -g danger # This installs Danger 21 | - brew install danger/tap/danger-swift # This installs Danger-Swift 22 | - brew install swiftlint # This is for the Danger SwiftLint plugin. 23 | ``` 24 | 25 | Then use the following `Dangerfile.swift`. 26 | 27 | ```swift 28 | // Dangerfile.swift 29 | 30 | import Danger 31 | import DangerSwiftLint // package: https://github.com/ashfurrow/danger-swiftlint.git 32 | 33 | SwiftLint.lint() 34 | ``` 35 | 36 | That will lint the created and modified files 37 | 38 | #### Inline mode 39 | 40 | If you want the lint result shows in diff instead of comment, you can use inline_mode option. Violations that out of the diff will show in danger's fail or warn section. 41 | 42 | ```swift 43 | SwiftLint.lint(inline: true) 44 | ``` 45 | 46 | #### Config & Directory 47 | 48 | You can also specify a path to the config file using `configFile` parameter and a path to the directory you want to lint using `directory` parameter. This is helpful when you want to have different config files for different directories. E.g. Harvey wants to lint test files differently than the source files, thus they have the following setup: 49 | 50 | ```swift 51 | SwiftLint.lint(directory: "Sources", configFile: ".swiftlint.yml") 52 | SwiftLint.lint(directory: "Tests", configFile: "Tests/HarveyTests/.swiftlint.yml") 53 | ``` 54 | 55 | ### Lint all files 56 | 57 | By default, only files that were added or modified are linted. 58 | 59 | It's not possible to use [nested configurations](https://github.com/realm/SwiftLint#nested-configurations) in that case, because Danger SwiftLint lints each file on it's own, and by doing that the nested configuration is disabled. If you want to learn more details about this, read the whole issue [here](https://github.com/ashfurrow/danger-swiftlint/issues/4). 60 | 61 | However, you can use the `lintAllFiles` option to lint all the files. In that case, Danger SwiftLint doesn't lint files individually, which makes nested configuration to work. It'd be the same as you were running `swiftlint` on the root folder: 62 | 63 | ```swift 64 | SwiftLint.lint(lintAllFiles: true) 65 | ``` 66 | 67 | ### Custom SwiftLint binary path 68 | 69 | By default, Danger SwiftLint runs `swiftlint` assuming it's installed globally. However, there're cases where it makes sense to use a different path. One example would be if you've installed SwiftLint using [CocoaPods](https://github.com/CocoaPods/CocoaPods). 70 | 71 | To use another binary, you can use the `swiftlintPath` option: 72 | 73 | ```swift 74 | SwiftLint.lint(swiftlintPath: "Pods/SwiftLint/swiftlint") 75 | ``` 76 | 77 | # Contributing 78 | 79 | If you find a bug, please [open an issue](https://github.com/ashfurrow/danger-swiftlint/issues/new)! Or a pull request :wink: 80 | 81 | No, seriously. 82 | 83 | This is the first command line Swift I've ever written, and it's the first Danger Swift plugin _anyone_ has ever written, so if something doesn't work, I could really use your help figuring out the problem. 84 | 85 | A good place to start is writing a failing unit test. Then you can try to fix the bug. First, you'll need to fork the repo and clone your fork locally. Build it and run the unit tests. 86 | 87 | ```sh 88 | git clone https://github.com/YOUR_USERNAME/danger-swiftlint.git 89 | cd danger-swiftlint 90 | swift build 91 | swift test 92 | ``` 93 | 94 | Alright, verify that everything so far works before going further. To write your tests and modify the plugin files, run `swift package generate-xcodeproj`. Open the generated Xcode project and enjoy the modernities of code autocomplete and inline documentation. You can even run the unit tests from Xcode (sometimes results are inconsistent with running `swift test`). 95 | 96 | One place that unit tests have a hard time covering is the integration with the `swiftlint` command line tool. If you're changing code there, open a pull request ([like this one](https://github.com/Moya/Harvey/pull/15)) to test everything works. 97 | 98 | # Customizing 99 | 100 | There are tonnes of ways this plugin can be customized for individual use cases. After building [the Ruby version](https://github.com/ashfurrow/danger-ruby-swiftlint) of this plugin, I realized that it's really difficult to scale up a tool that works for everyone. So instead, I'm treating this project as a template, that you to do fork and customize however you like! 101 | 102 | 1. [Fork](https://github.com/ashfurrow/danger-swiftlint#fork-destination-box) this project. 103 | 1. Change the `import DangerSwiftLint` package URL to point to your fork. 104 | 1. After making your changes to the plugin, push them to your fork and **push a new tag**. 105 | 106 | Because you need to tag a new version, testing your plugin can be tricky. I've built some basic unit tests, so you should be able to use test-driven development for most of your changes. 107 | 108 | If you think you've got a real general-purpose feature that most users of this plugin would benefit from, I would be grateful for a pull request. 109 | 110 | # License 111 | 112 | [#MIT4Lyfe](LICENSE) 113 | 114 | # A Fun GIF 115 | 116 |
117 | Your feeling when you lint your swift code 118 | 119 |
120 | -------------------------------------------------------------------------------- /Sources/DangerSwiftLint/CurrentPathProvider.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | internal protocol CurrentPathProvider { 4 | var currentPath: String { get } 5 | } 6 | 7 | internal final class DefaultCurrentPathProvider: CurrentPathProvider { 8 | var currentPath: String { 9 | return ShellExecutor().execute("pwd") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Sources/DangerSwiftLint/DangerSwiftLint.swift: -------------------------------------------------------------------------------- 1 | import Danger 2 | import Foundation 3 | 4 | public struct SwiftLint { 5 | internal static let danger = Danger() 6 | internal static let shellExecutor = ShellExecutor() 7 | 8 | /// This is the main entry point for linting Swift in PRs using Danger-Swift. 9 | /// Call this function anywhere from within your Dangerfile.swift. 10 | @discardableResult 11 | public static func lint(inline: Bool = false, directory: String? = nil, 12 | configFile: String? = nil, lintAllFiles: Bool = false, 13 | swiftlintPath: String = "swiftlint") -> [Violation] { 14 | // First, for debugging purposes, print the working directory. 15 | print("Working directory: \(shellExecutor.execute("pwd"))") 16 | return self.lint(danger: danger, shellExecutor: shellExecutor, inline: inline, directory: directory, 17 | configFile: configFile, lintAllFiles: lintAllFiles, swiftlintPath: swiftlintPath) 18 | } 19 | } 20 | 21 | /// This extension is for internal workings of the plugin. It is marked as internal for unit testing. 22 | internal extension SwiftLint { 23 | static func lint( 24 | danger: DangerDSL, 25 | shellExecutor: ShellExecutor, 26 | inline: Bool = false, 27 | directory: String? = nil, 28 | configFile: String? = nil, 29 | lintAllFiles: Bool = false, 30 | swiftlintPath: String = "swiftlint", 31 | currentPathProvider: CurrentPathProvider = DefaultCurrentPathProvider(), 32 | markdownAction: (String) -> Void = markdown, 33 | failAction: (String) -> Void = fail, 34 | failInlineAction: (String, String, Int) -> Void = fail, 35 | warnInlineAction: (String, String, Int) -> Void = warn) -> [Violation] { 36 | // Gathers modified+created files, invokes SwiftLint on each, and posts collected errors+warnings to Danger. 37 | 38 | var violations: [Violation] 39 | if lintAllFiles { 40 | var arguments = ["lint", "--quiet", "--reporter json"] 41 | if let directory = directory { 42 | arguments.append("--path \"\(directory)\"") 43 | } 44 | if let configFile = configFile { 45 | arguments.append("--config \"\(configFile)\"") 46 | } 47 | let outputJSON = shellExecutor.execute(swiftlintPath, arguments: arguments) 48 | violations = makeViolations(from: outputJSON, failAction: failAction) 49 | } else { 50 | var files = danger.git.createdFiles + danger.git.modifiedFiles 51 | if let directory = directory { 52 | files = files.filter { $0.hasPrefix(directory) } 53 | } 54 | 55 | violations = files.filter { $0.hasSuffix(".swift") }.flatMap { file -> [Violation] in 56 | var arguments = ["lint", "--quiet", "--path \"\(file)\"", "--reporter json"] 57 | if let configFile = configFile { 58 | arguments.append("--config \"\(configFile)\"") 59 | } 60 | let outputJSON = shellExecutor.execute(swiftlintPath, arguments: arguments) 61 | return makeViolations(from: outputJSON, failAction: failAction) 62 | } 63 | } 64 | 65 | let currentPath = currentPathProvider.currentPath 66 | violations = violations.map { violation in 67 | let updatedPath = violation.file.deletingPrefix(currentPath).deletingPrefix("/") 68 | var violation = violation 69 | violation.update(file: updatedPath) 70 | return violation 71 | } 72 | 73 | if !violations.isEmpty { 74 | if inline { 75 | violations.forEach { violation in 76 | switch violation.severity { 77 | case .error: 78 | failInlineAction(violation.reason, violation.file, violation.line) 79 | case .warning: 80 | warnInlineAction(violation.reason, violation.file, violation.line) 81 | } 82 | } 83 | } else { 84 | var markdownMessage = """ 85 | ### SwiftLint found issues 86 | 87 | | Severity | File | Reason | 88 | | -------- | ---- | ------ |\n 89 | """ 90 | markdownMessage += violations.map { $0.toMarkdown() }.joined(separator: "\n") 91 | markdownAction(markdownMessage) 92 | } 93 | } 94 | 95 | return violations 96 | } 97 | 98 | private static func makeViolations(from response: String, failAction: (String) -> Void) -> [Violation] { 99 | let decoder = JSONDecoder() 100 | do { 101 | let violations = try decoder.decode([Violation].self, from: response.data(using: .utf8)!) 102 | return violations 103 | } catch { 104 | failAction("Error deserializing SwiftLint JSON response (\(response)): \(error)") 105 | return [] 106 | } 107 | } 108 | } 109 | 110 | private extension String { 111 | func deletingPrefix(_ prefix: String) -> String { 112 | guard hasPrefix(prefix) else { return self } 113 | return String(dropFirst(prefix.count)) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Sources/DangerSwiftLint/ShellExecutor.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | internal class ShellExecutor { 4 | func execute(_ command: String, arguments: [String] = []) -> String { 5 | let script = "\(command) \(arguments.joined(separator: " "))" 6 | print("Executing \(script)") 7 | 8 | var env = ProcessInfo.processInfo.environment 9 | let task = Process() 10 | task.launchPath = env["SHELL"] 11 | task.arguments = ["-l", "-c", script] 12 | task.currentDirectoryPath = FileManager.default.currentDirectoryPath 13 | 14 | let pipe = Pipe() 15 | task.standardOutput = pipe 16 | task.launch() 17 | task.waitUntilExit() 18 | 19 | let data = pipe.fileHandleForReading.readDataToEndOfFile() 20 | return String(data: data, encoding: String.Encoding.utf8)! 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Sources/DangerSwiftLint/Violation.swift: -------------------------------------------------------------------------------- 1 | public struct Violation: Codable { 2 | enum Severity: String, Codable { 3 | case warning = "Warning" 4 | case error = "Error" 5 | } 6 | 7 | let ruleID: String 8 | let reason: String 9 | let line: Int 10 | let character: Int? 11 | let severity: Severity 12 | let type: String 13 | 14 | private(set) var file: String 15 | 16 | enum CodingKeys: String, CodingKey { 17 | case ruleID = "rule_id" 18 | case reason, line, character, file, severity, type 19 | } 20 | 21 | public init(from decoder: Decoder) throws { 22 | let values = try decoder.container(keyedBy: CodingKeys.self) 23 | ruleID = try values.decode(String.self, forKey: .ruleID) 24 | reason = try values.decode(String.self, forKey: .reason) 25 | line = try values.decode(Int.self, forKey: .line) 26 | character = try values.decode(Int?.self, forKey: .character) 27 | file = try values.decode(String.self, forKey: .file) 28 | severity = try values.decode(Severity.self, forKey: .severity) 29 | type = try values.decode(String.self, forKey: .type) 30 | } 31 | 32 | public func toMarkdown() -> String { 33 | let formattedFile = file.split(separator: "/").last! + ":\(line)" 34 | return "\(severity.rawValue) | \(formattedFile) | \(reason) |" 35 | } 36 | 37 | mutating func update(file: String) { 38 | self.file = file 39 | } 40 | } 41 | 42 | 43 | /* 44 | "rule_id" : "opening_brace", 45 | "reason" : "Opening braces should be preceded by a single space and on the same line as the declaration.", 46 | "character" : 39, 47 | "file" : "\/Users\/ash\/bin\/Harvey\/Sources\/Harvey\/Harvey.swift", 48 | "severity" : "Warning", 49 | "type" : "Opening Brace Spacing", 50 | "line" : 8 51 | */ 52 | -------------------------------------------------------------------------------- /Tests/DangerSwiftLintTests/DangerSwiftLintTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Danger 3 | @testable import DangerSwiftLint 4 | 5 | class DangerSwiftLintTests: XCTestCase { 6 | var executor: FakeShellExecutor! 7 | var fakePathProvider: FakeCurrentPathProvider! 8 | var danger: DangerDSL! 9 | var markdownMessage: String? 10 | 11 | override func setUp() { 12 | executor = FakeShellExecutor() 13 | fakePathProvider = FakeCurrentPathProvider() 14 | fakePathProvider.currentPath = "/Users/ash/bin" 15 | 16 | let localPath = URL(string: #file)!.deletingLastPathComponent(2).absoluteString 17 | FileManager.default.changeCurrentDirectoryPath(localPath) 18 | danger = parseDangerDSL(at: "./Tests/Fixtures/harness.json") 19 | markdownMessage = nil 20 | } 21 | 22 | func testExecutesTheShell() { 23 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, currentPathProvider: fakePathProvider) 24 | XCTAssertNotEqual(executor.invocations.dropFirst().count, 0) 25 | XCTAssertEqual(executor.invocations.first?.command, "swiftlint") 26 | } 27 | 28 | func testExecutesTheShellWithCustomSwiftLintPath() { 29 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, swiftlintPath: "Pods/SwiftLint/swiftlint", currentPathProvider: fakePathProvider) 30 | XCTAssertNotEqual(executor.invocations.dropFirst().count, 0) 31 | XCTAssertEqual(executor.invocations.first?.command, "Pods/SwiftLint/swiftlint") 32 | } 33 | 34 | func testExecuteSwiftLintInInlineMode() { 35 | mockViolationJSON() 36 | var warns = [(String, String, Int)]() 37 | let warnAction: (String, String, Int) -> Void = { warns.append(($0, $1, $2)) } 38 | 39 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, inline: true, currentPathProvider: fakePathProvider, warnInlineAction: warnAction) 40 | 41 | XCTAssertEqual(warns.first?.0, "Opening braces should be preceded by a single space and on the same line as the declaration.") 42 | XCTAssertEqual(warns.first?.1, "SomeFile.swift") 43 | XCTAssertEqual(warns.first?.2, 8) 44 | } 45 | 46 | func testExecutesSwiftLintWithConfigWhenPassed() { 47 | let configFile = "/Path/to/config/.swiftlint.yml" 48 | 49 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, configFile: configFile, currentPathProvider: fakePathProvider) 50 | 51 | let swiftlintCommands = executor.invocations.filter { $0.command == "swiftlint" } 52 | XCTAssertTrue(swiftlintCommands.count > 0) 53 | swiftlintCommands.forEach { command, arguments in 54 | XCTAssertTrue(arguments.contains("--config \"\(configFile)\"")) 55 | } 56 | } 57 | 58 | func testExecutesSwiftLintWithDirectoryPassed() { 59 | let directory = "Tests" 60 | danger = parseDangerDSL(at: "./Tests/Fixtures/harness_directories.json") 61 | 62 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, directory: directory, currentPathProvider: fakePathProvider) 63 | 64 | let swiftlintCommands = executor.invocations.filter { $0.command == "swiftlint" } 65 | XCTAssertEqual(swiftlintCommands.count, 1) 66 | XCTAssertTrue(swiftlintCommands.first!.arguments.contains("--path \"Tests/SomeFile.swift\"")) 67 | } 68 | 69 | func testExecutesSwiftLintWhenLintingAllFiles() { 70 | danger = parseDangerDSL(at: "./Tests/Fixtures/harness_directories.json") 71 | 72 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, lintAllFiles: true, currentPathProvider: fakePathProvider) 73 | 74 | let swiftlintCommands = executor.invocations.filter { $0.command == "swiftlint" } 75 | XCTAssertEqual(swiftlintCommands.count, 1) 76 | XCTAssertFalse(swiftlintCommands.first!.arguments.contains("--path")) 77 | } 78 | 79 | func testExecutesSwiftLintWhenLintingAllFilesWithDirectoryPassed() { 80 | let directory = "Tests" 81 | danger = parseDangerDSL(at: "./Tests/Fixtures/harness_directories.json") 82 | 83 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, directory: directory, lintAllFiles: true, currentPathProvider: fakePathProvider) 84 | 85 | let swiftlintCommands = executor.invocations.filter { $0.command == "swiftlint" } 86 | XCTAssertEqual(swiftlintCommands.count, 1) 87 | XCTAssertFalse(swiftlintCommands.first!.arguments.contains("--path \"Tests/SomeFile.swift\"")) 88 | XCTAssertTrue(swiftlintCommands.first!.arguments.contains("--path \"Tests\"")) 89 | } 90 | 91 | func testFiltersOnSwiftFiles() { 92 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, currentPathProvider: fakePathProvider) 93 | 94 | let quoteCharacterSet = CharacterSet(charactersIn: "\"") 95 | let filesExtensions = Set(executor.invocations.dropFirst().compactMap { $0.arguments[2].split(separator: ".").last?.trimmingCharacters(in: quoteCharacterSet) }) 96 | XCTAssertEqual(filesExtensions, ["swift"]) 97 | } 98 | 99 | func testPrintsNoMarkdownIfNoViolations() { 100 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, currentPathProvider: fakePathProvider) 101 | XCTAssertNil(markdownMessage) 102 | } 103 | 104 | func testViolations() { 105 | mockViolationJSON() 106 | let violations = SwiftLint.lint(danger: danger, shellExecutor: executor, currentPathProvider: fakePathProvider, markdownAction: writeMarkdown) 107 | XCTAssertEqual(violations.count, 2) // Two files, one (identical oops) violation returned for each. 108 | } 109 | 110 | func testMarkdownReporting() { 111 | mockViolationJSON() 112 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, currentPathProvider: fakePathProvider, markdownAction: writeMarkdown) 113 | XCTAssertNotNil(markdownMessage) 114 | XCTAssertTrue(markdownMessage!.contains("SwiftLint found issues")) 115 | } 116 | 117 | func testQuotesPathArguments() { 118 | danger = parseDangerDSL(at: "./Tests/Fixtures/harness_directories.json") 119 | 120 | _ = SwiftLint.lint(danger: danger, shellExecutor: executor, currentPathProvider: fakePathProvider) 121 | 122 | let swiftlintCommands = executor.invocations.filter { $0.command == "swiftlint" } 123 | 124 | XCTAssertTrue(swiftlintCommands.count > 0) 125 | 126 | let spacedDirSwiftlintCommands = swiftlintCommands.filter { (_, arguments) in 127 | arguments.contains("--path \"Test Dir/SomeThirdFile.swift\"") 128 | } 129 | 130 | XCTAssertEqual(spacedDirSwiftlintCommands.count, 1) 131 | } 132 | 133 | func mockViolationJSON() { 134 | executor.output = """ 135 | [ 136 | { 137 | "rule_id" : "opening_brace", 138 | "reason" : "Opening braces should be preceded by a single space and on the same line as the declaration.", 139 | "character" : 39, 140 | "file" : "/Users/ash/bin/SomeFile.swift", 141 | "severity" : "Warning", 142 | "type" : "Opening Brace Spacing", 143 | "line" : 8 144 | } 145 | ] 146 | """ 147 | } 148 | 149 | func writeMarkdown(_ m: String) { 150 | markdownMessage = m 151 | } 152 | 153 | func parseDangerDSL(at path: String) -> DangerDSL { 154 | let dslJSONContents = FileManager.default.contents(atPath: path)! 155 | let decoder = JSONDecoder() 156 | if #available(OSX 10.12, *) { 157 | decoder.dateDecodingStrategy = .iso8601 158 | } else { 159 | let dateFormatter = DateFormatter() 160 | dateFormatter.locale = Locale(identifier: "en_US_POSIX") 161 | dateFormatter.timeZone = TimeZone(secondsFromGMT: 0) 162 | dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZ" 163 | decoder.dateDecodingStrategy = .formatted(dateFormatter) 164 | } 165 | return try! decoder.decode(DSL.self, from: dslJSONContents).danger 166 | } 167 | 168 | static var allTests = [ 169 | ("testExecutesTheShell", testExecutesTheShell), 170 | ("testExecutesSwiftLintWithConfigWhenPassed", testExecutesSwiftLintWithConfigWhenPassed), 171 | ("testExecutesSwiftLintWithDirectoryPassed", testExecutesSwiftLintWithDirectoryPassed), 172 | ("testExecutesSwiftLintWhenLintingAllFiles", testExecutesSwiftLintWhenLintingAllFiles), 173 | ("testExecutesSwiftLintWhenLintingAllFilesWithDirectoryPassed", testExecutesSwiftLintWhenLintingAllFilesWithDirectoryPassed), 174 | ("testFiltersOnSwiftFiles", testFiltersOnSwiftFiles), 175 | ("testPrintsNoMarkdownIfNoViolations", testPrintsNoMarkdownIfNoViolations), 176 | ("testViolations", testViolations), 177 | ("testMarkdownReporting", testMarkdownReporting), 178 | ("testQuotesPathArguments", testQuotesPathArguments) 179 | ] 180 | } 181 | -------------------------------------------------------------------------------- /Tests/DangerSwiftLintTests/FakeCurrentPathProvider.swift: -------------------------------------------------------------------------------- 1 | @testable import DangerSwiftLint 2 | 3 | final class FakeCurrentPathProvider: CurrentPathProvider { 4 | var currentPath: String = "" 5 | } 6 | -------------------------------------------------------------------------------- /Tests/DangerSwiftLintTests/FakeShellExecutor.swift: -------------------------------------------------------------------------------- 1 | @testable import DangerSwiftLint 2 | 3 | class FakeShellExecutor: ShellExecutor { 4 | typealias Invocation = (command: String, arguments: [String]) 5 | 6 | var invocations = Array() /// All of the invocations received by this instance. 7 | var output = "[]" /// This is returned by `execute` as the process' standard output. We default to an empty JSON array. 8 | 9 | override func execute(_ command: String, arguments: String...) -> String { 10 | invocations.append((command: command, arguments: arguments)) 11 | return output 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Tests/DangerSwiftLintTests/URL+Utils.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension URL { 4 | func deletingLastPathComponent(_ count: Int) -> URL { 5 | guard count > 0 else { return self } 6 | 7 | var newUrl = self 8 | (0...count).forEach { _ in newUrl.deleteLastPathComponent() } 9 | 10 | return newUrl 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/DangerSwiftLintTests/ViolationTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import DangerSwiftLint 3 | 4 | class ViolnationTests: XCTestCase { 5 | func testDecoding() { 6 | let json = """ 7 | { 8 | "rule_id" : "opening_brace", 9 | "reason" : "Opening braces should be preceded by a single space and on the same line as the declaration.", 10 | "character" : 39, 11 | "file" : "/Users/ash/bin/Harvey/Sources/Harvey/Harvey.swift", 12 | "severity" : "Warning", 13 | "type" : "Opening Brace Spacing", 14 | "line" : 8 15 | } 16 | """ 17 | let subject = try! JSONDecoder().decode(Violation.self, from: json.data(using: String.Encoding.utf8)!) 18 | XCTAssertEqual(subject.ruleID, "opening_brace") 19 | XCTAssertEqual(subject.reason, "Opening braces should be preceded by a single space and on the same line as the declaration.") 20 | XCTAssertEqual(subject.line, 8) 21 | XCTAssertEqual(subject.character, 39) 22 | XCTAssertEqual(subject.file, "/Users/ash/bin/Harvey/Sources/Harvey/Harvey.swift") 23 | XCTAssertEqual(subject.severity, .warning) 24 | XCTAssertEqual(subject.type, "Opening Brace Spacing") 25 | } 26 | 27 | 28 | static var allTests = [ 29 | ("testDecoding", testDecoding) 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /Tests/Fixtures/harness.json: -------------------------------------------------------------------------------- 1 | { 2 | "danger": { 3 | "git": { 4 | "modified_files": [ 5 | "SomeFile.swift", 6 | "SomeOtherFile.swift", 7 | "circle.yml" 8 | ], 9 | "created_files": [], 10 | "deleted_files": [], 11 | "commits": [ 12 | { 13 | "sha": "2568af9776e537f0fde421786d03a06dfdef3586", 14 | "parents": [ 15 | "02107d91cf9ffc99a5941965cc890bc970bd8ce3" 16 | ], 17 | "author": { 18 | "name": "Ash Furrow", 19 | "email": "ash@ashfurrow.com", 20 | "date": "2017-12-09T17:14:49Z" 21 | }, 22 | "committer": { 23 | "name": "Ash Furrow", 24 | "email": "ash@ashfurrow.com", 25 | "date": "2017-12-09T17:18:26Z" 26 | }, 27 | "message": "First draft of SwiftLint DangerSwift plugin.", 28 | "tree": { 29 | "sha": "35083e4e85c919783afc8c399b10b8b41147a3a5", 30 | "url": "https://api.github.com/repos/Moya/Harvey/git/trees/35083e4e85c919783afc8c399b10b8b41147a3a5" 31 | }, 32 | "url": "https://api.github.com/repos/Moya/Harvey/commits/2568af9776e537f0fde421786d03a06dfdef3586" 33 | }, 34 | { 35 | "sha": "bc9a2a7c2b878c8b377033335573cda01981eb6e", 36 | "parents": [ 37 | "2568af9776e537f0fde421786d03a06dfdef3586" 38 | ], 39 | "author": { 40 | "name": "Ash Furrow", 41 | "email": "ash@ashfurrow.com", 42 | "date": "2017-12-09T17:32:54Z" 43 | }, 44 | "committer": { 45 | "name": "Ash Furrow", 46 | "email": "ash@ashfurrow.com", 47 | "date": "2017-12-09T17:32:54Z" 48 | }, 49 | "message": "Typo.", 50 | "tree": { 51 | "sha": "1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5", 52 | "url": "https://api.github.com/repos/Moya/Harvey/git/trees/1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5" 53 | }, 54 | "url": "https://api.github.com/repos/Moya/Harvey/commits/bc9a2a7c2b878c8b377033335573cda01981eb6e" 55 | } 56 | ] 57 | }, 58 | "github": { 59 | "issue": { 60 | "url": "https://api.github.com/repos/Moya/Harvey/issues/15", 61 | "repository_url": "https://api.github.com/repos/Moya/Harvey", 62 | "labels_url": "https://api.github.com/repos/Moya/Harvey/issues/15/labels{/name}", 63 | "comments_url": "https://api.github.com/repos/Moya/Harvey/issues/15/comments", 64 | "events_url": "https://api.github.com/repos/Moya/Harvey/issues/15/events", 65 | "html_url": "https://github.com/Moya/Harvey/pull/15", 66 | "id": 280736285, 67 | "number": 15, 68 | "title": "WIP: First draft of SwiftLint DangerSwift plugin.", 69 | "user": { 70 | "login": "ashfurrow", 71 | "id": 498212, 72 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 73 | "gravatar_id": "", 74 | "url": "https://api.github.com/users/ashfurrow", 75 | "html_url": "https://github.com/ashfurrow", 76 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 77 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 78 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 79 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 80 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 81 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 82 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 83 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 84 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 85 | "type": "User", 86 | "site_admin": false 87 | }, 88 | "labels": [], 89 | "state": "open", 90 | "locked": false, 91 | "assignee": null, 92 | "assignees": [], 93 | "milestone": null, 94 | "comments": 2, 95 | "created_at": "2017-12-09T17:15:29Z", 96 | "updated_at": "2017-12-09T17:34:42Z", 97 | "closed_at": null, 98 | "author_association": "OWNER", 99 | "pull_request": { 100 | "url": "https://api.github.com/repos/Moya/Harvey/pulls/15", 101 | "html_url": "https://github.com/Moya/Harvey/pull/15", 102 | "diff_url": "https://github.com/Moya/Harvey/pull/15.diff", 103 | "patch_url": "https://github.com/Moya/Harvey/pull/15.patch" 104 | }, 105 | "body": "Based on this work: https://github.com/ashfurrow/danger-swiftlint", 106 | "closed_by": null 107 | }, 108 | "pr": { 109 | "url": "https://api.github.com/repos/Moya/Harvey/pulls/15", 110 | "id": 157395438, 111 | "html_url": "https://github.com/Moya/Harvey/pull/15", 112 | "diff_url": "https://github.com/Moya/Harvey/pull/15.diff", 113 | "patch_url": "https://github.com/Moya/Harvey/pull/15.patch", 114 | "issue_url": "https://api.github.com/repos/Moya/Harvey/issues/15", 115 | "number": 15, 116 | "state": "open", 117 | "locked": false, 118 | "title": "WIP: First draft of SwiftLint DangerSwift plugin.", 119 | "user": { 120 | "login": "ashfurrow", 121 | "id": 498212, 122 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 123 | "gravatar_id": "", 124 | "url": "https://api.github.com/users/ashfurrow", 125 | "html_url": "https://github.com/ashfurrow", 126 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 127 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 128 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 129 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 130 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 131 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 132 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 133 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 134 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 135 | "type": "User", 136 | "site_admin": false 137 | }, 138 | "body": "Based on this work: https://github.com/ashfurrow/danger-swiftlint", 139 | "created_at": "2017-12-09T17:15:29Z", 140 | "updated_at": "2017-12-09T17:34:42Z", 141 | "closed_at": null, 142 | "merged_at": null, 143 | "merge_commit_sha": "067773a36e4a7fa8573614a09399470cd9022165", 144 | "assignee": null, 145 | "assignees": [], 146 | "requested_reviewers": {"users": [], "teams": []}, 147 | "milestone": null, 148 | "commits_url": "https://api.github.com/repos/Moya/Harvey/pulls/15/commits", 149 | "review_comments_url": "https://api.github.com/repos/Moya/Harvey/pulls/15/comments", 150 | "review_comment_url": "https://api.github.com/repos/Moya/Harvey/pulls/comments{/number}", 151 | "comments_url": "https://api.github.com/repos/Moya/Harvey/issues/15/comments", 152 | "statuses_url": "https://api.github.com/repos/Moya/Harvey/statuses/bc9a2a7c2b878c8b377033335573cda01981eb6e", 153 | "head": { 154 | "label": "Moya:danger-swift", 155 | "ref": "danger-swift", 156 | "sha": "bc9a2a7c2b878c8b377033335573cda01981eb6e", 157 | "user": { 158 | "login": "Moya", 159 | "id": 13662162, 160 | "avatar_url": "https://avatars3.githubusercontent.com/u/13662162?v=4", 161 | "gravatar_id": "", 162 | "url": "https://api.github.com/users/Moya", 163 | "html_url": "https://github.com/Moya", 164 | "followers_url": "https://api.github.com/users/Moya/followers", 165 | "following_url": "https://api.github.com/users/Moya/following{/other_user}", 166 | "gists_url": "https://api.github.com/users/Moya/gists{/gist_id}", 167 | "starred_url": "https://api.github.com/users/Moya/starred{/owner}{/repo}", 168 | "subscriptions_url": "https://api.github.com/users/Moya/subscriptions", 169 | "organizations_url": "https://api.github.com/users/Moya/orgs", 170 | "repos_url": "https://api.github.com/users/Moya/repos", 171 | "events_url": "https://api.github.com/users/Moya/events{/privacy}", 172 | "received_events_url": "https://api.github.com/users/Moya/received_events", 173 | "type": "Organization", 174 | "site_admin": false 175 | }, 176 | "repo": { 177 | "id": 104667327, 178 | "name": "Harvey", 179 | "full_name": "Moya/Harvey", 180 | "owner": { 181 | "login": "Moya", 182 | "id": 13662162, 183 | "avatar_url": "https://avatars3.githubusercontent.com/u/13662162?v=4", 184 | "gravatar_id": "", 185 | "url": "https://api.github.com/users/Moya", 186 | "html_url": "https://github.com/Moya", 187 | "followers_url": "https://api.github.com/users/Moya/followers", 188 | "following_url": "https://api.github.com/users/Moya/following{/other_user}", 189 | "gists_url": "https://api.github.com/users/Moya/gists{/gist_id}", 190 | "starred_url": "https://api.github.com/users/Moya/starred{/owner}{/repo}", 191 | "subscriptions_url": "https://api.github.com/users/Moya/subscriptions", 192 | "organizations_url": "https://api.github.com/users/Moya/orgs", 193 | "repos_url": "https://api.github.com/users/Moya/repos", 194 | "events_url": "https://api.github.com/users/Moya/events{/privacy}", 195 | "received_events_url": "https://api.github.com/users/Moya/received_events", 196 | "type": "Organization", 197 | "site_admin": false 198 | }, 199 | "private": false, 200 | "html_url": "https://github.com/Moya/Harvey", 201 | "description": "Network response stubbing library written in Swift.", 202 | "fork": false, 203 | "url": "https://api.github.com/repos/Moya/Harvey", 204 | "forks_url": "https://api.github.com/repos/Moya/Harvey/forks", 205 | "keys_url": "https://api.github.com/repos/Moya/Harvey/keys{/key_id}", 206 | "collaborators_url": "https://api.github.com/repos/Moya/Harvey/collaborators{/collaborator}", 207 | "teams_url": "https://api.github.com/repos/Moya/Harvey/teams", 208 | "hooks_url": "https://api.github.com/repos/Moya/Harvey/hooks", 209 | "issue_events_url": "https://api.github.com/repos/Moya/Harvey/issues/events{/number}", 210 | "events_url": "https://api.github.com/repos/Moya/Harvey/events", 211 | "assignees_url": "https://api.github.com/repos/Moya/Harvey/assignees{/user}", 212 | "branches_url": "https://api.github.com/repos/Moya/Harvey/branches{/branch}", 213 | "tags_url": "https://api.github.com/repos/Moya/Harvey/tags", 214 | "blobs_url": "https://api.github.com/repos/Moya/Harvey/git/blobs{/sha}", 215 | "git_tags_url": "https://api.github.com/repos/Moya/Harvey/git/tags{/sha}", 216 | "git_refs_url": "https://api.github.com/repos/Moya/Harvey/git/refs{/sha}", 217 | "trees_url": "https://api.github.com/repos/Moya/Harvey/git/trees{/sha}", 218 | "statuses_url": "https://api.github.com/repos/Moya/Harvey/statuses/{sha}", 219 | "languages_url": "https://api.github.com/repos/Moya/Harvey/languages", 220 | "stargazers_url": "https://api.github.com/repos/Moya/Harvey/stargazers", 221 | "contributors_url": "https://api.github.com/repos/Moya/Harvey/contributors", 222 | "subscribers_url": "https://api.github.com/repos/Moya/Harvey/subscribers", 223 | "subscription_url": "https://api.github.com/repos/Moya/Harvey/subscription", 224 | "commits_url": "https://api.github.com/repos/Moya/Harvey/commits{/sha}", 225 | "git_commits_url": "https://api.github.com/repos/Moya/Harvey/git/commits{/sha}", 226 | "comments_url": "https://api.github.com/repos/Moya/Harvey/comments{/number}", 227 | "issue_comment_url": "https://api.github.com/repos/Moya/Harvey/issues/comments{/number}", 228 | "contents_url": "https://api.github.com/repos/Moya/Harvey/contents/{+path}", 229 | "compare_url": "https://api.github.com/repos/Moya/Harvey/compare/{base}...{head}", 230 | "merges_url": "https://api.github.com/repos/Moya/Harvey/merges", 231 | "archive_url": "https://api.github.com/repos/Moya/Harvey/{archive_format}{/ref}", 232 | "downloads_url": "https://api.github.com/repos/Moya/Harvey/downloads", 233 | "issues_url": "https://api.github.com/repos/Moya/Harvey/issues{/number}", 234 | "pulls_url": "https://api.github.com/repos/Moya/Harvey/pulls{/number}", 235 | "milestones_url": "https://api.github.com/repos/Moya/Harvey/milestones{/number}", 236 | "notifications_url": "https://api.github.com/repos/Moya/Harvey/notifications{?since,all,participating}", 237 | "labels_url": "https://api.github.com/repos/Moya/Harvey/labels{/name}", 238 | "releases_url": "https://api.github.com/repos/Moya/Harvey/releases{/id}", 239 | "deployments_url": "https://api.github.com/repos/Moya/Harvey/deployments", 240 | "created_at": "2017-09-24T18:38:39Z", 241 | "updated_at": "2017-12-05T03:46:51Z", 242 | "pushed_at": "2017-12-09T17:32:58Z", 243 | "git_url": "git://github.com/Moya/Harvey.git", 244 | "ssh_url": "git@github.com:Moya/Harvey.git", 245 | "clone_url": "https://github.com/Moya/Harvey.git", 246 | "svn_url": "https://github.com/Moya/Harvey", 247 | "homepage": "", 248 | "size": 33, 249 | "stargazers_count": 58, 250 | "watchers_count": 58, 251 | "language": "Swift", 252 | "has_issues": true, 253 | "has_projects": true, 254 | "has_downloads": true, 255 | "has_wiki": true, 256 | "has_pages": false, 257 | "forks_count": 4, 258 | "mirror_url": null, 259 | "archived": false, 260 | "open_issues_count": 3, 261 | "license": { 262 | "key": "mit", 263 | "name": "MIT License", 264 | "spdx_id": "MIT", 265 | "url": "https://api.github.com/licenses/mit" 266 | }, 267 | "forks": 4, 268 | "open_issues": 3, 269 | "watchers": 58, 270 | "default_branch": "master" 271 | } 272 | }, 273 | "base": { 274 | "label": "Moya:master", 275 | "ref": "master", 276 | "sha": "49bc7d15000c884133e5592db30c7a1399a4936e", 277 | "user": { 278 | "login": "Moya", 279 | "id": 13662162, 280 | "avatar_url": "https://avatars3.githubusercontent.com/u/13662162?v=4", 281 | "gravatar_id": "", 282 | "url": "https://api.github.com/users/Moya", 283 | "html_url": "https://github.com/Moya", 284 | "followers_url": "https://api.github.com/users/Moya/followers", 285 | "following_url": "https://api.github.com/users/Moya/following{/other_user}", 286 | "gists_url": "https://api.github.com/users/Moya/gists{/gist_id}", 287 | "starred_url": "https://api.github.com/users/Moya/starred{/owner}{/repo}", 288 | "subscriptions_url": "https://api.github.com/users/Moya/subscriptions", 289 | "organizations_url": "https://api.github.com/users/Moya/orgs", 290 | "repos_url": "https://api.github.com/users/Moya/repos", 291 | "events_url": "https://api.github.com/users/Moya/events{/privacy}", 292 | "received_events_url": "https://api.github.com/users/Moya/received_events", 293 | "type": "Organization", 294 | "site_admin": false 295 | }, 296 | "repo": { 297 | "id": 104667327, 298 | "name": "Harvey", 299 | "full_name": "Moya/Harvey", 300 | "owner": { 301 | "login": "Moya", 302 | "id": 13662162, 303 | "avatar_url": "https://avatars3.githubusercontent.com/u/13662162?v=4", 304 | "gravatar_id": "", 305 | "url": "https://api.github.com/users/Moya", 306 | "html_url": "https://github.com/Moya", 307 | "followers_url": "https://api.github.com/users/Moya/followers", 308 | "following_url": "https://api.github.com/users/Moya/following{/other_user}", 309 | "gists_url": "https://api.github.com/users/Moya/gists{/gist_id}", 310 | "starred_url": "https://api.github.com/users/Moya/starred{/owner}{/repo}", 311 | "subscriptions_url": "https://api.github.com/users/Moya/subscriptions", 312 | "organizations_url": "https://api.github.com/users/Moya/orgs", 313 | "repos_url": "https://api.github.com/users/Moya/repos", 314 | "events_url": "https://api.github.com/users/Moya/events{/privacy}", 315 | "received_events_url": "https://api.github.com/users/Moya/received_events", 316 | "type": "Organization", 317 | "site_admin": false 318 | }, 319 | "private": false, 320 | "html_url": "https://github.com/Moya/Harvey", 321 | "description": "Network response stubbing library written in Swift.", 322 | "fork": false, 323 | "url": "https://api.github.com/repos/Moya/Harvey", 324 | "forks_url": "https://api.github.com/repos/Moya/Harvey/forks", 325 | "keys_url": "https://api.github.com/repos/Moya/Harvey/keys{/key_id}", 326 | "collaborators_url": "https://api.github.com/repos/Moya/Harvey/collaborators{/collaborator}", 327 | "teams_url": "https://api.github.com/repos/Moya/Harvey/teams", 328 | "hooks_url": "https://api.github.com/repos/Moya/Harvey/hooks", 329 | "issue_events_url": "https://api.github.com/repos/Moya/Harvey/issues/events{/number}", 330 | "events_url": "https://api.github.com/repos/Moya/Harvey/events", 331 | "assignees_url": "https://api.github.com/repos/Moya/Harvey/assignees{/user}", 332 | "branches_url": "https://api.github.com/repos/Moya/Harvey/branches{/branch}", 333 | "tags_url": "https://api.github.com/repos/Moya/Harvey/tags", 334 | "blobs_url": "https://api.github.com/repos/Moya/Harvey/git/blobs{/sha}", 335 | "git_tags_url": "https://api.github.com/repos/Moya/Harvey/git/tags{/sha}", 336 | "git_refs_url": "https://api.github.com/repos/Moya/Harvey/git/refs{/sha}", 337 | "trees_url": "https://api.github.com/repos/Moya/Harvey/git/trees{/sha}", 338 | "statuses_url": "https://api.github.com/repos/Moya/Harvey/statuses/{sha}", 339 | "languages_url": "https://api.github.com/repos/Moya/Harvey/languages", 340 | "stargazers_url": "https://api.github.com/repos/Moya/Harvey/stargazers", 341 | "contributors_url": "https://api.github.com/repos/Moya/Harvey/contributors", 342 | "subscribers_url": "https://api.github.com/repos/Moya/Harvey/subscribers", 343 | "subscription_url": "https://api.github.com/repos/Moya/Harvey/subscription", 344 | "commits_url": "https://api.github.com/repos/Moya/Harvey/commits{/sha}", 345 | "git_commits_url": "https://api.github.com/repos/Moya/Harvey/git/commits{/sha}", 346 | "comments_url": "https://api.github.com/repos/Moya/Harvey/comments{/number}", 347 | "issue_comment_url": "https://api.github.com/repos/Moya/Harvey/issues/comments{/number}", 348 | "contents_url": "https://api.github.com/repos/Moya/Harvey/contents/{+path}", 349 | "compare_url": "https://api.github.com/repos/Moya/Harvey/compare/{base}...{head}", 350 | "merges_url": "https://api.github.com/repos/Moya/Harvey/merges", 351 | "archive_url": "https://api.github.com/repos/Moya/Harvey/{archive_format}{/ref}", 352 | "downloads_url": "https://api.github.com/repos/Moya/Harvey/downloads", 353 | "issues_url": "https://api.github.com/repos/Moya/Harvey/issues{/number}", 354 | "pulls_url": "https://api.github.com/repos/Moya/Harvey/pulls{/number}", 355 | "milestones_url": "https://api.github.com/repos/Moya/Harvey/milestones{/number}", 356 | "notifications_url": "https://api.github.com/repos/Moya/Harvey/notifications{?since,all,participating}", 357 | "labels_url": "https://api.github.com/repos/Moya/Harvey/labels{/name}", 358 | "releases_url": "https://api.github.com/repos/Moya/Harvey/releases{/id}", 359 | "deployments_url": "https://api.github.com/repos/Moya/Harvey/deployments", 360 | "created_at": "2017-09-24T18:38:39Z", 361 | "updated_at": "2017-12-05T03:46:51Z", 362 | "pushed_at": "2017-12-09T17:32:58Z", 363 | "git_url": "git://github.com/Moya/Harvey.git", 364 | "ssh_url": "git@github.com:Moya/Harvey.git", 365 | "clone_url": "https://github.com/Moya/Harvey.git", 366 | "svn_url": "https://github.com/Moya/Harvey", 367 | "homepage": "", 368 | "size": 33, 369 | "stargazers_count": 58, 370 | "watchers_count": 58, 371 | "language": "Swift", 372 | "has_issues": true, 373 | "has_projects": true, 374 | "has_downloads": true, 375 | "has_wiki": true, 376 | "has_pages": false, 377 | "forks_count": 4, 378 | "mirror_url": null, 379 | "archived": false, 380 | "open_issues_count": 3, 381 | "license": { 382 | "key": "mit", 383 | "name": "MIT License", 384 | "spdx_id": "MIT", 385 | "url": "https://api.github.com/licenses/mit" 386 | }, 387 | "forks": 4, 388 | "open_issues": 3, 389 | "watchers": 58, 390 | "default_branch": "master" 391 | } 392 | }, 393 | "_links": { 394 | "self": { 395 | "href": "https://api.github.com/repos/Moya/Harvey/pulls/15" 396 | }, 397 | "html": { 398 | "href": "https://github.com/Moya/Harvey/pull/15" 399 | }, 400 | "issue": { 401 | "href": "https://api.github.com/repos/Moya/Harvey/issues/15" 402 | }, 403 | "comments": { 404 | "href": "https://api.github.com/repos/Moya/Harvey/issues/15/comments" 405 | }, 406 | "review_comments": { 407 | "href": "https://api.github.com/repos/Moya/Harvey/pulls/15/comments" 408 | }, 409 | "review_comment": { 410 | "href": "https://api.github.com/repos/Moya/Harvey/pulls/comments{/number}" 411 | }, 412 | "commits": { 413 | "href": "https://api.github.com/repos/Moya/Harvey/pulls/15/commits" 414 | }, 415 | "statuses": { 416 | "href": "https://api.github.com/repos/Moya/Harvey/statuses/bc9a2a7c2b878c8b377033335573cda01981eb6e" 417 | } 418 | }, 419 | "author_association": "OWNER", 420 | "merged": false, 421 | "mergeable": true, 422 | "rebaseable": true, 423 | "mergeable_state": "unstable", 424 | "merged_by": null, 425 | "comments": 2, 426 | "review_comments": 0, 427 | "maintainer_can_modify": false, 428 | "commits": 2, 429 | "additions": 18, 430 | "deletions": 16, 431 | "changed_files": 2 432 | }, 433 | "commits": [ 434 | { 435 | "sha": "2568af9776e537f0fde421786d03a06dfdef3586", 436 | "commit": { 437 | "author": { 438 | "name": "Ash Furrow", 439 | "email": "ash@ashfurrow.com", 440 | "date": "2017-12-09T17:14:49Z" 441 | }, 442 | "committer": { 443 | "name": "Ash Furrow", 444 | "email": "ash@ashfurrow.com", 445 | "date": "2017-12-09T17:18:26Z" 446 | }, 447 | "message": "First draft of SwiftLint DangerSwift plugin.", 448 | "tree": { 449 | "sha": "35083e4e85c919783afc8c399b10b8b41147a3a5", 450 | "url": "https://api.github.com/repos/Moya/Harvey/git/trees/35083e4e85c919783afc8c399b10b8b41147a3a5" 451 | }, 452 | "url": "https://api.github.com/repos/Moya/Harvey/git/commits/2568af9776e537f0fde421786d03a06dfdef3586", 453 | "comment_count": 0, 454 | "verification": { 455 | "verified": true, 456 | "reason": "valid", 457 | "signature": "-----BEGIN PGP SIGNATURE-----\n\niQFGBAABCgAwFiEEREhi2UsA5UmdVzQVAZk6xwQ0X+0FAlosGuISHGFzaEBhc2hm\ndXJyb3cuY29tAAoJEAGZOscENF/tCv4H/2Gbs5tFImpJcQ8icJvh/9/rzouY2Pqb\nh5behuErjoAPuwUblnNJO2+rFDA4kSJbnx8vJEfc0CF5k68zWzEB8ZLsxGgEBZrr\nRjV0pmPrSeCFnCgHSMHPerd7jnEvSZ2HIj+87fZotWa5HSTrN3mo7EN+LxamKlGy\nglRnGMfvb6PbjgoS4RZvrwXQVxuZ5u8kSfTZ5nLQ1z7UZnuN59t/ECQPNVnxSWM8\nwc59WLfutd6CcUP4mc4tEQYxrClibSlwcjeHo+PFyRZCXcyz51l+4r0qqytoQ330\nqlcw7HKtsPTPdPnsWXoRX5ONWCaFZD5FgLWvWeEH2i5ZLcEoWwvK4w8=\n=ZKQS\n-----END PGP SIGNATURE-----", 458 | "payload": "tree 35083e4e85c919783afc8c399b10b8b41147a3a5\nparent 02107d91cf9ffc99a5941965cc890bc970bd8ce3\nauthor Ash Furrow 1512839689 -0500\ncommitter Ash Furrow 1512839906 -0500\n\nFirst draft of SwiftLint DangerSwift plugin.\n" 459 | } 460 | }, 461 | "url": "https://api.github.com/repos/Moya/Harvey/commits/2568af9776e537f0fde421786d03a06dfdef3586", 462 | "html_url": "https://github.com/Moya/Harvey/commit/2568af9776e537f0fde421786d03a06dfdef3586", 463 | "comments_url": "https://api.github.com/repos/Moya/Harvey/commits/2568af9776e537f0fde421786d03a06dfdef3586/comments", 464 | "author": { 465 | "login": "ashfurrow", 466 | "id": 498212, 467 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 468 | "gravatar_id": "", 469 | "url": "https://api.github.com/users/ashfurrow", 470 | "html_url": "https://github.com/ashfurrow", 471 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 472 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 473 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 474 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 475 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 476 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 477 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 478 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 479 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 480 | "type": "User", 481 | "site_admin": false 482 | }, 483 | "committer": { 484 | "login": "ashfurrow", 485 | "id": 498212, 486 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 487 | "gravatar_id": "", 488 | "url": "https://api.github.com/users/ashfurrow", 489 | "html_url": "https://github.com/ashfurrow", 490 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 491 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 492 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 493 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 494 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 495 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 496 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 497 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 498 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 499 | "type": "User", 500 | "site_admin": false 501 | }, 502 | "parents": [ 503 | { 504 | "sha": "02107d91cf9ffc99a5941965cc890bc970bd8ce3", 505 | "url": "https://api.github.com/repos/Moya/Harvey/commits/02107d91cf9ffc99a5941965cc890bc970bd8ce3", 506 | "html_url": "https://github.com/Moya/Harvey/commit/02107d91cf9ffc99a5941965cc890bc970bd8ce3" 507 | } 508 | ] 509 | }, 510 | { 511 | "sha": "bc9a2a7c2b878c8b377033335573cda01981eb6e", 512 | "commit": { 513 | "author": { 514 | "name": "Ash Furrow", 515 | "email": "ash@ashfurrow.com", 516 | "date": "2017-12-09T17:32:54Z" 517 | }, 518 | "committer": { 519 | "name": "Ash Furrow", 520 | "email": "ash@ashfurrow.com", 521 | "date": "2017-12-09T17:32:54Z" 522 | }, 523 | "message": "Typo.", 524 | "tree": { 525 | "sha": "1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5", 526 | "url": "https://api.github.com/repos/Moya/Harvey/git/trees/1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5" 527 | }, 528 | "url": "https://api.github.com/repos/Moya/Harvey/git/commits/bc9a2a7c2b878c8b377033335573cda01981eb6e", 529 | "comment_count": 0, 530 | "verification": { 531 | "verified": true, 532 | "reason": "valid", 533 | "signature": "-----BEGIN PGP SIGNATURE-----\n\niQFGBAABCgAwFiEEREhi2UsA5UmdVzQVAZk6xwQ0X+0FAlosHkYSHGFzaEBhc2hm\ndXJyb3cuY29tAAoJEAGZOscENF/tyIgIAINBSXAYb83hgyyoGSX7oFEZjAKoF7l7\n9W7cRrYKu2+SRuun84pDqU9BIPotFphotWVVCKMk3rlRlyO1QAy70EfIMzzn3L7n\n7sV//7AceGqm19PJ1lpdeNIigJhzi/Bb5/TDjUq/TAcpMZWF8mVuYY2glbWyaZEW\n27n3l0k04OssGvI3k2yZNL+hLKssuJbJEEg/f8Fxqr7f0VziLQ1cUxAcsk4zhxIQ\nPmiQnzGFLQmfXj3sMliKhhu3hOc2xn4d7mAfQwgexhgDNuWbXkkLMZnA10aDaNlC\nXxakGyqmuoOfkcgXe3LzxqRLZV8t+g0XFnohb0rHIn7Ra6gP0YXz0wk=\n=5W8t\n-----END PGP SIGNATURE-----", 534 | "payload": "tree 1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5\nparent 2568af9776e537f0fde421786d03a06dfdef3586\nauthor Ash Furrow 1512840774 -0500\ncommitter Ash Furrow 1512840774 -0500\n\nTypo.\n" 535 | } 536 | }, 537 | "url": "https://api.github.com/repos/Moya/Harvey/commits/bc9a2a7c2b878c8b377033335573cda01981eb6e", 538 | "html_url": "https://github.com/Moya/Harvey/commit/bc9a2a7c2b878c8b377033335573cda01981eb6e", 539 | "comments_url": "https://api.github.com/repos/Moya/Harvey/commits/bc9a2a7c2b878c8b377033335573cda01981eb6e/comments", 540 | "author": { 541 | "login": "ashfurrow", 542 | "id": 498212, 543 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 544 | "gravatar_id": "", 545 | "url": "https://api.github.com/users/ashfurrow", 546 | "html_url": "https://github.com/ashfurrow", 547 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 548 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 549 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 550 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 551 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 552 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 553 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 554 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 555 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 556 | "type": "User", 557 | "site_admin": false 558 | }, 559 | "committer": { 560 | "login": "ashfurrow", 561 | "id": 498212, 562 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 563 | "gravatar_id": "", 564 | "url": "https://api.github.com/users/ashfurrow", 565 | "html_url": "https://github.com/ashfurrow", 566 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 567 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 568 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 569 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 570 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 571 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 572 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 573 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 574 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 575 | "type": "User", 576 | "site_admin": false 577 | }, 578 | "parents": [ 579 | { 580 | "sha": "2568af9776e537f0fde421786d03a06dfdef3586", 581 | "url": "https://api.github.com/repos/Moya/Harvey/commits/2568af9776e537f0fde421786d03a06dfdef3586", 582 | "html_url": "https://github.com/Moya/Harvey/commit/2568af9776e537f0fde421786d03a06dfdef3586" 583 | } 584 | ] 585 | } 586 | ], 587 | "reviews": [], 588 | "requested_reviewers": {"users": [], "teams": []}, 589 | "thisPR": { 590 | "number": 15, 591 | "repo": "Harvey", 592 | "owner": "Moya" 593 | } 594 | }, 595 | "settings": { 596 | "github": { 597 | "accessToken": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 598 | "additionalHeaders": {} 599 | }, 600 | "cliArgs": {} 601 | } 602 | } 603 | } 604 | -------------------------------------------------------------------------------- /Tests/Fixtures/harness_directories.json: -------------------------------------------------------------------------------- 1 | { 2 | "danger": { 3 | "git": { 4 | "modified_files": [ 5 | "Tests/SomeFile.swift", 6 | "Harvey/SomeOtherFile.swift", 7 | "Test Dir/SomeThirdFile.swift", 8 | "circle.yml" 9 | ], 10 | "created_files": [], 11 | "deleted_files": [], 12 | "commits": [ 13 | { 14 | "sha": "2568af9776e537f0fde421786d03a06dfdef3586", 15 | "parents": [ 16 | "02107d91cf9ffc99a5941965cc890bc970bd8ce3" 17 | ], 18 | "author": { 19 | "name": "Ash Furrow", 20 | "email": "ash@ashfurrow.com", 21 | "date": "2017-12-09T17:14:49Z" 22 | }, 23 | "committer": { 24 | "name": "Ash Furrow", 25 | "email": "ash@ashfurrow.com", 26 | "date": "2017-12-09T17:18:26Z" 27 | }, 28 | "message": "First draft of SwiftLint DangerSwift plugin.", 29 | "tree": { 30 | "sha": "35083e4e85c919783afc8c399b10b8b41147a3a5", 31 | "url": "https://api.github.com/repos/Moya/Harvey/git/trees/35083e4e85c919783afc8c399b10b8b41147a3a5" 32 | }, 33 | "url": "https://api.github.com/repos/Moya/Harvey/commits/2568af9776e537f0fde421786d03a06dfdef3586" 34 | }, 35 | { 36 | "sha": "bc9a2a7c2b878c8b377033335573cda01981eb6e", 37 | "parents": [ 38 | "2568af9776e537f0fde421786d03a06dfdef3586" 39 | ], 40 | "author": { 41 | "name": "Ash Furrow", 42 | "email": "ash@ashfurrow.com", 43 | "date": "2017-12-09T17:32:54Z" 44 | }, 45 | "committer": { 46 | "name": "Ash Furrow", 47 | "email": "ash@ashfurrow.com", 48 | "date": "2017-12-09T17:32:54Z" 49 | }, 50 | "message": "Typo.", 51 | "tree": { 52 | "sha": "1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5", 53 | "url": "https://api.github.com/repos/Moya/Harvey/git/trees/1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5" 54 | }, 55 | "url": "https://api.github.com/repos/Moya/Harvey/commits/bc9a2a7c2b878c8b377033335573cda01981eb6e" 56 | } 57 | ] 58 | }, 59 | "github": { 60 | "issue": { 61 | "url": "https://api.github.com/repos/Moya/Harvey/issues/15", 62 | "repository_url": "https://api.github.com/repos/Moya/Harvey", 63 | "labels_url": "https://api.github.com/repos/Moya/Harvey/issues/15/labels{/name}", 64 | "comments_url": "https://api.github.com/repos/Moya/Harvey/issues/15/comments", 65 | "events_url": "https://api.github.com/repos/Moya/Harvey/issues/15/events", 66 | "html_url": "https://github.com/Moya/Harvey/pull/15", 67 | "id": 280736285, 68 | "number": 15, 69 | "title": "WIP: First draft of SwiftLint DangerSwift plugin.", 70 | "user": { 71 | "login": "ashfurrow", 72 | "id": 498212, 73 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 74 | "gravatar_id": "", 75 | "url": "https://api.github.com/users/ashfurrow", 76 | "html_url": "https://github.com/ashfurrow", 77 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 78 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 79 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 80 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 81 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 82 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 83 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 84 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 85 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 86 | "type": "User", 87 | "site_admin": false 88 | }, 89 | "labels": [], 90 | "state": "open", 91 | "locked": false, 92 | "assignee": null, 93 | "assignees": [], 94 | "milestone": null, 95 | "comments": 2, 96 | "created_at": "2017-12-09T17:15:29Z", 97 | "updated_at": "2017-12-09T17:34:42Z", 98 | "closed_at": null, 99 | "author_association": "OWNER", 100 | "pull_request": { 101 | "url": "https://api.github.com/repos/Moya/Harvey/pulls/15", 102 | "html_url": "https://github.com/Moya/Harvey/pull/15", 103 | "diff_url": "https://github.com/Moya/Harvey/pull/15.diff", 104 | "patch_url": "https://github.com/Moya/Harvey/pull/15.patch" 105 | }, 106 | "body": "Based on this work: https://github.com/ashfurrow/danger-swiftlint", 107 | "closed_by": null 108 | }, 109 | "pr": { 110 | "url": "https://api.github.com/repos/Moya/Harvey/pulls/15", 111 | "id": 157395438, 112 | "html_url": "https://github.com/Moya/Harvey/pull/15", 113 | "diff_url": "https://github.com/Moya/Harvey/pull/15.diff", 114 | "patch_url": "https://github.com/Moya/Harvey/pull/15.patch", 115 | "issue_url": "https://api.github.com/repos/Moya/Harvey/issues/15", 116 | "number": 15, 117 | "state": "open", 118 | "locked": false, 119 | "title": "WIP: First draft of SwiftLint DangerSwift plugin.", 120 | "user": { 121 | "login": "ashfurrow", 122 | "id": 498212, 123 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 124 | "gravatar_id": "", 125 | "url": "https://api.github.com/users/ashfurrow", 126 | "html_url": "https://github.com/ashfurrow", 127 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 128 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 129 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 130 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 131 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 132 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 133 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 134 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 135 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 136 | "type": "User", 137 | "site_admin": false 138 | }, 139 | "body": "Based on this work: https://github.com/ashfurrow/danger-swiftlint", 140 | "created_at": "2017-12-09T17:15:29Z", 141 | "updated_at": "2017-12-09T17:34:42Z", 142 | "closed_at": null, 143 | "merged_at": null, 144 | "merge_commit_sha": "067773a36e4a7fa8573614a09399470cd9022165", 145 | "assignee": null, 146 | "assignees": [], 147 | "requested_reviewers": {"users": [], "teams": []}, 148 | "milestone": null, 149 | "commits_url": "https://api.github.com/repos/Moya/Harvey/pulls/15/commits", 150 | "review_comments_url": "https://api.github.com/repos/Moya/Harvey/pulls/15/comments", 151 | "review_comment_url": "https://api.github.com/repos/Moya/Harvey/pulls/comments{/number}", 152 | "comments_url": "https://api.github.com/repos/Moya/Harvey/issues/15/comments", 153 | "statuses_url": "https://api.github.com/repos/Moya/Harvey/statuses/bc9a2a7c2b878c8b377033335573cda01981eb6e", 154 | "head": { 155 | "label": "Moya:danger-swift", 156 | "ref": "danger-swift", 157 | "sha": "bc9a2a7c2b878c8b377033335573cda01981eb6e", 158 | "user": { 159 | "login": "Moya", 160 | "id": 13662162, 161 | "avatar_url": "https://avatars3.githubusercontent.com/u/13662162?v=4", 162 | "gravatar_id": "", 163 | "url": "https://api.github.com/users/Moya", 164 | "html_url": "https://github.com/Moya", 165 | "followers_url": "https://api.github.com/users/Moya/followers", 166 | "following_url": "https://api.github.com/users/Moya/following{/other_user}", 167 | "gists_url": "https://api.github.com/users/Moya/gists{/gist_id}", 168 | "starred_url": "https://api.github.com/users/Moya/starred{/owner}{/repo}", 169 | "subscriptions_url": "https://api.github.com/users/Moya/subscriptions", 170 | "organizations_url": "https://api.github.com/users/Moya/orgs", 171 | "repos_url": "https://api.github.com/users/Moya/repos", 172 | "events_url": "https://api.github.com/users/Moya/events{/privacy}", 173 | "received_events_url": "https://api.github.com/users/Moya/received_events", 174 | "type": "Organization", 175 | "site_admin": false 176 | }, 177 | "repo": { 178 | "id": 104667327, 179 | "name": "Harvey", 180 | "full_name": "Moya/Harvey", 181 | "owner": { 182 | "login": "Moya", 183 | "id": 13662162, 184 | "avatar_url": "https://avatars3.githubusercontent.com/u/13662162?v=4", 185 | "gravatar_id": "", 186 | "url": "https://api.github.com/users/Moya", 187 | "html_url": "https://github.com/Moya", 188 | "followers_url": "https://api.github.com/users/Moya/followers", 189 | "following_url": "https://api.github.com/users/Moya/following{/other_user}", 190 | "gists_url": "https://api.github.com/users/Moya/gists{/gist_id}", 191 | "starred_url": "https://api.github.com/users/Moya/starred{/owner}{/repo}", 192 | "subscriptions_url": "https://api.github.com/users/Moya/subscriptions", 193 | "organizations_url": "https://api.github.com/users/Moya/orgs", 194 | "repos_url": "https://api.github.com/users/Moya/repos", 195 | "events_url": "https://api.github.com/users/Moya/events{/privacy}", 196 | "received_events_url": "https://api.github.com/users/Moya/received_events", 197 | "type": "Organization", 198 | "site_admin": false 199 | }, 200 | "private": false, 201 | "html_url": "https://github.com/Moya/Harvey", 202 | "description": "Network response stubbing library written in Swift.", 203 | "fork": false, 204 | "url": "https://api.github.com/repos/Moya/Harvey", 205 | "forks_url": "https://api.github.com/repos/Moya/Harvey/forks", 206 | "keys_url": "https://api.github.com/repos/Moya/Harvey/keys{/key_id}", 207 | "collaborators_url": "https://api.github.com/repos/Moya/Harvey/collaborators{/collaborator}", 208 | "teams_url": "https://api.github.com/repos/Moya/Harvey/teams", 209 | "hooks_url": "https://api.github.com/repos/Moya/Harvey/hooks", 210 | "issue_events_url": "https://api.github.com/repos/Moya/Harvey/issues/events{/number}", 211 | "events_url": "https://api.github.com/repos/Moya/Harvey/events", 212 | "assignees_url": "https://api.github.com/repos/Moya/Harvey/assignees{/user}", 213 | "branches_url": "https://api.github.com/repos/Moya/Harvey/branches{/branch}", 214 | "tags_url": "https://api.github.com/repos/Moya/Harvey/tags", 215 | "blobs_url": "https://api.github.com/repos/Moya/Harvey/git/blobs{/sha}", 216 | "git_tags_url": "https://api.github.com/repos/Moya/Harvey/git/tags{/sha}", 217 | "git_refs_url": "https://api.github.com/repos/Moya/Harvey/git/refs{/sha}", 218 | "trees_url": "https://api.github.com/repos/Moya/Harvey/git/trees{/sha}", 219 | "statuses_url": "https://api.github.com/repos/Moya/Harvey/statuses/{sha}", 220 | "languages_url": "https://api.github.com/repos/Moya/Harvey/languages", 221 | "stargazers_url": "https://api.github.com/repos/Moya/Harvey/stargazers", 222 | "contributors_url": "https://api.github.com/repos/Moya/Harvey/contributors", 223 | "subscribers_url": "https://api.github.com/repos/Moya/Harvey/subscribers", 224 | "subscription_url": "https://api.github.com/repos/Moya/Harvey/subscription", 225 | "commits_url": "https://api.github.com/repos/Moya/Harvey/commits{/sha}", 226 | "git_commits_url": "https://api.github.com/repos/Moya/Harvey/git/commits{/sha}", 227 | "comments_url": "https://api.github.com/repos/Moya/Harvey/comments{/number}", 228 | "issue_comment_url": "https://api.github.com/repos/Moya/Harvey/issues/comments{/number}", 229 | "contents_url": "https://api.github.com/repos/Moya/Harvey/contents/{+path}", 230 | "compare_url": "https://api.github.com/repos/Moya/Harvey/compare/{base}...{head}", 231 | "merges_url": "https://api.github.com/repos/Moya/Harvey/merges", 232 | "archive_url": "https://api.github.com/repos/Moya/Harvey/{archive_format}{/ref}", 233 | "downloads_url": "https://api.github.com/repos/Moya/Harvey/downloads", 234 | "issues_url": "https://api.github.com/repos/Moya/Harvey/issues{/number}", 235 | "pulls_url": "https://api.github.com/repos/Moya/Harvey/pulls{/number}", 236 | "milestones_url": "https://api.github.com/repos/Moya/Harvey/milestones{/number}", 237 | "notifications_url": "https://api.github.com/repos/Moya/Harvey/notifications{?since,all,participating}", 238 | "labels_url": "https://api.github.com/repos/Moya/Harvey/labels{/name}", 239 | "releases_url": "https://api.github.com/repos/Moya/Harvey/releases{/id}", 240 | "deployments_url": "https://api.github.com/repos/Moya/Harvey/deployments", 241 | "created_at": "2017-09-24T18:38:39Z", 242 | "updated_at": "2017-12-05T03:46:51Z", 243 | "pushed_at": "2017-12-09T17:32:58Z", 244 | "git_url": "git://github.com/Moya/Harvey.git", 245 | "ssh_url": "git@github.com:Moya/Harvey.git", 246 | "clone_url": "https://github.com/Moya/Harvey.git", 247 | "svn_url": "https://github.com/Moya/Harvey", 248 | "homepage": "", 249 | "size": 33, 250 | "stargazers_count": 58, 251 | "watchers_count": 58, 252 | "language": "Swift", 253 | "has_issues": true, 254 | "has_projects": true, 255 | "has_downloads": true, 256 | "has_wiki": true, 257 | "has_pages": false, 258 | "forks_count": 4, 259 | "mirror_url": null, 260 | "archived": false, 261 | "open_issues_count": 3, 262 | "license": { 263 | "key": "mit", 264 | "name": "MIT License", 265 | "spdx_id": "MIT", 266 | "url": "https://api.github.com/licenses/mit" 267 | }, 268 | "forks": 4, 269 | "open_issues": 3, 270 | "watchers": 58, 271 | "default_branch": "master" 272 | } 273 | }, 274 | "base": { 275 | "label": "Moya:master", 276 | "ref": "master", 277 | "sha": "49bc7d15000c884133e5592db30c7a1399a4936e", 278 | "user": { 279 | "login": "Moya", 280 | "id": 13662162, 281 | "avatar_url": "https://avatars3.githubusercontent.com/u/13662162?v=4", 282 | "gravatar_id": "", 283 | "url": "https://api.github.com/users/Moya", 284 | "html_url": "https://github.com/Moya", 285 | "followers_url": "https://api.github.com/users/Moya/followers", 286 | "following_url": "https://api.github.com/users/Moya/following{/other_user}", 287 | "gists_url": "https://api.github.com/users/Moya/gists{/gist_id}", 288 | "starred_url": "https://api.github.com/users/Moya/starred{/owner}{/repo}", 289 | "subscriptions_url": "https://api.github.com/users/Moya/subscriptions", 290 | "organizations_url": "https://api.github.com/users/Moya/orgs", 291 | "repos_url": "https://api.github.com/users/Moya/repos", 292 | "events_url": "https://api.github.com/users/Moya/events{/privacy}", 293 | "received_events_url": "https://api.github.com/users/Moya/received_events", 294 | "type": "Organization", 295 | "site_admin": false 296 | }, 297 | "repo": { 298 | "id": 104667327, 299 | "name": "Harvey", 300 | "full_name": "Moya/Harvey", 301 | "owner": { 302 | "login": "Moya", 303 | "id": 13662162, 304 | "avatar_url": "https://avatars3.githubusercontent.com/u/13662162?v=4", 305 | "gravatar_id": "", 306 | "url": "https://api.github.com/users/Moya", 307 | "html_url": "https://github.com/Moya", 308 | "followers_url": "https://api.github.com/users/Moya/followers", 309 | "following_url": "https://api.github.com/users/Moya/following{/other_user}", 310 | "gists_url": "https://api.github.com/users/Moya/gists{/gist_id}", 311 | "starred_url": "https://api.github.com/users/Moya/starred{/owner}{/repo}", 312 | "subscriptions_url": "https://api.github.com/users/Moya/subscriptions", 313 | "organizations_url": "https://api.github.com/users/Moya/orgs", 314 | "repos_url": "https://api.github.com/users/Moya/repos", 315 | "events_url": "https://api.github.com/users/Moya/events{/privacy}", 316 | "received_events_url": "https://api.github.com/users/Moya/received_events", 317 | "type": "Organization", 318 | "site_admin": false 319 | }, 320 | "private": false, 321 | "html_url": "https://github.com/Moya/Harvey", 322 | "description": "Network response stubbing library written in Swift.", 323 | "fork": false, 324 | "url": "https://api.github.com/repos/Moya/Harvey", 325 | "forks_url": "https://api.github.com/repos/Moya/Harvey/forks", 326 | "keys_url": "https://api.github.com/repos/Moya/Harvey/keys{/key_id}", 327 | "collaborators_url": "https://api.github.com/repos/Moya/Harvey/collaborators{/collaborator}", 328 | "teams_url": "https://api.github.com/repos/Moya/Harvey/teams", 329 | "hooks_url": "https://api.github.com/repos/Moya/Harvey/hooks", 330 | "issue_events_url": "https://api.github.com/repos/Moya/Harvey/issues/events{/number}", 331 | "events_url": "https://api.github.com/repos/Moya/Harvey/events", 332 | "assignees_url": "https://api.github.com/repos/Moya/Harvey/assignees{/user}", 333 | "branches_url": "https://api.github.com/repos/Moya/Harvey/branches{/branch}", 334 | "tags_url": "https://api.github.com/repos/Moya/Harvey/tags", 335 | "blobs_url": "https://api.github.com/repos/Moya/Harvey/git/blobs{/sha}", 336 | "git_tags_url": "https://api.github.com/repos/Moya/Harvey/git/tags{/sha}", 337 | "git_refs_url": "https://api.github.com/repos/Moya/Harvey/git/refs{/sha}", 338 | "trees_url": "https://api.github.com/repos/Moya/Harvey/git/trees{/sha}", 339 | "statuses_url": "https://api.github.com/repos/Moya/Harvey/statuses/{sha}", 340 | "languages_url": "https://api.github.com/repos/Moya/Harvey/languages", 341 | "stargazers_url": "https://api.github.com/repos/Moya/Harvey/stargazers", 342 | "contributors_url": "https://api.github.com/repos/Moya/Harvey/contributors", 343 | "subscribers_url": "https://api.github.com/repos/Moya/Harvey/subscribers", 344 | "subscription_url": "https://api.github.com/repos/Moya/Harvey/subscription", 345 | "commits_url": "https://api.github.com/repos/Moya/Harvey/commits{/sha}", 346 | "git_commits_url": "https://api.github.com/repos/Moya/Harvey/git/commits{/sha}", 347 | "comments_url": "https://api.github.com/repos/Moya/Harvey/comments{/number}", 348 | "issue_comment_url": "https://api.github.com/repos/Moya/Harvey/issues/comments{/number}", 349 | "contents_url": "https://api.github.com/repos/Moya/Harvey/contents/{+path}", 350 | "compare_url": "https://api.github.com/repos/Moya/Harvey/compare/{base}...{head}", 351 | "merges_url": "https://api.github.com/repos/Moya/Harvey/merges", 352 | "archive_url": "https://api.github.com/repos/Moya/Harvey/{archive_format}{/ref}", 353 | "downloads_url": "https://api.github.com/repos/Moya/Harvey/downloads", 354 | "issues_url": "https://api.github.com/repos/Moya/Harvey/issues{/number}", 355 | "pulls_url": "https://api.github.com/repos/Moya/Harvey/pulls{/number}", 356 | "milestones_url": "https://api.github.com/repos/Moya/Harvey/milestones{/number}", 357 | "notifications_url": "https://api.github.com/repos/Moya/Harvey/notifications{?since,all,participating}", 358 | "labels_url": "https://api.github.com/repos/Moya/Harvey/labels{/name}", 359 | "releases_url": "https://api.github.com/repos/Moya/Harvey/releases{/id}", 360 | "deployments_url": "https://api.github.com/repos/Moya/Harvey/deployments", 361 | "created_at": "2017-09-24T18:38:39Z", 362 | "updated_at": "2017-12-05T03:46:51Z", 363 | "pushed_at": "2017-12-09T17:32:58Z", 364 | "git_url": "git://github.com/Moya/Harvey.git", 365 | "ssh_url": "git@github.com:Moya/Harvey.git", 366 | "clone_url": "https://github.com/Moya/Harvey.git", 367 | "svn_url": "https://github.com/Moya/Harvey", 368 | "homepage": "", 369 | "size": 33, 370 | "stargazers_count": 58, 371 | "watchers_count": 58, 372 | "language": "Swift", 373 | "has_issues": true, 374 | "has_projects": true, 375 | "has_downloads": true, 376 | "has_wiki": true, 377 | "has_pages": false, 378 | "forks_count": 4, 379 | "mirror_url": null, 380 | "archived": false, 381 | "open_issues_count": 3, 382 | "license": { 383 | "key": "mit", 384 | "name": "MIT License", 385 | "spdx_id": "MIT", 386 | "url": "https://api.github.com/licenses/mit" 387 | }, 388 | "forks": 4, 389 | "open_issues": 3, 390 | "watchers": 58, 391 | "default_branch": "master" 392 | } 393 | }, 394 | "_links": { 395 | "self": { 396 | "href": "https://api.github.com/repos/Moya/Harvey/pulls/15" 397 | }, 398 | "html": { 399 | "href": "https://github.com/Moya/Harvey/pull/15" 400 | }, 401 | "issue": { 402 | "href": "https://api.github.com/repos/Moya/Harvey/issues/15" 403 | }, 404 | "comments": { 405 | "href": "https://api.github.com/repos/Moya/Harvey/issues/15/comments" 406 | }, 407 | "review_comments": { 408 | "href": "https://api.github.com/repos/Moya/Harvey/pulls/15/comments" 409 | }, 410 | "review_comment": { 411 | "href": "https://api.github.com/repos/Moya/Harvey/pulls/comments{/number}" 412 | }, 413 | "commits": { 414 | "href": "https://api.github.com/repos/Moya/Harvey/pulls/15/commits" 415 | }, 416 | "statuses": { 417 | "href": "https://api.github.com/repos/Moya/Harvey/statuses/bc9a2a7c2b878c8b377033335573cda01981eb6e" 418 | } 419 | }, 420 | "author_association": "OWNER", 421 | "merged": false, 422 | "mergeable": true, 423 | "rebaseable": true, 424 | "mergeable_state": "unstable", 425 | "merged_by": null, 426 | "comments": 2, 427 | "review_comments": 0, 428 | "maintainer_can_modify": false, 429 | "commits": 2, 430 | "additions": 18, 431 | "deletions": 16, 432 | "changed_files": 2 433 | }, 434 | "commits": [ 435 | { 436 | "sha": "2568af9776e537f0fde421786d03a06dfdef3586", 437 | "commit": { 438 | "author": { 439 | "name": "Ash Furrow", 440 | "email": "ash@ashfurrow.com", 441 | "date": "2017-12-09T17:14:49Z" 442 | }, 443 | "committer": { 444 | "name": "Ash Furrow", 445 | "email": "ash@ashfurrow.com", 446 | "date": "2017-12-09T17:18:26Z" 447 | }, 448 | "message": "First draft of SwiftLint DangerSwift plugin.", 449 | "tree": { 450 | "sha": "35083e4e85c919783afc8c399b10b8b41147a3a5", 451 | "url": "https://api.github.com/repos/Moya/Harvey/git/trees/35083e4e85c919783afc8c399b10b8b41147a3a5" 452 | }, 453 | "url": "https://api.github.com/repos/Moya/Harvey/git/commits/2568af9776e537f0fde421786d03a06dfdef3586", 454 | "comment_count": 0, 455 | "verification": { 456 | "verified": true, 457 | "reason": "valid", 458 | "signature": "-----BEGIN PGP SIGNATURE-----\n\niQFGBAABCgAwFiEEREhi2UsA5UmdVzQVAZk6xwQ0X+0FAlosGuISHGFzaEBhc2hm\ndXJyb3cuY29tAAoJEAGZOscENF/tCv4H/2Gbs5tFImpJcQ8icJvh/9/rzouY2Pqb\nh5behuErjoAPuwUblnNJO2+rFDA4kSJbnx8vJEfc0CF5k68zWzEB8ZLsxGgEBZrr\nRjV0pmPrSeCFnCgHSMHPerd7jnEvSZ2HIj+87fZotWa5HSTrN3mo7EN+LxamKlGy\nglRnGMfvb6PbjgoS4RZvrwXQVxuZ5u8kSfTZ5nLQ1z7UZnuN59t/ECQPNVnxSWM8\nwc59WLfutd6CcUP4mc4tEQYxrClibSlwcjeHo+PFyRZCXcyz51l+4r0qqytoQ330\nqlcw7HKtsPTPdPnsWXoRX5ONWCaFZD5FgLWvWeEH2i5ZLcEoWwvK4w8=\n=ZKQS\n-----END PGP SIGNATURE-----", 459 | "payload": "tree 35083e4e85c919783afc8c399b10b8b41147a3a5\nparent 02107d91cf9ffc99a5941965cc890bc970bd8ce3\nauthor Ash Furrow 1512839689 -0500\ncommitter Ash Furrow 1512839906 -0500\n\nFirst draft of SwiftLint DangerSwift plugin.\n" 460 | } 461 | }, 462 | "url": "https://api.github.com/repos/Moya/Harvey/commits/2568af9776e537f0fde421786d03a06dfdef3586", 463 | "html_url": "https://github.com/Moya/Harvey/commit/2568af9776e537f0fde421786d03a06dfdef3586", 464 | "comments_url": "https://api.github.com/repos/Moya/Harvey/commits/2568af9776e537f0fde421786d03a06dfdef3586/comments", 465 | "author": { 466 | "login": "ashfurrow", 467 | "id": 498212, 468 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 469 | "gravatar_id": "", 470 | "url": "https://api.github.com/users/ashfurrow", 471 | "html_url": "https://github.com/ashfurrow", 472 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 473 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 474 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 475 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 476 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 477 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 478 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 479 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 480 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 481 | "type": "User", 482 | "site_admin": false 483 | }, 484 | "committer": { 485 | "login": "ashfurrow", 486 | "id": 498212, 487 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 488 | "gravatar_id": "", 489 | "url": "https://api.github.com/users/ashfurrow", 490 | "html_url": "https://github.com/ashfurrow", 491 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 492 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 493 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 494 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 495 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 496 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 497 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 498 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 499 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 500 | "type": "User", 501 | "site_admin": false 502 | }, 503 | "parents": [ 504 | { 505 | "sha": "02107d91cf9ffc99a5941965cc890bc970bd8ce3", 506 | "url": "https://api.github.com/repos/Moya/Harvey/commits/02107d91cf9ffc99a5941965cc890bc970bd8ce3", 507 | "html_url": "https://github.com/Moya/Harvey/commit/02107d91cf9ffc99a5941965cc890bc970bd8ce3" 508 | } 509 | ] 510 | }, 511 | { 512 | "sha": "bc9a2a7c2b878c8b377033335573cda01981eb6e", 513 | "commit": { 514 | "author": { 515 | "name": "Ash Furrow", 516 | "email": "ash@ashfurrow.com", 517 | "date": "2017-12-09T17:32:54Z" 518 | }, 519 | "committer": { 520 | "name": "Ash Furrow", 521 | "email": "ash@ashfurrow.com", 522 | "date": "2017-12-09T17:32:54Z" 523 | }, 524 | "message": "Typo.", 525 | "tree": { 526 | "sha": "1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5", 527 | "url": "https://api.github.com/repos/Moya/Harvey/git/trees/1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5" 528 | }, 529 | "url": "https://api.github.com/repos/Moya/Harvey/git/commits/bc9a2a7c2b878c8b377033335573cda01981eb6e", 530 | "comment_count": 0, 531 | "verification": { 532 | "verified": true, 533 | "reason": "valid", 534 | "signature": "-----BEGIN PGP SIGNATURE-----\n\niQFGBAABCgAwFiEEREhi2UsA5UmdVzQVAZk6xwQ0X+0FAlosHkYSHGFzaEBhc2hm\ndXJyb3cuY29tAAoJEAGZOscENF/tyIgIAINBSXAYb83hgyyoGSX7oFEZjAKoF7l7\n9W7cRrYKu2+SRuun84pDqU9BIPotFphotWVVCKMk3rlRlyO1QAy70EfIMzzn3L7n\n7sV//7AceGqm19PJ1lpdeNIigJhzi/Bb5/TDjUq/TAcpMZWF8mVuYY2glbWyaZEW\n27n3l0k04OssGvI3k2yZNL+hLKssuJbJEEg/f8Fxqr7f0VziLQ1cUxAcsk4zhxIQ\nPmiQnzGFLQmfXj3sMliKhhu3hOc2xn4d7mAfQwgexhgDNuWbXkkLMZnA10aDaNlC\nXxakGyqmuoOfkcgXe3LzxqRLZV8t+g0XFnohb0rHIn7Ra6gP0YXz0wk=\n=5W8t\n-----END PGP SIGNATURE-----", 535 | "payload": "tree 1cc69ec26ed9bdedc9ec97fca66e43e22f9129c5\nparent 2568af9776e537f0fde421786d03a06dfdef3586\nauthor Ash Furrow 1512840774 -0500\ncommitter Ash Furrow 1512840774 -0500\n\nTypo.\n" 536 | } 537 | }, 538 | "url": "https://api.github.com/repos/Moya/Harvey/commits/bc9a2a7c2b878c8b377033335573cda01981eb6e", 539 | "html_url": "https://github.com/Moya/Harvey/commit/bc9a2a7c2b878c8b377033335573cda01981eb6e", 540 | "comments_url": "https://api.github.com/repos/Moya/Harvey/commits/bc9a2a7c2b878c8b377033335573cda01981eb6e/comments", 541 | "author": { 542 | "login": "ashfurrow", 543 | "id": 498212, 544 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 545 | "gravatar_id": "", 546 | "url": "https://api.github.com/users/ashfurrow", 547 | "html_url": "https://github.com/ashfurrow", 548 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 549 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 550 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 551 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 552 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 553 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 554 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 555 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 556 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 557 | "type": "User", 558 | "site_admin": false 559 | }, 560 | "committer": { 561 | "login": "ashfurrow", 562 | "id": 498212, 563 | "avatar_url": "https://avatars3.githubusercontent.com/u/498212?v=4", 564 | "gravatar_id": "", 565 | "url": "https://api.github.com/users/ashfurrow", 566 | "html_url": "https://github.com/ashfurrow", 567 | "followers_url": "https://api.github.com/users/ashfurrow/followers", 568 | "following_url": "https://api.github.com/users/ashfurrow/following{/other_user}", 569 | "gists_url": "https://api.github.com/users/ashfurrow/gists{/gist_id}", 570 | "starred_url": "https://api.github.com/users/ashfurrow/starred{/owner}{/repo}", 571 | "subscriptions_url": "https://api.github.com/users/ashfurrow/subscriptions", 572 | "organizations_url": "https://api.github.com/users/ashfurrow/orgs", 573 | "repos_url": "https://api.github.com/users/ashfurrow/repos", 574 | "events_url": "https://api.github.com/users/ashfurrow/events{/privacy}", 575 | "received_events_url": "https://api.github.com/users/ashfurrow/received_events", 576 | "type": "User", 577 | "site_admin": false 578 | }, 579 | "parents": [ 580 | { 581 | "sha": "2568af9776e537f0fde421786d03a06dfdef3586", 582 | "url": "https://api.github.com/repos/Moya/Harvey/commits/2568af9776e537f0fde421786d03a06dfdef3586", 583 | "html_url": "https://github.com/Moya/Harvey/commit/2568af9776e537f0fde421786d03a06dfdef3586" 584 | } 585 | ] 586 | } 587 | ], 588 | "reviews": [], 589 | "requested_reviewers": {"users": [], "teams": []}, 590 | "thisPR": { 591 | "number": 15, 592 | "repo": "Harvey", 593 | "owner": "Moya" 594 | } 595 | }, 596 | "settings": { 597 | "github": { 598 | "accessToken": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 599 | "additionalHeaders": {} 600 | }, 601 | "cliArgs": {} 602 | } 603 | } 604 | } 605 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import danger_swiftlintTests 3 | 4 | XCTMain([ 5 | testCase(danger_swiftlintTests.allTests), 6 | ]) 7 | -------------------------------------------------------------------------------- /docs/Deploy.md: -------------------------------------------------------------------------------- 1 | Deploying is weird because you're not _really_ deploying. Whatever is on master is what gets downloaded as the plugin (via [Marathon](https://github.com/JohnSundell/Marathon)). So just tag a release to make it official. 2 | --------------------------------------------------------------------------------