forked from yonaskolb/XcodeGen
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revert "Remove GraphViz feature (yonaskolb#1485)"
This reverts commit 7eb5e9b.
- Loading branch information
Showing
6 changed files
with
206 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import DOT | ||
import Foundation | ||
import GraphViz | ||
import ProjectSpec | ||
|
||
extension Dependency { | ||
var graphVizName: String { | ||
switch self.type { | ||
case .bundle, .package, .sdk, .framework, .carthage: | ||
return "[\(self.type)]\\n\(reference)" | ||
case .target: | ||
return reference | ||
} | ||
} | ||
} | ||
|
||
extension Dependency.DependencyType: CustomStringConvertible { | ||
public var description: String { | ||
switch self { | ||
case .bundle: return "bundle" | ||
case .package: return "package" | ||
case .framework: return "framework" | ||
case .carthage: return "carthage" | ||
case .sdk: return "sdk" | ||
case .target: return "target" | ||
} | ||
} | ||
} | ||
|
||
extension Node { | ||
init(target: Target) { | ||
self.init(target.name) | ||
self.shape = .box | ||
} | ||
|
||
init(dependency: Dependency) { | ||
self.init(dependency.reference) | ||
self.shape = .box | ||
self.label = dependency.graphVizName | ||
} | ||
} | ||
|
||
public class GraphVizGenerator { | ||
|
||
public init() {} | ||
|
||
public func generateModuleGraphViz(targets: [Target]) -> String { | ||
return DOTEncoder().encode(generateGraph(targets: targets)) | ||
} | ||
|
||
func generateGraph(targets: [Target]) -> Graph { | ||
var graph = Graph(directed: true) | ||
targets.forEach { target in | ||
target.dependencies.forEach { dependency in | ||
let from = Node(target: target) | ||
graph.append(from) | ||
let to = Node(dependency: dependency) | ||
graph.append(to) | ||
var edge = Edge(from: from, to: to) | ||
edge.style = .dashed | ||
graph.append(edge) | ||
} | ||
} | ||
return graph | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import ProjectSpec | ||
import Spectre | ||
@testable import XcodeGenKit | ||
import XCTest | ||
|
||
private let app = Target( | ||
name: "MyApp", | ||
type: .application, | ||
platform: .iOS, | ||
settings: Settings(buildSettings: ["SETTING_1": "VALUE"]), | ||
dependencies: [ | ||
Dependency(type: .target, reference: "MyInternalFramework"), | ||
Dependency(type: .bundle, reference: "Resources"), | ||
Dependency(type: .carthage(findFrameworks: true, linkType: .static), reference: "MyStaticFramework"), | ||
Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "MyDynamicFramework"), | ||
Dependency(type: .framework, reference: "MyExternalFramework"), | ||
Dependency(type: .package(products: ["MyPackage"]), reference: "MyPackage"), | ||
Dependency(type: .sdk(root: "MySDK"), reference: "MySDK"), | ||
] | ||
) | ||
|
||
private let framework = Target( | ||
name: "MyFramework", | ||
type: .framework, | ||
platform: .iOS, | ||
settings: Settings(buildSettings: ["SETTING_2": "VALUE"]) | ||
) | ||
|
||
private let uiTest = Target( | ||
name: "MyAppUITests", | ||
type: .uiTestBundle, | ||
platform: .iOS, | ||
settings: Settings(buildSettings: ["SETTING_3": "VALUE"]), | ||
dependencies: [Dependency(type: .target, reference: "MyApp")] | ||
) | ||
|
||
private let targets = [app, framework, uiTest] | ||
|
||
class GraphVizGeneratorTests: XCTestCase { | ||
|
||
func testGraphOutput() throws { | ||
describe { | ||
let graph = GraphVizGenerator().generateGraph(targets: targets) | ||
$0.it("generates the expected number of nodes") { | ||
try expect(graph.nodes.count) == 16 | ||
} | ||
$0.it("generates box nodes") { | ||
try expect(graph.nodes.filter { $0.shape == .box }.count) == 16 | ||
} | ||
$0.it("generates the expected carthage nodes") { | ||
try expect(graph.nodes.filter { $0.label?.contains("[carthage]") ?? false }.count) == 2 | ||
} | ||
$0.it("generates the expected sdk nodes") { | ||
try expect(graph.nodes.filter { $0.label?.contains("[sdk]") ?? false }.count) == 1 | ||
} | ||
$0.it("generates the expected Framework nodes") { | ||
try expect(graph.nodes.filter { $0.label?.contains("[framework]") ?? false }.count) == 1 | ||
} | ||
$0.it("generates the expected package nodes") { | ||
try expect(graph.nodes.filter { $0.label?.contains("[package]") ?? false }.count) == 1 | ||
} | ||
$0.it("generates the expected bundle nodes") { | ||
try expect(graph.nodes.filter { $0.label?.contains("[bundle]") ?? false }.count) == 1 | ||
} | ||
$0.it("generates the expected edges") { | ||
try expect(graph.edges.count) == 8 | ||
} | ||
$0.it("generates dashed edges") { | ||
try expect(graph.edges.filter { $0.style == .dashed }.count) == 8 | ||
} | ||
$0.it("generates the expected output") { | ||
let output = GraphVizGenerator().generateModuleGraphViz(targets: targets) | ||
try expect(output) == """ | ||
digraph { | ||
MyApp [shape=box] | ||
MyInternalFramework [label=MyInternalFramework shape=box] | ||
MyApp [shape=box] | ||
Resources [label="[bundle]\\nResources" shape=box] | ||
MyApp [shape=box] | ||
MyStaticFramework [label="[carthage]\\nMyStaticFramework" shape=box] | ||
MyApp [shape=box] | ||
MyDynamicFramework [label="[carthage]\\nMyDynamicFramework" shape=box] | ||
MyApp [shape=box] | ||
MyExternalFramework [label="[framework]\\nMyExternalFramework" shape=box] | ||
MyApp [shape=box] | ||
MyPackage [label="[package]\\nMyPackage" shape=box] | ||
MyApp [shape=box] | ||
MySDK [label="[sdk]\\nMySDK" shape=box] | ||
MyAppUITests [shape=box] | ||
MyApp [label=MyApp shape=box] | ||
MyApp -> MyInternalFramework [style=dashed] | ||
MyApp -> Resources [style=dashed] | ||
MyApp -> MyStaticFramework [style=dashed] | ||
MyApp -> MyDynamicFramework [style=dashed] | ||
MyApp -> MyExternalFramework [style=dashed] | ||
MyApp -> MyPackage [style=dashed] | ||
MyApp -> MySDK [style=dashed] | ||
MyAppUITests -> MyApp [style=dashed] | ||
} | ||
""" | ||
} | ||
} | ||
} | ||
} |