diff --git a/CHANGELOG.md b/CHANGELOG.md index 9540e9b8..afe48699 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## master +* Show an alert if CP is going to re-integrate your project + [orta](https://github.com/orta) + [#299](https://github.com/CocoaPods/CocoaPods-app/pull/299) + * Polish for Source Menus & Pod Autocomplete improvements [orta](https://github.com/orta) [#298](https://github.com/CocoaPods/CocoaPods-app/pull/298) diff --git a/app/CPReflectionService/RBObject+CocoaPods.rb b/app/CPReflectionService/RBObject+CocoaPods.rb index 82c9f929..d34677e0 100644 --- a/app/CPReflectionService/RBObject+CocoaPods.rb +++ b/app/CPReflectionService/RBObject+CocoaPods.rb @@ -58,7 +58,14 @@ def self.analyze_podfile(podfile, installation_root) end uses_frameworks = config.podfile.target_definitions.first.last.to_hash["uses_frameworks"] - { "projects" => user_projects, "pod_targets" => pod_targets, "uses_frameworks" => uses_frameworks} + last_installed_version = config.sandbox.manifest.cocoapods_version.to_s + + { + "projects" => user_projects, + "pod_targets" => pod_targets, + "uses_frameworks" => uses_frameworks, + "cocoapods_build_version" => last_installed_version + } end def self.sources_manager diff --git a/app/CocoaPods/CPDocumentController.swift b/app/CocoaPods/CPDocumentController.swift index 95674262..95567c21 100644 --- a/app/CocoaPods/CPDocumentController.swift +++ b/app/CocoaPods/CPDocumentController.swift @@ -73,9 +73,9 @@ class CPDocumentController: NSDocumentController { } else { let projectName = xcodeprojURL.lastPathComponent! - let localized = NSLocalizedString("POD_DEINTEGRATE_CONFIRMATION", comment: "") + let localized = ~"POD_DEINTEGRATE_CONFIRMATION" let alert = NSAlert() - alert.messageText = NSLocalizedString("POD_DEINTEGRATE_INFO", comment: "") + alert.messageText = ~"POD_DEINTEGRATE_INFO" alert.informativeText = String.localizedStringWithFormat(localized, projectName) alert.runModal() } diff --git a/app/CocoaPods/CPPodfileEditorViewController.swift b/app/CocoaPods/CPPodfileEditorViewController.swift index c8c7a453..1ea90ad3 100644 --- a/app/CocoaPods/CPPodfileEditorViewController.swift +++ b/app/CocoaPods/CPPodfileEditorViewController.swift @@ -342,7 +342,18 @@ extension EditorLineSelection { extension CPPodfileEditorViewController: CPUserProjectDelegate { func contentDidChangeinUserProject(userProject: CPUserProject) { - editor.string = userProject.contents + let contentChanged = editor.string != userProject.contents + let appIsActive = NSApplication.sharedApplication().active + + if contentChanged && !appIsActive { + let selection = editor.textView.selectedRange() + let scroll = editor.scrollView.visibleRect + + editor.string = userProject.contents + + editor.textView.selectedRange = selection + editor.scrollView.scrollPoint(scroll.origin) + } // Passing the message on to the syntax checker syntaxChecker.textDidChange(NSNotification(name: "", object: nil)) diff --git a/app/CocoaPods/CPPodfilePluginCoordinator.swift b/app/CocoaPods/CPPodfilePluginCoordinator.swift index ffa5e202..2f646489 100644 --- a/app/CocoaPods/CPPodfilePluginCoordinator.swift +++ b/app/CocoaPods/CPPodfilePluginCoordinator.swift @@ -49,7 +49,7 @@ class CPPodfilePluginCoordinator: NSObject { dispatch_async(dispatch_get_main_queue()) { let inflectedPlugin = (self.pluginsToInstall.count == 1) ? "plugin" : "plugins" - self.controller.showWarningLabelWithSender("You need to install \(self.pluginsToInstall.count) \(inflectedPlugin) for this Podfile", actionTitle: "Install", target: self, action: "showInstaller", animated:true) + self.controller.showWarningLabelWithSender("You need to install \(self.pluginsToInstall.count) \(inflectedPlugin) for this Podfile", actionTitle: "Install", target: self, action: #selector(CPPodfilePluginCoordinator.showInstaller), animated:true) } } } diff --git a/app/CocoaPods/CPPodfileViewController.swift b/app/CocoaPods/CPPodfileViewController.swift index 32729959..e4dcdbf3 100644 --- a/app/CocoaPods/CPPodfileViewController.swift +++ b/app/CocoaPods/CPPodfileViewController.swift @@ -56,12 +56,31 @@ class CPPodfileViewController: NSViewController, NSTabViewDelegate { // we should show "Podfile for ProjectName" instead userProject.registerForFullMetadataCallback { guard let targets = self.userProject.xcodeIntegrationDictionary["projects"] as? [String:AnyObject] else { return } - if targets.keys.count == 1 { - let project = targets.keys.first! - let url = NSURL(fileURLWithPath: project) - let name = url.lastPathComponent!.stringByReplacingOccurrencesOfString(".xcproj", withString: "") - self.actionTitleLabel.stringValue = "Podfile for \(name)" - } + self.updatePodfileNameIfPossible(targets) + } + } + + /// As CP will deintegrate, and re-integrate that app, we should show a warning + /// that is is going to happen + /// buildVersion will be cast to a string + func shouldShowInstallWarningForMajorChange(buildVersion: AnyObject?) -> Bool { + guard + let version = buildVersion as? String, + let majorLastInstallVersion = version.componentsSeparatedByString(".").first, + appVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as? String, + majorAppVersion = appVersion.componentsSeparatedByString(".").first + + else { return false} + + return Int(majorAppVersion) > Int(majorLastInstallVersion) + } + + func updatePodfileNameIfPossible(targets: [String: AnyObject]) { + if targets.keys.count == 1 { + let project = targets.keys.first! + let url = NSURL(fileURLWithPath: project) + let name = url.lastPathComponent!.stringByReplacingOccurrencesOfString(".xcproj", withString: "") + actionTitleLabel.stringValue = "Podfile for \(name)" } } @@ -70,33 +89,50 @@ class CPPodfileViewController: NSViewController, NSTabViewDelegate { } @IBAction func install(obj: AnyObject) { - userProject.saveDocument(self) let options = InstallOptions(verbose: false) - installAction.performAction(.Install(options: options)) - showConsoleTab(self) + performInstallAction(.Install(options: options)) } @IBAction func installVerbose(obj: AnyObject) { - userProject.saveDocument(self) let options = InstallOptions(verbose: true) - installAction.performAction(.Install(options: options)) - showConsoleTab(self) + performInstallAction(.Install(options: options)) } @IBAction func installUpdate(obj: AnyObject) { - userProject.saveDocument(self) let options = InstallOptions(verbose: false) - installAction.performAction(.Update(options: options)) - showConsoleTab(self) + performInstallAction(.Update(options: options)) } @IBAction func installUpdateVerbose(obj: AnyObject) { - userProject.saveDocument(self) let options = InstallOptions(verbose: true) - installAction.performAction(.Update(options: options)) + performInstallAction(.Update(options: options)) + } + + func performInstallAction(action: InstallActionType) { + userProject.saveDocument(self) + + let lastInstalledVersion = userProject.xcodeIntegrationDictionary["cocoapods_build_version"] + if shouldShowInstallWarningForMajorChange(lastInstalledVersion) { + if promptForInstallMigration(lastInstalledVersion) == false { return } + } + + installAction.performAction(action) showConsoleTab(self) } + func promptForInstallMigration(buildVersion: AnyObject?) -> Bool { + guard let + appVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as? String, + version = buildVersion as? String else { return true } + + let alert = NSAlert() + alert.messageText = ~"REINTEGRATION_ALERT_FORMAT_TITLE" + alert.informativeText = String(format: ~"REINTEGRATION_ALERT_FORMAT_MESSAGE", version, appVersion) + alert.addButtonWithTitle(~"REINTEGRATION_ALERT_CONFIRM") + alert.addButtonWithTitle(~"REINTEGRATION_ALERT_CANCEL") + return alert.runModal() == NSAlertFirstButtonReturn + } + @IBOutlet var installMenu: NSMenu! @IBAction func showInstallOptions(button: NSButton) { guard let event = NSApp.currentEvent else { return } diff --git a/app/CocoaPods/CPSpotlightDocumentSource.swift b/app/CocoaPods/CPSpotlightDocumentSource.swift index d607d23c..29ff161d 100644 --- a/app/CocoaPods/CPSpotlightDocumentSource.swift +++ b/app/CocoaPods/CPSpotlightDocumentSource.swift @@ -47,7 +47,7 @@ class CPSpotlightDocumentSource: CPDocumentSource { func queryGatheringFinished(notification: NSNotification) { // let NSMetadataQuery finish when there are files available, if not finish the query - self.performSelector(Selector("queryFinished"), withObject: nil, afterDelay: 2.0) + self.performSelector(#selector(CPSpotlightDocumentSource.queryFinished), withObject: nil, afterDelay: 2.0) } func queryFinished() { diff --git a/app/CocoaPods/CPUserProject.m b/app/CocoaPods/CPUserProject.m index 243a1756..ea1845ce 100644 --- a/app/CocoaPods/CPUserProject.m +++ b/app/CocoaPods/CPUserProject.m @@ -89,7 +89,6 @@ - (void)presentedItemDidChange }); } } - } @end diff --git a/app/CocoaPods/Supporting Files/Localizable.strings b/app/CocoaPods/Supporting Files/Localizable.strings index 60ec836d..dbb9ff85 100644 --- a/app/CocoaPods/Supporting Files/Localizable.strings +++ b/app/CocoaPods/Supporting Files/Localizable.strings @@ -43,4 +43,9 @@ "REPO_UPDATE_FAILED_NOTIFICATION_TITLE" = "Repo not Updated"; "PLUGIN_FAILED_TO_INSTALL_MESSAGE" = "Failed to Install Plugins"; -"PLUGINS_ALL_INSTALLED_MESSAGE" = "Installed Plugins"; \ No newline at end of file +"PLUGINS_ALL_INSTALLED_MESSAGE" = "Installed Plugins"; + +"REINTEGRATION_ALERT_FORMAT_TITLE" = "Re-integration"; +"REINTEGRATION_ALERT_FORMAT_MESSAGE" = "CocoaPods is going to migrate your project from %@ to %@, this is considered a breaking change. To migrate, CocoaPods will re-install your integration from scratch, including re-downloading all Pods"; +"REINTEGRATION_ALERT_CONFIRM" = "Okay, lets do it"; +"REINTEGRATION_ALERT_CANCEL" = "Cancel"; \ No newline at end of file