From 2fd9d2972ba13ddf373933e61a949f0c552db2b4 Mon Sep 17 00:00:00 2001 From: Daniel Tomlinson Date: Wed, 10 Feb 2016 22:16:26 +0000 Subject: [PATCH] [App] Run pod init on xcode projects --- app/CocoaPods.xcodeproj/project.pbxproj | 4 ++ app/CocoaPods/CLI Integrations/CPCLITask.h | 9 +++ app/CocoaPods/CLI Integrations/CPCLITask.m | 22 +++++-- app/CocoaPods/CPDocumentController.swift | 14 +++- app/CocoaPods/CPPodfileInitController.swift | 73 +++++++++++++++++++++ 5 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 app/CocoaPods/CPPodfileInitController.swift diff --git a/app/CocoaPods.xcodeproj/project.pbxproj b/app/CocoaPods.xcodeproj/project.pbxproj index bb248bd1..6d547a14 100644 --- a/app/CocoaPods.xcodeproj/project.pbxproj +++ b/app/CocoaPods.xcodeproj/project.pbxproj @@ -82,6 +82,7 @@ 60E693BD1C4AC6390058DF5F /* CPHomeSidebarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60E693BC1C4AC6390058DF5F /* CPHomeSidebarButton.swift */; }; 60FE01671B9B7AA70027EEE3 /* SMLTextView+CocoaPods.m in Sources */ = {isa = PBXBuildFile; fileRef = 60FE01661B9B7AA70027EEE3 /* SMLTextView+CocoaPods.m */; }; 60FE01701B9B7F1E0027EEE3 /* SUUpdater+DebugMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 60FE016F1B9B7F1E0027EEE3 /* SUUpdater+DebugMode.m */; }; + 657841C91C6BE0EC00B6671E /* CPPodfileInitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657841C81C6BE0EC00B6671E /* CPPodfileInitController.swift */; }; 66F2E29C1C492C5500A1AF1F /* NSColor+CPColors.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F2E29B1C492C5500A1AF1F /* NSColor+CPColors.m */; }; 770382F41A2035B400435285 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 770382F31A2035B400435285 /* Localizable.strings */; }; 77356D751A2253F1002822CF /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 77356D741A2253F1002822CF /* Media.xcassets */; }; @@ -263,6 +264,7 @@ 60FE01661B9B7AA70027EEE3 /* SMLTextView+CocoaPods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SMLTextView+CocoaPods.m"; sourceTree = ""; }; 60FE016F1B9B7F1E0027EEE3 /* SUUpdater+DebugMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SUUpdater+DebugMode.m"; sourceTree = ""; }; 62FB6E124C8280A7EBFD41C6 /* Pods_CocoaPodsTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CocoaPodsTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 657841C81C6BE0EC00B6671E /* CPPodfileInitController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPPodfileInitController.swift; sourceTree = ""; }; 66F2E29A1C492C5500A1AF1F /* NSColor+CPColors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+CPColors.h"; sourceTree = ""; }; 66F2E29B1C492C5500A1AF1F /* NSColor+CPColors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSColor+CPColors.m"; sourceTree = ""; }; 750B3A66521735BD745849E5 /* Pods-CocoaPodsTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CocoaPodsTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CocoaPodsTests/Pods-CocoaPodsTests.debug.xcconfig"; sourceTree = ""; }; @@ -577,6 +579,7 @@ 93FB07E01C503572007B2CDA /* CPDocumentSource.swift */, 60E693B41C4A71E50058DF5F /* CPSidebarDocumentsController.swift */, 934FF1881C4F1E2A000B4302 /* CPDocumentController.swift */, + 657841C81C6BE0EC00B6671E /* CPPodfileInitController.swift */, ); name = "Home Window"; sourceTree = ""; @@ -993,6 +996,7 @@ 60814A881C2BCFEA00D6663E /* CPWhiteCheckedButton.m in Sources */, 331188571BEBCB0F00272793 /* CPCLIToolInstallationController.m in Sources */, 60E693B51C4A71E50058DF5F /* CPSidebarDocumentsController.swift in Sources */, + 657841C91C6BE0EC00B6671E /* CPPodfileInitController.swift in Sources */, 606C84721C14C4CA00C6D15F /* CPPodfileMetadataViewController.swift in Sources */, 60E693AC1C49BFDF0058DF5F /* CPHomeWindowDocumentEntry.m in Sources */, FA16FAD21C144BF300DC3791 /* URLHandler.swift in Sources */, diff --git a/app/CocoaPods/CLI Integrations/CPCLITask.h b/app/CocoaPods/CLI Integrations/CPCLITask.h index 118ecc45..113c12e2 100644 --- a/app/CocoaPods/CLI Integrations/CPCLITask.h +++ b/app/CocoaPods/CLI Integrations/CPCLITask.h @@ -37,6 +37,15 @@ delegate:(id)delegate qualityOfService:(NSQualityOfService)qualityOfService; +/** + * @param workingDirectory The directory for which the command should be performed. + * @param command The `pod` command to execute, such as `install` or `update.` + */ +- (instancetype)initWithWorkingDirectory:(NSString *)workingDirectory + command:(NSString *)command + delegate:(id)delegate + qualityOfService:(NSQualityOfService)qualityOfService; + /** * Perform the task. */ diff --git a/app/CocoaPods/CLI Integrations/CPCLITask.m b/app/CocoaPods/CLI Integrations/CPCLITask.m index c1a2d939..73f2b53a 100644 --- a/app/CocoaPods/CLI Integrations/CPCLITask.m +++ b/app/CocoaPods/CLI Integrations/CPCLITask.m @@ -6,7 +6,7 @@ @interface CPCLITask () @property (nonatomic, weak) id delegate; -@property (nonatomic, weak) CPUserProject *userProject; +@property (nonatomic, weak) NSString *workingDirectory; @property (nonatomic, copy) NSString *command; @property (nonatomic) NSTask *task; @@ -27,14 +27,26 @@ - (instancetype)initWithUserProject:(CPUserProject *)userProject delegate:(id)delegate qualityOfService:(NSQualityOfService)qualityOfService { - if (self = [super init]) { - self.userProject = userProject; + return [self initWithWorkingDirectory:[[userProject.fileURL URLByDeletingLastPathComponent] path] + command:command + delegate:delegate + qualityOfService:qualityOfService]; +} + +- (instancetype)initWithWorkingDirectory:(NSString *)workingDirectory + command:(NSString *)command + delegate:(id)delegate + qualityOfService:(NSQualityOfService)qualityOfService +{ + self = [super init]; + if (self) { + self.workingDirectory = workingDirectory; self.command = command; self.delegate = delegate; self.qualityOfService = qualityOfService; self.terminationStatus = 1; } - + return self; } @@ -57,7 +69,7 @@ - (void)run @"TERM": @"xterm-256color" }; - NSString *workingDirectory = [[self.userProject.fileURL URLByDeletingLastPathComponent] path]; + NSString *workingDirectory = self.workingDirectory; NSString *launchPath = @"/bin/sh"; NSString *envBundleScript = [[NSBundle mainBundle] pathForResource:@"bundle-env" ofType:nil diff --git a/app/CocoaPods/CPDocumentController.swift b/app/CocoaPods/CPDocumentController.swift index 41d3ac3b..ecbfe963 100644 --- a/app/CocoaPods/CPDocumentController.swift +++ b/app/CocoaPods/CPDocumentController.swift @@ -9,6 +9,8 @@ class CPDocumentController: NSDocumentController { static let RecentDocumentUpdateNotification = "CPDocumentControllerRecentDocumentUpdateNotification" static let ClearRecentDocumentsNotification = "CPDocumentControllerClearRecentDocumentsNotification" + var podInitController: CPPodfileInitController? + // All of the `openDocument...` calls end up calling this one method, so adding our notification here is simple override func openDocumentWithContentsOfURL(url: NSURL, display displayDocument: Bool, completionHandler: (NSDocument?, Bool, NSError?) -> Void) { @@ -29,7 +31,17 @@ class CPDocumentController: NSDocumentController { openPanel.beginWithCompletionHandler { buttonIndex in guard buttonIndex == NSFileHandlingPanelOKButton else { return } guard let fileURL = openPanel.URL else { return } - print(fileURL) + + self.podInitController = CPPodfileInitController(xcodeprojURL: fileURL, completionHandler: { podfileURL, error -> () in + guard let podfileURL = podfileURL else { + let alert = NSAlert(error: error! as NSError) + alert.informativeText = error!.message + alert.runModal() + + return + } + self.openDocumentWithContentsOfURL(podfileURL, display: true) { _ in } + }) } } diff --git a/app/CocoaPods/CPPodfileInitController.swift b/app/CocoaPods/CPPodfileInitController.swift new file mode 100644 index 00000000..678f6166 --- /dev/null +++ b/app/CocoaPods/CPPodfileInitController.swift @@ -0,0 +1,73 @@ +// +// CPPodfileInitController.swift +// CocoaPods +// +// Created by Daniel Tomlinson on 10/02/2016. +// Copyright © 2016 CocoaPods. All rights reserved. +// + +import Foundation + +public enum CPPodfileInitErrors: ErrorType { + case CommandError(String) + case NSURLError + + var message: String { + switch self { + case .CommandError(let s): return s + case .NSURLError: return "NSURL unexpectedly nil" + } + } +} + +public class CPPodfileInitController: NSObject, CPCLITaskDelegate { + private var task: CPCLITask! + private let completionHandler: (NSURL?, CPPodfileInitErrors?) -> () + private let output = NSMutableAttributedString() + private let projectURL: NSURL + + init(xcodeprojURL: NSURL, completionHandler: (podfileURL: NSURL?, error: CPPodfileInitErrors?) -> ()) { + self.completionHandler = completionHandler + self.projectURL = xcodeprojURL + + super.init() + let task = CPCLITask(workingDirectory: xcodeprojURL.URLByDeletingLastPathComponent!.path, + command: "init", + delegate: self, + qualityOfService: .UserInitiated) + self.task = task + + self.task.run() + } + + public func task(task: CPCLITask!, didUpdateOutputContents updatedOutput: NSAttributedString!) { + output.appendAttributedString(updatedOutput) + } + + public func taskCompleted(task: CPCLITask!) { + guard task.finishedSuccessfully() else { + self.callbackWithError(CPPodfileInitErrors.CommandError(self.output.string)) + return + } + + guard let podfileURL = projectURL.URLByDeletingLastPathComponent?.URLByAppendingPathComponent("Podfile") where NSFileManager().fileExistsAtPath(podfileURL.path ?? "") + else { + self.callbackWithError(CPPodfileInitErrors.NSURLError) + return + } + + callbackWithSuccess(podfileURL) + } + + private func callbackWithError(error: CPPodfileInitErrors) { + dispatch_async(dispatch_get_main_queue()) { + self.completionHandler(nil, error) + } + } + + private func callbackWithSuccess(url: NSURL) { + dispatch_async(dispatch_get_main_queue()) { + self.completionHandler(url, nil) + } + } +} \ No newline at end of file