Skip to content
This repository has been archived by the owner on Nov 3, 2020. It is now read-only.

Commit

Permalink
Merge pull request #245 from CocoaPods/dan-new-podfile
Browse files Browse the repository at this point in the history
Adds support for running `pod init` on an Xcode Project
  • Loading branch information
orta committed Feb 12, 2016
2 parents 6b69cc0 + bc70d9e commit c4c3b29
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 7 deletions.
4 changes: 4 additions & 0 deletions app/CocoaPods.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,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 */; };
Expand Down Expand Up @@ -265,6 +266,7 @@
60FE01661B9B7AA70027EEE3 /* SMLTextView+CocoaPods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SMLTextView+CocoaPods.m"; sourceTree = "<group>"; };
60FE016F1B9B7F1E0027EEE3 /* SUUpdater+DebugMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SUUpdater+DebugMode.m"; sourceTree = "<group>"; };
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 = "<group>"; };
66F2E29A1C492C5500A1AF1F /* NSColor+CPColors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+CPColors.h"; sourceTree = "<group>"; };
66F2E29B1C492C5500A1AF1F /* NSColor+CPColors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSColor+CPColors.m"; sourceTree = "<group>"; };
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 = "<group>"; };
Expand Down Expand Up @@ -580,6 +582,7 @@
93FB07E01C503572007B2CDA /* CPDocumentSource.swift */,
60E693B41C4A71E50058DF5F /* CPSidebarDocumentsController.swift */,
934FF1881C4F1E2A000B4302 /* CPDocumentController.swift */,
657841C81C6BE0EC00B6671E /* CPPodfileInitController.swift */,
);
name = "Home Window";
sourceTree = "<group>";
Expand Down Expand Up @@ -996,6 +999,7 @@
60814A881C2BCFEA00D6663E /* CPWhiteCheckedButton.m in Sources */,
331188571BEBCB0F00272793 /* CPCLIToolInstallationController.m in Sources */,
60E693B51C4A71E50058DF5F /* CPSidebarDocumentsController.swift in Sources */,
657841C91C6BE0EC00B6671E /* CPPodfileInitController.swift in Sources */,
5BD58BBD1C6D2A7C003787F5 /* CPXcodeProjectCell.swift in Sources */,
606C84721C14C4CA00C6D15F /* CPPodfileMetadataViewController.swift in Sources */,
60E693AC1C49BFDF0058DF5F /* CPHomeWindowDocumentEntry.m in Sources */,
Expand Down
9 changes: 7 additions & 2 deletions app/CocoaPods/Base.lproj/MainMenu.xib
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15D9c" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10089" systemVersion="15A284" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10089"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
Expand Down Expand Up @@ -86,6 +86,11 @@
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="bib-Uj-vzu">
<items>
<menuItem title="New Podfile from Xcode Project" keyEquivalent="n" id="Q1o-LS-sQI">
<connections>
<action selector="newDocument:" target="Qtz-kf-riq" id="oL2-Tr-Eyw"/>
</connections>
</menuItem>
<menuItem title="Open Podfile…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="Qtz-kf-riq" id="uid-Xs-MhY"/>
Expand Down
9 changes: 9 additions & 0 deletions app/CocoaPods/CLI Integrations/CPCLITask.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@
delegate:(id<CPCLITaskDelegate>)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<CPCLITaskDelegate>)delegate
qualityOfService:(NSQualityOfService)qualityOfService;

/**
* Perform the task.
*/
Expand Down
22 changes: 17 additions & 5 deletions app/CocoaPods/CLI Integrations/CPCLITask.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ @interface CPCLITask ()

@property (nonatomic, weak) id<CPCLITaskDelegate> delegate;

@property (nonatomic, weak) CPUserProject *userProject;
@property (nonatomic, weak) NSString *workingDirectory;
@property (nonatomic, copy) NSString *command;

@property (nonatomic) NSTask *task;
Expand All @@ -27,14 +27,26 @@ - (instancetype)initWithUserProject:(CPUserProject *)userProject
delegate:(id<CPCLITaskDelegate>)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<CPCLITaskDelegate>)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;
}

Expand All @@ -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
Expand Down
24 changes: 24 additions & 0 deletions app/CocoaPods/CPDocumentController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -21,6 +23,28 @@ class CPDocumentController: NSDocumentController {
}
}

override func newDocument(sender: AnyObject?) {
let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = false
openPanel.allowedFileTypes = ["xcodeproj"]

openPanel.beginWithCompletionHandler { buttonIndex in
guard buttonIndex == NSFileHandlingPanelOKButton else { return }
guard let fileURL = openPanel.URL else { return }

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 }
})
}
}

// `noteNewRecentDocument` ends up calling to this method so we can just override this one method

override func noteNewRecentDocumentURL(url: NSURL) {
Expand Down
65 changes: 65 additions & 0 deletions app/CocoaPods/CPPodfileInitController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
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)
}
}
}

0 comments on commit c4c3b29

Please sign in to comment.