Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPM danger #174

Merged
merged 16 commits into from
Jan 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)

## 1.1.0
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