From aa980e2f5dcb1656e1aea3b2afd3222f4cde4ad2 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Sun, 13 Dec 2015 21:40:02 -0500 Subject: [PATCH 01/10] Initial work on showing an install recommendation --- app/CocoaPods.xcodeproj/project.pbxproj | 26 ++-- .../Base.lproj/CPHomeWindowController.xib | 129 +++++++++++++----- .../CPCLIToolInstallationController.h | 7 + .../CPCLIToolInstallationController.m | 15 +- app/CocoaPods/CPAppDelegate.m | 29 ++-- app/CocoaPods/CPBrownVisualEffectsView.swift | 9 +- app/CocoaPods/CPHomeWindowController.h | 3 + app/CocoaPods/CPHomeWindowController.m | 48 ++++++- 8 files changed, 196 insertions(+), 70 deletions(-) diff --git a/app/CocoaPods.xcodeproj/project.pbxproj b/app/CocoaPods.xcodeproj/project.pbxproj index 5930f483..097c899f 100644 --- a/app/CocoaPods.xcodeproj/project.pbxproj +++ b/app/CocoaPods.xcodeproj/project.pbxproj @@ -142,8 +142,8 @@ 1F9177561BA27592006698C9 /* CPHomeWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPHomeWindowController.m; sourceTree = ""; }; 1F91775B1BA27598006698C9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/CPHomeWindowController.xib; sourceTree = ""; }; 217877836B7D3B2373163464 /* Pods_CocoaPods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CocoaPods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 331188551BEBCB0F00272793 /* CPCLIToolInstallationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPCLIToolInstallationController.h; sourceTree = ""; }; - 331188561BEBCB0F00272793 /* CPCLIToolInstallationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPCLIToolInstallationController.m; sourceTree = ""; }; + 331188551BEBCB0F00272793 /* CPCLIToolInstallationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CPCLIToolInstallationController.h; path = "CLI Integrations/CPCLIToolInstallationController.h"; sourceTree = ""; }; + 331188561BEBCB0F00272793 /* CPCLIToolInstallationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CPCLIToolInstallationController.m; path = "CLI Integrations/CPCLIToolInstallationController.m"; sourceTree = ""; }; 331188581BEBCB4200272793 /* CPCLITask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPCLITask.h; sourceTree = ""; }; 331188591BEBCB4200272793 /* CPCLITask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPCLITask.m; sourceTree = ""; }; 48BFECFC4C849B1ABEB40B43 /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -266,8 +266,6 @@ children = ( 331188581BEBCB4200272793 /* CPCLITask.h */, 331188591BEBCB4200272793 /* CPCLITask.m */, - 331188551BEBCB0F00272793 /* CPCLIToolInstallationController.h */, - 331188561BEBCB0F00272793 /* CPCLIToolInstallationController.m */, ); path = "CLI Integrations"; sourceTree = ""; @@ -381,6 +379,15 @@ name = Resources; sourceTree = ""; }; + 6033ECB01C1E588300C2EDAD /* Command Line Tools */ = { + isa = PBXGroup; + children = ( + 331188551BEBCB0F00272793 /* CPCLIToolInstallationController.h */, + 331188561BEBCB0F00272793 /* CPCLIToolInstallationController.m */, + ); + name = "Command Line Tools"; + sourceTree = ""; + }; 6051191E1C08C4AC0037B95E /* Custom Subviews */ = { isa = PBXGroup; children = ( @@ -434,13 +441,6 @@ name = "Presenting Text"; sourceTree = ""; }; - 606D1EDB1BF93079000B7148 /* Views */ = { - isa = PBXGroup; - children = ( - ); - name = Views; - sourceTree = ""; - }; 60F02D1A1C0A2A6D003600FE /* CocoaPodsTests */ = { isa = PBXGroup; children = ( @@ -453,6 +453,7 @@ 60FE01621B9B76400027EEE3 /* Home Window */ = { isa = PBXGroup; children = ( + 6033ECB01C1E588300C2EDAD /* Command Line Tools */, 6051191E1C08C4AC0037B95E /* Custom Subviews */, 601F910E1BE6405B00AD22B1 /* Resources */, 1F9177551BA27592006698C9 /* CPHomeWindowController.h */, @@ -460,7 +461,6 @@ 1F91775C1BA27598006698C9 /* CPHomeWindowController.xib */, 6085133D1BB6A3D500595B97 /* CPRecentDocumentsController.h */, 6085133E1BB6A3D500595B97 /* CPRecentDocumentsController.m */, - 603F7F1D1C1DE895006C2571 /* CPMenuVisiblityDirector.swift */, ); name = "Home Window"; sourceTree = ""; @@ -481,9 +481,9 @@ 60FE01641B9B76520027EEE3 /* Project */ = { isa = PBXGroup; children = ( + 603F7F1D1C1DE895006C2571 /* CPMenuVisiblityDirector.swift */, 601F910B1BE63B8100AD22B1 /* CPExternalLinksHelper.h */, 601F910C1BE63B8100AD22B1 /* CPExternalLinksHelper.m */, - 606D1EDB1BF93079000B7148 /* Views */, ); name = Project; sourceTree = ""; diff --git a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib index 050142b2..bca5f9f9 100644 --- a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib +++ b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib @@ -1,12 +1,14 @@ - + - + + + @@ -20,22 +22,21 @@ - - + + - + - + - + - + - @@ -63,7 +64,6 @@ - @@ -74,7 +74,6 @@ - @@ -86,7 +85,6 @@ - @@ -110,7 +108,6 @@ - @@ -123,34 +120,28 @@ - - - - - + + - + @@ -190,7 +179,6 @@ - @@ -199,11 +187,9 @@ - - - + @@ -212,7 +198,7 @@ - + @@ -222,7 +208,6 @@ - @@ -235,6 +220,84 @@ + + + + + + + + By installing the CocoaPods Command Line Tools you can run the pod command from your favorite terminal, and it will actually run the sandboxed command provided inside CocoaPods.app bundle. + + + + + + + + + This is done my making a symbolic link for the App's sandboxed pod command in +/usr/local/bin/pod + + + + + + + + + + + + + + + + + + Do you want to Install the +Command-Line Tools? + + + + + + + + + + + + + + diff --git a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h index c84226bc..0b957c06 100644 --- a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h +++ b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h @@ -8,6 +8,13 @@ extern NSString * const kCPCLIToolInstalledToDestinationsKey; + (instancetype)controllerWithSuggestedDestinationURL:(NSURL *)suggestedDestinationURL; +// Checks if binstub is not installed yet and is not configured to not request the +// user for installation again (`kCPRequestCLIToolInstallationAgainKey`). +// +// Returns whether or not installation should be performed. + +- (BOOL)shouldInstallBinstubIfNecessary; + // Only performs the installation if it's not installed yet and is not configured to not request the // user for installation again (`kCPRequestCLIToolInstallationAgainKey`). // diff --git a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m index 909a4988..90f34401 100644 --- a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m +++ b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m @@ -29,7 +29,7 @@ - (instancetype)initWithSuggestedDestinationURL:(NSURL *)suggestedDestinationURL return self; } -- (BOOL)installBinstubIfNecessary; +- (BOOL)shouldInstallBinstubIfNecessary; { [self verifyExistingInstallDestinations]; @@ -43,7 +43,16 @@ - (BOOL)installBinstubIfNecessary; return NO; } - return [self installBinstub]; + return YES; +} + + +- (BOOL)installBinstubIfNecessary; +{ + if ([self shouldInstallBinstubIfNecessary]) { + return [self installBinstub]; + } + return NO; } - (BOOL)installBinstub; @@ -171,7 +180,7 @@ - (NSURL *)binstubSourceURL; #pragma mark - User interaction (modal windows) -// Returns wether or not the user chose to perform the installation and, in case the user chose a +// Returns whether or not the user chose to perform the installation and, in case the user chose a // different installation destination, the `destinationURL` is updated. // // In case the user chose to cancel the operation, this preference is stored and the user will not diff --git a/app/CocoaPods/CPAppDelegate.m b/app/CocoaPods/CPAppDelegate.m index 2ee30b3b..ce02e967 100644 --- a/app/CocoaPods/CPAppDelegate.m +++ b/app/CocoaPods/CPAppDelegate.m @@ -3,11 +3,10 @@ #import "CPHomeWindowController.h" #import "CPReflectionServiceProtocol.h" #import "CocoaPods-Swift.h" - -NSString * const kCPCLIToolSuggestedDestination = @"/usr/local/bin/pod"; +#import "CPCLIToolInstallationController.h" @interface CPAppDelegate () -@property (strong) CPHomeWindowController *homeWindowController; +@property (nonatomic, strong) CPHomeWindowController *homeWindowController; @property (strong) NSXPCConnection *reflectionService; @property (strong) URLHandler *urlHandler; @end @@ -24,15 +23,11 @@ - (void)applicationWillFinishLaunching:(NSNotification *)notification; - (void)applicationDidFinishLaunching:(NSNotification *)notification; { #ifdef DEBUG - //[[NSUserDefaults standardUserDefaults] removeObjectForKey:kCPRequestCLIToolInstallationAgainKey]; - //[[NSUserDefaults standardUserDefaults] removeObjectForKey:kCPCLIToolInstalledToDestinationsKey]; - //[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"CPShowVerboseCommandOutput"]; - //NSLog(@"%@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]); + [[NSUserDefaults standardUserDefaults] removeObjectForKey:kCPDoNotRequestCLIToolInstallationAgainKey]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:kCPCLIToolInstalledToDestinationsKey]; #endif [self startReflectionService]; - - [[self CLIToolInstallationController] installBinstubIfNecessary]; } - (void)startReflectionService; @@ -78,30 +73,28 @@ - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows: return YES; } - #pragma mark - Actions - (IBAction)installBinstubIfNecessary:(id)sender; { - [[self CLIToolInstallationController] installBinstub]; + [self.homeWindowController installBinstub:sender]; } - (IBAction)showHomeWindow:(id)sender; { - if (self.homeWindowController == nil) { - self.homeWindowController = [[CPHomeWindowController alloc] init]; - } - [self.homeWindowController showWindow:sender]; [self.homeWindowController.window center]; } #pragma mark - Private -- (CPCLIToolInstallationController *)CLIToolInstallationController; +- (CPHomeWindowController *)homeWindowController { - NSURL *destinationURL = [NSURL fileURLWithPath:kCPCLIToolSuggestedDestination]; - return [CPCLIToolInstallationController controllerWithSuggestedDestinationURL:destinationURL]; + if (_homeWindowController == nil) { + _homeWindowController = [[CPHomeWindowController alloc] init]; + } + return _homeWindowController; } + @end diff --git a/app/CocoaPods/CPBrownVisualEffectsView.swift b/app/CocoaPods/CPBrownVisualEffectsView.swift index 87fa5c04..c01acb04 100644 --- a/app/CocoaPods/CPBrownVisualEffectsView.swift +++ b/app/CocoaPods/CPBrownVisualEffectsView.swift @@ -18,4 +18,11 @@ class BrownView: NSView { NSColor.init(colorLiteralRed: 56/256, green: 1/256, blue: 0, alpha: 0.6).set() NSRectFill(dirtyRect); } -} \ No newline at end of file +} + +class BlueView: NSView { + override func drawRect(dirtyRect: NSRect) { + NSColor(calibratedRed:0.227, green:0.463, blue:0.733, alpha:1.00).set() + NSRectFill(dirtyRect); + } +} diff --git a/app/CocoaPods/CPHomeWindowController.h b/app/CocoaPods/CPHomeWindowController.h index a1c9d831..426ac004 100644 --- a/app/CocoaPods/CPHomeWindowController.h +++ b/app/CocoaPods/CPHomeWindowController.h @@ -2,4 +2,7 @@ @interface CPHomeWindowController : NSWindowController +/// Forces the installation of the binstub +- (IBAction)installBinstub:(id)sender; + @end diff --git a/app/CocoaPods/CPHomeWindowController.m b/app/CocoaPods/CPHomeWindowController.m index 38f64bfc..1fd04108 100644 --- a/app/CocoaPods/CPHomeWindowController.m +++ b/app/CocoaPods/CPHomeWindowController.m @@ -1,7 +1,9 @@ #import "CPHomeWindowController.h" #import "CPRecentDocumentsController.h" +#import "CocoaPods-Swift.h" +#import "CPCLIToolInstallationController.h" -#pragma mark - +NSString * const kCPCLIToolSuggestedDestination = @"/usr/local/bin/pod"; @interface CPHomeWindowController () @@ -13,6 +15,9 @@ @interface CPHomeWindowController () @property (weak) IBOutlet NSButton *openSearchButton; @property (weak) IBOutlet NSButton *openChangelogButton; +@property (strong) IBOutlet BlueView *installCommandLineToolsView; +@property (weak) IBOutlet NSLayoutConstraint *commandLineToolsHeightConstraint; + @end @implementation CPHomeWindowController @@ -35,9 +40,14 @@ - (void)windowDidLoad; NSString *versionNumber = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; self.cocoapodsVersionTextField.stringValue = versionNumber; + + if ([[self CLIToolInstallationController] shouldInstallBinstubIfNecessary]) { + [self addCLIInstallerMessageAnimated:YES]; + } } -- (void)didDoubleTapOnRecentItem:(NSTableView *)sender { +- (void)didDoubleTapOnRecentItem:(NSTableView *)sender; +{ NSInteger row = [sender selectedRow]; CPHomeWindowDocumentEntry *item = self.recentDocumentsController.recentDocuments[row]; @@ -48,5 +58,39 @@ - (void)didDoubleTapOnRecentItem:(NSTableView *)sender { }]; } +// Takes the installCommandLineToolsView and pulls it out of the nib +// adding it into the contentview of the window, then animates it down +// to peak into the message. + +- (void)addCLIInstallerMessageAnimated:(BOOL)animate; +{ + NSView *content = self.window.contentView; + self.commandLineToolsHeightConstraint.constant = 2; + [content addSubview:self.installCommandLineToolsView]; + + NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:self.installCommandLineToolsView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:content attribute:NSLayoutAttributeTop multiplier:1 constant:20]; + [content addConstraint:topConstraint]; + + id constraint = animate ? self.commandLineToolsHeightConstraint.animator : self.commandLineToolsHeightConstraint; + [constraint setConstant:68]; +} + +- (IBAction)showFullCLIInstallerMessageAnimated:(id)sender; +{ + NSView *content = self.window.contentView; + [self.commandLineToolsHeightConstraint.animator setConstant:CGRectGetHeight(content.bounds)]; +} + +- (IBAction)installBinstub:(id)sender; +{ + [[self CLIToolInstallationController] installBinstub]; +} + +- (CPCLIToolInstallationController *)CLIToolInstallationController; +{ + NSURL *destinationURL = [NSURL fileURLWithPath:kCPCLIToolSuggestedDestination]; + return [CPCLIToolInstallationController controllerWithSuggestedDestinationURL:destinationURL]; +} + @end From a60ea6372834972845cee384cf614b14090cd10e Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Sun, 13 Dec 2015 22:49:59 -0500 Subject: [PATCH 02/10] Initial stab at the content for the install section --- app/CocoaPods.xcodeproj/project.pbxproj | 20 ++-- .../Base.lproj/CPHomeWindowController.xib | 93 ++++++++++++------ app/CocoaPods/CPBorderedButton.swift | 20 ++++ app/CocoaPods/CPHomeWindowController.m | 11 ++- .../CP-Term.imageset/CP-Term.png | Bin 0 -> 11109 bytes .../CP-Term.imageset/CP-Terminal-1.png | Bin 0 -> 11109 bytes .../CP-Term.imageset/Contents.json | 22 +++++ .../ConsoleWindow.imageset/ConsoleWindow.png | Bin 0 -> 7464 bytes .../ConsoleWindow@2x.png | Bin 0 -> 7464 bytes .../ConsoleWindow.imageset/Contents.json | 22 +++++ .../Home Screen.xcassets/Contents.json | 6 ++ .../Podfile-icon.imageset/Contents.json | 21 ++++ .../Podfile-icon@2x.png | Bin .../Contents.json | 44 +++++++++ .../TransparentButtonBG.png | Bin 0 -> 413 bytes .../TransparentButtonBG@2x.png | Bin 0 -> 875 bytes 16 files changed, 215 insertions(+), 44 deletions(-) create mode 100644 app/CocoaPods/CPBorderedButton.swift create mode 100644 app/CocoaPods/Home Screen.xcassets/CP-Term.imageset/CP-Term.png create mode 100644 app/CocoaPods/Home Screen.xcassets/CP-Term.imageset/CP-Terminal-1.png create mode 100644 app/CocoaPods/Home Screen.xcassets/CP-Term.imageset/Contents.json create mode 100644 app/CocoaPods/Home Screen.xcassets/ConsoleWindow.imageset/ConsoleWindow.png create mode 100644 app/CocoaPods/Home Screen.xcassets/ConsoleWindow.imageset/ConsoleWindow@2x.png create mode 100644 app/CocoaPods/Home Screen.xcassets/ConsoleWindow.imageset/Contents.json create mode 100644 app/CocoaPods/Home Screen.xcassets/Contents.json create mode 100644 app/CocoaPods/Home Screen.xcassets/Podfile-icon.imageset/Contents.json rename app/CocoaPods/{ => Home Screen.xcassets/Podfile-icon.imageset}/Podfile-icon@2x.png (100%) create mode 100644 app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/Contents.json create mode 100644 app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/TransparentButtonBG.png create mode 100644 app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/TransparentButtonBG@2x.png diff --git a/app/CocoaPods.xcodeproj/project.pbxproj b/app/CocoaPods.xcodeproj/project.pbxproj index 097c899f..5b1ede42 100644 --- a/app/CocoaPods.xcodeproj/project.pbxproj +++ b/app/CocoaPods.xcodeproj/project.pbxproj @@ -40,8 +40,9 @@ 5E946F3F1C1621F000EFEA7B /* CPTabViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E946F3E1C1621F000EFEA7B /* CPTabViewDelegate.swift */; }; 5EF5B7871C17990400F8C39E /* CPSideButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EF5B7861C17990400F8C39E /* CPSideButton.swift */; }; 601F910D1BE63B8100AD22B1 /* CPExternalLinksHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 601F910C1BE63B8100AD22B1 /* CPExternalLinksHelper.m */; }; - 601F91101BE6406600AD22B1 /* Podfile-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 601F910F1BE6406600AD22B1 /* Podfile-icon@2x.png */; }; 601F91151BE6435E00AD22B1 /* NSURL+TersePaths.m in Sources */ = {isa = PBXBuildFile; fileRef = 601F91141BE6435E00AD22B1 /* NSURL+TersePaths.m */; }; + 6033ECB21C1E6B4D00C2EDAD /* Home Screen.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6033ECB11C1E6B4D00C2EDAD /* Home Screen.xcassets */; }; + 6033ECB41C1E6D7000C2EDAD /* CPBorderedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6033ECB31C1E6D7000C2EDAD /* CPBorderedButton.swift */; }; 6035BFF01C07C916003250A8 /* CPHiddenTabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6035BFEF1C07C916003250A8 /* CPHiddenTabViewController.swift */; }; 603F7F1E1C1DE895006C2571 /* CPMenuVisiblityDirector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 603F7F1D1C1DE895006C2571 /* CPMenuVisiblityDirector.swift */; }; 604C26CE1C07843C00E16D84 /* CPPodfileConsoleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604C26CC1C07843C00E16D84 /* CPPodfileConsoleViewController.swift */; }; @@ -183,9 +184,10 @@ 5EF5B7861C17990400F8C39E /* CPSideButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPSideButton.swift; sourceTree = ""; }; 601F910B1BE63B8100AD22B1 /* CPExternalLinksHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPExternalLinksHelper.h; sourceTree = ""; }; 601F910C1BE63B8100AD22B1 /* CPExternalLinksHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPExternalLinksHelper.m; sourceTree = ""; }; - 601F910F1BE6406600AD22B1 /* Podfile-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Podfile-icon@2x.png"; sourceTree = ""; }; 601F91131BE6435E00AD22B1 /* NSURL+TersePaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+TersePaths.h"; sourceTree = ""; }; 601F91141BE6435E00AD22B1 /* NSURL+TersePaths.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+TersePaths.m"; sourceTree = ""; }; + 6033ECB11C1E6B4D00C2EDAD /* Home Screen.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Home Screen.xcassets"; sourceTree = ""; }; + 6033ECB31C1E6D7000C2EDAD /* CPBorderedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPBorderedButton.swift; sourceTree = ""; }; 6035BFEF1C07C916003250A8 /* CPHiddenTabViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPHiddenTabViewController.swift; sourceTree = ""; }; 603F7F1D1C1DE895006C2571 /* CPMenuVisiblityDirector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPMenuVisiblityDirector.swift; sourceTree = ""; }; 604C26CC1C07843C00E16D84 /* CPPodfileConsoleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPPodfileConsoleViewController.swift; sourceTree = ""; }; @@ -371,14 +373,6 @@ path = pod; sourceTree = ""; }; - 601F910E1BE6405B00AD22B1 /* Resources */ = { - isa = PBXGroup; - children = ( - 601F910F1BE6406600AD22B1 /* Podfile-icon@2x.png */, - ); - name = Resources; - sourceTree = ""; - }; 6033ECB01C1E588300C2EDAD /* Command Line Tools */ = { isa = PBXGroup; children = ( @@ -392,6 +386,7 @@ isa = PBXGroup; children = ( 6051191F1C08C4C00037B95E /* CPReturnTriggeringTableView.swift */, + 6033ECB31C1E6D7000C2EDAD /* CPBorderedButton.swift */, ); name = "Custom Subviews"; sourceTree = ""; @@ -455,12 +450,12 @@ children = ( 6033ECB01C1E588300C2EDAD /* Command Line Tools */, 6051191E1C08C4AC0037B95E /* Custom Subviews */, - 601F910E1BE6405B00AD22B1 /* Resources */, 1F9177551BA27592006698C9 /* CPHomeWindowController.h */, 1F9177561BA27592006698C9 /* CPHomeWindowController.m */, 1F91775C1BA27598006698C9 /* CPHomeWindowController.xib */, 6085133D1BB6A3D500595B97 /* CPRecentDocumentsController.h */, 6085133E1BB6A3D500595B97 /* CPRecentDocumentsController.m */, + 6033ECB11C1E6B4D00C2EDAD /* Home Screen.xcassets */, ); name = "Home Window"; sourceTree = ""; @@ -672,9 +667,9 @@ 51D2E5B11A212A0800C0B153 /* Syntax Definitions in Resources */, 606D1ED21BF90705000B7148 /* Podfile.storyboard in Resources */, 6075BA651C068B5F00A5C491 /* Podfile.xcassets in Resources */, + 6033ECB21C1E6B4D00C2EDAD /* Home Screen.xcassets in Resources */, 5180FE941AD2A51300314D61 /* LICENSE in Resources */, 1F91775A1BA27598006698C9 /* CPHomeWindowController.xib in Resources */, - 601F91101BE6406600AD22B1 /* Podfile-icon@2x.png in Resources */, 77356D751A2253F1002822CF /* Media.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -834,6 +829,7 @@ FA16FAD21C144BF300DC3791 /* URLHandler.swift in Sources */, 51165E261A17AFF500DCFC94 /* CPAppDelegate.m in Sources */, 6051191D1C08A1EA0037B95E /* CPModifiedDecorationsWindow.swift in Sources */, + 6033ECB41C1E6D7000C2EDAD /* CPBorderedButton.swift in Sources */, 606D1ED51BF91040000B7148 /* CPPodfileEditorViewController.swift in Sources */, 51165E571A1B925300DCFC94 /* CPUserProject.m in Sources */, 60FE01671B9B7AA70027EEE3 /* SMLTextView+CocoaPods.m in Sources */, diff --git a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib index bca5f9f9..f973b7a8 100644 --- a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib +++ b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib @@ -226,51 +226,33 @@ - + By installing the CocoaPods Command Line Tools you can run the pod command from your favorite terminal, and it will actually run the sandboxed command provided inside CocoaPods.app bundle. - + - + - + This is done my making a symbolic link for the App's sandboxed pod command in /usr/local/bin/pod - - - - - - - - - + - + Do you want to Install the Command-Line Tools? - + - - + + + + + + + + + + + + + + + + + + + + + + -> Moya (5.1.0) + Network abstraction layer written in Swift + pod 'Moya', '~> 5.1.0' + - Homepage: https://github.com/Moya/Moya + - Source: https://github.com/Moya/Moya.git + - Versions: 5.1.0, 5.0.0, 4.5.0, 4.4.0, 4.3.1, 4.2.0, 4.1.0, 4.0.3, 4.0.2, 4.0.1, 4.0.0, 3.0.1, 3.0.0, 2.4.1, 2.4.0, 2.3.0, 2.2.2, 2.2.1, 2.1.0, 2.0.2, 2.0.1, 2.0.0, 1.1.1, 1.1.0, 1.0.0, 0.8.0, 0.7.1, 0.7.0, 0.6.1, 0.6 [master repo] + - Subspecs: + - Moya/Core (5.1.0) + - Moya/ReactiveCocoa (5.1.0) + - Moya/RxSwift (5.1.0) + + + + + + + + + + + + @@ -300,7 +334,10 @@ Command-Line Tools? + + + diff --git a/app/CocoaPods/CPBorderedButton.swift b/app/CocoaPods/CPBorderedButton.swift new file mode 100644 index 00000000..db41143d --- /dev/null +++ b/app/CocoaPods/CPBorderedButton.swift @@ -0,0 +1,20 @@ +import Cocoa + +class CPBorderedButton: NSButton { + + /// Sets centered white text for the font + override func awakeFromNib() { + (self.cell as? NSButtonCell)?.imageDimsWhenDisabled = false + + + + let style = NSMutableParagraphStyle() + style.alignment = .Center + + self.attributedTitle = NSAttributedString(string: title, attributes: [ + NSForegroundColorAttributeName: NSColor(calibratedWhite: 1, alpha: 1), + NSFontAttributeName: font!, + NSParagraphStyleAttributeName: style + ]) + } +} diff --git a/app/CocoaPods/CPHomeWindowController.m b/app/CocoaPods/CPHomeWindowController.m index 1fd04108..b2328575 100644 --- a/app/CocoaPods/CPHomeWindowController.m +++ b/app/CocoaPods/CPHomeWindowController.m @@ -58,9 +58,9 @@ - (void)didDoubleTapOnRecentItem:(NSTableView *)sender; }]; } -// Takes the installCommandLineToolsView and pulls it out of the nib -// adding it into the contentview of the window, then animates it down -// to peak into the message. +/// Takes the installCommandLineToolsView and pulls it out of the nib +/// adding it into the contentview of the window, then animates it down +/// to peak into the message. - (void)addCLIInstallerMessageAnimated:(BOOL)animate; { @@ -75,12 +75,16 @@ - (void)addCLIInstallerMessageAnimated:(BOOL)animate; [constraint setConstant:68]; } +/// Expands the message to the full height of the home screen window + - (IBAction)showFullCLIInstallerMessageAnimated:(id)sender; { NSView *content = self.window.contentView; [self.commandLineToolsHeightConstraint.animator setConstant:CGRectGetHeight(content.bounds)]; } +/// Installs the bind stub + - (IBAction)installBinstub:(id)sender; { [[self CLIToolInstallationController] installBinstub]; @@ -92,5 +96,4 @@ - (CPCLIToolInstallationController *)CLIToolInstallationController; return [CPCLIToolInstallationController controllerWithSuggestedDestinationURL:destinationURL]; } - @end diff --git a/app/CocoaPods/Home Screen.xcassets/CP-Term.imageset/CP-Term.png b/app/CocoaPods/Home Screen.xcassets/CP-Term.imageset/CP-Term.png new file mode 100644 index 0000000000000000000000000000000000000000..fa44bbdab215b7d8d664b791c1227ea97724e5be GIT binary patch literal 11109 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 MJl9aDlrsE=$q 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 literal 0 HcmV?d00001 diff --git a/app/CocoaPods/Home Screen.xcassets/ConsoleWindow.imageset/ConsoleWindow@2x.png b/app/CocoaPods/Home Screen.xcassets/ConsoleWindow.imageset/ConsoleWindow@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a0570c93d67d4d9a1e4f0530cf41339b63c06c73 GIT binary patch literal 7464 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 literal 0 HcmV?d00001 diff --git a/app/CocoaPods/Home Screen.xcassets/ConsoleWindow.imageset/Contents.json b/app/CocoaPods/Home Screen.xcassets/ConsoleWindow.imageset/Contents.json new file mode 100644 index 00000000..606bfadb --- /dev/null +++ b/app/CocoaPods/Home Screen.xcassets/ConsoleWindow.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ConsoleWindow.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ConsoleWindow@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/app/CocoaPods/Home Screen.xcassets/Contents.json b/app/CocoaPods/Home Screen.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/app/CocoaPods/Home Screen.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/app/CocoaPods/Home Screen.xcassets/Podfile-icon.imageset/Contents.json b/app/CocoaPods/Home Screen.xcassets/Podfile-icon.imageset/Contents.json new file mode 100644 index 00000000..30560abc --- /dev/null +++ b/app/CocoaPods/Home Screen.xcassets/Podfile-icon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Podfile-icon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/app/CocoaPods/Podfile-icon@2x.png b/app/CocoaPods/Home Screen.xcassets/Podfile-icon.imageset/Podfile-icon@2x.png similarity index 100% rename from app/CocoaPods/Podfile-icon@2x.png rename to app/CocoaPods/Home Screen.xcassets/Podfile-icon.imageset/Podfile-icon@2x.png diff --git a/app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/Contents.json b/app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/Contents.json new file mode 100644 index 00000000..9fd1b821 --- /dev/null +++ b/app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/Contents.json @@ -0,0 +1,44 @@ +{ + "images" : [ + { + "resizing" : { + "mode" : "3-part-horizontal", + "center" : { + "mode" : "tile", + "width" : 1 + }, + "cap-insets" : { + "right" : 7, + "left" : 8 + } + }, + "idiom" : "universal", + "filename" : "TransparentButtonBG.png", + "scale" : "1x" + }, + { + "resizing" : { + "mode" : "3-part-horizontal", + "center" : { + "mode" : "stretch", + "width" : 1 + }, + "cap-insets" : { + "right" : 10, + "left" : 10 + } + }, + "idiom" : "universal", + "filename" : "TransparentButtonBG@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/TransparentButtonBG.png b/app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/TransparentButtonBG.png new file mode 100644 index 0000000000000000000000000000000000000000..1f4e9924e3a4daa92337b7b1488a6f5eec6061bd GIT binary patch literal 413 zcmeAS@N?(olHy`uVBq!ia0vp^sX#2r!3HEX<~%3`QY`6?zK#qG8~eHcB(gFvFot-# zIEG}fzMW;8<>V;RYJ98XAuEe?b845#N|lIZ!HPS2)+pR;%Dm&|pmS*ln|7c_V!EbE zYnT&@>cgkI7b$&{)UROU`~0}M+D88RA@hex)|X6tBf>6xedkj=g+(kxvQ=PT+0`ap zhEGSnbRBykoO#6iL03@d71#3zBBdv|n>d<(tXXj>ktt>V0=caGbCF*HAAe9>`&gZ! znJH?)oYGU~r;cx5*ma!qKw`r??<}u1>>$;{XdnIXco~7Nn~YUU{>;U zaSW+oe0%qNcW7S7&Fo9d-G{9}%g=&3*I48?~qU6XtGRvnFTC zMgi4@C!Nv`yQtZVU3vM#?tSIC{_0(+_4nQfPk(Onz1r;k^5Um5V)@G-2RStU=PEJZ zzxe+9{M53pGm|YhP2M3gBdk%*e4Ag~ME1LR<+{5s28eiVIx+j*gvB>!&($<|%Cywv z`w3I7&4!ih7cUB!Bpnl>l=^Mn9rgSZ{*QtZqFB>*Y^;4^veV;K<wdx@17K+ zl=}6A(M`L3ue4cjDIR$KPo>iPRF&^Bduxj~YWF=N!*4r2iq)FHeW5Y()5a-{q5Bef z#oAw=U2(tu(7sfQ^6&*~nZ6|KD|=-9`@wBd{dw0Ce=5EYa$sb6apd!@?pCIte{7av zaU16Gn*9#}ini5e{0i*aw0y${?*HC5W4SagaMY~j^R@ru`)IjSW6Xm1<7ev^Mof`8 zxsu88z#VyfkZs~iM2Xfz&fX4=`{dNOv7mH>;6*MkoW9P|2y^~Si6*Wz{{#0?f_Y*b$Q*w46wis)1iJ!6;oGxz| zej>G~Wrs*cx5Ll$2kuYASSvUFT;?38rXMux@Erb0v6GAAwGC34Y~MXMj$Ep+|6gf- aJ!87Ja4KVC!$x54VeoYIb6Mw<&;$S!Gk-e( literal 0 HcmV?d00001 From 1da29150a23617fbdf47429f8cda39403fb89552 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Tue, 15 Dec 2015 17:16:55 -0500 Subject: [PATCH 03/10] Improve wording --- app/CocoaPods/Base.lproj/CPHomeWindowController.xib | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib index f973b7a8..c18ec171 100644 --- a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib +++ b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib @@ -227,16 +227,17 @@ - By installing the CocoaPods Command Line Tools you can run the pod command from your favorite terminal, and it will actually run the sandboxed command provided inside CocoaPods.app bundle. + By installing the CocoaPods Command Line Tools you can run the pod command from your favourite terminal. This means you get instant access to the whole +command-line API. - + - This is done my making a symbolic link for the App's sandboxed pod command in + This is done by making a symbolic link to the bundled pod command in: /usr/local/bin/pod @@ -303,7 +304,7 @@ Command-Line Tools? - -> Moya (5.1.0) + -> Moya (5.1.0) Network abstraction layer written in Swift pod 'Moya', '~> 5.1.0' - Homepage: https://github.com/Moya/Moya @@ -312,7 +313,7 @@ Command-Line Tools? - Subspecs: - Moya/Core (5.1.0) - Moya/ReactiveCocoa (5.1.0) - - Moya/RxSwift (5.1.0) + - Moya/RxSwift (5.1.0) From 03cb8be07ad872d76749dc15af6c3ad86a7bb529 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Wed, 23 Dec 2015 17:38:38 +0000 Subject: [PATCH 04/10] [Command Line Tools] Hook up Change directory for the binstub, support hiding the view --- app/CocoaPods.xcodeproj/project.pbxproj | 10 ++- .../Base.lproj/CPHomeWindowController.xib | 36 +++++---- .../CPCLIToolInstallationController.h | 35 +++++--- .../CPCLIToolInstallationController.m | 75 +++--------------- app/CocoaPods/CPBorderedButton.h | 5 ++ app/CocoaPods/CPBorderedButton.m | 26 ++++++ app/CocoaPods/CPBorderedButton.swift | 20 ----- app/CocoaPods/CPHomeWindowController.m | 40 +++++++--- .../Contents.json | 4 +- .../TransparentButtonBG.png | Bin 413 -> 261 bytes .../TransparentButtonBG@2x.png | Bin 875 -> 627 bytes 11 files changed, 124 insertions(+), 127 deletions(-) create mode 100644 app/CocoaPods/CPBorderedButton.h create mode 100644 app/CocoaPods/CPBorderedButton.m delete mode 100644 app/CocoaPods/CPBorderedButton.swift diff --git a/app/CocoaPods.xcodeproj/project.pbxproj b/app/CocoaPods.xcodeproj/project.pbxproj index 5b1ede42..768bac13 100644 --- a/app/CocoaPods.xcodeproj/project.pbxproj +++ b/app/CocoaPods.xcodeproj/project.pbxproj @@ -42,7 +42,6 @@ 601F910D1BE63B8100AD22B1 /* CPExternalLinksHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 601F910C1BE63B8100AD22B1 /* CPExternalLinksHelper.m */; }; 601F91151BE6435E00AD22B1 /* NSURL+TersePaths.m in Sources */ = {isa = PBXBuildFile; fileRef = 601F91141BE6435E00AD22B1 /* NSURL+TersePaths.m */; }; 6033ECB21C1E6B4D00C2EDAD /* Home Screen.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6033ECB11C1E6B4D00C2EDAD /* Home Screen.xcassets */; }; - 6033ECB41C1E6D7000C2EDAD /* CPBorderedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6033ECB31C1E6D7000C2EDAD /* CPBorderedButton.swift */; }; 6035BFF01C07C916003250A8 /* CPHiddenTabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6035BFEF1C07C916003250A8 /* CPHiddenTabViewController.swift */; }; 603F7F1E1C1DE895006C2571 /* CPMenuVisiblityDirector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 603F7F1D1C1DE895006C2571 /* CPMenuVisiblityDirector.swift */; }; 604C26CE1C07843C00E16D84 /* CPPodfileConsoleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604C26CC1C07843C00E16D84 /* CPPodfileConsoleViewController.swift */; }; @@ -56,6 +55,7 @@ 606D1EDA1BF911EF000B7148 /* CPPodfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606D1ED91BF911EF000B7148 /* CPPodfileViewController.swift */; }; 6075BA651C068B5F00A5C491 /* Podfile.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6075BA641C068B5F00A5C491 /* Podfile.xcassets */; }; 6075BA671C06963700A5C491 /* CPInstallAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6075BA661C06963700A5C491 /* CPInstallAction.swift */; }; + 60814A851C2B100F00D6663E /* CPBorderedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 60814A841C2B100F00D6663E /* CPBorderedButton.m */; }; 6085133F1BB6A3D500595B97 /* CPRecentDocumentsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6085133E1BB6A3D500595B97 /* CPRecentDocumentsController.m */; }; 60F02D1C1C0A2A6D003600FE /* CocoaPodsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60F02D1B1C0A2A6D003600FE /* CocoaPodsTests.swift */; }; 60F02D251C0A2E63003600FE /* Pods-CocoaPods.debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 60F02D231C0A2E63003600FE /* Pods-CocoaPods.debug.xcconfig */; }; @@ -187,7 +187,6 @@ 601F91131BE6435E00AD22B1 /* NSURL+TersePaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+TersePaths.h"; sourceTree = ""; }; 601F91141BE6435E00AD22B1 /* NSURL+TersePaths.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+TersePaths.m"; sourceTree = ""; }; 6033ECB11C1E6B4D00C2EDAD /* Home Screen.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Home Screen.xcassets"; sourceTree = ""; }; - 6033ECB31C1E6D7000C2EDAD /* CPBorderedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPBorderedButton.swift; sourceTree = ""; }; 6035BFEF1C07C916003250A8 /* CPHiddenTabViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPHiddenTabViewController.swift; sourceTree = ""; }; 603F7F1D1C1DE895006C2571 /* CPMenuVisiblityDirector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPMenuVisiblityDirector.swift; sourceTree = ""; }; 604C26CC1C07843C00E16D84 /* CPPodfileConsoleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPPodfileConsoleViewController.swift; sourceTree = ""; }; @@ -203,6 +202,8 @@ 606D1ED91BF911EF000B7148 /* CPPodfileViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPPodfileViewController.swift; sourceTree = ""; }; 6075BA641C068B5F00A5C491 /* Podfile.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Podfile.xcassets; sourceTree = ""; }; 6075BA661C06963700A5C491 /* CPInstallAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPInstallAction.swift; sourceTree = ""; }; + 60814A831C2B100F00D6663E /* CPBorderedButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPBorderedButton.h; sourceTree = ""; }; + 60814A841C2B100F00D6663E /* CPBorderedButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPBorderedButton.m; sourceTree = ""; }; 6085133D1BB6A3D500595B97 /* CPRecentDocumentsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPRecentDocumentsController.h; sourceTree = ""; }; 6085133E1BB6A3D500595B97 /* CPRecentDocumentsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPRecentDocumentsController.m; sourceTree = ""; }; 60F02D191C0A2A6D003600FE /* CocoaPodsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CocoaPodsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -386,7 +387,8 @@ isa = PBXGroup; children = ( 6051191F1C08C4C00037B95E /* CPReturnTriggeringTableView.swift */, - 6033ECB31C1E6D7000C2EDAD /* CPBorderedButton.swift */, + 60814A831C2B100F00D6663E /* CPBorderedButton.h */, + 60814A841C2B100F00D6663E /* CPBorderedButton.m */, ); name = "Custom Subviews"; sourceTree = ""; @@ -809,6 +811,7 @@ 510F09751C0A73B800F40F2B /* CPRubyErrors.m in Sources */, 603F7F1E1C1DE895006C2571 /* CPMenuVisiblityDirector.swift in Sources */, 7C4B007D1B9B441800B6C782 /* CPANSIEscapeHelper.m in Sources */, + 60814A851C2B100F00D6663E /* CPBorderedButton.m in Sources */, 5E946F3F1C1621F000EFEA7B /* CPTabViewDelegate.swift in Sources */, 605119281C0909420037B95E /* CPPodfileReflection.m in Sources */, 6035BFF01C07C916003250A8 /* CPHiddenTabViewController.swift in Sources */, @@ -829,7 +832,6 @@ FA16FAD21C144BF300DC3791 /* URLHandler.swift in Sources */, 51165E261A17AFF500DCFC94 /* CPAppDelegate.m in Sources */, 6051191D1C08A1EA0037B95E /* CPModifiedDecorationsWindow.swift in Sources */, - 6033ECB41C1E6D7000C2EDAD /* CPBorderedButton.swift in Sources */, 606D1ED51BF91040000B7148 /* CPPodfileEditorViewController.swift in Sources */, 51165E571A1B925300DCFC94 /* CPUserProject.m in Sources */, 60FE01671B9B7AA70027EEE3 /* SMLTextView+CocoaPods.m in Sources */, diff --git a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib index c18ec171..90011fa5 100644 --- a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib +++ b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib @@ -23,7 +23,7 @@ - + @@ -234,18 +234,15 @@ command-line API. - - + + - This is done by making a symbolic link to the bundled pod command in: -/usr/local/bin/pod - - + Do you want to Install the @@ -264,18 +261,18 @@ Command-Line Tools? - - - + @@ -324,7 +314,7 @@ Command-Line Tools? - + @@ -334,6 +324,16 @@ Command-Line Tools? + @@ -348,5 +348,6 @@ Command-Line Tools? + diff --git a/app/CocoaPods/CPBorderedButton.m b/app/CocoaPods/CPBorderedButton.m index 96732b3b..eb7ac278 100644 --- a/app/CocoaPods/CPBorderedButton.m +++ b/app/CocoaPods/CPBorderedButton.m @@ -11,17 +11,10 @@ -(void)awakeFromNib [self setTitle:self.title]; } -- (void)setTitle:(NSString *)title -{ - NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; - style.alignment = NSTextAlignmentCenter; +@end - self.attributedTitle = [[NSAttributedString alloc] initWithString:title attributes: @{ - NSForegroundColorAttributeName: [NSColor colorWithCalibratedWhite:1 alpha:1], - NSFontAttributeName: self.font ?: [NSFont labelFontOfSize:12], - NSParagraphStyleAttributeName: style - }]; -} +@interface CPBorderedButtonCell() +@property (strong) NSColor *textColor; @end @@ -39,4 +32,27 @@ - (NSRect)titleRectForBounds:(NSRect)rect return titleFrame; } +- (void)highlight:(BOOL)flag withFrame:(NSRect)cellFrame inView:(NSView*)controlView +{ + [super highlight:flag withFrame:cellFrame inView:controlView]; + self.textColor = flag ? [NSColor colorWithCalibratedRed:0.227 green:0.463 blue:0.733 alpha:1] + : [NSColor colorWithCalibratedWhite:1 alpha:1]; + // Re-renders the text via the function below + self.title = self.title; +} + +- (void)setTitle:(NSString *)title +{ + NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; + style.alignment = NSTextAlignmentCenter; + + self.attributedTitle = [[NSAttributedString alloc] initWithString:title attributes: @{ + NSForegroundColorAttributeName: self.textColor ?: [NSColor colorWithCalibratedWhite:1 alpha:1], + NSFontAttributeName: self.font ?: [NSFont labelFontOfSize:12], + NSParagraphStyleAttributeName: style + }]; +} + + + @end \ No newline at end of file diff --git a/app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/Contents.json b/app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/Contents.json index 5511cdba..7ac1b14a 100644 --- a/app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/Contents.json +++ b/app/CocoaPods/Home Screen.xcassets/TransparentButtonBG.imageset/Contents.json @@ -5,11 +5,11 @@ "mode" : "3-part-horizontal", "center" : { "mode" : "tile", - "width" : 9 + "width" : 7 }, "cap-insets" : { "right" : 7, - "left" : 7 + "left" : 9 } }, "idiom" : "universal", @@ -21,11 +21,11 @@ "mode" : "3-part-horizontal", "center" : { "mode" : "stretch", - "width" : 1 + "width" : 40 }, "cap-insets" : { - "right" : 10, - "left" : 10 + "right" : 9, + "left" : 9 } }, "idiom" : "universal", diff --git a/app/CocoaPods/Home Screen.xcassets/TransparentButtonBGFilled.imageset/Contents.json b/app/CocoaPods/Home Screen.xcassets/TransparentButtonBGFilled.imageset/Contents.json new file mode 100644 index 00000000..80cf0af1 --- /dev/null +++ b/app/CocoaPods/Home Screen.xcassets/TransparentButtonBGFilled.imageset/Contents.json @@ -0,0 +1,44 @@ +{ + "images" : [ + { + "resizing" : { + "mode" : "3-part-horizontal", + "center" : { + "mode" : "tile", + "width" : 33 + }, + "cap-insets" : { + "right" : 10, + "left" : 6 + } + }, + "idiom" : "universal", + "filename" : "TransparentButtonBGFilled.png", + "scale" : "1x" + }, + { + "resizing" : { + "mode" : "3-part-horizontal", + "center" : { + "mode" : "tile", + "width" : 12 + }, + "cap-insets" : { + "right" : 12, + "left" : 8 + } + }, + "idiom" : "universal", + "filename" : "TransparentButtonBGFilled@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/app/CocoaPods/Home Screen.xcassets/TransparentButtonBGFilled.imageset/TransparentButtonBGFilled.png b/app/CocoaPods/Home Screen.xcassets/TransparentButtonBGFilled.imageset/TransparentButtonBGFilled.png new file mode 100644 index 0000000000000000000000000000000000000000..ecfffdc79d23d9f6b409098237bcac6deab64543 GIT binary patch literal 256 zcmV+b0ssDqP)f*Bkh2|2R9ci1?CzD%e7FrMz^bhm!Y zBHVb1w`G3VLpH@Zf+eTKMb4T&?fmOD$N#lD@&F-do1EE7MkO!CAwHeKQZ9 zaO+RoRASvI-t_SNwyEEWXTCISoRsim?zFUN4(oK&98%O1rnE%zN*F6_5;pKUw1%xm zQs5@1glb|K^D&-|H!MAq3|2EHv$>Qpxp~gG+F;16WX-r(HUtW#nI@cR zIN^6dgLAW#0YT#gd{#QH@?}yzcqaGFkq)65!e{2Xtu*8GsqB6u_Qu9(*X29M?%JCy zN|v~N_}Lrz{+WV4?~>oWzkJ}$$p=h6X>WKoWLNzABqmkJarN_x%)2TJ&b;4v=iv1~ z`!WN=wsQ;LNVQxjOn#Ogz}uR=z09rn>_g4Xwi&XgZc4U%VDGID{?R?-_{sG@zHZ%d aOx<{4X!+^b=R1K>&*16m=d#Wzp$PzwS?*W> literal 0 HcmV?d00001 From 92e6f46a7721e0bf66d6f8bc320862e4f0fa3926 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Thu, 24 Dec 2015 07:43:33 +0000 Subject: [PATCH 08/10] [Command Line Tools] Add a do not show again button --- app/CocoaPods.xcodeproj/project.pbxproj | 6 ++ .../Base.lproj/CPHomeWindowController.xib | 70 +++++++++++-------- app/CocoaPods/CPBorderedButton.m | 2 - app/CocoaPods/CPHomeWindowController.m | 7 ++ app/CocoaPods/CPWhiteCheckedButton.h | 5 ++ app/CocoaPods/CPWhiteCheckedButton.m | 19 +++++ 6 files changed, 77 insertions(+), 32 deletions(-) create mode 100644 app/CocoaPods/CPWhiteCheckedButton.h create mode 100644 app/CocoaPods/CPWhiteCheckedButton.m diff --git a/app/CocoaPods.xcodeproj/project.pbxproj b/app/CocoaPods.xcodeproj/project.pbxproj index 46ae6935..c335cf8f 100644 --- a/app/CocoaPods.xcodeproj/project.pbxproj +++ b/app/CocoaPods.xcodeproj/project.pbxproj @@ -56,6 +56,7 @@ 6075BA651C068B5F00A5C491 /* Podfile.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6075BA641C068B5F00A5C491 /* Podfile.xcassets */; }; 6075BA671C06963700A5C491 /* CPInstallAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6075BA661C06963700A5C491 /* CPInstallAction.swift */; }; 60814A851C2B100F00D6663E /* CPBorderedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 60814A841C2B100F00D6663E /* CPBorderedButton.m */; }; + 60814A881C2BCFEA00D6663E /* CPWhiteCheckedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 60814A871C2BCFEA00D6663E /* CPWhiteCheckedButton.m */; }; 6085133F1BB6A3D500595B97 /* CPRecentDocumentsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6085133E1BB6A3D500595B97 /* CPRecentDocumentsController.m */; }; 60F02D1C1C0A2A6D003600FE /* CocoaPodsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60F02D1B1C0A2A6D003600FE /* CocoaPodsTests.swift */; }; 60F02D251C0A2E63003600FE /* Pods-CocoaPods.debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 60F02D231C0A2E63003600FE /* Pods-CocoaPods.debug.xcconfig */; }; @@ -204,6 +205,8 @@ 6075BA661C06963700A5C491 /* CPInstallAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPInstallAction.swift; sourceTree = ""; }; 60814A831C2B100F00D6663E /* CPBorderedButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPBorderedButton.h; sourceTree = ""; }; 60814A841C2B100F00D6663E /* CPBorderedButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPBorderedButton.m; sourceTree = ""; }; + 60814A861C2BCFEA00D6663E /* CPWhiteCheckedButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPWhiteCheckedButton.h; sourceTree = ""; }; + 60814A871C2BCFEA00D6663E /* CPWhiteCheckedButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPWhiteCheckedButton.m; sourceTree = ""; }; 6085133D1BB6A3D500595B97 /* CPRecentDocumentsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPRecentDocumentsController.h; sourceTree = ""; }; 6085133E1BB6A3D500595B97 /* CPRecentDocumentsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPRecentDocumentsController.m; sourceTree = ""; }; 60F02D191C0A2A6D003600FE /* CocoaPodsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CocoaPodsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -389,6 +392,8 @@ 6051191F1C08C4C00037B95E /* CPReturnTriggeringTableView.swift */, 60814A831C2B100F00D6663E /* CPBorderedButton.h */, 60814A841C2B100F00D6663E /* CPBorderedButton.m */, + 60814A861C2BCFEA00D6663E /* CPWhiteCheckedButton.h */, + 60814A871C2BCFEA00D6663E /* CPWhiteCheckedButton.m */, ); name = "Custom Subviews"; sourceTree = ""; @@ -828,6 +833,7 @@ 601F91151BE6435E00AD22B1 /* NSURL+TersePaths.m in Sources */, 605119231C08F02D0037B95E /* CPBrownVisualEffectsView.swift in Sources */, 60FE01701B9B7F1E0027EEE3 /* SUUpdater+DebugMode.m in Sources */, + 60814A881C2BCFEA00D6663E /* CPWhiteCheckedButton.m in Sources */, 331188571BEBCB0F00272793 /* CPCLIToolInstallationController.m in Sources */, FA16FAD21C144BF300DC3791 /* URLHandler.swift in Sources */, 51165E261A17AFF500DCFC94 /* CPAppDelegate.m in Sources */, diff --git a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib index 3abe50dc..9c7692cc 100644 --- a/app/CocoaPods/Base.lproj/CPHomeWindowController.xib +++ b/app/CocoaPods/Base.lproj/CPHomeWindowController.xib @@ -224,17 +224,18 @@ - + - By installing the CocoaPods Command Line Tools you can run the pod command from your favourite terminal. This means you get instant access to the whole -command-line API. + By installing the CocoaPods Command Line Tools you can run the pod command from your favourite terminal. + +This means you get access to the whole command-line API, not just what the CocoaPods App does. - + @@ -252,8 +253,8 @@ Command-Line Tools? - - - - - - - - - + @@ -288,34 +281,40 @@ Command-Line Tools? - + - -> Moya (5.1.0) - Network abstraction layer written in Swift - pod 'Moya', '~> 5.1.0' - - Homepage: https://github.com/Moya/Moya - - Source: https://github.com/Moya/Moya.git - - Versions: 5.1.0, 5.0.0, 4.5.0, 4.4.0, 4.3.1, 4.2.0, 4.1.0, 4.0.3, 4.0.2, 4.0.1, 4.0.0, 3.0.1, 3.0.0, 2.4.1, 2.4.0, 2.3.0, 2.2.2, 2.2.1, 2.1.0, 2.0.2, 2.0.1, 2.0.0, 1.1.1, 1.1.0, 1.0.0, 0.8.0, 0.7.1, 0.7.0, 0.6.1, 0.6 [master repo] + -> Alamofire (3.1.4) + Elegant HTTP Networking in Swift + pod 'Alamofire', '~> 3.1.4' + - Homepage: https://github.com/Alamofire/Alamofire + - Source: https://github.com/Alamofire/Alamofire.git + - Versions: 3.1.4, 3.1.3, 3.1.2, 3.1.1, 3.1.0, 3.0.1, 3.0.0, 3.0.0-beta.3, 3.0.0-beta.2, 3.0.0-beta.1, 2.0.2, 2.0.1, 2.0.0, 2.0.0-beta.4, 2.0.0-beta.3, 2.0.0-beta.2, + +-> RxAlamofire (0.3.3) + RxSwift wrapper around the elegant HTTP networking in Swift Alamofire + pod 'RxAlamofire', '~> 0.3.3' + - Homepage: https://github.com/RxSwiftCommunity/RxAlamofire + - Source: https://github.com/RxSwiftCommunity/RxAlamofire.git + - Versions: 0.3.3, 0.3.2, 0.3.1, 0.3, 0.2, 0.1 [master repo] - Subspecs: - - Moya/Core (5.1.0) - - Moya/ReactiveCocoa (5.1.0) - - Moya/RxSwift (5.1.0) + - RxAlamofire/Core (0.3.3) + - RxAlamofire/RxCocoa (0.3.3) - - + + - - + + @@ -326,7 +325,7 @@ Command-Line Tools? + @@ -341,6 +350,7 @@ Command-Line Tools? + diff --git a/app/CocoaPods/CPBorderedButton.m b/app/CocoaPods/CPBorderedButton.m index eb7ac278..c562e3bb 100644 --- a/app/CocoaPods/CPBorderedButton.m +++ b/app/CocoaPods/CPBorderedButton.m @@ -53,6 +53,4 @@ - (void)setTitle:(NSString *)title }]; } - - @end \ No newline at end of file diff --git a/app/CocoaPods/CPHomeWindowController.m b/app/CocoaPods/CPHomeWindowController.m index bb088835..d70c5bfa 100644 --- a/app/CocoaPods/CPHomeWindowController.m +++ b/app/CocoaPods/CPHomeWindowController.m @@ -116,6 +116,13 @@ - (IBAction)changeInstallationPath:(id)sender; [self.cliToolController runModalDestinationChangeSavePanel]; } +- (IBAction)setDontShowTheCLIWarningAgain:(NSButton *)sender; +{ + [[NSUserDefaults standardUserDefaults] setBool:sender.state == NSOnState forKey:kCPDoNotRequestCLIToolInstallationAgainKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + + - (CPCLIToolInstallationController *)createCLIToolInstallationController; { NSURL *destinationURL = [NSURL fileURLWithPath:kCPCLIToolSuggestedDestination]; diff --git a/app/CocoaPods/CPWhiteCheckedButton.h b/app/CocoaPods/CPWhiteCheckedButton.h new file mode 100644 index 00000000..e11a68d2 --- /dev/null +++ b/app/CocoaPods/CPWhiteCheckedButton.h @@ -0,0 +1,5 @@ +#import + +@interface CPWhiteCheckedButton : NSButton + +@end diff --git a/app/CocoaPods/CPWhiteCheckedButton.m b/app/CocoaPods/CPWhiteCheckedButton.m new file mode 100644 index 00000000..90250e4a --- /dev/null +++ b/app/CocoaPods/CPWhiteCheckedButton.m @@ -0,0 +1,19 @@ +#import "CPWhiteCheckedButton.h" + +@implementation CPWhiteCheckedButton + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; + style.alignment = NSTextAlignmentCenter; + + self.attributedTitle = [[NSAttributedString alloc] initWithString:self.title attributes: @{ + NSForegroundColorAttributeName: [NSColor colorWithCalibratedWhite:1 alpha:1], + NSFontAttributeName: self.font ?: [NSFont labelFontOfSize:12], + NSParagraphStyleAttributeName: style + }]; +} + +@end From bef4711a0ccafedcc2e08b91daa5020c2bc35107 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Thu, 24 Dec 2015 07:58:31 +0000 Subject: [PATCH 09/10] [Command Line Tools] Offer feedback when a cli tools install fails --- .../CPCLIToolInstallationController.h | 1 + .../CPCLIToolInstallationController.m | 12 ++++++++++-- app/CocoaPods/CPHomeWindowController.m | 7 ++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h index 5c4f2795..13cd17ca 100644 --- a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h +++ b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h @@ -5,6 +5,7 @@ extern NSString * const kCPCLIToolInstalledToDestinationsKey; @interface CPCLIToolInstallationController : NSObject @property (readonly) NSURL *destinationURL; +@property (readonly) NSString *errorMessage; + (instancetype)controllerWithSuggestedDestinationURL:(NSURL *)suggestedDestinationURL; diff --git a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m index 1b89b5f2..1c4ebe68 100644 --- a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m +++ b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m @@ -8,10 +8,12 @@ NSString * const kCPCLIToolInstalledToDestinationsKey = @"CPCLIToolInstalledToDestinations"; @interface CPCLIToolInstallationController () -// The current destination to install the binstub to. +/// The current destination to install the binstub to. @property (strong) NSURL *destinationURL; -// A list of existing URL->BookmarkData mappings. +/// A list of existing URL->BookmarkData mappings. @property (strong) NSDictionary *previouslyInstalledToDestinations; +/// An error message if something fails +@property (strong) NSString *errorMessage; @end @implementation CPCLIToolInstallationController @@ -204,6 +206,8 @@ - (BOOL)runModalDestinationChangeSavePanel; // - (BOOL)installBinstubAccordingToPrivileges; { + self.errorMessage = nil; + NSURL *destinationDirURL = [self.destinationURL URLByDeletingLastPathComponent]; if (access([destinationDirURL.path UTF8String], W_OK) == 0) { return [self installBinstubToAccessibleDestination]; @@ -226,6 +230,7 @@ - (BOOL)installBinstubToAccessibleDestination; error:&error]; if (error) { NSLog(@"Failed to copy source `%@` (%@)", sourceURL.path, error); + self.errorMessage = @"Failed to move pod command to the new folder"; } return succeeded; } @@ -251,6 +256,7 @@ - (BOOL)installBinstubToPrivilegedDestination; SFAuthorization *authorization = [SFAuthorization authorization]; if (![authorization obtainWithRight:name flags:flags error:&error]) { NSLog(@"Did not authorize."); + self.errorMessage = @"Did not get authorization to save pod command"; return NO; } @@ -260,6 +266,7 @@ - (BOOL)installBinstubToPrivilegedDestination; OSStatus serialized = AuthorizationMakeExternalForm(authorizationRef, &serializedRef); if (serialized != errAuthorizationSuccess) { NSLog(@"Failed to serialize AuthorizationRef (%d)", serialized); + self.errorMessage = @"Could not use given authorization to save pod command"; return NO; } @@ -284,6 +291,7 @@ - (BOOL)installBinstubToPrivilegedDestination; FILE *source_file = fopen([sourceURL.path UTF8String], "r"); if (source_file == NULL) { NSLog(@"Failed to open source `%@` (%d - %s)", sourceURL.path, errno, strerror(errno)); + self.errorMessage = @"Could open a file to save pod command"; } else { int c; while ((c = fgetc(source_file)) != EOF) { diff --git a/app/CocoaPods/CPHomeWindowController.m b/app/CocoaPods/CPHomeWindowController.m index d70c5bfa..16d056a5 100644 --- a/app/CocoaPods/CPHomeWindowController.m +++ b/app/CocoaPods/CPHomeWindowController.m @@ -103,7 +103,9 @@ - (IBAction)installBinstub:(id)sender; // Hide the alert [self.commandLineToolsHeightConstraint.animator setConstant:0]; } else { - + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = self.cliToolController.errorMessage; + [alert runModal]; } } @@ -116,6 +118,9 @@ - (IBAction)changeInstallationPath:(id)sender; [self.cliToolController runModalDestinationChangeSavePanel]; } +/// This _does_ work, if you're in a dev build though, it's set +/// to delete this key on launch in CPAppDelegate + - (IBAction)setDontShowTheCLIWarningAgain:(NSButton *)sender; { [[NSUserDefaults standardUserDefaults] setBool:sender.state == NSOnState forKey:kCPDoNotRequestCLIToolInstallationAgainKey]; From c5c6aea6b45108383dd1584d9e1ae513254b777f Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Thu, 24 Dec 2015 14:38:27 +0000 Subject: [PATCH 10/10] [Command Line Tools] Offer the chance to overwrite / cancel if you're goign to overwrite --- .../CPCLIToolInstallationController.h | 2 +- .../CPCLIToolInstallationController.m | 62 ++++++++++++------- app/CocoaPods/CPHomeWindowController.m | 3 +- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h index 13cd17ca..9fc100ac 100644 --- a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h +++ b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.h @@ -23,7 +23,7 @@ extern NSString * const kCPCLIToolInstalledToDestinationsKey; /// - (BOOL)installBinstubIfNecessary; -/// Always tries to perform the installation. +/// Always tries to perform the installation, unless the user cancels an overwrite. /// /// Returns whether or not installation has been performed. /// diff --git a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m index 1c4ebe68..a541666f 100644 --- a/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m +++ b/app/CocoaPods/CLI Integrations/CPCLIToolInstallationController.m @@ -45,7 +45,7 @@ - (BOOL)shouldInstallBinstubIfNecessary; return NO; } - return [self savedBinStub]; + return [self binstubAlreadyExists]; } @@ -61,11 +61,15 @@ - (BOOL)installBinstub; { BOOL installed = NO; [self verifyExistingInstallDestinations]; - NSLog(@"Try to install binstub to `%@`.", self.destinationURL.path); - installed = [self installBinstubAccordingToPrivileges]; - if (installed) { - NSLog(@"Successfully wrote binstub to destination."); - [self saveInstallationDestination]; + + if ([self promptIfOverwriting]) { + NSLog(@"Try to install binstub to `%@`.", self.destinationURL.path); + + installed = [self installBinstubAccordingToPrivileges]; + if (installed) { + NSLog(@"Successfully wrote binstub to destination."); + [self saveInstallationDestination]; + } } return installed; @@ -162,26 +166,43 @@ - (void)saveInstallationDestination; } } -#pragma mark - Utility +// Prompts to warn someone that they're going to have a binstub replaced +// returns whether the install action should continue -// Never ask the user to automatically install again. -// -- (void)setDoNotRequestInstallationAgain; +- (BOOL)promptIfOverwriting { - NSLog(@"Not going to automatically request binstub installation anymore."); - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kCPDoNotRequestCLIToolInstallationAgainKey]; - [[NSUserDefaults standardUserDefaults] synchronize]; + if ([self binstubAlreadyExists] == NO) { + return YES; + } + + NSAlert *alert = [NSAlert new]; + alert.alertStyle = NSCriticalAlertStyle; + NSString *formatString = NSLocalizedString(@"INSTALL_CLI_WARNING_MESSAGE_TEXT", nil); + alert.messageText = [NSString stringWithFormat:formatString, self.destinationURL.path]; + alert.informativeText = NSLocalizedString(@"INSTALL_CLI_WARNING_INFORMATIVE_TEXT", nil); + [alert addButtonWithTitle:NSLocalizedString(@"INSTALL_CLI_WARNING_OVERWRITE", nil)]; + [alert addButtonWithTitle:NSLocalizedString(@"CANCEL", nil)]; + + return [alert runModal] == NSAlertFirstButtonReturn; } +#pragma mark - Utility + - (NSURL *)binstubSourceURL; { NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; return [NSURL fileURLWithPathComponents:@[ bundlePath, @"Contents", @"Helpers", @"pod" ]]; } -- (BOOL)savedBinStub; +- (BOOL)binstubAlreadyExists; +{ + return access([self.destinationURL.path UTF8String], F_OK) == 0; +} + +- (BOOL)hasWriteAccessToBinstub; { - return access([self.destinationURL.path UTF8String], F_OK); + NSURL *destinationDirURL = [self.destinationURL URLByDeletingLastPathComponent]; + return access([destinationDirURL.path UTF8String], W_OK) == 0; } - (BOOL)runModalDestinationChangeSavePanel; @@ -194,6 +215,7 @@ - (BOOL)runModalDestinationChangeSavePanel; if ([savePanel runModal] == NSFileHandlingPanelCancelButton) { return NO; } + self.destinationURL = savePanel.URL; return YES; } @@ -207,9 +229,7 @@ - (BOOL)runModalDestinationChangeSavePanel; - (BOOL)installBinstubAccordingToPrivileges; { self.errorMessage = nil; - - NSURL *destinationDirURL = [self.destinationURL URLByDeletingLastPathComponent]; - if (access([destinationDirURL.path UTF8String], W_OK) == 0) { + if ([self hasWriteAccessToBinstub]) { return [self installBinstubToAccessibleDestination]; } else { return [self installBinstubToPrivilegedDestination]; @@ -225,9 +245,9 @@ - (BOOL)installBinstubToAccessibleDestination; { NSError *error = nil; NSURL *sourceURL = self.binstubSourceURL; - BOOL succeeded = [[NSFileManager defaultManager] copyItemAtURL:sourceURL - toURL:self.destinationURL - error:&error]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + [fileManager removeItemAtURL:self.destinationURL error:&error]; + BOOL succeeded = [fileManager copyItemAtURL:sourceURL toURL:self.destinationURL error:&error]; if (error) { NSLog(@"Failed to copy source `%@` (%@)", sourceURL.path, error); self.errorMessage = @"Failed to move pod command to the new folder"; diff --git a/app/CocoaPods/CPHomeWindowController.m b/app/CocoaPods/CPHomeWindowController.m index 16d056a5..87bb9d64 100644 --- a/app/CocoaPods/CPHomeWindowController.m +++ b/app/CocoaPods/CPHomeWindowController.m @@ -102,7 +102,8 @@ - (IBAction)installBinstub:(id)sender; if ([self.cliToolController installBinstub]) { // Hide the alert [self.commandLineToolsHeightConstraint.animator setConstant:0]; - } else { + + } else if(self.cliToolController.errorMessage) { NSAlert *alert = [[NSAlert alloc] init]; alert.messageText = self.cliToolController.errorMessage; [alert runModal];