From 5894f0375b4e4750afb5bbcbace8d87a5c4a4db8 Mon Sep 17 00:00:00 2001 From: Jeff Kelley Date: Mon, 18 Jan 2016 15:36:18 -0500 Subject: [PATCH 1/2] Use protocols to build array of project entities. --- .../CPMetadataTableViewDataSource.swift | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/app/CocoaPods/CPMetadataTableViewDataSource.swift b/app/CocoaPods/CPMetadataTableViewDataSource.swift index 78d6a425..b5ff167d 100644 --- a/app/CocoaPods/CPMetadataTableViewDataSource.swift +++ b/app/CocoaPods/CPMetadataTableViewDataSource.swift @@ -1,5 +1,32 @@ import Cocoa +protocol XcodeProjectFlattenable { + func flattenForTargets(targets: [CPCocoaPodsTarget]) -> [AnyObject] +} + +extension CPXcodeProject: XcodeProjectFlattenable { + func flattenForTargets(targets: [CPCocoaPodsTarget]) -> [AnyObject] { + return [self] + self.targets.flatMap { $0.flattenForTargets(targets) } + } +} + +extension CPXcodeTarget: XcodeProjectFlattenable { + func flattenForTargets(targets: [CPCocoaPodsTarget]) -> [AnyObject] { + return [self] + cocoapodsTargets.flatMap { targetName -> [AnyObject] in + targets.filter { $0.name == targetName }.flatMap { $0.pods } + } + ["spacer"] + } +} + +extension Array where Element : XcodeProjectFlattenable { + func flattenForTargets(targets: [CPCocoaPodsTarget]) -> [AnyObject] { + return flatMap { element -> [AnyObject] in + return (element as XcodeProjectFlattenable).flattenForTargets(targets) + } + } +} + + class CPMetadataTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDelegate { var flattenedXcodeProject: [AnyObject] = [] @@ -12,29 +39,10 @@ class CPMetadataTableViewDataSource: NSObject, NSTableViewDataSource, NSTableVie tableView.reloadData() } - // TODO: I bet someone could code-golf this pretty well private func flattenXcodeProjects(projects:[CPXcodeProject], targets:[CPCocoaPodsTarget]) -> [AnyObject] { - var flattenedObjects: [AnyObject] = [] - - for xcodeproject in projects { - flattenedObjects.append(xcodeproject) - - for target in xcodeproject.targets { - flattenedObjects.append(target) - - for targetName in target.cocoapodsTargets { - targets.filter { $0.name == targetName }.forEach { pod_target in - for pod in pod_target.pods { - flattenedObjects.append(pod) - } - } - } - flattenedObjects.append("spacer") - } - } - return flattenedObjects + return projects.flattenForTargets(targets) } - + // Nothing is selectable except the buttons func tableView(tableView: NSTableView, shouldSelectRow row: Int) -> Bool { return false From 589da4363c1c3ec690d997404b18d741a4d0a36b Mon Sep 17 00:00:00 2001 From: Jeff Kelley Date: Mon, 18 Jan 2016 16:12:46 -0500 Subject: [PATCH 2/2] Use protocols to extract and display metadata. --- .../CPMetadataTableViewDataSource.swift | 118 +++++++++--------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/app/CocoaPods/CPMetadataTableViewDataSource.swift b/app/CocoaPods/CPMetadataTableViewDataSource.swift index b5ff167d..f9ef9493 100644 --- a/app/CocoaPods/CPMetadataTableViewDataSource.swift +++ b/app/CocoaPods/CPMetadataTableViewDataSource.swift @@ -1,97 +1,103 @@ import Cocoa -protocol XcodeProjectFlattenable { - func flattenForTargets(targets: [CPCocoaPodsTarget]) -> [AnyObject] +protocol CPMetadataRepresentable: class { + var viewIdentifier: String { get } + var viewOwner: AnyObject? { get } + var rowHeight: CGFloat { get } } -extension CPXcodeProject: XcodeProjectFlattenable { - func flattenForTargets(targets: [CPCocoaPodsTarget]) -> [AnyObject] { - return [self] + self.targets.flatMap { $0.flattenForTargets(targets) } - } +extension CPXcodeProject: CPMetadataRepresentable { + var viewIdentifier: String { return "xcodeproject_metadata" } + var viewOwner: AnyObject? { return self } + var rowHeight: CGFloat { return 120 } +} + +extension CPXcodeTarget: CPMetadataRepresentable { + var viewIdentifier: String { return "target_metadata" } + var viewOwner: AnyObject? { return self } + var rowHeight: CGFloat { return 150 } +} + +extension CPPod: CPMetadataRepresentable { + var viewIdentifier: String { return "pod_metadata" } + var viewOwner: AnyObject? { return self } + var rowHeight: CGFloat { return 30 } +} + +class Spacer: NSObject, CPMetadataRepresentable { + var viewIdentifier: String { return "spacer" } + var viewOwner: AnyObject? { return nil } + var rowHeight: CGFloat { return 30 } } -extension CPXcodeTarget: XcodeProjectFlattenable { - func flattenForTargets(targets: [CPCocoaPodsTarget]) -> [AnyObject] { - return [self] + cocoapodsTargets.flatMap { targetName -> [AnyObject] in - targets.filter { $0.name == targetName }.flatMap { $0.pods } - } + ["spacer"] +protocol CPMetadataExtractable { + func metadataForTargets(targets: [CPCocoaPodsTarget]) -> [CPMetadataRepresentable] +} + +extension CPXcodeProject: CPMetadataExtractable { + func metadataForTargets(targets: [CPCocoaPodsTarget]) -> [CPMetadataRepresentable] { + return [self] + self.targets.flatMap { $0.metadataForTargets(targets) } } } -extension Array where Element : XcodeProjectFlattenable { - func flattenForTargets(targets: [CPCocoaPodsTarget]) -> [AnyObject] { - return flatMap { element -> [AnyObject] in - return (element as XcodeProjectFlattenable).flattenForTargets(targets) +extension CPXcodeTarget: CPMetadataExtractable { + func metadataForTargets(targets: [CPCocoaPodsTarget]) -> [CPMetadataRepresentable] { + let pods = cocoapodsTargets.flatMap { targetName -> [CPMetadataRepresentable] in + targets.filter { $0.name == targetName } + .flatMap { $0.pods } + .map { $0 as CPMetadataRepresentable } } + + return [self as CPMetadataRepresentable] + pods + [Spacer() as CPMetadataRepresentable] } } +extension Array where Element : CPMetadataExtractable { + func metadataForTargets(targets: [CPCocoaPodsTarget]) -> [CPMetadataRepresentable] { + return flatMap { element -> [CPMetadataRepresentable] in + return (element as CPMetadataExtractable).metadataForTargets(targets) + } + } +} class CPMetadataTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDelegate { - var flattenedXcodeProject: [AnyObject] = [] + var projectMetadataEntries: [CPMetadataRepresentable] = [] { + didSet { + tableView.reloadData() + } + } + var plugins = ["No plugins"] @IBOutlet weak var tableView: NSTableView! func setXcodeProjects(projects:[CPXcodeProject], targets:[CPCocoaPodsTarget]) { - flattenedXcodeProject = flattenXcodeProjects(projects, targets:targets) - tableView.reloadData() + projectMetadataEntries = projects.metadataForTargets(targets) } - private func flattenXcodeProjects(projects:[CPXcodeProject], targets:[CPCocoaPodsTarget]) -> [AnyObject] { - return projects.flattenForTargets(targets) - } - // Nothing is selectable except the buttons func tableView(tableView: NSTableView, shouldSelectRow row: Int) -> Bool { return false } func numberOfRowsInTableView(tableView: NSTableView) -> Int { - return flattenedXcodeProject.count + return projectMetadataEntries.count } // Allows the UI to be set up via bindings func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? { - return flattenedXcodeProject[row] + return projectMetadataEntries[row] } func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? { - let data = flattenedXcodeProject[row] - if let xcodeproj = data as? CPXcodeProject { - return tableView.makeViewWithIdentifier("xcodeproject_metadata", owner: xcodeproj) - - } else if let target = data as? CPXcodeTarget { - return tableView.makeViewWithIdentifier("target_metadata", owner: target) - - } else if let pod = data as? CPPod { - return tableView.makeViewWithIdentifier("pod_metadata", owner: pod) - - } else if let _ = data as? NSString { - return tableView.makeViewWithIdentifier("spacer", owner: nil) - } - - print("Should not have data unaccounted for in the flattened xcode project"); - return nil + let data = projectMetadataEntries[row] + + return tableView.makeViewWithIdentifier(data.viewIdentifier, + owner: data.viewOwner) } func tableView(tableView: NSTableView, heightOfRow row: Int) -> CGFloat { - let data = flattenedXcodeProject[row] - if let _ = data as? CPXcodeProject { - return 120 - - } else if let _ = data as? CPXcodeTarget { - return 150 - - } else if let _ = data as? CPPod { - return 30 - - // Spacer - } else if let _ = data as? NSString { - return 30 - } - - return 0 + return projectMetadataEntries[row].rowHeight } }