Skip to content

Commit

Permalink
Merged by Peril
Browse files Browse the repository at this point in the history
SPM danger
  • Loading branch information
peril-staging[bot] committed Jan 25, 2019
2 parents 470d8ed + fd6679e commit 0acbb9e
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 68 deletions.
22 changes: 22 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,25 @@ matrix:
- sudo chmod -R a+rwx /usr/local/
- make install
- DEBUG="*" danger-swift ci

- os: osx
name: Danger with SPM
osx_image: xcode10
install:
- node -v
- npm install -g danger
script:
- swift run danger-swift ci

- os: linux
name: Danger with SPM
language: generic
sudo: required
dist: trusty
install:
- node -v
- npm install -g danger
- eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
- swiftenv global 4.2
script:
- swift run danger-swift ci
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

## Master

- Support a full Danger SPM usage [#174](https://github.com/danger/danger-swift/pull/174) by [@f-meloni][]
- Replace codable where was not needed by [@f-meloni][] - [#177](https://github.com/danger/swift/pull/177)
- Fix malformed Swiftlint inline paths by [@absolute-heike][] - [#176](https://github.com/danger/swift/pull/176)

Expand Down
3 changes: 3 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ let package = Package(
products: [
.library(name: "Danger", type: .dynamic, targets: ["Danger"]),
.library(name: "DangerFixtures", type: .dynamic, targets: ["DangerFixtures"]),
.library(name: "DangerDeps", type: .dynamic, targets: ["Danger-Swift"]), // dev
.executable(name: "danger-swift", targets: ["Runner"]),
],
dependencies: [
Expand All @@ -23,8 +24,10 @@ let package = Package(
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.35.8"), // dev
.package(url: "https://github.com/Realm/SwiftLint", from: "0.28.1"), // dev
.package(url: "https://github.com/f-meloni/Rocket", from: "0.4.0"), // dev
.package(url: "https://github.com/jpsim/Yams.git", from: "1.0.0"), // dev
],
targets: [
.target(name: "Danger-Swift", dependencies: ["Danger", "Yams"]), // dev
.target(name: "Danger", dependencies: ["ShellOut", "OctoKit", "Logger"]),
.target(name: "RunnerLib", dependencies: ["Logger", "ShellOut"]),
.target(name: "Runner", dependencies: ["RunnerLib", "MarathonCore", "Logger"]),
Expand Down
Empty file added Sources/Danger-Swift/Fake.swift
Empty file.
31 changes: 20 additions & 11 deletions Sources/Runner/Commands/Edit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,24 @@ func editDanger(logger: Logger) throws {
// If dangerfile was not found, attempt to create one at Dangerfile.swift
let dangerfilePath = Runtime.getDangerfile() ?? createDangerfile()

guard let libPath = Runtime.getLibDangerPath() else {
let potentialFolders = Runtime.potentialLibraryFolders
logger.logError("Could not find a libDanger to link against at any of: \(potentialFolders)",
"Or via Homebrew, or Marathon",
separator: "\n")
exit(1)
let absoluteLibPath: String
let libName: String

if let spmDanger = SPMDanger() {
spmDanger.buildDepsIfNeeded()
absoluteLibPath = FileManager.default.currentDirectoryPath + "/" + SPMDanger.buildFolder
libName = spmDanger.depsLibName
} else {
guard let libPath = Runtime.getLibDangerPath() else {
let potentialFolders = Runtime.potentialLibraryFolders
logger.logError("Could not find a libDanger to link against at any of: \(potentialFolders)",
"Or via Homebrew, or Marathon",
separator: "\n")
exit(1)
}

absoluteLibPath = try Folder(path: libPath).path
libName = "Danger"
}

guard let dangerfileContent = try? File(path: dangerfilePath).readAsString() else {
Expand All @@ -36,16 +48,13 @@ func editDanger(logger: Logger) throws {
let importsFinder = ImportsFinder()
let importedFiles = importsFinder.findImports(inString: dangerfileContent)

let absoluteLibPath = try Folder(path: libPath).path

let arguments = CommandLine.arguments
let scriptManager = try getScriptManager(logger)
let script = try scriptManager.script(atPath: dangerfilePath, allowRemote: true)

let path = NSTemporaryDirectory()
let configPath = path + "config.xcconfig"
let configPath = NSTemporaryDirectory() + "config.xcconfig"

try createConfig(atPath: configPath, lib: absoluteLibPath)
try createConfig(atPath: configPath, libPath: absoluteLibPath, libName: libName)

try script.setupForEdit(arguments: arguments, importedFiles: importedFiles, configPath: configPath)

Expand Down
82 changes: 45 additions & 37 deletions Sources/Runner/Commands/Runner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,45 +48,56 @@ func runDanger(logger: Logger) throws {
}
logger.debug("Running Dangerfile at: \(dangerfilePath)")

guard let libDangerPath = Runtime.getLibDangerPath() else {
let potentialFolders = Runtime.potentialLibraryFolders
logger.logError("Could not find a libDanger to link against at any of: \(potentialFolders)",
"Or via Homebrew, or Marathon",
separator: "\n")
exit(1)
}

var libArgs: [String] = []
libArgs += ["-L", libDangerPath] // Link to libDanger inside this folder
libArgs += ["-I", libDangerPath] // Find libDanger inside this folder

// Set up plugin infra
let importsOnly = try File(path: dangerfilePath).readAsString()
let importExternalDeps = importsOnly.components(separatedBy: .newlines).filter { $0.hasPrefix("import") && $0.contains("package: ") } // swiftlint:disable:this line_length

if importExternalDeps.count > 0 {
logger.logInfo("Cloning and building inline dependencies:",
"\(importExternalDeps.joined(separator: ", ")),",
"this might take some time.")

try Folder(path: ".").createFileIfNeeded(withName: "_dangerfile_imports.swift")
let tempDangerfile = try File(path: "_dangerfile_imports.swift")
try tempDangerfile.write(string: importExternalDeps.joined(separator: "\n"))
defer { try? tempDangerfile.delete() }

let scriptManager = try getScriptManager(logger)
let script = try scriptManager.script(atPath: tempDangerfile.path, allowRemote: true)

try script.build()
let marathonPath = script.folder.path
let artifactPaths = [".build/debug", ".build/release"]

let marathonLibPath = artifactPaths.first(where: { fileManager.fileExists(atPath: marathonPath + $0) })
if marathonLibPath != nil {
libArgs += ["-L", marathonPath + marathonLibPath!]
libArgs += ["-I", marathonPath + marathonLibPath!]
libArgs += ["-lMarathonDependencies"]

if let spmDanger = SPMDanger() {
spmDanger.buildDepsIfNeeded()
libArgs += ["-L", SPMDanger.buildFolder]
libArgs += ["-I", SPMDanger.buildFolder]
libArgs += [spmDanger.libImport]
} else {
guard let libDangerPath = Runtime.getLibDangerPath() else {
let potentialFolders = Runtime.potentialLibraryFolders
logger.logError("Could not find a libDanger to link against at any of: \(potentialFolders)",
"Or via Homebrew, or Marathon",
separator: "\n")
exit(1)
}

libArgs += ["-L", libDangerPath] // Link to libDanger inside this folder
libArgs += ["-I", libDangerPath] // Find libDanger inside this folder

let importExternalDeps = importsOnly.components(separatedBy: .newlines).filter { $0.hasPrefix("import") && $0.contains("package: ") } // swiftlint:disable:this line_length

if importExternalDeps.count > 0 {
logger.logInfo("Cloning and building inline dependencies:",
"\(importExternalDeps.joined(separator: ", ")),",
"this might take some time.")

try Folder(path: ".").createFileIfNeeded(withName: "_dangerfile_imports.swift")
let tempDangerfile = try File(path: "_dangerfile_imports.swift")
try tempDangerfile.write(string: importExternalDeps.joined(separator: "\n"))
defer { try? tempDangerfile.delete() }

let scriptManager = try getScriptManager(logger)
let script = try scriptManager.script(atPath: tempDangerfile.path, allowRemote: true)

try script.build()
let marathonPath = script.folder.path
let artifactPaths = [".build/debug", ".build/release"]

let marathonLibPath = artifactPaths.first(where: { fileManager.fileExists(atPath: marathonPath + $0) })
if marathonLibPath != nil {
libArgs += ["-L", marathonPath + marathonLibPath!]
libArgs += ["-I", marathonPath + marathonLibPath!]
libArgs += ["-lMarathonDependencies"]
}
}

libArgs += ["-lDanger"] // Eval the code with the Target Danger added
}

logger.debug("Preparing to compile")
Expand All @@ -112,9 +123,6 @@ func runDanger(logger: Logger) throws {

var args = [String]()
args += ["--driver-mode=swift"] // Eval in swift mode, I think?
args += ["-L", libDangerPath] // Find libs inside this folder
args += ["-I", libDangerPath] // Find libs inside this folder
args += ["-lDanger"] // Eval the code with the Target Danger added
args += libArgs
args += [tempDangerfilePath] // The Dangerfile
args += Array(CommandLine.arguments.dropFirst()) // Arguments sent to Danger
Expand Down
8 changes: 4 additions & 4 deletions Sources/Runner/EditXcodeProj.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import Files
import Foundation

// Creates an xcconfig file that can be used to correctly link danger library to the xcodeproj
func createConfig(atPath configPath: String, lib: String) throws {
func createConfig(atPath configPath: String, libPath: String, libName: String) throws {
let config = """
LIBRARY_SEARCH_PATHS = \(lib)
OTHER_SWIFT_FLAGS = -DXcode -I \(lib) -L \(lib)
OTHER_LDFLAGS = -l danger
LIBRARY_SEARCH_PATHS = \(libPath)
OTHER_SWIFT_FLAGS = -DXcode -I \(libPath) -L \(libPath)
OTHER_LDFLAGS = -l \(libName)
"""

try config.write(toFile: configPath, atomically: false, encoding: .utf8)
Expand Down
13 changes: 7 additions & 6 deletions Sources/Runner/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import Logger
import RunnerLib

/// Version for showing in verbose mode
let DangerVersion = "1.1.0"
let MinimumDangerJSVersion = "6.1.6"
let DangerVersion = "1.1.0" // swiftlint:disable:this identifier_name
let MinimumDangerJSVersion = "6.1.6" // swiftlint:disable:this identifier_name

private func runCommand(_ command: DangerCommand, logger: Logger) throws {
switch command {
Expand All @@ -19,11 +19,11 @@ private func runCommand(_ command: DangerCommand, logger: Logger) throws {
}

let cliLength = ProcessInfo.processInfo.arguments.count
do {
let isVerbose = CommandLine.arguments.contains("--verbose") || (ProcessInfo.processInfo.environment["DEBUG"] != nil)
let isSilent = CommandLine.arguments.contains("--silent")
let logger = Logger(isVerbose: isVerbose, isSilent: isSilent)
let isVerbose = CommandLine.arguments.contains("--verbose") || (ProcessInfo.processInfo.environment["DEBUG"] != nil)
let isSilent = CommandLine.arguments.contains("--silent")
let logger = Logger(isVerbose: isVerbose, isSilent: isSilent)

do {
if cliLength > 1 {
logger.debug("Launching Danger Swift \(CommandLine.arguments[1]) (v\(DangerVersion))")

Expand All @@ -43,5 +43,6 @@ do {
try runDanger(logger: logger)
}
} catch {
logger.logError(error)
exit(1)
}
3 changes: 3 additions & 0 deletions Sources/RunnerLib/DangerJSVersionFinder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ public final class DangerJSVersionFinder {
}

public protocol ShellOutExecuting {
@discardableResult
func shellOut(command: String) throws -> String
}

public struct ShellOutExecutor: ShellOutExecuting {
public init() {}

public func shellOut(command: String) throws -> String {
return try ShellOut.shellOut(to: command)
}
Expand Down
36 changes: 36 additions & 0 deletions Sources/RunnerLib/SPMDanger.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Foundation

public struct SPMDanger {
private static let dangerDepsPrefix = "DangerDeps"
public static let buildFolder = ".build/debug"
public let depsLibName: String

public init?(packagePath: String = "Package.swift") {
let packageContent = (try? String(contentsOfFile: packagePath)) ?? ""

let regex = try? NSRegularExpression(pattern: "\\.library\\(name:[\\ ]?\"(\(SPMDanger.dangerDepsPrefix)[A-Za-z]*)",
options: .allowCommentsAndWhitespace)
let firstMatch = regex?.firstMatch(in: packageContent,
options: .withTransparentBounds,
range: NSRange(location: 0, length: packageContent.count))

if let depsLibNameRange = firstMatch?.range(at: 1),
let range = Range(depsLibNameRange, in: packageContent) {
depsLibName = String(packageContent[range])
} else {
return nil
}
}

public func buildDepsIfNeeded(executor: ShellOutExecuting = ShellOutExecutor(),
fileManager: FileManager = .default) {
if !fileManager.fileExists(atPath: "\(SPMDanger.buildFolder)/lib\(depsLibName).dylib"), // OSX
!fileManager.fileExists(atPath: "\(SPMDanger.buildFolder)/lib\(depsLibName).so") { // Linux
_ = try? executor.shellOut(command: "swift build --product \(depsLibName)")
}
}

public var libImport: String {
return "-l\(depsLibName)"
}
}
10 changes: 0 additions & 10 deletions Tests/RunnerLibTests/DangerJSVersionFinderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,3 @@ final class DangerJSVersionFinderTests: XCTestCase {
XCTAssertEqual(version, executor.result)
}
}

private final class MockedExecutor: ShellOutExecuting {
var receivedCommand: String!
var result = ""

func shellOut(command: String) throws -> String {
receivedCommand = command
return result
}
}
11 changes: 11 additions & 0 deletions Tests/RunnerLibTests/MockedExecutor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import RunnerLib

final class MockedExecutor: ShellOutExecuting {
var receivedCommand: String!
var result = ""

func shellOut(command: String) throws -> String {
receivedCommand = command
return result
}
}
Loading

0 comments on commit 0acbb9e

Please sign in to comment.