From 6bab7c5a70991c02b01089a895171dbdc4dd8079 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 26 May 2018 18:44:28 +0900 Subject: [PATCH] Initial commit --- .gitignore | 4 + Package.resolved | 79 +++++++++++++++++++ Package.swift | 23 ++++++ README.md | 3 + Sources/DangerIBLinter/DangerIBLinter.swift | 42 ++++++++++ Sources/DangerIBLinter/ShellExecutor.swift | 29 +++++++ Sources/DangerIBLinter/Violation.swift | 44 +++++++++++ .../DangerIBLinterTests.swift | 16 ++++ .../DangerIBLinterTests/XCTestManifests.swift | 9 +++ Tests/LinuxMain.swift | 7 ++ 10 files changed, 256 insertions(+) create mode 100644 .gitignore create mode 100644 Package.resolved create mode 100644 Package.swift create mode 100644 README.md create mode 100644 Sources/DangerIBLinter/DangerIBLinter.swift create mode 100644 Sources/DangerIBLinter/ShellExecutor.swift create mode 100644 Sources/DangerIBLinter/Violation.swift create mode 100644 Tests/DangerIBLinterTests/DangerIBLinterTests.swift create mode 100644 Tests/DangerIBLinterTests/XCTestManifests.swift create mode 100644 Tests/LinuxMain.swift diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..02c0875 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +/.build +/Packages +/*.xcodeproj diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..1d4d0e4 --- /dev/null +++ b/Package.resolved @@ -0,0 +1,79 @@ +{ + "object": { + "pins": [ + { + "package": "danger-swift", + "repositoryURL": "https://github.com/danger/danger-swift.git", + "state": { + "branch": null, + "revision": "dd0d6457adf72eedeb10076e1887d49431fd56a6", + "version": "0.4.0" + } + }, + { + "package": "Files", + "repositoryURL": "https://github.com/JohnSundell/Files.git", + "state": { + "branch": null, + "revision": "06f95bd1bf4f8d5f50bc6bb30b808c253acd4c88", + "version": "2.2.1" + } + }, + { + "package": "Marathon", + "repositoryURL": "https://github.com/JohnSundell/Marathon.git", + "state": { + "branch": null, + "revision": "959e82b044f7dbb2680c6e7cdaa80d70e9dfa4ca", + "version": "3.0.0" + } + }, + { + "package": "Releases", + "repositoryURL": "https://github.com/JohnSundell/Releases.git", + "state": { + "branch": null, + "revision": "e74f0895855b56147cb96f2d45aba3ec37da64fb", + "version": "3.0.0" + } + }, + { + "package": "Require", + "repositoryURL": "https://github.com/JohnSundell/Require.git", + "state": { + "branch": null, + "revision": "7cfbd0d8a2dede0e01f6f0d8ab2c7acef1df112e", + "version": "2.0.1" + } + }, + { + "package": "ShellOut", + "repositoryURL": "https://github.com/JohnSundell/ShellOut.git", + "state": { + "branch": null, + "revision": "f1c253a34a40df4bfd268b09fdb101b059f6d52d", + "version": "2.1.0" + } + }, + { + "package": "Unbox", + "repositoryURL": "https://github.com/JohnSundell/Unbox.git", + "state": { + "branch": null, + "revision": "17ad6aa1cc2f1efa27a0bbbdb66f79796708aa95", + "version": "2.5.0" + } + }, + { + "package": "Wrap", + "repositoryURL": "https://github.com/JohnSundell/Wrap.git", + "state": { + "branch": null, + "revision": "8085c925060b84a1fc0caef444c130da2c8154c3", + "version": "3.0.1" + } + } + ] + }, + "version": 1 +} diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..61730df --- /dev/null +++ b/Package.swift @@ -0,0 +1,23 @@ +// swift-tools-version:4.0 + +import PackageDescription + +let package = Package( + name: "DangerIBLinter", + products: [ + .library( + name: "DangerIBLinter", + targets: ["DangerIBLinter"]), + ], + dependencies: [ + .package(url: "https://github.com/danger/danger-swift.git", from: "0.3.0") + ], + targets: [ + .target( + name: "DangerIBLinter", + dependencies: ["Danger"]), + .testTarget( + name: "DangerIBLinterTests", + dependencies: ["DangerIBLinter"]), + ] +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..db76e18 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# DangerIBLinter + +A description of this package. diff --git a/Sources/DangerIBLinter/DangerIBLinter.swift b/Sources/DangerIBLinter/DangerIBLinter.swift new file mode 100644 index 0000000..d34a9fb --- /dev/null +++ b/Sources/DangerIBLinter/DangerIBLinter.swift @@ -0,0 +1,42 @@ +import Foundation +import Danger + +public struct IBLinter { + static let danger = Danger() +} + +extension IBLinter { + + public static func lint(inline: Bool = true) throws { + let arguments = [ + "--reporter", "json" + ] + let shellExecutor = ShellExecutor() + let output = shellExecutor.execute("iblinter", arguments: arguments) + let pwd = shellExecutor.execute("pwd") + let decoder = JSONDecoder() + let files = danger.git.createdFiles + danger.git.modifiedFiles + let violations = try decoder.decode([Violation].self, from: output.data(using: .utf8)!) + let filteredViolations = violations.map { $0.convert(gitRoot: pwd) } + .filter { + files.contains($0.relativePath) + } + + if inline { + filteredViolations + .forEach { + fail(message: $0.message, file: $0.relativePath, line: 0) + } + } else { + let header = """ + ### IBLinter found issues + | Severity | File | Reason | + | -------- | ---- | ------ |\n + """ + let markdownMessage = filteredViolations.reduce(header) { + $0 + $1.toMarkdown() + "\n" + } + markdown(markdownMessage) + } + } +} diff --git a/Sources/DangerIBLinter/ShellExecutor.swift b/Sources/DangerIBLinter/ShellExecutor.swift new file mode 100644 index 0000000..75d4d0f --- /dev/null +++ b/Sources/DangerIBLinter/ShellExecutor.swift @@ -0,0 +1,29 @@ +// +// ShellExecutor.swift +// DangerIBLinter +// +// Created by SaitoYuta on 2018/05/26. +// + +import Foundation + +internal class ShellExecutor { + func execute(_ command: String, arguments: [String] = []) -> String { + let script = "\(command) \(arguments.joined(separator: " "))" + print("Executing \(script)") + + var env = ProcessInfo.processInfo.environment + let task = Process() + task.launchPath = env["SHELL"] + task.arguments = ["-l", "-c", script] + task.currentDirectoryPath = FileManager.default.currentDirectoryPath + + let pipe = Pipe() + task.standardOutput = pipe + task.launch() + task.waitUntilExit() + + let data = pipe.fileHandleForReading.readDataToEndOfFile() + return String(data: data, encoding: String.Encoding.utf8)! + } +} diff --git a/Sources/DangerIBLinter/Violation.swift b/Sources/DangerIBLinter/Violation.swift new file mode 100644 index 0000000..f5914d7 --- /dev/null +++ b/Sources/DangerIBLinter/Violation.swift @@ -0,0 +1,44 @@ +// +// Violation.swift +// DangerIBLinter +// +// Created by SaitoYuta on 2018/05/26. +// + +import Foundation + +enum AbsolutePath {} +enum RelativePath {} + +enum Level: String, Codable { + case warning + case error +} + +struct Violation: Codable { + let message: String + let level: Level + private let path: String +} + +extension Violation where PathType == AbsolutePath { + var absolutePath: String { return path } + + func convert(gitRoot: String) -> Violation { + guard let range = path.range(of: gitRoot)else { + fatalError() + } + var relativePath = path + relativePath.removeSubrange(range) + return .init(message: message, level: level, path: relativePath) + } +} + +extension Violation where PathType == RelativePath { + var relativePath: String { return path } + + func toMarkdown() -> String { + let formattedFile = path.split(separator: "/").last! + ":0" + return "\(level.rawValue) | \(formattedFile) | \(message) |" + } +} diff --git a/Tests/DangerIBLinterTests/DangerIBLinterTests.swift b/Tests/DangerIBLinterTests/DangerIBLinterTests.swift new file mode 100644 index 0000000..f685e5c --- /dev/null +++ b/Tests/DangerIBLinterTests/DangerIBLinterTests.swift @@ -0,0 +1,16 @@ +import XCTest +@testable import DangerIBLinter + +final class DangerIBLinterTests: XCTestCase { + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct + // results. + XCTAssertEqual(DangerIBLinter().text, "Hello, World!") + } + + + static var allTests = [ + ("testExample", testExample), + ] +} diff --git a/Tests/DangerIBLinterTests/XCTestManifests.swift b/Tests/DangerIBLinterTests/XCTestManifests.swift new file mode 100644 index 0000000..76202e4 --- /dev/null +++ b/Tests/DangerIBLinterTests/XCTestManifests.swift @@ -0,0 +1,9 @@ +import XCTest + +#if !os(macOS) +public func allTests() -> [XCTestCaseEntry] { + return [ + testCase(DangerIBLinterTests.allTests), + ] +} +#endif \ No newline at end of file diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift new file mode 100644 index 0000000..1b909c7 --- /dev/null +++ b/Tests/LinuxMain.swift @@ -0,0 +1,7 @@ +import XCTest + +import DangerIBLinterTests + +var tests = [XCTestCaseEntry]() +tests += DangerIBLinterTests.allTests() +XCTMain(tests) \ No newline at end of file