├── .gitignore ├── AskPass └── Askpass-Prefix.pch ├── LICENSE.md ├── Podfile ├── Podfile.lock ├── README.md ├── Vagrant Manager.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── Vagrant Manager.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── Vagrant Manager ├── AboutWindow.h ├── AboutWindow.m ├── AboutWindow.xib ├── AppDelegate.h ├── AppDelegate.m ├── Askpass.m ├── Base.lproj │ └── MainMenu.xib ├── BaseWindowController.h ├── BaseWindowController.m ├── Bookmark.h ├── Bookmark.m ├── BookmarkManager.h ├── BookmarkManager.m ├── CustomCommand.h ├── CustomCommand.m ├── CustomCommandManager.h ├── CustomCommandManager.m ├── CustomProvider.h ├── CustomProvider.m ├── CustomProviderManager.h ├── CustomProviderManager.m ├── Environment.h ├── Environment.m ├── Environments.plist ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── appicon-128x128@2x.png │ │ ├── appicon-16x16.png │ │ ├── appicon-16x16@2x.png │ │ ├── appicon-256x256.png │ │ ├── appicon-256x256@2x.png │ │ ├── appicon-32x32.png │ │ ├── appicon-32x32@2x.png │ │ ├── appicon-512x512.png │ │ ├── appicon-512x512@2x.png │ │ └── appicon_128.png ├── MachineMenuItemViewController.h ├── MachineMenuItemViewController.m ├── MachineMenuItemViewController.xib ├── ManageBookmarksWindow.h ├── ManageBookmarksWindow.m ├── ManageBookmarksWindow.xib ├── ManageCustomCommandsWindow.h ├── ManageCustomCommandsWindow.m ├── ManageCustomCommandsWindow.xib ├── ManageCustomProvidersWindow.h ├── ManageCustomProvidersWindow.m ├── ManageCustomProvidersWindow.xib ├── MenuDelegate.h ├── NFSScanner.h ├── NFSScanner.m ├── NativeMenu.h ├── NativeMenu.m ├── NativeMenuItem.h ├── NativeMenuItem.m ├── ParallelsMachineInfo.h ├── ParallelsMachineInfo.m ├── ParallelsServiceProvider.h ├── ParallelsServiceProvider.m ├── PasswordHelper.h ├── PasswordHelper.m ├── PreferencesWindow.h ├── PreferencesWindow.m ├── PreferencesWindow.xib ├── RegisterWindow.h ├── RegisterWindow.m ├── RegisterWindow.xib ├── TaskOutputWindow.h ├── TaskOutputWindow.m ├── TaskOutputWindow.xib ├── Util.h ├── Util.m ├── Vagrant Manager-Info.plist ├── Vagrant Manager-Prefix.pch ├── VagrantGlobalStatusScanner.h ├── VagrantGlobalStatusScanner.m ├── VagrantInstance.h ├── VagrantInstance.m ├── VagrantInstanceCache.h ├── VagrantInstanceCache.m ├── VagrantMachine.h ├── VagrantMachine.m ├── VagrantManager.h ├── VagrantManager.m ├── VersionComparison.h ├── VersionComparison.m ├── VirtualBoxMachineInfo.h ├── VirtualBoxMachineInfo.m ├── VirtualBoxServiceProvider.h ├── VirtualBoxServiceProvider.m ├── VirtualMachineInfo.h ├── VirtualMachineInfo.m ├── VirtualMachineInfoWindow.xib ├── VirtualMachineServiceProvider.h ├── bm_status_icon_off.png ├── bm_status_icon_off@2x.png ├── bm_status_icon_on.png ├── bm_status_icon_on@2x.png ├── bm_status_icon_suspended.png ├── bm_status_icon_suspended@2x.png ├── destroy.png ├── destroy@2x.png ├── dsa_pub.pem ├── en.lproj │ └── InfoPlist.strings ├── halt.png ├── halt@2x.png ├── main.m ├── provision.png ├── provision@2x.png ├── rdp.png ├── rdp@2x.png ├── reload.png ├── reload@2x.png ├── resume.png ├── resume@2x.png ├── ssh.png ├── ssh@2x.png ├── status_icon_off.png ├── status_icon_off@2x.png ├── status_icon_on.png ├── status_icon_on@2x.png ├── status_icon_problem.png ├── status_icon_problem@2x.png ├── status_icon_suspended.png ├── status_icon_suspended@2x.png ├── suspend.png ├── suspend@2x.png ├── up.png ├── up@2x.png ├── vagrant_logo_off-clean.png ├── vagrant_logo_off-clean@2x.png ├── vagrant_logo_off-flat.png ├── vagrant_logo_off-flat@2x.png ├── vagrant_logo_on-clean.png ├── vagrant_logo_on-clean@2x.png ├── vagrant_logo_on-flat.png ├── vagrant_logo_on-flat@2x.png ├── vagrant_logo_refresh_1-clean.png ├── vagrant_logo_refresh_1-clean@2x.png ├── vagrant_logo_refresh_1-flat.png ├── vagrant_logo_refresh_1-flat@2x.png ├── vagrant_logo_refresh_2-clean.png ├── vagrant_logo_refresh_2-clean@2x.png ├── vagrant_logo_refresh_2-flat.png ├── vagrant_logo_refresh_2-flat@2x.png ├── vagrant_logo_refresh_3-clean.png ├── vagrant_logo_refresh_3-clean@2x.png ├── vagrant_logo_refresh_3-flat.png ├── vagrant_logo_refresh_3-flat@2x.png ├── vagrant_logo_refresh_4-clean.png ├── vagrant_logo_refresh_4-clean@2x.png ├── vagrant_logo_refresh_4-flat.png ├── vagrant_logo_refresh_4-flat@2x.png ├── vagrant_logo_refresh_5-clean.png ├── vagrant_logo_refresh_5-clean@2x.png ├── vagrant_logo_refresh_5-flat.png └── vagrant_logo_refresh_5-flat@2x.png └── dmg ├── .gitignore ├── appdmg.json ├── appicon-512x512@2x.png └── background.png /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # CocoaPods 23 | Pods 24 | assets/clean.psd 25 | assets/default.psd 26 | assets/flat.psd 27 | assets/indicators.psd 28 | assets/problem.psd 29 | -------------------------------------------------------------------------------- /AskPass/Askpass-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Lanayo Technology 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.8' 2 | 3 | target "Vagrant Manager" do 4 | pod 'Sparkle' 5 | end 6 | 7 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Sparkle (1.22.0) 3 | 4 | DEPENDENCIES: 5 | - Sparkle 6 | 7 | SPEC REPOS: 8 | trunk: 9 | - Sparkle 10 | 11 | SPEC CHECKSUMS: 12 | Sparkle: 593ac2e677c07bcb6c3b22d621240e7cbedaab57 13 | 14 | PODFILE CHECKSUM: e45240f106f07044e1efd268e5e93b5b059de8a3 15 | 16 | COCOAPODS: 1.8.4 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Looking for the Windows version? Check out [Vagrant Manager for Windows](https://github.com/lanayotech/vagrant-manager-windows) 2 | 3 | # Vagrant Manager for OS X 4 | 5 | Vagrant Manager is an OS X status bar menu app that lets you manage all of your vagrant machines from one central location. 6 | More information is available at http://vagrantmanager.com/ 7 | 8 | ![demo.gif](http://vagrantmanager.com/demo.gif) 9 | 10 | ## Downloads 11 | Download Vagrant Manager from the [GitHub Releases Page](https://github.com/lanayotech/vagrant-manager/releases) 12 | 13 | ## Installation Notes 14 | * Vagrant Manager can automatically detect most machines, undetected machines will require manual configuration via bookmarks. 15 | * Make sure that you have VirtualBox and Vagrant installed, and the `VBoxManage` and `vagrant` commands are in your path so that Vagrant Manager can execute them. If you use Parallels, ensure the `prlctl` command is also in your path. 16 | * Currently, vagrant machines must already be initialized in order for Vagrant Manager to detect them. Make sure you have run vagrant init on any machine you want to appear in Vagrant Manager. Once Vagrant Manager has detected a machine, you can bookmark it so that it will not disappear when you destroy the machine. You can also manually add a bookmark and specify the path to your Vagrantfile. 17 | * Vagrant Manager requires OS X 10.8 Mountain Lion or higher 18 | 19 | ## Building DMG 20 | * Use [appdmg](https://github.com/LinusU/node-appdmg) to build the distribution DMG. 21 | * Put the `Vagrant Manager.app` file in the `dmg` foler 22 | * Run `appdmg dmg/appdmg.json ` 23 | 24 | ## Contributing to Vagrant Manager 25 | 26 | We love code contributions! If you would like to contribute, here are some notes and guidlines: 27 | 28 | * All development happens on the **develop** branch, so it is always the most up-to-date 29 | * The **master** branch only contains tagged releases 30 | * If you are going to be submitting a pull request, please branch from **develop**, and submit your pull request back to the **develop** branch 31 | * [Helpful article about forking](https://help.github.com/articles/fork-a-repo) 32 | * [Helpful article about pull requests](https://help.github.com/articles/using-pull-requests) 33 | -------------------------------------------------------------------------------- /Vagrant Manager.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Vagrant Manager.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Vagrant Manager.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Vagrant Manager/AboutWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // AboutWindowController.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | #import "BaseWindowController.h" 11 | 12 | @interface AboutWindow : BaseWindowController = __MAC_10_11 14 | , WebPolicyDelegate, WebFrameLoadDelegate, WebUIDelegate 15 | #endif 16 | > 17 | 18 | @property (weak) IBOutlet WebView *webView; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Vagrant Manager/AboutWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // AboutWindowController.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "AboutWindow.h" 9 | #import "Environment.h" 10 | 11 | @interface AboutWindow () 12 | 13 | @end 14 | 15 | @implementation AboutWindow 16 | 17 | - (id)initWithWindow:(NSWindow *)window { 18 | self = [super initWithWindow:window]; 19 | 20 | return self; 21 | } 22 | 23 | - (void)windowDidLoad { 24 | [super windowDidLoad]; 25 | 26 | BOOL isDarkMode = [[[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"] isEqualToString:@"Dark"]; 27 | 28 | NSString *styles = @""; 29 | 30 | if (isDarkMode) { 31 | styles = @""; 32 | } 33 | 34 | NSString *str = [NSString stringWithFormat:@"%@
Copyright ©{YEAR} Lanayo Tech

Vagrant Manager {VERSION}

For more information visit:
{URL}

or check us out on GitHub:
{GITHUB_URL}
", styles]; 35 | 36 | NSString *dateString = [NSString stringWithCString:__DATE__ encoding:NSASCIIStringEncoding]; 37 | NSString *yearString = [dateString substringWithRange:NSMakeRange([dateString length] - 4, 4)]; 38 | 39 | str = [str stringByReplacingOccurrencesOfString:@"{YEAR}" withString:yearString]; 40 | str = [str stringByReplacingOccurrencesOfString:@"{VERSION}" withString:[[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"]]; 41 | str = [str stringByReplacingOccurrencesOfString:@"{URL}" withString:[[Environment sharedInstance] aboutURL]]; 42 | str = [str stringByReplacingOccurrencesOfString:@"{GITHUB_URL}" withString:[[Environment sharedInstance] githubURL]]; 43 | str = [str stringByReplacingOccurrencesOfString:@"\n" withString:@"
"]; 44 | 45 | self.webView.policyDelegate = self; 46 | [self.webView setDrawsBackground:NO]; 47 | [self.webView.mainFrame loadHTMLString:str baseURL:nil]; 48 | } 49 | 50 | - (void)webView:(WebView*)webView decidePolicyForNavigationAction:(NSDictionary*)actionInformation request:(NSURLRequest*)request frame:(WebFrame*)frame decisionListener:(id)listener { 51 | NSString *host = [[request URL] host]; 52 | if(host) { 53 | [[NSWorkspace sharedWorkspace] openURL:[request URL]]; 54 | } else { 55 | [listener use]; 56 | } 57 | } 58 | 59 | - (void)use { 60 | } 61 | 62 | - (void)download { 63 | } 64 | 65 | - (void)ignore { 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Vagrant Manager/AboutWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Vagrant Manager/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "TaskOutputWindow.h" 10 | #import "AboutWindow.h" 11 | #import "PreferencesWindow.h" 12 | #import "VirtualBoxMachineInfo.h" 13 | #import "VirtualBoxServiceProvider.h" 14 | #import "ParallelsServiceProvider.h" 15 | #include 16 | #import "MenuDelegate.h" 17 | #import "NativeMenu.h" 18 | #import "VagrantManager.h" 19 | 20 | #define MENU_ITEM_BOOKMARKED_VM 1 21 | #define MENU_ITEM_DETECTED_VM 2 22 | 23 | @interface AppDelegate : NSObject { 24 | NSMutableArray *bookmarks; 25 | } 26 | 27 | @property (assign) IBOutlet NSWindow *window; 28 | @property (strong, nonatomic) NSTimer *refreshTimer; 29 | 30 | - (void)refreshVagrantMachines; 31 | - (void)addOpenWindow:(id)window; 32 | - (void)removeOpenWindow:(id)window; 33 | - (void)updateRunningVmCount; 34 | - (void)refreshTimerState; 35 | - (NSImage*)getThemedImage:(NSString*)imageName; 36 | - (void)showNotificationWithTitle:(NSString*)title informativeText:(NSString*)informativeText taskWindowUUID:(NSString*)taskWindowUUID; 37 | - (void)showUserNotificationWithTitle:(NSString*)title informativeText:(NSString*)informativeText taskWindowUUID:(NSString*)taskWindowUUID; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Vagrant Manager/Askpass.m: -------------------------------------------------------------------------------- 1 | #include 2 | #import "PasswordHelper.h" 3 | 4 | int main() { 5 | NSArray *promptArray = [PasswordHelper promptForPassword]; 6 | NSInteger returnCode = [[promptArray objectAtIndex:1] intValue]; 7 | if (returnCode == 0) { 8 | void *pword = (void*)[[promptArray objectAtIndex:0] UTF8String]; 9 | printf("%s\n", (char*)pword); 10 | return 0; 11 | } else if (returnCode == 1) { 12 | return 1; 13 | } 14 | } 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Vagrant Manager/BaseWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseWindowController.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface BaseWindowController : NSWindowController 11 | 12 | @property BOOL isClosed; 13 | 14 | - (void)windowWillClose:(NSNotification *)notification; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Vagrant Manager/BaseWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseWindowController.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "BaseWindowController.h" 9 | 10 | @implementation BaseWindowController 11 | 12 | - (void)windowWillClose:(NSNotification *)notification { 13 | [[Util getApp] removeOpenWindow:self]; 14 | self.isClosed = YES; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Vagrant Manager/Bookmark.h: -------------------------------------------------------------------------------- 1 | // 2 | // Bookmark.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "VirtualMachineInfo.h" 10 | 11 | @interface Bookmark : NSObject 12 | 13 | @property (strong, nonatomic) NSString *displayName; 14 | @property (strong, nonatomic) NSString *path; 15 | @property (strong, nonatomic) NSString *providerIdentifier; 16 | @property BOOL launchOnStartup; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Vagrant Manager/Bookmark.m: -------------------------------------------------------------------------------- 1 | // 2 | // Bookmark.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "Bookmark.h" 9 | 10 | @implementation Bookmark 11 | 12 | - (id)copyWithZone:(NSZone*)zone { 13 | Bookmark *bookmark = [[[self class] allocWithZone:zone] init]; 14 | 15 | if(bookmark) { 16 | bookmark.displayName = self.displayName; 17 | bookmark.path = self.path; 18 | bookmark.providerIdentifier = self.providerIdentifier; 19 | bookmark.launchOnStartup = self.launchOnStartup; 20 | } 21 | 22 | return bookmark; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Vagrant Manager/BookmarkManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // BookmarkManager.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface BookmarkManager : NSObject { 11 | NSMutableArray *_bookmarks; 12 | } 13 | 14 | + (BookmarkManager*)sharedManager; 15 | 16 | - (void)loadBookmarks; 17 | - (void)saveBookmarks; 18 | - (void)clearBookmarks; 19 | - (NSMutableArray*)getBookmarks; 20 | - (Bookmark*)addBookmark:(Bookmark*)bookmark; 21 | - (Bookmark*)addBookmarkWithPath:(NSString*)path displayName:(NSString*)displayName providerIdentifier:(NSString*)providerIdentifier launchOnStartup:(BOOL)launchOnStartup; 22 | - (void)removeBookmarkWithPath:(NSString*)path; 23 | - (Bookmark*)getBookmarkWithPath:(NSString*)path; 24 | - (int)getIndexOfBookmarkWithPath:(NSString*)path; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Vagrant Manager/BookmarkManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // BookmarkManager.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "BookmarkManager.h" 9 | 10 | @implementation BookmarkManager 11 | 12 | + (BookmarkManager*)sharedManager { 13 | static BookmarkManager *manager; 14 | @synchronized(self) { 15 | if(manager == nil) { 16 | manager = [[BookmarkManager alloc] init]; 17 | } 18 | } 19 | 20 | return manager; 21 | } 22 | 23 | - (id)init { 24 | self = [super init]; 25 | 26 | if(self) { 27 | _bookmarks = [[NSMutableArray alloc] init]; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | //load bookmarks from shared preferences 34 | - (void)loadBookmarks { 35 | @synchronized(_bookmarks) { 36 | [_bookmarks removeAllObjects]; 37 | 38 | NSArray *savedBookmarks = [[NSUserDefaults standardUserDefaults] arrayForKey:@"bookmarks"]; 39 | if(savedBookmarks) { 40 | for(NSDictionary *savedBookmark in savedBookmarks) { 41 | [self addBookmarkWithPath:[savedBookmark objectForKey:@"path"] displayName:[savedBookmark objectForKey:@"displayName"] providerIdentifier:[savedBookmark objectForKey:@"providerIdentifier"] launchOnStartup:[[savedBookmark objectForKey:@"launchOnStartup"] boolValue]]; 42 | } 43 | } 44 | } 45 | } 46 | 47 | //save bookmarks to shared preferences 48 | - (void)saveBookmarks { 49 | @synchronized(_bookmarks) { 50 | NSMutableArray *bookmarks = [self getBookmarks]; 51 | if(bookmarks) { 52 | NSMutableArray *arr = [[NSMutableArray alloc] init]; 53 | for(Bookmark *b in bookmarks) { 54 | [arr addObject:@{@"displayName":b.displayName, @"path":b.path, @"providerIdentifier":b.providerIdentifier?:@"", @"launchOnStartup":[NSNumber numberWithBool:b.launchOnStartup]}]; 55 | } 56 | 57 | [[NSUserDefaults standardUserDefaults] setObject:arr forKey:@"bookmarks"]; 58 | [[NSUserDefaults standardUserDefaults] synchronize]; 59 | } 60 | } 61 | } 62 | 63 | - (void)clearBookmarks { 64 | @synchronized(_bookmarks) { 65 | [_bookmarks removeAllObjects]; 66 | } 67 | } 68 | 69 | - (Bookmark*)addBookmark:(Bookmark*)bookmark { 70 | Bookmark *existing = [self getBookmarkWithPath:bookmark.path]; 71 | 72 | if(existing) { 73 | return existing; 74 | } 75 | 76 | @synchronized(_bookmarks) { 77 | [_bookmarks addObject:bookmark]; 78 | } 79 | 80 | return bookmark; 81 | } 82 | 83 | - (NSMutableArray*)getBookmarks { 84 | NSMutableArray *bookmarks; 85 | @synchronized(_bookmarks) { 86 | bookmarks = [NSMutableArray arrayWithArray:_bookmarks]; 87 | } 88 | return bookmarks; 89 | } 90 | 91 | - (Bookmark*)addBookmarkWithPath:(NSString*)path displayName:(NSString*)displayName providerIdentifier:(NSString*)providerIdentifier launchOnStartup:(BOOL)launchOnStartup { 92 | Bookmark *bookmark = [self getBookmarkWithPath:path]; 93 | if(bookmark) { 94 | return bookmark; 95 | } 96 | 97 | bookmark = [[Bookmark alloc] init]; 98 | bookmark.displayName = displayName; 99 | bookmark.path = path; 100 | bookmark.launchOnStartup = launchOnStartup; 101 | if(!providerIdentifier || [providerIdentifier length] == 0) { 102 | bookmark.providerIdentifier = [[VagrantManager sharedManager] detectVagrantProvider:path]; 103 | } else { 104 | bookmark.providerIdentifier = providerIdentifier; 105 | } 106 | @synchronized(_bookmarks) { 107 | [_bookmarks addObject:bookmark]; 108 | } 109 | 110 | return bookmark; 111 | } 112 | 113 | - (void)removeBookmarkWithPath:(NSString*)path { 114 | Bookmark *bookmark = [self getBookmarkWithPath:path]; 115 | if(bookmark) { 116 | @synchronized(_bookmarks) { 117 | [_bookmarks removeObject:bookmark]; 118 | } 119 | } 120 | } 121 | 122 | - (Bookmark*)getBookmarkWithPath:(NSString*)path { 123 | @synchronized(_bookmarks) { 124 | for(Bookmark *bookmark in _bookmarks) { 125 | if([bookmark.path isEqualToString:path]) { 126 | return bookmark; 127 | } 128 | } 129 | } 130 | 131 | return nil; 132 | } 133 | 134 | - (int)getIndexOfBookmarkWithPath:(NSString*)path { 135 | for(int i=0; i<_bookmarks.count; ++i) { 136 | Bookmark *bookmark = [_bookmarks objectAtIndex:i]; 137 | if([bookmark.path isEqualToString:path]) { 138 | return i; 139 | } 140 | } 141 | 142 | return -1; 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /Vagrant Manager/CustomCommand.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCommandManager.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface CustomCommand : NSObject 11 | 12 | @property (strong, nonatomic) NSString *displayName; 13 | @property (strong, nonatomic) NSString *command; 14 | @property BOOL runInTerminal; 15 | @property BOOL runOnHost; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Vagrant Manager/CustomCommand.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCommandManager.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "CustomCommand.h" 9 | 10 | @implementation CustomCommand 11 | 12 | - (id)init { 13 | self = [super init]; 14 | 15 | if(self) { 16 | self.displayName = @""; 17 | self.command = @""; 18 | } 19 | 20 | return self; 21 | } 22 | 23 | - (id)copyWithZone:(NSZone*)zone { 24 | CustomCommand *command = [[[self class] allocWithZone:zone] init]; 25 | 26 | if(command) { 27 | command.displayName = self.displayName; 28 | command.command = self.command; 29 | command.runInTerminal = self.runInTerminal; 30 | command.runOnHost = self.runOnHost; 31 | } 32 | 33 | return command; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Vagrant Manager/CustomCommandManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCommandManager.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "CustomCommand.h" 10 | 11 | @interface CustomCommandManager : NSObject { 12 | NSMutableArray *_commands; 13 | } 14 | 15 | + (CustomCommandManager*)sharedManager; 16 | 17 | - (void)loadCustomCommands; 18 | - (void)saveCustomCommands; 19 | - (void)clearCustomCommands; 20 | - (NSMutableArray*)getCustomCommands; 21 | - (CustomCommand*)addCustomCommand:(CustomCommand*)command; 22 | - (CustomCommand*)addCustomCommandWithDisplayName:(NSString*)displayName command:(NSString*)command runInTerminal:(BOOL)runInTerminal runOnHost:(BOOL)runOnHost; 23 | - (void)removeCustomCommand:(CustomCommand*)command; 24 | - (void)setCustomCommands:(NSArray*)customCommands; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Vagrant Manager/CustomCommandManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCommandManager.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "CustomCommandManager.h" 9 | 10 | @implementation CustomCommandManager 11 | 12 | + (CustomCommandManager*)sharedManager { 13 | static CustomCommandManager *manager; 14 | @synchronized(self) { 15 | if(manager == nil) { 16 | manager = [[CustomCommandManager alloc] init]; 17 | } 18 | } 19 | 20 | return manager; 21 | } 22 | 23 | - (id)init { 24 | self = [super init]; 25 | 26 | if(self) { 27 | _commands = [[NSMutableArray alloc] init]; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | //load commands from shared preferences 34 | - (void)loadCustomCommands { 35 | @synchronized(_commands) { 36 | [_commands removeAllObjects]; 37 | 38 | NSArray *savedCommands = [[NSUserDefaults standardUserDefaults] arrayForKey:@"customCommands"]; 39 | if(savedCommands) { 40 | for(NSDictionary *savedCommand in savedCommands) { 41 | [self addCustomCommandWithDisplayName:[savedCommand objectForKey:@"displayName"] command:[savedCommand objectForKey:@"command"] runInTerminal:[[savedCommand objectForKey:@"runInTerminal"] boolValue] runOnHost:[[savedCommand objectForKey:@"runOnHost"] boolValue]]; 42 | } 43 | } 44 | } 45 | } 46 | 47 | //save commands to shared preferences 48 | - (void)saveCustomCommands { 49 | @synchronized(_commands) { 50 | NSMutableArray *customCommands = [self getCustomCommands]; 51 | if(customCommands) { 52 | NSMutableArray *arr = [[NSMutableArray alloc] init]; 53 | for(CustomCommand *c in customCommands) { 54 | [arr addObject:@{@"displayName":c.displayName, @"command":c.command, @"runInTerminal":[NSNumber numberWithBool:c.runInTerminal], @"runOnHost":[NSNumber numberWithBool:c.runOnHost]}]; 55 | } 56 | 57 | [[NSUserDefaults standardUserDefaults] setObject:arr forKey:@"customCommands"]; 58 | [[NSUserDefaults standardUserDefaults] synchronize]; 59 | } 60 | } 61 | } 62 | 63 | - (void)clearCustomCommands { 64 | @synchronized(_commands) { 65 | [_commands removeAllObjects]; 66 | } 67 | } 68 | 69 | - (CustomCommand*)addCustomCommand:(CustomCommand *)command { 70 | @synchronized(_commands) { 71 | [_commands addObject:command]; 72 | } 73 | 74 | return command; 75 | } 76 | 77 | - (void)setCustomCommands:(NSArray*)customCommands { 78 | @synchronized(_commands) { 79 | [_commands removeAllObjects]; 80 | for(id customCommand in customCommands) { 81 | if([customCommand isKindOfClass:[CustomCommand class]]) { 82 | [_commands addObject:customCommand]; 83 | } 84 | } 85 | } 86 | } 87 | 88 | - (NSMutableArray*)getCustomCommands { 89 | NSMutableArray *commands; 90 | @synchronized(_commands) { 91 | commands = [NSMutableArray arrayWithArray:_commands]; 92 | } 93 | return commands; 94 | } 95 | 96 | - (CustomCommand*)addCustomCommandWithDisplayName:(NSString*)displayName command:(NSString*)command runInTerminal:(BOOL)runInTerminal runOnHost:(BOOL)runOnHost { 97 | CustomCommand *customCommand = [[CustomCommand alloc] init]; 98 | customCommand.displayName = displayName; 99 | customCommand.command = command; 100 | customCommand.runInTerminal = runInTerminal; 101 | customCommand.runOnHost = runOnHost; 102 | 103 | @synchronized(_commands) { 104 | [_commands addObject:customCommand]; 105 | } 106 | 107 | return customCommand; 108 | } 109 | 110 | - (void)removeCustomCommand:(CustomCommand *)command { 111 | @synchronized(_commands) { 112 | [_commands removeObject:command]; 113 | } 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /Vagrant Manager/CustomProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomProvider.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface CustomProvider : NSObject 11 | 12 | @property (strong, nonatomic) NSString *name; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Vagrant Manager/CustomProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomProvider.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "CustomProvider.h" 9 | 10 | @implementation CustomProvider 11 | 12 | - (id)init { 13 | self = [super init]; 14 | 15 | if(self) { 16 | self.name = @""; 17 | } 18 | 19 | return self; 20 | } 21 | 22 | - (id)copyWithZone:(NSZone*)zone { 23 | CustomProvider *provider = [[[self class] allocWithZone:zone] init]; 24 | 25 | if(provider) { 26 | provider.name = self.name; 27 | } 28 | 29 | return provider; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Vagrant Manager/CustomProviderManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomProviderManager.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "CustomProvider.h" 10 | 11 | @interface CustomProviderManager : NSObject { 12 | NSMutableArray *_providers; 13 | } 14 | 15 | + (CustomProviderManager*)sharedManager; 16 | 17 | - (void)loadCustomProviders; 18 | - (void)saveCustomProviders; 19 | - (void)clearCustomProviders; 20 | - (NSMutableArray*)getCustomProviders; 21 | - (CustomProvider*)addCustomProvider:(CustomProvider*)provider; 22 | - (CustomProvider*)addCustomProviderWithName:(NSString*)name; 23 | - (void)removeCustomProvider:(CustomProvider*)provider; 24 | - (void)setCustomProviders:(NSArray*)CustomProviders; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Vagrant Manager/CustomProviderManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomProviderManager.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "CustomProviderManager.h" 9 | 10 | @implementation CustomProviderManager 11 | 12 | + (CustomProviderManager*)sharedManager { 13 | static CustomProviderManager *manager; 14 | @synchronized(self) { 15 | if(manager == nil) { 16 | manager = [[CustomProviderManager alloc] init]; 17 | } 18 | } 19 | 20 | return manager; 21 | } 22 | 23 | - (id)init { 24 | self = [super init]; 25 | 26 | if(self) { 27 | _providers = [[NSMutableArray alloc] init]; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | //load providers from shared preferences 34 | - (void)loadCustomProviders { 35 | @synchronized(_providers) { 36 | [_providers removeAllObjects]; 37 | 38 | NSArray *savedProviders = [[NSUserDefaults standardUserDefaults] arrayForKey:@"CustomProviders"]; 39 | 40 | if(savedProviders) { 41 | for(NSDictionary *savedProvider in savedProviders) { 42 | [self addCustomProviderWithName:[savedProvider objectForKey:@"name"]]; 43 | } 44 | } 45 | } 46 | } 47 | 48 | //save providers to shared preferences 49 | - (void)saveCustomProviders { 50 | @synchronized(_providers) { 51 | NSMutableArray *providers = [self getCustomProviders]; 52 | 53 | if(providers) { 54 | NSMutableArray *arr = [[NSMutableArray alloc] init]; 55 | for(CustomProvider *cp in providers) { 56 | [arr addObject:@{@"name":cp.name}]; 57 | } 58 | 59 | [[NSUserDefaults standardUserDefaults] setObject:arr forKey:@"CustomProviders"]; 60 | [[NSUserDefaults standardUserDefaults] synchronize]; 61 | } 62 | } 63 | } 64 | 65 | - (void)clearCustomProviders { 66 | @synchronized(_providers) { 67 | [_providers removeAllObjects]; 68 | } 69 | } 70 | 71 | - (CustomProvider*)addCustomProvider:(CustomProvider *)provider { 72 | @synchronized(_providers) { 73 | [_providers addObject:provider]; 74 | } 75 | 76 | return provider; 77 | } 78 | 79 | - (void)setCustomProviders:(NSArray*)CustomProviders { 80 | @synchronized(_providers) { 81 | [_providers removeAllObjects]; 82 | for(id provider in CustomProviders) { 83 | if([provider isKindOfClass:[CustomProvider class]]) { 84 | [_providers addObject:provider]; 85 | } 86 | } 87 | } 88 | } 89 | 90 | - (NSMutableArray*)getCustomProviders { 91 | NSMutableArray *providers; 92 | @synchronized(_providers) { 93 | providers = [NSMutableArray arrayWithArray:_providers]; 94 | } 95 | return providers; 96 | } 97 | 98 | - (CustomProvider*)addCustomProviderWithName:(NSString*)name { 99 | CustomProvider *provider = [[CustomProvider alloc] init]; 100 | provider.name = name; 101 | 102 | @synchronized(_providers) { 103 | [_providers addObject:provider]; 104 | } 105 | 106 | return provider; 107 | } 108 | 109 | - (void)removeCustomProvider:(CustomProvider *)provider { 110 | @synchronized(_providers) { 111 | [_providers removeObject:provider]; 112 | } 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /Vagrant Manager/Environment.h: -------------------------------------------------------------------------------- 1 | @interface Environment : NSObject 2 | 3 | @property (strong, nonatomic) NSString *aboutURL; 4 | @property (strong, nonatomic) NSString *githubURL; 5 | @property (strong, nonatomic) NSDictionary *environments; 6 | @property (strong, nonatomic) NSString *configurationName; 7 | 8 | + (Environment*)sharedInstance; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Vagrant Manager/Environment.m: -------------------------------------------------------------------------------- 1 | #import "Environment.h" 2 | 3 | @implementation Environment 4 | 5 | static Environment *sharedInstance = nil; 6 | 7 | - (void)initSharedInstance { 8 | self.configurationName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"Configuration"]; 9 | 10 | NSBundle *bundle = [NSBundle mainBundle]; 11 | NSString *envsPListPath = [bundle pathForResource:@"Environments" ofType:@"plist"]; 12 | 13 | self.environments = [[NSDictionary alloc] initWithContentsOfFile:envsPListPath]; 14 | 15 | self.aboutURL = [self getStringForKey:@"about_url"]; 16 | self.githubURL = [self getStringForKey:@"github_url"]; 17 | } 18 | 19 | + (Environment*)sharedInstance { 20 | @synchronized(self) { 21 | if (sharedInstance == nil) { 22 | sharedInstance = [[self alloc] init]; 23 | [sharedInstance initSharedInstance]; 24 | } 25 | return sharedInstance; 26 | } 27 | } 28 | 29 | - (NSString*)getStringForKey:(NSString*)key { 30 | return [self getStringForKey:key withDefaultValue:nil]; 31 | } 32 | 33 | - (NSString*)getStringForKey:(NSString*)key withDefaultValue:(NSString*)defaultValue { 34 | NSString *val = [[self.environments objectForKey:self.configurationName] objectForKey:key]; 35 | 36 | if(!val) { 37 | val = [[self.environments objectForKey:@"_default"] objectForKey:key]; 38 | } 39 | 40 | if(!val) { 41 | val = defaultValue; 42 | } 43 | 44 | return val; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Vagrant Manager/Environments.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | 7 | appcast_url 8 | http://vagrant.localhost:8080/appcast/vagrant_manager.xml 9 | 10 | _default 11 | 12 | github_url 13 | https://github.com/lanayotech/vagrant-manager 14 | app_info_url 15 | http://api.lanayo.com/info/vagrant_manager 16 | about_url 17 | http://www.vagrantmanager.com/ 18 | appcast_url 19 | http://www.vagrantmanager.com/appcast/vagrant_manager 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "appicon-16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "appicon-16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "appicon-32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "appicon-32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "appicon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "appicon-128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "appicon-256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "appicon-256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "appicon-512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "appicon-512x512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-128x128@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-16x16.png -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-16x16@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-256x256.png -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-256x256@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-32x32.png -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-32x32@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-512x512.png -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon-512x512@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/Images.xcassets/AppIcon.appiconset/appicon_128.png -------------------------------------------------------------------------------- /Vagrant Manager/MachineMenuItemViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MachineMenuItemViewController.h 3 | // Vagrant Manager 4 | // 5 | // Created by Chris Ayoub on 5/17/14. 6 | // Copyright (c) 2014 Lanayo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MachineMenuItemViewController : NSViewController 12 | 13 | @property (weak) IBOutlet NSImageView *statusImageView; 14 | @property (weak) IBOutlet NSTextField *machineNameTextField; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Vagrant Manager/MachineMenuItemViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MachineMenuItemViewController.m 3 | // Vagrant Manager 4 | // 5 | // Created by Chris Ayoub on 5/17/14. 6 | // Copyright (c) 2014 Lanayo. All rights reserved. 7 | // 8 | 9 | #import "MachineMenuItemViewController.h" 10 | 11 | @interface MachineMenuItemViewController () 12 | 13 | @end 14 | 15 | @implementation MachineMenuItemViewController 16 | 17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 18 | { 19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 20 | if (self) { 21 | // Initialization code here. 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Vagrant Manager/MachineMenuItemViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Vagrant Manager/ManageBookmarksWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // ManageBookmarksWindow.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "BaseWindowController.h" 10 | 11 | @interface ManageBookmarksWindow : BaseWindowController { 12 | NSMutableArray *bookmarks; 13 | } 14 | 15 | @property (weak) IBOutlet NSButton *recursiveScanCheckbox; 16 | @property (weak) IBOutlet NSTableView *bookmarkTableView; 17 | @property (weak) IBOutlet NSButton *cancelScanButton; 18 | @property (weak) IBOutlet NSTextField *directoryLabelTextField; 19 | @property (weak) IBOutlet NSButton *addBookmarksButton; 20 | @property (weak) IBOutlet NSButton *removeBookmarksButton; 21 | @property (weak) IBOutlet NSButton *cancelButton; 22 | @property (weak) IBOutlet NSButton *saveButton; 23 | 24 | - (IBAction)cancelButtonClicked:(id)sender; 25 | - (IBAction)saveButtonClicked:(id)sender; 26 | - (IBAction)addBookmarksButtonClicked:(id)sender; 27 | - (IBAction)removeBookmarksButtonClicked:(id)sender; 28 | - (IBAction)recursiveScanCheckboxClicked:(id)sender; 29 | - (IBAction)cancelScanButtonClicked:(id)sender; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Vagrant Manager/ManageBookmarksWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // ManageBookmarksWindow.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "ManageBookmarksWindow.h" 9 | #import "BookmarkManager.h" 10 | 11 | @interface ManageBookmarksWindow () 12 | 13 | @end 14 | 15 | @implementation ManageBookmarksWindow { 16 | __block BOOL _scanCancelled; 17 | } 18 | 19 | - (id)initWithWindow:(NSWindow *)window { 20 | self = [super initWithWindow:window]; 21 | 22 | return self; 23 | } 24 | 25 | - (void)windowDidLoad { 26 | [super windowDidLoad]; 27 | 28 | bookmarks = [[NSMutableArray alloc] initWithArray:[[BookmarkManager sharedManager] getBookmarks] copyItems:YES]; 29 | 30 | _scanCancelled = NO; 31 | 32 | self.bookmarkTableView.delegate = self; 33 | self.bookmarkTableView.dataSource = self; 34 | 35 | [self.recursiveScanCheckbox setState:[[NSUserDefaults standardUserDefaults] integerForKey:@"recursiveBookmarkScan"] ? NSOnState : NSOffState]; 36 | 37 | for (NSTableColumn *tableColumn in self.bookmarkTableView.tableColumns ) { 38 | NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:tableColumn.identifier ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; 39 | [tableColumn setSortDescriptorPrototype:sortDescriptor]; 40 | } 41 | 42 | [self.bookmarkTableView registerForDraggedTypes:[NSArray arrayWithObjects:NSPasteboardTypeString, nil]]; 43 | } 44 | 45 | - (void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)oldDescriptors { 46 | bookmarks = [NSMutableArray arrayWithArray:[bookmarks sortedArrayUsingDescriptors:self.bookmarkTableView.sortDescriptors]]; 47 | [self.bookmarkTableView reloadData]; 48 | } 49 | 50 | - (IBAction)addBookmarksButtonClicked:(id)sender { 51 | NSOpenPanel* openDlg = [NSOpenPanel openPanel]; 52 | 53 | [openDlg setCanChooseFiles:NO]; 54 | [openDlg setCanChooseDirectories:YES]; 55 | [openDlg setAllowsMultipleSelection:YES]; 56 | 57 | [openDlg beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) { 58 | if(result == NSFileHandlingPanelOKButton) { 59 | NSMutableArray *bookmarksSnapshot = [bookmarks mutableCopy]; 60 | 61 | [self.cancelScanButton setHidden:NO]; 62 | [self.saveButton setEnabled:NO]; 63 | [self.cancelButton setEnabled:NO]; 64 | [self.addBookmarksButton setEnabled:NO]; 65 | [self.removeBookmarksButton setEnabled:NO]; 66 | [self.bookmarkTableView setEnabled:NO]; 67 | 68 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 69 | 70 | NSArray *urls = [openDlg URLs]; 71 | 72 | NSFileManager *fileManager = [[NSFileManager alloc] init]; 73 | 74 | NSMutableArray *bookmarkPaths = [[NSMutableArray alloc] init]; 75 | for(Bookmark *b in bookmarks) { 76 | [bookmarkPaths addObject:b.path]; 77 | } 78 | 79 | for(NSURL *directoryURL in urls) { 80 | if ([[NSUserDefaults standardUserDefaults] integerForKey:@"recursiveBookmarkScan"] == NSOnState) { 81 | NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:directoryURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsHiddenFiles errorHandler:nil]; 82 | 83 | for (NSURL *url in enumerator) { 84 | NSString *path = [url.path stringByDeletingLastPathComponent]; 85 | 86 | if (_scanCancelled) { 87 | _scanCancelled = NO; 88 | bookmarks = bookmarksSnapshot; 89 | return; 90 | } 91 | 92 | dispatch_async(dispatch_get_main_queue(), ^{ 93 | self.directoryLabelTextField.stringValue = path; 94 | }); 95 | 96 | if ([[url.path lastPathComponent] isEqualToString:@"Vagrantfile"] && ![bookmarkPaths containsObject:path]) { 97 | [self addBookmarkWithPath:path displayName:[path lastPathComponent] launchOnStartup:NO]; 98 | } 99 | } 100 | } else { 101 | if ([fileManager fileExistsAtPath:[NSString stringWithFormat:@"%@/Vagrantfile", directoryURL.path]] && ![bookmarkPaths containsObject:directoryURL.path]) { 102 | [self addBookmarkWithPath:directoryURL.path displayName:[directoryURL.path lastPathComponent] launchOnStartup:NO]; 103 | } 104 | } 105 | } 106 | 107 | dispatch_async(dispatch_get_main_queue(), ^{ 108 | _scanCancelled = NO; 109 | [self.cancelScanButton setHidden:YES]; 110 | [self.saveButton setEnabled:YES]; 111 | [self.cancelButton setEnabled:YES]; 112 | [self.addBookmarksButton setEnabled:YES]; 113 | [self.removeBookmarksButton setEnabled:YES]; 114 | [self.bookmarkTableView setEnabled:YES]; 115 | self.directoryLabelTextField.stringValue = @""; 116 | [self.bookmarkTableView reloadData]; 117 | }); 118 | 119 | }); 120 | } 121 | }]; 122 | } 123 | 124 | - (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id < NSDraggingInfo >)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation { 125 | NSIndexSet *rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:NSPasteboardTypeString]]; 126 | Bookmark *targetObject = [bookmarks objectAtIndex:row]; 127 | 128 | NSArray *bookmarksToMove = [bookmarks objectsAtIndexes:rowIndexes]; 129 | [bookmarks removeObjectsAtIndexes:rowIndexes]; 130 | 131 | NSUInteger targetIndex = [bookmarks indexOfObjectIdenticalTo:targetObject]; 132 | 133 | [bookmarksToMove enumerateObjectsUsingBlock:^(Bookmark *bookmark, NSUInteger idx, BOOL *stop) { 134 | [bookmarks insertObject:bookmark atIndex:targetIndex+idx]; 135 | }]; 136 | 137 | [tableView reloadData]; 138 | return YES; 139 | } 140 | 141 | - (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id )info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation { 142 | 143 | NSIndexSet *rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:NSPasteboardTypeString]]; 144 | 145 | if ([info draggingSource] == self.bookmarkTableView && operation == NSTableViewDropAbove && ![rowIndexes containsIndex:row] && row < bookmarks.count) { 146 | return (NSDragOperation)operation; 147 | } 148 | 149 | return NSDragOperationNone; 150 | } 151 | 152 | - (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pasteboard { 153 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes]; 154 | [pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:self]; 155 | [pasteboard setData:data forType:NSPasteboardTypeString]; 156 | return YES; 157 | } 158 | 159 | - (void)addBookmarkWithPath:(NSString*)path displayName:(NSString*)displayName launchOnStartup:(BOOL)launchOnStartup { 160 | Bookmark *bookmark = [[Bookmark alloc] init]; 161 | bookmark.displayName = displayName; 162 | bookmark.path = [Util trimTrailingSlash:path]; 163 | bookmark.providerIdentifier = [[VagrantManager sharedManager] detectVagrantProvider:path]; 164 | bookmark.launchOnStartup = launchOnStartup; 165 | 166 | [bookmarks addObject:bookmark]; 167 | } 168 | 169 | - (void)controlTextDidEndEditing:(NSNotification *)notification { 170 | NSTextField *textField = notification.object; 171 | if(![textField isKindOfClass:[NSComboBox class]]) { 172 | Bookmark *bookmark = [bookmarks objectAtIndex:textField.tag]; 173 | bookmark.displayName = textField.stringValue; 174 | } 175 | } 176 | 177 | - (IBAction)removeBookmarksButtonClicked:(id)sender { 178 | [bookmarks removeObjectsAtIndexes:[self.bookmarkTableView selectedRowIndexes]]; 179 | [self.bookmarkTableView reloadData]; 180 | } 181 | 182 | - (IBAction)recursiveScanCheckboxClicked:(id)sender { 183 | [[NSUserDefaults standardUserDefaults] setBool:self.recursiveScanCheckbox.state forKey:@"recursiveBookmarkScan"]; 184 | } 185 | 186 | - (IBAction)cancelScanButtonClicked:(id)sender { 187 | _scanCancelled = YES; 188 | [self.cancelScanButton setHidden:YES]; 189 | [self.saveButton setEnabled:YES]; 190 | [self.cancelButton setEnabled:YES]; 191 | [self.addBookmarksButton setEnabled:YES]; 192 | [self.removeBookmarksButton setEnabled:YES]; 193 | [self.bookmarkTableView setEnabled:YES]; 194 | dispatch_async(dispatch_get_main_queue(), ^{ 195 | self.directoryLabelTextField.stringValue = @""; 196 | }); 197 | } 198 | 199 | - (IBAction)cancelButtonClicked:(id)sender { 200 | [self close]; 201 | } 202 | 203 | - (IBAction)saveButtonClicked:(id)sender { 204 | [self.window makeFirstResponder:nil]; 205 | 206 | [[BookmarkManager sharedManager] clearBookmarks]; 207 | for(Bookmark *bookmark in bookmarks) { 208 | [[BookmarkManager sharedManager] addBookmark:bookmark]; 209 | } 210 | [[BookmarkManager sharedManager] saveBookmarks]; 211 | [[NSNotificationCenter defaultCenter] postNotificationName:@"vagrant-manager.bookmarks-updated" object:nil]; 212 | [self close]; 213 | } 214 | 215 | - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 216 | Bookmark *bookmark = [bookmarks objectAtIndex:row]; 217 | 218 | if([tableColumn.identifier isEqualToString:@"providerIdentifier"]) { 219 | NSComboBox *view = [tableView makeViewWithIdentifier:@"ProviderCellView" owner:self]; 220 | 221 | if(!view) { 222 | view = [[NSComboBox alloc] initWithFrame:CGRectMake(0, 0, tableColumn.width, 24)]; 223 | NSArray *providerIdentifiers = [[VagrantManager sharedManager] getProviderIdentifiers]; 224 | for(NSString *providerIdentifier in providerIdentifiers) { 225 | [view addItemWithObjectValue:providerIdentifier]; 226 | } 227 | view.identifier = @"ProviderCellView"; 228 | } 229 | view.tag = row; 230 | view.delegate = self; 231 | [view setStringValue:bookmark.providerIdentifier]; 232 | 233 | return view; 234 | } 235 | 236 | if([tableColumn.identifier isEqualToString:@"launchOnStartup"]) { 237 | NSButton *view = [tableView makeViewWithIdentifier:@"LaunchOnStartupCellView" owner:self]; 238 | 239 | if(!view) { 240 | view = [[NSButton alloc] initWithFrame:CGRectMake(0, 0, tableColumn.width, 24)]; 241 | [view setButtonType:NSSwitchButton]; 242 | view.identifier = @"LaunchOnStartupCellView"; 243 | view.alignment = NSTextAlignmentCenter; 244 | view.imagePosition = NSImageOnly; 245 | [view setTitle:@""]; 246 | } 247 | view.tag = row; 248 | [view setTarget:self]; 249 | [view setAction:@selector(launchOnStartupButtonClicked:)]; 250 | [view setState:bookmark.launchOnStartup ? NSOnState : NSOffState]; 251 | 252 | return view; 253 | } 254 | 255 | NSTextField *view = [tableView makeViewWithIdentifier:@"TableCellView" owner:self]; 256 | if(!view) { 257 | view = [[NSTextField alloc] initWithFrame:CGRectMake(0, 0, tableColumn.width, 24)]; 258 | [view setBezeled:NO]; 259 | [view setDrawsBackground:NO]; 260 | view.delegate = self; 261 | [view.cell setLineBreakMode:NSLineBreakByTruncatingTail]; 262 | view.identifier = @"TableCellView"; 263 | } 264 | 265 | [view.cell setEditable:NO]; 266 | view.tag = row; 267 | 268 | 269 | if ([tableColumn.identifier isEqualToString:@"path"]) { 270 | view.stringValue = bookmark.path; 271 | } else if ([tableColumn.identifier isEqualToString:@"displayName"]) { 272 | [view.cell setEditable:YES]; 273 | view.stringValue = bookmark.displayName; 274 | } 275 | 276 | return view; 277 | } 278 | 279 | - (void)launchOnStartupButtonClicked:(NSButton*)sender { 280 | Bookmark *bookmark = [bookmarks objectAtIndex:sender.tag]; 281 | bookmark.launchOnStartup = sender.state == NSOnState; 282 | } 283 | 284 | - (void)comboBoxSelectionDidChange:(NSNotification *)notification { 285 | NSComboBox *comboBox = notification.object; 286 | Bookmark *bookmark = [bookmarks objectAtIndex:comboBox.tag]; 287 | bookmark.providerIdentifier = [comboBox objectValueOfSelectedItem]; 288 | } 289 | 290 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { 291 | return bookmarks.count; 292 | } 293 | 294 | - (void)windowWillClose:(NSNotification *)notification { 295 | [super windowWillClose:notification]; 296 | _scanCancelled = YES; 297 | } 298 | 299 | @end 300 | -------------------------------------------------------------------------------- /Vagrant Manager/ManageCustomCommandsWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCommandManager.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "BaseWindowController.h" 10 | 11 | @interface ManageCustomCommandsWindow : BaseWindowController { 12 | NSMutableArray *_commands; 13 | } 14 | 15 | @property (weak) IBOutlet NSButton *addCommandButton; 16 | @property (weak) IBOutlet NSButton *removeCommandButton; 17 | @property (weak) IBOutlet NSTableView *commandsTableView; 18 | 19 | - (IBAction)addCommandButtonClicked:(id)sender; 20 | - (IBAction)removeCommandButtonClicked:(id)sender; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Vagrant Manager/ManageCustomCommandsWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCommandManager.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2015 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "ManageCustomCommandsWindow.h" 9 | #import "CustomCommandManager.h" 10 | 11 | @implementation ManageCustomCommandsWindow 12 | 13 | - (void)windowDidLoad { 14 | [super windowDidLoad]; 15 | 16 | _commands = [[CustomCommandManager sharedManager] getCustomCommands]; 17 | [self.commandsTableView registerForDraggedTypes:[NSArray arrayWithObjects:NSPasteboardTypeString, nil]]; 18 | 19 | [self.commandsTableView reloadData]; 20 | } 21 | 22 | - (void)addCommandButtonClicked:(id)sender { 23 | CustomCommand *customCommand = [[CustomCommand alloc] init]; 24 | customCommand.displayName = @"New Command"; 25 | 26 | [_commands addObject:customCommand]; 27 | [self saveCustomCommands]; 28 | 29 | [self.commandsTableView reloadData]; 30 | } 31 | 32 | - (IBAction)removeCommandButtonClicked:(id)sender { 33 | [_commands removeObjectsAtIndexes:[self.commandsTableView selectedRowIndexes]]; 34 | 35 | [self saveCustomCommands]; 36 | 37 | [self.commandsTableView reloadData]; 38 | } 39 | 40 | - (void)saveCustomCommands { 41 | [[CustomCommandManager sharedManager] setCustomCommands:_commands]; 42 | [[CustomCommandManager sharedManager] saveCustomCommands]; 43 | _commands = [[CustomCommandManager sharedManager] getCustomCommands]; 44 | [[NSNotificationCenter defaultCenter] postNotificationName:@"vagrant-manager.custom-commands-updated" object:nil]; 45 | } 46 | 47 | - (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id < NSDraggingInfo >)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation { 48 | NSIndexSet *rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:NSPasteboardTypeString]]; 49 | 50 | NSArray *commandsToMove = [_commands objectsAtIndexes:rowIndexes]; 51 | [_commands removeObjectsAtIndexes:rowIndexes]; 52 | 53 | [_commands insertObjects:commandsToMove atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(row, [commandsToMove count])]]; 54 | 55 | [tableView reloadData]; 56 | 57 | [self saveCustomCommands]; 58 | 59 | return YES; 60 | } 61 | 62 | - (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id )info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation { 63 | 64 | NSIndexSet *rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:NSPasteboardTypeString]]; 65 | 66 | if ([info draggingSource] == self.commandsTableView && operation == NSTableViewDropAbove && ![rowIndexes containsIndex:row] && row < _commands.count) { 67 | return (NSDragOperation)operation; 68 | } 69 | 70 | return NSDragOperationNone; 71 | } 72 | 73 | - (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pasteboard { 74 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes]; 75 | [pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:self]; 76 | [pasteboard setData:data forType:NSPasteboardTypeString]; 77 | return YES; 78 | } 79 | 80 | 81 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { 82 | return _commands.count; 83 | } 84 | 85 | - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 86 | CustomCommand *customCommand = [_commands objectAtIndex:row]; 87 | if([tableColumn.identifier isEqualToString:@"name"]) { 88 | return customCommand.displayName; 89 | } else if([tableColumn.identifier isEqualToString:@"command"]) { 90 | return customCommand.command; 91 | } else if([tableColumn.identifier isEqualToString:@"runInTerminal"]) { 92 | return [NSNumber numberWithBool:customCommand.runInTerminal]; 93 | } else if([tableColumn.identifier isEqualToString:@"runOnHost"]) { 94 | return [NSNumber numberWithBool:customCommand.runOnHost]; 95 | } else { 96 | return @""; 97 | } 98 | } 99 | 100 | - (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 101 | CustomCommand *customCommand = [_commands objectAtIndex:row]; 102 | 103 | if([tableColumn.identifier isEqualToString:@"name"]) { 104 | customCommand.displayName = object; 105 | } else if([tableColumn.identifier isEqualToString:@"command"]) { 106 | customCommand.command = object; 107 | } else if([tableColumn.identifier isEqualToString:@"runInTerminal"]) { 108 | customCommand.runInTerminal = [object boolValue]; 109 | } else if([tableColumn.identifier isEqualToString:@"runOnHost"]) { 110 | customCommand.runOnHost = [object boolValue]; 111 | } 112 | 113 | [self saveCustomCommands]; 114 | 115 | [self.commandsTableView reloadData]; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /Vagrant Manager/ManageCustomCommandsWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 104 | 107 | 108 | 109 | 110 | 111 | 112 | 123 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /Vagrant Manager/ManageCustomProvidersWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // ManageCustomProvidersWindow.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2019 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "BaseWindowController.h" 10 | 11 | @interface ManageCustomProvidersWindow : BaseWindowController { 12 | NSMutableArray *_providers; 13 | } 14 | 15 | @property (weak) IBOutlet NSButton *addProviderButton; 16 | @property (weak) IBOutlet NSButton *removeProviderButton; 17 | @property (weak) IBOutlet NSTableView *providersTableView; 18 | 19 | - (IBAction)addProviderButtonClicked:(id)sender; 20 | - (IBAction)removeProviderButtonClicked:(id)sender; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Vagrant Manager/ManageCustomProvidersWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // ManageCustomProvidersWindow.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2019 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "ManageCustomProvidersWindow.h" 9 | #import "CustomProviderManager.h" 10 | 11 | @implementation ManageCustomProvidersWindow 12 | 13 | - (void)windowDidLoad { 14 | [super windowDidLoad]; 15 | 16 | _providers = [[CustomProviderManager sharedManager] getCustomProviders]; 17 | [self.providersTableView registerForDraggedTypes:[NSArray arrayWithObjects:NSPasteboardTypeString, nil]]; 18 | 19 | [self.providersTableView reloadData]; 20 | } 21 | 22 | - (void)addProviderButtonClicked:(id)sender { 23 | CustomProvider *customProvider = [[CustomProvider alloc] init]; 24 | customProvider.name = @"New Provider"; 25 | 26 | [_providers addObject:customProvider]; 27 | [self saveCustomProviders]; 28 | 29 | [self.providersTableView reloadData]; 30 | } 31 | 32 | - (IBAction)removeProviderButtonClicked:(id)sender { 33 | [_providers removeObjectsAtIndexes:[self.providersTableView selectedRowIndexes]]; 34 | 35 | [self saveCustomProviders]; 36 | 37 | [self.providersTableView reloadData]; 38 | } 39 | 40 | - (void)saveCustomProviders { 41 | [[CustomProviderManager sharedManager] setCustomProviders:_providers]; 42 | [[CustomProviderManager sharedManager] saveCustomProviders]; 43 | _providers = [[CustomProviderManager sharedManager] getCustomProviders]; 44 | [[NSNotificationCenter defaultCenter] postNotificationName:@"vagrant-manager.custom-providers-updated" object:nil]; 45 | } 46 | 47 | - (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id < NSDraggingInfo >)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation { 48 | NSIndexSet *rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:NSPasteboardTypeString]]; 49 | 50 | NSArray *providersToMove = [_providers objectsAtIndexes:rowIndexes]; 51 | [_providers removeObjectsAtIndexes:rowIndexes]; 52 | 53 | [_providers insertObjects:providersToMove atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(row, [providersToMove count])]]; 54 | 55 | [tableView reloadData]; 56 | 57 | [self saveCustomProviders]; 58 | 59 | return YES; 60 | } 61 | 62 | - (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id )info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation { 63 | 64 | NSIndexSet *rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:NSPasteboardTypeString]]; 65 | 66 | if ([info draggingSource] == self.providersTableView && operation == NSTableViewDropAbove && ![rowIndexes containsIndex:row] && row < _providers.count) { 67 | return (NSDragOperation)operation; 68 | } 69 | 70 | return NSDragOperationNone; 71 | } 72 | 73 | - (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pasteboard { 74 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes]; 75 | [pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:self]; 76 | [pasteboard setData:data forType:NSPasteboardTypeString]; 77 | return YES; 78 | } 79 | 80 | 81 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { 82 | return _providers.count; 83 | } 84 | 85 | - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 86 | CustomProvider *customProvider = [_providers objectAtIndex:row]; 87 | if([tableColumn.identifier isEqualToString:@"name"]) { 88 | return customProvider.name; 89 | } else { 90 | return @""; 91 | } 92 | } 93 | 94 | - (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 95 | CustomProvider *customProvider = [_providers objectAtIndex:row]; 96 | 97 | if([tableColumn.identifier isEqualToString:@"name"]) { 98 | customProvider.name = object; 99 | } 100 | 101 | [self saveCustomProviders]; 102 | 103 | [self.providersTableView reloadData]; 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /Vagrant Manager/ManageCustomProvidersWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 67 | 70 | 71 | 72 | 73 | 74 | 75 | 86 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /Vagrant Manager/MenuDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // MenuDelegate.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VagrantInstance.h" 9 | #import "VagrantMachine.h" 10 | #import "CustomCommand.h" 11 | 12 | @protocol MenuDelegate 13 | 14 | - (void)performVagrantAction:(NSString*)action withInstance:(VagrantInstance*)instance; 15 | - (void)performVagrantAction:(NSString*)action withMachine:(VagrantMachine*)machine; 16 | - (void)performCustomCommand:(CustomCommand*)customCommand withInstance:(VagrantInstance*)instance; 17 | - (void)performCustomCommand:(CustomCommand*)customCommand withMachine:(VagrantMachine*)machine; 18 | - (void)openInstanceInFinder:(VagrantInstance*)instance; 19 | - (void)openInstanceInTerminal:(VagrantInstance*)instance; 20 | - (void)editVagrantfile:(VagrantInstance*)instance; 21 | - (void)addBookmarkWithInstance:(VagrantInstance*)instance; 22 | - (void)removeBookmarkWithInstance:(VagrantInstance*)instance; 23 | - (void)checkForVagrantUpdates:(BOOL)showAlert; 24 | - (void)editHostsFile; 25 | 26 | @end -------------------------------------------------------------------------------- /Vagrant Manager/NFSScanner.h: -------------------------------------------------------------------------------- 1 | // 2 | // NfsScanner.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface NFSScanner : NSObject 11 | 12 | - (NSArray*)getNFSInstancePaths; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Vagrant Manager/NFSScanner.m: -------------------------------------------------------------------------------- 1 | // 2 | // NfsScanner.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "NFSScanner.h" 9 | 10 | @implementation NFSScanner 11 | 12 | //find vagrant instances in the NFS exports file 13 | - (NSArray*)getNFSInstancePaths { 14 | NSMutableArray *paths = [[NSMutableArray alloc] init]; 15 | 16 | //get contents of /etc/exports 17 | NSError *err; 18 | NSString *fileContents = [NSString stringWithContentsOfFile:@"/etc/exports" encoding:NSUTF8StringEncoding error:&err]; 19 | 20 | if(fileContents) { 21 | //search for vagrant NFS paths 22 | NSMutableArray *lines = [[fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] mutableCopy]; 23 | [lines removeObject:@""]; 24 | 25 | for(NSString *line in lines) { 26 | 27 | if([line rangeOfString:@"# VAGRANT-"].location != NSNotFound) { 28 | continue; 29 | } 30 | 31 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(? 1) { 35 | NSString *path = [line substringWithRange:[pathResult rangeAtIndex:1]]; 36 | BOOL vagrantFileExists = [[NSFileManager defaultManager] fileExistsAtPath:[NSString pathWithComponents:@[path, @"Vagrantfile"]]]; 37 | 38 | if(vagrantFileExists) { 39 | [paths addObject:path]; 40 | } 41 | } 42 | } 43 | } 44 | } 45 | 46 | return [NSArray arrayWithArray:paths]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Vagrant Manager/NativeMenu.h: -------------------------------------------------------------------------------- 1 | // 2 | // NativeMenu.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "MenuDelegate.h" 10 | #import "PreferencesWindow.h" 11 | #import "AboutWindow.h" 12 | #import "ManageBookmarksWindow.h" 13 | #import "ManageCustomCommandsWindow.h" 14 | #import "ManageCustomProvidersWindow.h" 15 | #import "NativeMenuItem.h" 16 | #import "CustomCommand.h" 17 | 18 | @interface NativeMenu : NSObject { 19 | PreferencesWindow *preferencesWindow; 20 | AboutWindow *aboutWindow; 21 | ManageBookmarksWindow *manageBookmarksWindow; 22 | ManageCustomCommandsWindow *manageCustomCommandsWindow; 23 | ManageCustomProvidersWindow *manageCustomProvidersWindow; 24 | } 25 | 26 | @property (weak) id delegate; 27 | 28 | - (void)rebuildMenu; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Vagrant Manager/NativeMenuItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // NativeMenuItem.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "VagrantMachine.h" 10 | #import "CustomCommand.h" 11 | 12 | @class NativeMenuItem; 13 | 14 | @protocol NativeMenuItemDelegate 15 | 16 | - (void)nativeMenuItemUpAllMachines:(NativeMenuItem*)menuItem withProvision:(BOOL)provision; 17 | - (void)nativeMenuItemSSHInstance:(NativeMenuItem*)menuItem; 18 | - (void)nativeMenuItemRDPInstance:(NativeMenuItem*)menuItem; 19 | - (void)nativeMenuItemSuspendAllMachines:(NativeMenuItem*)menuItem; 20 | - (void)nativeMenuItemReloadAllMachines:(NativeMenuItem*)menuItem; 21 | - (void)nativeMenuItemHaltAllMachines:(NativeMenuItem*)menuItem; 22 | - (void)nativeMenuItemDestroyAllMachines:(NativeMenuItem*)menuItem; 23 | - (void)nativeMenuItemProvisionAllMachines:(NativeMenuItem*)menuItem; 24 | - (void)nativeMenuItemCustomCommandAllMachines:(NativeMenuItem*)menuItem withCommand:(CustomCommand*)customCommand; 25 | - (void)nativeMenuItemOpenFinder:(NativeMenuItem*)menuItem; 26 | - (void)nativeMenuItemOpenTerminal:(NativeMenuItem*)menuItem; 27 | - (void)nativeMenuItemEditVagrantfile:(NativeMenuItem*)menuItem; 28 | - (void)nativeMenuItemUpdateProviderIdentifier:(NativeMenuItem*)menuItem withProviderIdentifier:(NSString*)providerIdentifier; 29 | - (void)nativeMenuItemRemoveBookmark:(NativeMenuItem*)menuItem; 30 | - (void)nativeMenuItemAddBookmark:(NativeMenuItem*)menuItem; 31 | 32 | - (void)nativeMenuItemUpMachine:(VagrantMachine*)machine withProvision:(BOOL)provision; 33 | - (void)nativeMenuItemSSHMachine:(VagrantMachine*)machine; 34 | - (void)nativeMenuItemRDPMachine:(VagrantMachine*)machine; 35 | - (void)nativeMenuItemSuspendMachine:(VagrantMachine*)machine; 36 | - (void)nativeMenuItemReloadMachine:(VagrantMachine*)machine; 37 | - (void)nativeMenuItemHaltMachine:(VagrantMachine*)machine; 38 | - (void)nativeMenuItemDestroyMachine:(VagrantMachine*)machine; 39 | - (void)nativeMenuItemProvisionMachine:(VagrantMachine*)machine; 40 | - (void)nativeMenuItemCustomCommandMachine:(VagrantMachine*)machine withCommand:(CustomCommand*)customCommand; 41 | 42 | @end 43 | 44 | @interface NativeMenuItem : NSObject 45 | 46 | @property id delegate; 47 | 48 | @property (strong) VagrantInstance *instance; 49 | @property (strong) NSMenuItem *menuItem; 50 | 51 | - (void)refresh; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Vagrant Manager/ParallelsMachineInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // ParallelsMachineInfo.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface ParallelsMachineInfo : VirtualMachineInfo 11 | 12 | + (ParallelsMachineInfo*)initWithInfo:(NSDictionary*)infoDictionary; 13 | 14 | - (NSString*)getSharedFolderPathWithName:(NSString*)name; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Vagrant Manager/ParallelsMachineInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // ParallelsMachineInfo.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "ParallelsMachineInfo.h" 9 | 10 | @implementation ParallelsMachineInfo 11 | 12 | //get a shared folder path by its name 13 | - (NSString*)getSharedFolderPathWithName:(NSString*)name { 14 | NSString *folder = [self.sharedFolders objectForKey:name]; 15 | if(!folder && [[name substringToIndex:1] isEqualToString:@"/"]) { 16 | folder = [self.sharedFolders objectForKey:[name substringFromIndex:1]]; 17 | } 18 | 19 | return folder; 20 | } 21 | 22 | //parse Parallels machine info 23 | + (ParallelsMachineInfo*)initWithInfo:(NSDictionary*)infoDictionary { 24 | ParallelsMachineInfo *vm = [[ParallelsMachineInfo alloc] init]; 25 | 26 | NSMutableDictionary *sharedFolders = [[NSMutableDictionary alloc] init]; 27 | 28 | vm.name = [infoDictionary objectForKey:@"Name"]; 29 | vm.os = [infoDictionary objectForKey:@"OS"]; 30 | vm.uuid = [infoDictionary objectForKey:@"ID"]; 31 | vm.stateString = [infoDictionary objectForKey:@"State"]; 32 | for(NSString *shareName in [[infoDictionary objectForKey:@"Host Shared Folders"] allKeys]) { 33 | id shareData = [[infoDictionary objectForKey:@"Host Shared Folders"] objectForKey:shareName]; 34 | if([shareData isKindOfClass:[NSDictionary class]] && [shareData objectForKey:@"path"]) { 35 | [sharedFolders setObject:[shareData objectForKey:@"path"] forKey:shareName]; 36 | } 37 | } 38 | 39 | //TODO: parse the rest of the properties into a single dimensional array 40 | //vm.properties = [NSDictionary dictionaryWithDictionary:infoPairs]; 41 | 42 | vm.sharedFolders = sharedFolders; 43 | 44 | return vm; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Vagrant Manager/ParallelsServiceProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // ParallelsServiceProvider.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface ParallelsServiceProvider : NSObject 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Vagrant Manager/ParallelsServiceProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // ParallelsServiceProvider.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "ParallelsServiceProvider.h" 9 | #import "ParallelsMachineInfo.h" 10 | 11 | @implementation ParallelsServiceProvider 12 | 13 | - (NSString*)getProviderIdentifier { 14 | return @"parallels"; 15 | } 16 | 17 | //get all Vagrant instances Parallels knows about 18 | - (NSArray*)getVagrantInstancePaths { 19 | NSMutableArray *paths = [[NSMutableArray alloc] init]; 20 | 21 | //get all virtual machines UUIDs from Parallels 22 | NSArray *infos = [self getAllVirtualMachineInfos]; 23 | 24 | //check each machine by uuid 25 | for(ParallelsMachineInfo *machineInfo in infos) { 26 | if(machineInfo) { 27 | //check for path mapped to /vagrant 28 | NSString *instancePath = [Util trimTrailingSlash:[machineInfo getSharedFolderPathWithName:@"vagrant"]]; 29 | 30 | if(instancePath) { 31 | if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/Vagrantfile", instancePath]] && ![paths containsObject:instancePath]) { 32 | //mapped path found, and not already added to list 33 | [paths addObject:instancePath]; 34 | } 35 | } 36 | } 37 | } 38 | 39 | return paths; 40 | } 41 | 42 | //get virtual machine info for all Parallels VMs 43 | - (NSArray*)getAllVirtualMachineInfos { 44 | NSMutableArray *infos = [[NSMutableArray alloc] init]; 45 | 46 | NSTask *task = [[NSTask alloc] init]; 47 | [task setLaunchPath:@"/bin/bash"]; 48 | 49 | [task setArguments:@[@"-l", @"-c", @"prlctl list --info --all --json"]]; 50 | 51 | NSPipe *pipe = [NSPipe pipe]; 52 | [task setStandardInput:[NSPipe pipe]]; 53 | [task setStandardOutput:pipe]; 54 | [task setStandardError:[NSPipe pipe]]; 55 | 56 | [task launch]; 57 | [task waitUntilExit]; 58 | 59 | NSData *outputData = [[pipe fileHandleForReading] readDataToEndOfFile]; 60 | 61 | if(task.terminationStatus == 0) { 62 | NSError *error = nil; 63 | NSArray *machineObjects = [NSJSONSerialization JSONObjectWithData:outputData options:0 error:&error]; 64 | 65 | if(!error && [machineObjects isKindOfClass:[NSArray class]]) { 66 | for(id machineObject in machineObjects) { 67 | if([machineObject isKindOfClass:[NSDictionary class]]) { 68 | [infos addObject:[ParallelsMachineInfo initWithInfo:machineObject]]; 69 | } 70 | } 71 | } 72 | } 73 | 74 | return [[NSArray alloc] initWithArray:infos]; 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /Vagrant Manager/PasswordHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordHelper.h 3 | // 4 | // Created by Ira Cooke on 27/07/2009. 5 | // Copyright 2009 Mudflat Software. 6 | // 7 | 8 | #import 9 | 10 | /*! This class consists entirely of class methods which provide a simple interface to keychain calls to set and retrieve passwords*/ 11 | @interface PasswordHelper : NSObject 12 | 13 | + (NSArray*)promptForPassword; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Vagrant Manager/PasswordHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordHelper.m 3 | // 4 | // Created by Ira Cooke on 27/07/2009. 5 | // Copyright 2009 Mudflat Software. 6 | // 7 | 8 | #import "PasswordHelper.h" 9 | 10 | @implementation PasswordHelper 11 | 12 | + (NSArray*) promptForPassword { 13 | CFUserNotificationRef passwordDialog; 14 | SInt32 error; 15 | CFOptionFlags responseFlags; 16 | int button; 17 | CFStringRef passwordRef; 18 | 19 | NSMutableArray *returnArray = [NSMutableArray arrayWithObjects:@"PasswordString", [NSNumber numberWithInt:0], [NSNumber numberWithInt:1], nil]; 20 | 21 | NSURL * iconUrl = 22 | [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", 23 | [[[NSBundle mainBundle] executablePath] stringByDeletingLastPathComponent], 24 | @"appicon_128.png" 25 | ]]; 26 | 27 | NSDictionary *panelDict = [NSDictionary dictionaryWithObjectsAndKeys: 28 | @"Enter Your Password", kCFUserNotificationAlertHeaderKey, 29 | @"Vagrant Requested Administrator Privileges", kCFUserNotificationAlertMessageKey, 30 | @"", kCFUserNotificationTextFieldTitlesKey, 31 | @"Cancel", kCFUserNotificationAlternateButtonTitleKey, 32 | (__bridge CFURLRef)iconUrl, kCFUserNotificationIconURLKey, 33 | nil]; 34 | 35 | passwordDialog = CFUserNotificationCreate(kCFAllocatorDefault, 36 | 0, 37 | kCFUserNotificationPlainAlertLevel 38 | | 39 | CFUserNotificationSecureTextField(0), 40 | &error, 41 | (__bridge CFDictionaryRef)panelDict); 42 | 43 | 44 | if (error) { 45 | // There was an error creating the password dialog 46 | CFRelease(passwordDialog); 47 | [returnArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:error]]; 48 | return returnArray; 49 | } 50 | 51 | error = CFUserNotificationReceiveResponse(passwordDialog, 52 | 0, 53 | &responseFlags); 54 | 55 | if (error) { 56 | CFRelease(passwordDialog); 57 | [returnArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:error]]; 58 | return returnArray; 59 | } 60 | 61 | 62 | button = responseFlags & 0x3; 63 | if (button == kCFUserNotificationAlternateResponse) { 64 | CFRelease(passwordDialog); 65 | [returnArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:1]]; 66 | return returnArray; 67 | } 68 | 69 | passwordRef = CFUserNotificationGetResponseValue(passwordDialog, 70 | kCFUserNotificationTextFieldValuesKey, 71 | 0); 72 | 73 | 74 | [returnArray replaceObjectAtIndex:0 withObject:(__bridge NSString*)passwordRef]; 75 | CFRelease(passwordDialog); 76 | return returnArray; 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /Vagrant Manager/PreferencesWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencesWindow.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "BaseWindowController.h" 10 | 11 | @interface PreferencesWindow : BaseWindowController { 12 | 13 | } 14 | 15 | @property (weak) IBOutlet NSButton *autoCloseCheckBox; 16 | @property (weak) IBOutlet NSButton *hideTaskWindowsCheckBox; 17 | @property (weak) IBOutlet NSButton *dontShowUpdateCheckBox; 18 | @property (weak) IBOutlet NSButton *optionKeyDestroyCheckBox; 19 | @property (weak) IBOutlet NSButton *usePathAsInstanceDisplayNameCheckBox; 20 | @property (weak) IBOutlet NSButton *useProviderMachineDetectionCheckBox; 21 | @property (weak) IBOutlet NSButton *includeMachineNamesCheckBox; 22 | @property (weak) IBOutlet NSButton *dontShowRunningVmCountCheckBox; 23 | @property (weak) IBOutlet NSPopUpButton *terminalPreferencePopUpButton; 24 | @property (weak) IBOutlet NSPopUpButton *terminalEditorPreferencePopUpButton; 25 | @property (weak) IBOutlet NSPopUpButton *statusBarIconThemePopUpButton; 26 | @property (weak) IBOutlet NSPopUpButton *updateStabilityPopUpButton; 27 | @property (weak) IBOutlet NSButton *sendProfileDataCheckBox; 28 | @property (weak) IBOutlet NSButton *launchAtLoginCheckBox; 29 | @property (weak) IBOutlet NSButton *haltOnExitCheckBox; 30 | @property (weak) IBOutlet NSButton *refreshEveryCheckBox; 31 | @property (weak) IBOutlet NSPopUpButton *intervalMenu; 32 | @property (weak) IBOutlet NSButton *dontAnimateStatusIconCheckBox; 33 | @property (weak) IBOutlet NSButton *showTaskNotificationCheckBox; 34 | 35 | 36 | - (IBAction)autoCloseCheckBoxClicked:(id)sender; 37 | - (IBAction)hideTaskWindowsCheckBoxClicked:(id)sender; 38 | - (IBAction)dontShowUpdateCheckBoxClicked:(id)sender; 39 | - (IBAction)optionKeyDestroyCheckBoxClicked:(id)sender; 40 | - (IBAction)usePathAsInstanceDisplayNameCheckBoxClicked:(id)sender; 41 | - (IBAction)useProviderMachineDetectionCheckBoxClicked:(id)sender; 42 | - (IBAction)includeMachineNamesCheckBoxClicked:(id)sender; 43 | - (IBAction)dontShowRunningVmCountCheckBoxClicked:(id)sender; 44 | - (IBAction)terminalPreferencePopUpButtonClicked:(id)sender; 45 | - (IBAction)statusBarIconThemePopUpButtonClicked:(id)sender; 46 | - (IBAction)updateStabilityPopUpButtonClicked:(id)sender; 47 | - (IBAction)sendProfileDataCheckBoxClicked:(id)sender; 48 | - (IBAction)launchAtLoginCheckBoxClicked:(id)sender; 49 | - (IBAction)haltOnExitCheckBoxClicked:(id)sender; 50 | - (IBAction)refreshEveryCheckBoxClicked:(id)sender; 51 | - (IBAction)intervalMenuChanged:(id)sender; 52 | - (IBAction)dontAnimateStatusIconCheckBoxClicked:(id)sender; 53 | - (IBAction)showTaskNotificationCheckBoxClicked:(id)sender; 54 | 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Vagrant Manager/RegisterWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // RegisterWindow.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface RegisterWindow : NSWindowController 11 | 12 | @property (weak) IBOutlet NSButton *validateButton; 13 | @property (weak) IBOutlet NSButton *purchaseLicenseButton; 14 | @property (weak) IBOutlet NSTextField *licenseKeyTextField; 15 | 16 | - (IBAction)validateButtonClicked:(id)sender; 17 | - (IBAction)purchaseLicenseButtonClicked:(id)sender; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Vagrant Manager/RegisterWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // RegisterWindow.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "RegisterWindow.h" 9 | #import "Environment.h" 10 | 11 | @interface RegisterWindow () 12 | 13 | @end 14 | 15 | @implementation RegisterWindow 16 | 17 | - (id)initWithWindow:(NSWindow *)window 18 | { 19 | self = [super initWithWindow:window]; 20 | if (self) { 21 | // Initialization code here. 22 | } 23 | return self; 24 | } 25 | 26 | - (void)windowDidLoad { 27 | [super windowDidLoad]; 28 | } 29 | 30 | - (IBAction)validateButtonClicked:(id)sender { 31 | Licensing *lic = [Licensing sharedInstance]; 32 | 33 | NSString *licenseKey = [self.licenseKeyTextField stringValue]; 34 | 35 | licenseKey = [licenseKey stringByReplacingOccurrencesOfString:@"-" withString:@""]; 36 | licenseKey = [licenseKey stringByReplacingOccurrencesOfString:@" " withString:@""]; 37 | licenseKey = [licenseKey stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 38 | 39 | NSMutableArray *arr = [[NSMutableArray alloc] init]; 40 | 41 | if([licenseKey length] > 32) { 42 | [arr addObject:[licenseKey substringWithRange:NSMakeRange(0, [licenseKey length] - 32)]]; 43 | [arr addObject:[licenseKey substringWithRange:NSMakeRange([licenseKey length] - 32, 8)]]; 44 | [arr addObject:[licenseKey substringWithRange:NSMakeRange([licenseKey length] - 32 + 8, 8)]]; 45 | [arr addObject:[licenseKey substringWithRange:NSMakeRange([licenseKey length] - 32 + 16, 8)]]; 46 | [arr addObject:[licenseKey substringWithRange:NSMakeRange([licenseKey length] - 32 + 24, 8)]]; 47 | } 48 | 49 | NSString *formattedLicenseKey = [arr componentsJoinedByString:@"-"]; 50 | 51 | if([lic validateLicense:formattedLicenseKey]) { 52 | [lic storeLicenseKey:formattedLicenseKey]; 53 | 54 | NSAlert *alert = [NSAlert alertWithMessageText:@"Thank you for registering!" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@""]; 55 | [alert runModal]; 56 | 57 | [[Util getApp] rebuildMenu:YES]; 58 | 59 | [self close]; 60 | } else { 61 | NSAlert *alert = [NSAlert alertWithMessageText:@"The license key you have entered is invalid." defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@""]; 62 | [alert runModal]; 63 | } 64 | } 65 | 66 | - (IBAction)purchaseLicenseButtonClicked:(id)sender { 67 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[[Environment sharedInstance] buyURL]]]; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Vagrant Manager/RegisterWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 45 | 56 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Vagrant Manager/TaskOutputWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // OutputWindow.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "VirtualMachineInfo.h" 10 | #import "Bookmark.h" 11 | 12 | @interface TaskOutputWindow : NSWindowController 13 | 14 | @property (strong, nonatomic) id target; 15 | @property (strong, nonatomic) NSString *taskCommand; 16 | @property (strong, nonatomic) NSString *taskAction; 17 | @property (strong, nonatomic) NSTask *task; 18 | @property (strong, nonatomic) NSString *windowUUID; 19 | 20 | @property (unsafe_unretained) IBOutlet NSTextView *outputTextView; 21 | @property (weak) IBOutlet NSProgressIndicator *progressBar; 22 | @property (weak) IBOutlet NSTextField *taskCommandLabel; 23 | @property (weak) IBOutlet NSTextField *taskStatusLabel; 24 | @property (weak) IBOutlet NSButton *closeWindowButton; 25 | @property (weak) IBOutlet NSButton *cancelButton; 26 | 27 | - (IBAction)closeButtonClicked:(id)sender; 28 | - (IBAction)cancelButtonClicked:(id)sender; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Vagrant Manager/TaskOutputWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // OutputWindow.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "TaskOutputWindow.h" 9 | #import "AppDelegate.h" 10 | 11 | @interface TaskOutputWindow () { 12 | BOOL _isClosed; 13 | } 14 | 15 | @end 16 | 17 | @implementation TaskOutputWindow 18 | 19 | - (id)initWithWindow:(NSWindow *)window { 20 | self = [super initWithWindow:window]; 21 | 22 | return self; 23 | } 24 | 25 | - (void)windowDidLoad { 26 | [super windowDidLoad]; 27 | 28 | CFUUIDRef uuid = CFUUIDCreate(NULL); 29 | self.windowUUID = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, uuid); 30 | CFRelease(uuid); 31 | 32 | NSPipe *taskOutputPipe = [NSPipe pipe]; 33 | [self.task setStandardInput:[NSFileHandle fileHandleWithNullDevice]]; 34 | [self.task setStandardOutput:taskOutputPipe]; 35 | [self.task setStandardError:taskOutputPipe]; 36 | 37 | //set up Askpass handler for sudo 38 | NSString *askPassPath = [NSBundle pathForResource:@"Askpass" ofType:@"" inDirectory:[[NSBundle mainBundle] bundlePath]]; 39 | NSMutableDictionary *env = [[[NSProcessInfo processInfo] environment] mutableCopy]; 40 | [env setObject:@"NONE" forKey:@"DISPLAY"]; 41 | [env setObject:askPassPath forKey:@"SUDO_ASKPASS"]; 42 | [self.task setEnvironment:env]; 43 | 44 | NSFileHandle *fh = [taskOutputPipe fileHandleForReading]; 45 | [fh waitForDataInBackgroundAndNotify]; 46 | 47 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedOutput:) name:NSFileHandleDataAvailableNotification object:fh]; 48 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskCompletion:) name: NSTaskDidTerminateNotification object:self.task]; 49 | 50 | NSString *name = [self.target isKindOfClass:[VagrantMachine class]] ? [NSString stringWithFormat:@"%@ - %@",((VagrantMachine*)self.target).instance.displayName, ((VagrantMachine*)self.target).name] : ((VagrantInstance*)self.target).displayName; 51 | 52 | self.window.title = [NSString stringWithFormat:@"%@ %@", name, self.taskAction]; 53 | 54 | self.taskCommandLabel.stringValue = self.taskCommand; 55 | self.taskStatusLabel.stringValue = @"Running task..."; 56 | [self.progressBar startAnimation:self]; 57 | 58 | [self.task launch]; 59 | 60 | [[NSNotificationCenter defaultCenter] postNotificationName:@"vagrant-manager.task-started" object:nil userInfo:@{@"target": self.target, @"uuid": self.windowUUID}]; 61 | } 62 | 63 | - (void)taskCompletion:(NSNotification*)notif { 64 | NSTask *task = [notif object]; 65 | 66 | [self.progressBar stopAnimation:self]; 67 | [self.progressBar setIndeterminate:NO]; 68 | [self.progressBar setDoubleValue:self.progressBar.maxValue]; 69 | 70 | NSButton *closeButton = [self.window standardWindowButton:NSWindowCloseButton]; 71 | [closeButton setEnabled:YES]; 72 | 73 | [self.closeWindowButton setEnabled:YES]; 74 | [self.cancelButton setHidden:YES]; 75 | 76 | NSString *notificationText; 77 | 78 | if(task.terminationStatus != 0) { 79 | self.taskStatusLabel.stringValue = @"Completed with errors"; 80 | notificationText = @"Task completed with errors"; 81 | [self showWindow:[Util getApp]]; 82 | } else { 83 | self.taskStatusLabel.stringValue = @"Completed successfully"; 84 | notificationText = @"Task completed successfully"; 85 | } 86 | 87 | NSString *name = [self.target isKindOfClass:[VagrantMachine class]] ? [NSString stringWithFormat:@"%@ - %@",((VagrantMachine*)self.target).instance.displayName, ((VagrantMachine*)self.target).name] : ((VagrantInstance*)self.target).displayName; 88 | 89 | [[Util getApp] showUserNotificationWithTitle:notificationText informativeText:[NSString stringWithFormat:@"%@ %@", name, self.taskAction] taskWindowUUID:self.windowUUID]; 90 | 91 | //notify app task is complete 92 | [[NSNotificationCenter defaultCenter] postNotificationName:@"vagrant-manager.task-completed" object:nil userInfo:@{@"target": self.target, @"uuid": self.windowUUID}]; 93 | 94 | if(([[NSUserDefaults standardUserDefaults] boolForKey:@"autoCloseTaskWindows"] || [[NSUserDefaults standardUserDefaults] boolForKey:@"hideTaskWindows"]) && task.terminationStatus == 0) { 95 | dispatch_async(dispatch_get_global_queue(0,0), ^{ 96 | [self close]; 97 | }); 98 | } 99 | } 100 | 101 | - (void)windowWillClose:(NSNotification *)notification { 102 | AppDelegate *app = [Util getApp]; 103 | 104 | @synchronized(self) { 105 | _isClosed = YES; 106 | } 107 | 108 | [app removeOpenWindow:self]; 109 | } 110 | 111 | - (void)receivedOutput:(NSNotification*)notif { 112 | NSFileHandle *fh = [notif object]; 113 | NSData *data = [fh availableData]; 114 | NSString *str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 115 | 116 | @synchronized(self) { 117 | if (!_isClosed) { 118 | //smart scrolling logic for command output 119 | BOOL scroll = (NSMaxY(self.outputTextView.visibleRect) == NSMaxY(self.outputTextView.bounds)); 120 | [self.outputTextView.textStorage appendAttributedString:[[NSAttributedString alloc] initWithString:str attributes:@{NSForegroundColorAttributeName: NSColor.controlTextColor}]]; 121 | if([NSFont fontWithName:@"Menlo" size:11]) { 122 | [self.outputTextView.textStorage setFont:[NSFont fontWithName:@"Menlo" size:11]]; 123 | } 124 | if (scroll) { 125 | [self.outputTextView scrollRangeToVisible: NSMakeRange(self.outputTextView.string.length, 0)]; 126 | } 127 | 128 | if(self.task.isRunning) { 129 | [fh waitForDataInBackgroundAndNotify]; 130 | } 131 | } 132 | } 133 | } 134 | 135 | - (IBAction)closeButtonClicked:(id)sender { 136 | [self close]; 137 | } 138 | 139 | - (IBAction)cancelButtonClicked:(id)sender { 140 | [NSApp activateIgnoringOtherApps:YES]; 141 | NSAlert *confirmAlert = [NSAlert alertWithMessageText:@"Are you sure you want to cancel the running task?" defaultButton:@"Confirm" alternateButton:@"Cancel" otherButton:nil informativeTextWithFormat:@""]; 142 | [confirmAlert.window makeKeyWindow]; 143 | NSInteger button = [confirmAlert runModal]; 144 | 145 | if(button == NSAlertDefaultReturn) { 146 | [self.task interrupt]; 147 | } 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /Vagrant Manager/TaskOutputWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 54 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 92 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /Vagrant Manager/Util.h: -------------------------------------------------------------------------------- 1 | // 2 | // Util.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "AppDelegate.h" 10 | 11 | @interface Util : NSObject 12 | 13 | + (AppDelegate*)getApp; 14 | + (NSString*)escapeShellArg:(NSString*)arg; 15 | + (NSString*)trimTrailingSlash:(NSString*)path; 16 | + (NSComparisonResult)compareVersion:(NSString*)version1 toVersion:(NSString*)version2; 17 | + (void)redirectConsoleLogToDocumentFolder; 18 | + (void)log:(NSObject*)message; 19 | + (NSString*)getMachineId; 20 | + (NSString*)getUpdateStability; 21 | + (NSString*)getVersionStability:(NSString*)version; 22 | + (int)getUpdateStabilityScore:(NSString*)updateStability; 23 | + (BOOL)shouldSendProfileData; 24 | @end 25 | -------------------------------------------------------------------------------- /Vagrant Manager/Util.m: -------------------------------------------------------------------------------- 1 | // 2 | // Util.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "Util.h" 9 | 10 | @implementation Util 11 | 12 | + (AppDelegate*)getApp { 13 | return (AppDelegate*)[[NSApplication sharedApplication] delegate]; 14 | } 15 | 16 | + (NSString*)escapeShellArg:(NSString*)arg { 17 | NSMutableString *result = [NSMutableString stringWithString:arg]; 18 | [result replaceOccurrencesOfString:@"'" withString:@"'\\''" options:0 range:NSMakeRange(0, [result length])]; 19 | [result insertString:@"'" atIndex:0]; 20 | [result appendString:@"'"]; 21 | return result; 22 | } 23 | 24 | + (NSString*)trimTrailingSlash:(NSString*)path { 25 | if(path.length > 1 && [[path substringFromIndex:path.length-1] isEqualToString:@"/"]) { 26 | return [path substringToIndex:path.length-1]; 27 | } else { 28 | return path; 29 | } 30 | } 31 | 32 | + (NSComparisonResult)compareVersion:(NSString*)version1 toVersion:(NSString*)version2 { 33 | if(!version1 || !version2) { 34 | //if either version is nil, don't upgrade 35 | return NSOrderedDescending; 36 | } 37 | 38 | return [self compareVersion:version1 toVersion:version2 skipExpansion:NO]; 39 | } 40 | 41 | + (NSComparisonResult)compareVersion:(NSString*)version1 toVersion:(NSString*)version2 skipExpansion:(BOOL)skipExpansion { 42 | if(!version1 || !version2) { 43 | //if either version is nil, don't upgrade 44 | return NSOrderedDescending; 45 | } 46 | 47 | NSMutableArray *version1parts = [[version1 componentsSeparatedByString:@"."] mutableCopy]; 48 | NSMutableArray *version2parts = [[version2 componentsSeparatedByString:@"."] mutableCopy]; 49 | 50 | int partsCount = (version1parts.count > version2parts.count) ? (int)version1parts.count : (int)version2parts.count; 51 | 52 | while(version1parts.count < partsCount) { 53 | [version1parts addObject:@"0"]; 54 | } 55 | 56 | while(version2parts.count < partsCount) { 57 | [version2parts addObject:@"0"]; 58 | } 59 | 60 | for(int i=0; i p2) { 67 | res = NSOrderedDescending; 68 | } else if(p1 < p2) { 69 | res = NSOrderedAscending; 70 | } else { 71 | res = NSOrderedSame; 72 | } 73 | } else { 74 | res = [self compareVersionPart:[version1parts objectAtIndex:i] toVersionPart:[version2parts objectAtIndex:i]]; 75 | } 76 | 77 | if(res != NSOrderedSame) { 78 | return res; 79 | } 80 | } 81 | 82 | return NSOrderedSame; 83 | } 84 | 85 | + (NSComparisonResult)compareVersionPart:(NSString*)part1 toVersionPart:(NSString*)part2 { 86 | NSArray *alphas = @[ 87 | @"RC", 88 | @"beta", 89 | @"b", 90 | @"alpha", 91 | @"a", 92 | @"debug", 93 | @"d" 94 | ]; 95 | 96 | for(int i=0; i 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | Configuration 26 | ${CONFIGURATION} 27 | LSApplicationCategoryType 28 | public.app-category.developer-tools 29 | LSMinimumSystemVersion 30 | ${MACOSX_DEPLOYMENT_TARGET} 31 | LSUIElement 32 | 33 | NSAppTransportSecurity 34 | 35 | NSAllowsArbitraryLoads 36 | 37 | 38 | NSAppleEventsUsageDescription 39 | This app uses apple events to communicate with terminal applications 40 | NSHumanReadableCopyright 41 | Copyright © 2014 Lanayo Technology 42 | NSMainNibFile 43 | MainMenu 44 | NSPrincipalClass 45 | NSApplication 46 | NSSupportsSuddenTermination 47 | 48 | SUFeedURL 49 | https://api.lanayo.com/appcast/vagrant_manager.xml 50 | SUPublicDSAKeyFile 51 | dsa_pub.pem 52 | 53 | 54 | -------------------------------------------------------------------------------- /Vagrant Manager/Vagrant Manager-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #import "Util.h" 10 | #endif -------------------------------------------------------------------------------- /Vagrant Manager/VagrantGlobalStatusScanner.h: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantGlobalStatusScanner.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface VagrantGlobalStatusScanner : NSObject 11 | 12 | - (NSArray*)getInstancePaths; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Vagrant Manager/VagrantGlobalStatusScanner.m: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantGlobalStatusScanner.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VagrantGlobalStatusScanner.h" 9 | 10 | @implementation VagrantGlobalStatusScanner 11 | 12 | //find vagrant instances listed in the vagrant global-status command output 13 | - (NSArray*)getInstancePaths { 14 | NSMutableArray *paths = [[NSMutableArray alloc] init]; 15 | 16 | //get output of vagrant global-status 17 | NSTask *task = [[NSTask alloc] init]; 18 | [task setLaunchPath:@"/bin/bash"]; 19 | [task setArguments:@[@"-l", @"-c", @"vagrant global-status"]]; 20 | 21 | NSPipe *pipe = [NSPipe pipe]; 22 | [task setStandardInput:[NSPipe pipe]]; 23 | [task setStandardOutput:pipe]; 24 | 25 | [task launch]; 26 | [task waitUntilExit]; 27 | 28 | if(task.terminationStatus == 0) { 29 | //parse instance info from global-status output 30 | NSData *outputData = [[pipe fileHandleForReading] readDataToEndOfFile]; 31 | NSString *outputString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; 32 | 33 | //search for machine state in output string 34 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\/.*)(\\n|$)" options:0 error:NULL]; 35 | NSArray *matches = [regex matchesInString:outputString options:0 range:NSMakeRange(0, [outputString length])]; 36 | for(NSTextCheckingResult *match in matches) { 37 | //NSRange idRange = [match rangeAtIndex:1]; 38 | //NSRange nameRange = [match rangeAtIndex:2]; 39 | //NSRange providerRange = [match rangeAtIndex:3]; 40 | //NSRange stateRange = [match rangeAtIndex:4]; 41 | NSRange pathRange = [match rangeAtIndex:5]; 42 | 43 | NSString *path = [[outputString substringWithRange:pathRange] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 44 | 45 | BOOL vagrantFileExists = [[NSFileManager defaultManager] fileExistsAtPath:[NSString pathWithComponents:@[path, @"/Vagrantfile"]]]; 46 | 47 | if(vagrantFileExists) { 48 | [paths addObject:path]; 49 | } 50 | } 51 | } 52 | 53 | return [NSArray arrayWithArray:paths]; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Vagrant Manager/VagrantInstance.h: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantInstance.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | #import "VagrantMachine.h" 11 | 12 | @interface VagrantInstance : NSObject 13 | 14 | @property (readonly) NSString *path; 15 | @property (readonly) NSString *displayName; 16 | @property (readonly) NSArray *machines; 17 | @property (strong, nonatomic) NSString *providerIdentifier; 18 | 19 | - (id)initWithPath:(NSString*)path providerIdentifier:(NSString*)providerIdentifier; 20 | - (id)initWithPath:(NSString*)path displayName:(NSString*)displayName providerIdentifier:(NSString*)providerIdentifier; 21 | 22 | - (VagrantMachine*)getMachineWithName:(NSString*)name; 23 | - (void)queryMachines; 24 | - (int)getRunningMachineCount; 25 | - (int)getMachineCountWithState:(VagrantMachineState)state; 26 | - (BOOL)hasVagrantfile; 27 | - (NSString*)getVagrantfilePath; 28 | 29 | - (NSString*)getPath; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Vagrant Manager/VagrantInstance.m: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantInstance.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VagrantInstance.h" 9 | 10 | @implementation VagrantInstance { 11 | NSString *_path; 12 | NSString *_displayName; 13 | NSMutableArray *_machines; 14 | } 15 | 16 | - (id)initWithPath:(NSString*)path displayName:(NSString*)displayName providerIdentifier:(NSString*)providerIdentifier { 17 | self = [self initWithPath:path providerIdentifier:providerIdentifier]; 18 | 19 | if(self) { 20 | _displayName = displayName; 21 | } 22 | 23 | return self; 24 | } 25 | 26 | - (id)initWithPath:(NSString*)path providerIdentifier:(NSString*)providerIdentifier { 27 | self = [super init]; 28 | 29 | if(self) { 30 | //provider identifier not passed in, try to determine it 31 | if(!providerIdentifier || [providerIdentifier length] == 0) { 32 | providerIdentifier = [[VagrantManager sharedManager] detectVagrantProvider:path]; 33 | } 34 | _path = path; 35 | self.providerIdentifier = providerIdentifier; 36 | 37 | //get display name based on last part of path 38 | NSArray *parts = [path componentsSeparatedByString:@"/"]; 39 | _displayName = [[parts lastObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 40 | if(_displayName.length < 1) { 41 | _displayName = @"Unknown"; 42 | } 43 | 44 | _machines = [[NSMutableArray alloc] init]; 45 | } 46 | 47 | return self; 48 | } 49 | 50 | - (NSString*)getPath { 51 | return _path; 52 | } 53 | 54 | - (NSString*)getDisplayName { 55 | return _displayName; 56 | } 57 | 58 | - (int)getRunningMachineCount { 59 | int runningCount = 0; 60 | for(VagrantMachine *machine in _machines) { 61 | if(machine.state == RunningState) { 62 | ++runningCount; 63 | } 64 | } 65 | 66 | return runningCount; 67 | } 68 | 69 | - (BOOL)hasVagrantfile { 70 | return [self getVagrantfilePath]!=nil; 71 | } 72 | 73 | - (NSString*)getVagrantfilePath { 74 | NSString *filePath = [NSString stringWithFormat:@"%@/Vagrantfile", _path]; 75 | 76 | if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { 77 | return filePath; 78 | } else { 79 | return nil; 80 | } 81 | } 82 | 83 | - (VagrantMachine*)getMachineWithName:(NSString*)name { 84 | for(VagrantMachine *machine in _machines) { 85 | if([machine.name isEqualToString:name]) { 86 | return machine; 87 | } 88 | } 89 | 90 | return nil; 91 | } 92 | 93 | //queries to state of all machines in this instance 94 | - (void)queryMachines { 95 | NSMutableArray *machines = [[NSMutableArray alloc] init]; 96 | 97 | if([self hasVagrantfile]) { 98 | //get output of vagrant status 99 | NSTask *task = [[NSTask alloc] init]; 100 | [task setLaunchPath:@"/bin/bash"]; 101 | [task setArguments:@[@"-l", @"-c", [NSString stringWithFormat:@"cd %@; vagrant status", [Util escapeShellArg:_path]]]]; 102 | 103 | NSPipe *pipe = [NSPipe pipe]; 104 | [task setStandardInput:[NSPipe pipe]]; 105 | [task setStandardOutput:pipe]; 106 | 107 | [task launch]; 108 | [task waitUntilExit]; 109 | 110 | if(task.terminationStatus == 0) { 111 | NSData *outputData = [[pipe fileHandleForReading] readDataToEndOfFile]; 112 | NSString *outputString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; 113 | 114 | //search for machine state in output string 115 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"([\\w-_\\.]+)\\s+([\\w\\s]+) \\(\\w+\\)" options:0 error:NULL]; 116 | NSArray *matches = [regex matchesInString:outputString options:0 range:NSMakeRange(0, [outputString length])]; 117 | for(NSTextCheckingResult *match in matches) { 118 | NSRange nameRange = [match rangeAtIndex:1]; 119 | NSRange stateRange = [match rangeAtIndex:2]; 120 | 121 | NSString *name = [[outputString substringWithRange:nameRange] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 122 | NSString *stateString = [[outputString substringWithRange:stateRange] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 123 | 124 | VagrantMachine *machine = [[VagrantMachine alloc] initWithInstance:self name:name state:UnknownState]; 125 | machine.stateString = stateString; 126 | [machines addObject:machine]; 127 | } 128 | } 129 | } 130 | 131 | _machines = machines; 132 | } 133 | 134 | - (NSArray*)getMachines { 135 | return [NSArray arrayWithArray:_machines]; 136 | } 137 | 138 | - (int)getMachineCountWithState:(VagrantMachineState)state { 139 | int count = 0; 140 | 141 | for(VagrantMachine *machine in _machines) { 142 | if(machine.state == state) { 143 | count++; 144 | } 145 | } 146 | 147 | return count; 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /Vagrant Manager/VagrantInstanceCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantInstanceCache.h 3 | // Vagrant Manager 4 | // 5 | // Copyright © 2019 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface VagrantInstanceCache : NSObject 13 | 14 | + (void)cacheInstance:(VagrantInstance*)instance; 15 | + (VagrantInstance*)restoreCachedInstance:(VagrantInstance*)instance; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Vagrant Manager/VagrantInstanceCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantInstanceCache.m 3 | // Vagrant Manager 4 | // 5 | // Copyright © 2019 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VagrantInstanceCache.h" 9 | 10 | NSString * const USER_DEFAULTS_CACHE_KEY = @"vagrant-instance-cache"; 11 | NSString * const VAGRANT_INSTANCE_PROVIDER_IDENTIFIER_KEY = @"providerIdentifier"; 12 | 13 | @implementation VagrantInstanceCache 14 | 15 | + (void)cacheInstance:(VagrantInstance*)instance { 16 | @synchronized(self) { 17 | NSMutableDictionary *cache = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:USER_DEFAULTS_CACHE_KEY] mutableCopy] ?: [@{} mutableCopy]; 18 | NSMutableDictionary *existingCache = [[self cacheForPath:instance.path] mutableCopy] ?: [@{} mutableCopy]; 19 | 20 | existingCache[VAGRANT_INSTANCE_PROVIDER_IDENTIFIER_KEY] = instance.providerIdentifier; 21 | [cache setObject:existingCache forKey:instance.path]; 22 | 23 | [[NSUserDefaults standardUserDefaults] setObject:cache forKey:USER_DEFAULTS_CACHE_KEY]; 24 | [[NSUserDefaults standardUserDefaults] synchronize]; 25 | } 26 | } 27 | 28 | + (NSDictionary * _Nullable)cacheForPath:(NSString*)path { 29 | NSDictionary *cache = [[NSUserDefaults standardUserDefaults] dictionaryForKey:USER_DEFAULTS_CACHE_KEY]; 30 | return [cache objectForKey:path]; 31 | } 32 | 33 | + (VagrantInstance*)restoreCachedInstance:(VagrantInstance*)instance { 34 | NSDictionary *cache = [[NSUserDefaults standardUserDefaults] dictionaryForKey:USER_DEFAULTS_CACHE_KEY]; 35 | NSDictionary *instanceCache = [cache objectForKey:instance.path]; 36 | 37 | instance.providerIdentifier = [instanceCache objectForKey:VAGRANT_INSTANCE_PROVIDER_IDENTIFIER_KEY] ?: instance.providerIdentifier; 38 | 39 | return instance; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Vagrant Manager/VagrantMachine.h: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantMachine.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @class VagrantInstance; 11 | 12 | typedef enum { 13 | UnknownState, 14 | NotCreatedState, 15 | PowerOffState, 16 | SavedState, 17 | RunningState, 18 | RestoringState 19 | } VagrantMachineState; 20 | 21 | @interface VagrantMachine : NSObject 22 | 23 | @property (weak) VagrantInstance *instance; 24 | @property (strong) NSString *name; 25 | @property (nonatomic) VagrantMachineState state; 26 | @property (strong, nonatomic) NSString *stateString; 27 | 28 | - (id)initWithInstance:(VagrantInstance*)instance name:(NSString*)name state:(VagrantMachineState)state; 29 | 30 | + (NSString*)getStringForState:(VagrantMachineState)state; 31 | + (VagrantMachineState)getStateForString:(NSString*)stateString; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Vagrant Manager/VagrantMachine.m: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantMachine.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VagrantMachine.h" 9 | 10 | @implementation VagrantMachine 11 | 12 | - (id)initWithInstance:(VagrantInstance*)instance name:(NSString*)name state:(VagrantMachineState)state { 13 | self = [super init]; 14 | 15 | if(self) { 16 | self.instance = instance; 17 | self.name = name; 18 | _state = state; 19 | _stateString = [VagrantMachine getStringForState:state]; 20 | } 21 | 22 | return self; 23 | } 24 | 25 | + (NSString*)getStringForState:(VagrantMachineState)state { 26 | if(state == NotCreatedState) { 27 | return @"not created"; 28 | } else if(state == PowerOffState) { 29 | return @"poweroff"; 30 | } else if(state == SavedState) { 31 | return @"saved"; 32 | } else if(state == RunningState) { 33 | return @"running"; 34 | } else if(state == RestoringState) { 35 | return @"restoring"; 36 | } else { 37 | return @"unknown"; 38 | } 39 | } 40 | 41 | + (VagrantMachineState)getStateForString:(NSString*)stateString { 42 | if([stateString isEqualToString:@"not created"]) { 43 | return NotCreatedState; 44 | } else if([stateString isEqualToString:@"poweroff"]) { 45 | return PowerOffState; 46 | } else if([stateString isEqualToString:@"saved"]) { 47 | return SavedState; 48 | } else if([stateString isEqualToString:@"running"]) { 49 | return RunningState; 50 | } else if([stateString isEqualToString:@"restoring"]) { 51 | return RestoringState; 52 | } else { 53 | return UnknownState; 54 | } 55 | } 56 | 57 | - (void)setStateString:(NSString*)stateString { 58 | _stateString = stateString; 59 | _state = [VagrantMachine getStateForString:stateString]; 60 | } 61 | 62 | - (VagrantMachineState)getState { 63 | return _state; 64 | } 65 | 66 | - (void)setState:(VagrantMachineState)state { 67 | _state = state; 68 | _stateString = [VagrantMachine getStringForState:state]; 69 | } 70 | 71 | - (NSString*)getStateString { 72 | return _stateString; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /Vagrant Manager/VagrantManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantInstanceCollection.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "VagrantInstance.h" 10 | #import "Bookmark.h" 11 | #import "VirtualMachineServiceProvider.h" 12 | 13 | @class VagrantManager; 14 | 15 | @protocol VagrantManagerDelegate 16 | 17 | - (void)vagrantManager:(VagrantManager*)vagrantManger instanceAdded:(VagrantInstance*)instance; 18 | - (void)vagrantManager:(VagrantManager*)vagrantManger instanceRemoved:(VagrantInstance*)instance; 19 | - (void)vagrantManager:(VagrantManager*)vagrantManger instanceUpdated:(VagrantInstance*)oldInstance withInstance:(VagrantInstance*)newInstance; 20 | 21 | @end 22 | 23 | @interface VagrantManager : NSObject 24 | 25 | @property (weak) id delegate; 26 | 27 | @property (readonly) NSArray *instances; 28 | 29 | + (VagrantManager*)sharedManager; 30 | 31 | - (NSArray*)getMachinesWithState:(VagrantMachineState)state; 32 | - (void)registerServiceProvider:(id)provider; 33 | - (void)refreshInstances; 34 | - (VagrantInstance*)getInstanceForPath:(NSString*)path; 35 | - (int)getRunningVmCount; 36 | - (NSString*)detectVagrantProvider:(NSString*)path; 37 | - (NSArray*)getProviderIdentifiers; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Vagrant Manager/VagrantManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // VagrantInstanceCollection.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VagrantManager.h" 9 | #import "NFSScanner.h" 10 | #import "VagrantGlobalStatusScanner.h" 11 | #import "BookmarkManager.h" 12 | #import "CustomProviderManager.h" 13 | #import "VagrantInstanceCache.h" 14 | 15 | @implementation VagrantManager { 16 | //all known vagrant instances 17 | NSMutableArray *_instances; 18 | 19 | //map provider identifiers to providers 20 | NSMutableDictionary *_providers; 21 | 22 | //this is the first time the machines are being refreshed 23 | BOOL _isFirstRefresh; 24 | } 25 | 26 | + (VagrantManager*)sharedManager { 27 | static VagrantManager *manager; 28 | @synchronized(self) { 29 | if(manager == nil) { 30 | manager = [[VagrantManager alloc] init]; 31 | } 32 | } 33 | 34 | return manager; 35 | } 36 | 37 | - (id)init { 38 | self = [super init]; 39 | 40 | if(self) { 41 | _instances = [[NSMutableArray alloc] init]; 42 | _providers = [[NSMutableDictionary alloc] init]; 43 | _isFirstRefresh = YES; 44 | } 45 | 46 | return self; 47 | } 48 | 49 | //get all instances 50 | - (NSArray*)getInstances { 51 | return [NSArray arrayWithArray:_instances]; 52 | } 53 | 54 | //get count of machines in running state 55 | - (int)getRunningVmCount { 56 | int count = 0; 57 | 58 | @synchronized(_instances) { 59 | for(VagrantInstance *instance in _instances) { 60 | for(VagrantMachine *machine in instance.machines) { 61 | if(machine.state == RunningState) { 62 | ++count; 63 | } 64 | } 65 | } 66 | } 67 | 68 | return count; 69 | } 70 | 71 | //get count of machines in a particular state 72 | - (NSArray*)getMachinesWithState:(VagrantMachineState)state { 73 | NSMutableArray *machines = [[NSMutableArray alloc] init]; 74 | for(VagrantInstance *instance in _instances) { 75 | for(VagrantMachine *machine in instance.machines) { 76 | if(machine.state == state) { 77 | [machines addObject:machine]; 78 | } 79 | } 80 | } 81 | 82 | return machines; 83 | } 84 | 85 | //register a new service provider 86 | - (void)registerServiceProvider:(id)provider { 87 | [_providers setObject:provider forKey:[provider getProviderIdentifier]]; 88 | } 89 | 90 | //get instance at a particular path 91 | - (VagrantInstance*)getInstanceForPath:(NSString*)path { 92 | path = [Util trimTrailingSlash:path]; 93 | 94 | for(VagrantInstance *instance in _instances) { 95 | if([instance.path isEqualToString:path]) { 96 | return instance; 97 | } 98 | } 99 | 100 | return nil; 101 | } 102 | 103 | //refresh list of instances by querying bookmarks, service providers, and NFS 104 | - (void)refreshInstances { 105 | NSMutableArray *instances = [[NSMutableArray alloc] init]; 106 | 107 | BookmarkManager *bookmarkManager = [BookmarkManager sharedManager]; 108 | 109 | //create instance for each bookmark 110 | NSMutableArray *bookmarks = [[BookmarkManager sharedManager] getBookmarks]; 111 | for(Bookmark *bookmark in bookmarks) { 112 | [instances addObject:[[VagrantInstance alloc] initWithPath:bookmark.path displayName:bookmark.displayName providerIdentifier:bookmark.providerIdentifier]]; 113 | } 114 | 115 | NSMutableArray *allPaths = [[NSMutableArray alloc] init]; 116 | 117 | //scan for NFS exports 118 | NFSScanner *nfsScanner = [[NFSScanner alloc] init]; 119 | for(NSString *path in [nfsScanner getNFSInstancePaths]) { 120 | //make sure it is not a bookmark and has not already been detected 121 | if(![bookmarkManager getBookmarkWithPath:path] && ![allPaths containsObject:path]) { 122 | [allPaths addObject:path]; 123 | [instances addObject:[[VagrantInstance alloc] initWithPath:path providerIdentifier:nil]]; 124 | } 125 | } 126 | 127 | //scan vagrant global-status output 128 | VagrantGlobalStatusScanner *globalStatusScanner = [[VagrantGlobalStatusScanner alloc] init]; 129 | for(NSString *path in [globalStatusScanner getInstancePaths]) { 130 | //make sure it is not a bookmark and has not already been detected 131 | if(![bookmarkManager getBookmarkWithPath:path] && ![allPaths containsObject:path]) { 132 | [allPaths addObject:path]; 133 | [instances addObject:[[VagrantInstance alloc] initWithPath:path providerIdentifier:nil]]; 134 | } 135 | } 136 | 137 | if ([[NSUserDefaults standardUserDefaults] boolForKey:@"useProviderMachineDetection"]) { 138 | //create instance for each detected path 139 | NSDictionary *detectedPaths = [self detectInstancePaths]; 140 | for(NSString *providerIdentifier in [detectedPaths allKeys]) { 141 | NSArray *paths = [detectedPaths objectForKey:providerIdentifier]; 142 | for(NSString *path in paths) { 143 | //make sure it is not a bookmark and has not already been detected 144 | if(![bookmarkManager getBookmarkWithPath:path] && ![allPaths containsObject:path]) { 145 | [allPaths addObject:path]; 146 | [instances addObject:[[VagrantInstance alloc] initWithPath:path providerIdentifier:providerIdentifier]]; 147 | } 148 | } 149 | } 150 | } 151 | 152 | //TODO: implement "last seen" functionality. Store paths of previously seen Vagrantfiles and check if they still exist 153 | 154 | NSMutableArray *validPaths = [[NSMutableArray alloc] init]; 155 | 156 | //query all known instances for machines, process in parallel 157 | dispatch_group_t queryMachinesGroup = dispatch_group_create(); 158 | dispatch_queue_t queryMachinesQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 159 | for(VagrantInstance *instance in instances) { 160 | dispatch_group_async(queryMachinesGroup, queryMachinesQueue, ^{ 161 | [VagrantInstanceCache restoreCachedInstance:instance]; 162 | 163 | //query instance machines 164 | [instance queryMachines]; 165 | 166 | @synchronized(_instances) { 167 | VagrantInstance *existingInstance = [self getInstanceForPath:instance.path]; 168 | if(existingInstance) { 169 | //instance already exists, check for changes 170 | int idx = (int)[_instances indexOfObject:existingInstance]; 171 | if(instance.machines.count != existingInstance.machines.count || ![existingInstance.displayName isEqualToString:instance.displayName] || ![existingInstance.providerIdentifier isEqualToString:instance.providerIdentifier]) { 172 | //instance has updated 173 | [_instances replaceObjectAtIndex:idx withObject:instance]; 174 | [self.delegate vagrantManager:self instanceUpdated:existingInstance withInstance:instance]; 175 | } else { 176 | for(VagrantMachine *machine in instance.machines) { 177 | VagrantMachine *existingMachine = [existingInstance getMachineWithName:machine.name]; 178 | 179 | if(!existingMachine || ![existingMachine.stateString isEqualToString:machine.stateString]) { 180 | //machine did not exist, or state has changed 181 | [_instances replaceObjectAtIndex:idx withObject:instance]; 182 | [self.delegate vagrantManager:self instanceUpdated:existingInstance withInstance:instance]; 183 | } 184 | } 185 | } 186 | } else { 187 | //new instance 188 | [_instances addObject:instance]; 189 | [self.delegate vagrantManager:self instanceAdded:instance]; 190 | } 191 | 192 | //add path to list for pruning stale instances 193 | [validPaths addObject:instance.path]; 194 | } 195 | }); 196 | } 197 | 198 | //wait for the machine queries to finish 199 | dispatch_group_wait(queryMachinesGroup, DISPATCH_TIME_FOREVER); 200 | 201 | for(int i=(int)_instances.count-1; i>=0; --i) { 202 | VagrantInstance *instance = [_instances objectAtIndex:i]; 203 | if(![validPaths containsObject:instance.path]) { 204 | [_instances removeObjectAtIndex:i]; 205 | [self.delegate vagrantManager:self instanceRemoved:instance]; 206 | 207 | //TODO: "last seen" functionality may have to be implemented here as well so that this instance doesn't disappear from the list during this pass 208 | } else { 209 | if(_isFirstRefresh) { 210 | Bookmark *bookmark = [[BookmarkManager sharedManager] getBookmarkWithPath:instance.path]; 211 | 212 | if(bookmark && bookmark.launchOnStartup) { 213 | dispatch_async(dispatch_get_main_queue(), ^{ 214 | [[Util getApp] performVagrantAction:@"up" withInstance:instance]; 215 | }); 216 | } 217 | } 218 | } 219 | } 220 | 221 | _isFirstRefresh = NO; 222 | } 223 | 224 | //query all service providers for instances 225 | - (NSDictionary*)detectInstancePaths { 226 | NSMutableArray *allPaths = [[NSMutableArray alloc] init]; 227 | NSMutableDictionary *keyedPaths = [[NSMutableDictionary alloc] init]; 228 | 229 | //find Vagrant instances for each registered provider 230 | for(id provider in [_providers allValues]) { 231 | NSArray *paths = [provider getVagrantInstancePaths]; 232 | NSMutableArray *uniquePaths = [[NSMutableArray alloc] init]; 233 | //make sure we haven't already detected this path 234 | for(NSString *path in paths) { 235 | NSString *p = [Util trimTrailingSlash:path]; 236 | if(![allPaths containsObject:p]) { 237 | [allPaths addObject:p]; 238 | [uniquePaths addObject:p]; 239 | } 240 | } 241 | [keyedPaths setObject:uniquePaths forKey:[provider getProviderIdentifier]]; 242 | } 243 | 244 | return [NSDictionary dictionaryWithDictionary:keyedPaths]; 245 | } 246 | 247 | //try to determine the vagrant provider for an instance 248 | - (NSString*)detectVagrantProvider:(NSString*)path { 249 | NSFileManager *fileManager = [NSFileManager defaultManager]; 250 | NSError *error = nil; 251 | NSArray *machinePaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSString stringWithFormat:@"%@/.vagrant/machines", path] error:&error]; 252 | 253 | // check for virtual machine id 254 | if(!error && machinePaths) { 255 | for(NSString *machinePath in machinePaths) { 256 | for(NSString *providerIdentifier in [self getProviderIdentifiers]) { 257 | if([fileManager fileExistsAtPath:[NSString stringWithFormat:@"%@/.vagrant/machines/%@/%@/id", path, machinePath, providerIdentifier]]) { 258 | return providerIdentifier; 259 | } 260 | } 261 | } 262 | } 263 | 264 | // no virtual machine id, check for just an existing provider folder as a fallback 265 | if(!error && machinePaths) { 266 | for(NSString *machinePath in machinePaths) { 267 | for(NSString *providerIdentifier in [self getProviderIdentifiers]) { 268 | if([fileManager fileExistsAtPath:[NSString stringWithFormat:@"%@/.vagrant/machines/%@/%@", path, machinePath, providerIdentifier]]) { 269 | return providerIdentifier; 270 | } 271 | } 272 | } 273 | } 274 | 275 | return @"virtualbox"; 276 | } 277 | 278 | - (NSArray*)getProviderIdentifiers { 279 | NSMutableArray *providerIdentifiers = [NSMutableArray arrayWithArray:[_providers allKeys]]; 280 | [providerIdentifiers addObject:@"vmware_workstation"]; 281 | [providerIdentifiers addObject:@"vmware_desktop"]; 282 | [providerIdentifiers addObject:@"vmware_fusion"]; 283 | [providerIdentifiers addObject:@"docker"]; 284 | for (CustomProvider* cp in [[CustomProviderManager sharedManager] getCustomProviders]) { 285 | [providerIdentifiers addObject:cp.name]; 286 | } 287 | return providerIdentifiers; 288 | } 289 | 290 | @end 291 | -------------------------------------------------------------------------------- /Vagrant Manager/VersionComparison.h: -------------------------------------------------------------------------------- 1 | // 2 | // VersionComparison.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface VersionComparison : NSObject 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Vagrant Manager/VersionComparison.m: -------------------------------------------------------------------------------- 1 | // 2 | // VersionComparison.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VersionComparison.h" 9 | 10 | @implementation VersionComparison 11 | 12 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB { 13 | return [Util compareVersion:versionA toVersion:versionB]; 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Vagrant Manager/VirtualBoxMachineInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualBoxMachineInfo.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | @interface VirtualBoxMachineInfo : NSObject 9 | 10 | @property (strong, nonatomic) NSString *uuid; 11 | @property (strong, nonatomic) NSString *stateString; 12 | @property (strong, nonatomic) NSString *name; 13 | @property (strong, nonatomic) NSString *os; 14 | @property (strong, nonatomic) NSDictionary *sharedFolders; 15 | @property (strong, nonatomic) NSDictionary *properties; 16 | 17 | + (VirtualBoxMachineInfo*)initWithInfo:(NSString*)infoString; 18 | 19 | - (NSString*)getSharedFolderPathWithName:(NSString*)name; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Vagrant Manager/VirtualBoxMachineInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualBoxMachineInfo.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VirtualBoxMachineInfo.h" 9 | 10 | @implementation VirtualBoxMachineInfo 11 | 12 | //get a shared folder based on its name 13 | - (NSString*)getSharedFolderPathWithName:(NSString*)name { 14 | NSString *folder = [self.sharedFolders objectForKey:name]; 15 | if(!folder && [[name substringToIndex:1] isEqualToString:@"/"]) { 16 | folder = [self.sharedFolders objectForKey:[name substringFromIndex:1]]; 17 | } 18 | 19 | return folder; 20 | } 21 | 22 | //parse VirtualBox machine info 23 | + (VirtualBoxMachineInfo*)initWithInfo:(NSString*)infoString { 24 | VirtualBoxMachineInfo *vm = [[VirtualBoxMachineInfo alloc] init]; 25 | 26 | NSArray *infoArray = [infoString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; 27 | 28 | NSMutableDictionary *infoPairs = [[NSMutableDictionary alloc] init]; 29 | 30 | NSMutableDictionary *sharedFolders = [[NSMutableDictionary alloc] init]; 31 | 32 | for(NSString *infoLine in infoArray) { 33 | NSString *name; 34 | NSString *value; 35 | 36 | NSRange equalRange = [infoLine rangeOfString:@"="]; 37 | if(equalRange.length == 0) { 38 | continue; 39 | } 40 | 41 | name = [infoLine substringToIndex:equalRange.location]; 42 | value = [infoLine substringFromIndex:equalRange.location + 1]; 43 | 44 | if(name.length == 0 || value.length == 0) { 45 | continue; 46 | } 47 | 48 | if([[name substringToIndex:1] isEqualToString:@"\""]) { 49 | name = [name substringWithRange:NSMakeRange(1, name.length - 2)]; 50 | } 51 | 52 | if([[value substringToIndex:1] isEqualToString:@"\""]) { 53 | value = [value substringWithRange:NSMakeRange(1, value.length - 2)]; 54 | } 55 | 56 | if([name isEqualToString:@"name"]) { 57 | vm.name = value; 58 | } else if([name isEqualToString:@"ostype"]) { 59 | vm.os = value; 60 | } else if([name isEqualToString:@"UUID"]) { 61 | vm.uuid = value; 62 | } else if([name isEqualToString:@"VMState"]) { 63 | vm.stateString = value; 64 | } else if([name hasPrefix:@"SharedFolderNameMachineMapping"] || [name hasPrefix:@"SharedFolderPathMachineMapping"]) { 65 | NSString *mappingId = [name substringFromIndex:30]; 66 | if(![sharedFolders objectForKey:mappingId]) { 67 | [sharedFolders setObject:[[NSMutableDictionary alloc] init] forKey:mappingId]; 68 | } 69 | if([name hasPrefix:@"SharedFolderNameMachineMapping"]) { 70 | [[sharedFolders objectForKey:mappingId] setObject:value forKey:@"name"]; 71 | } else if([name hasPrefix:@"SharedFolderPathMachineMapping"]) { 72 | [[sharedFolders objectForKey:mappingId] setObject:value forKey:@"path"]; 73 | } 74 | } else { 75 | [infoPairs setObject:value forKey:name]; 76 | } 77 | } 78 | 79 | NSMutableDictionary *validSharedFolders = [[NSMutableDictionary alloc] init]; 80 | for(NSMutableDictionary *sharedFolderKey in sharedFolders) { 81 | NSMutableDictionary *sharedFolder = [sharedFolders objectForKey:sharedFolderKey]; 82 | [validSharedFolders setObject:[sharedFolder objectForKey:@"path"] forKey:[sharedFolder objectForKey:@"name"]]; 83 | } 84 | 85 | vm.properties = [NSDictionary dictionaryWithDictionary:infoPairs]; 86 | vm.sharedFolders = [NSDictionary dictionaryWithDictionary:validSharedFolders]; 87 | 88 | return vm; 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /Vagrant Manager/VirtualBoxServiceProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualBoxServiceProvider.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VirtualBoxMachineInfo.h" 9 | #import "VirtualMachineServiceProvider.h" 10 | 11 | @interface VirtualBoxServiceProvider : NSObject 12 | 13 | @end -------------------------------------------------------------------------------- /Vagrant Manager/VirtualBoxServiceProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualBoxServiceProvider.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VirtualBoxServiceProvider.h" 9 | 10 | @implementation VirtualBoxServiceProvider 11 | 12 | - (NSString*)getProviderIdentifier { 13 | return @"virtualbox"; 14 | } 15 | 16 | //find all vagrant instances that VirtualBox knows about 17 | - (NSArray*)getVagrantInstancePaths { 18 | NSMutableArray *paths = [[NSMutableArray alloc] init]; 19 | 20 | //get all virtual machines UUIDs from VirtualBox 21 | NSArray *uuids = [self getAllVirtualMachineUUIDs]; 22 | 23 | //check each machine by uuid 24 | for(NSString *uuid in uuids) { 25 | //get virtual machine info from VirtualBox 26 | VirtualBoxMachineInfo *machineInfo = [self getVirtualMachineInfoFromUUID:uuid]; 27 | 28 | if(machineInfo) { 29 | //check for path mapped to /vagrant 30 | NSString *instancePath = [Util trimTrailingSlash:[machineInfo getSharedFolderPathWithName:@"/vagrant"]]; 31 | 32 | if(instancePath) { 33 | if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/Vagrantfile", instancePath]] && ![paths containsObject:instancePath]) { 34 | //mapped path found, and not already added to list 35 | [paths addObject:instancePath]; 36 | } 37 | } 38 | } 39 | } 40 | 41 | return paths; 42 | } 43 | 44 | //get machine ids of all VirtualBox VMs 45 | - (NSArray*)getAllVirtualMachineUUIDs { 46 | NSMutableArray *uuids = [[NSMutableArray alloc] init]; 47 | 48 | NSTask *task = [[NSTask alloc] init]; 49 | [task setLaunchPath:@"/bin/bash"]; 50 | 51 | [task setArguments:@[@"-l", @"-c", @"VBoxManage list vms"]]; 52 | 53 | NSPipe *pipe = [NSPipe pipe]; 54 | [task setStandardInput:[NSPipe pipe]]; 55 | [task setStandardOutput:pipe]; 56 | 57 | [task launch]; 58 | [task waitUntilExit]; 59 | 60 | NSData *outputData = [[pipe fileHandleForReading] readDataToEndOfFile]; 61 | NSString *outputString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; 62 | 63 | if(task.terminationStatus == 0) { 64 | //search for machine UUIDs 65 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\"[^\"]+\"\\s+\\{([^\\}]+)\\}" options:0 error:NULL]; 66 | NSArray *matches = [regex matchesInString:outputString options:0 range:NSMakeRange(0, [outputString length])]; 67 | for(NSTextCheckingResult *match in matches) { 68 | NSRange uuidRange = [match rangeAtIndex:1]; 69 | 70 | [uuids addObject:[outputString substringWithRange:uuidRange]]; 71 | } 72 | } 73 | 74 | return [[NSArray alloc] initWithArray:uuids]; 75 | } 76 | 77 | //get machine info for a VirtualBox VM 78 | - (VirtualBoxMachineInfo*)getVirtualMachineInfoFromUUID:(NSString*)uuid { 79 | NSTask *task = [[NSTask alloc] init]; 80 | [task setLaunchPath:@"/bin/bash"]; 81 | [task setArguments:@[@"-l", @"-c", [NSString stringWithFormat:@"VBoxManage showvminfo %@ --machinereadable", uuid]]]; 82 | 83 | NSPipe *pipe = [NSPipe pipe]; 84 | [task setStandardInput:[NSPipe pipe]]; 85 | [task setStandardOutput:pipe]; 86 | 87 | [task launch]; 88 | [task waitUntilExit]; 89 | 90 | NSData *outputData = [[pipe fileHandleForReading] readDataToEndOfFile]; 91 | NSString *outputString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; 92 | 93 | if(task.terminationStatus == 0) { 94 | return [VirtualBoxMachineInfo initWithInfo:outputString]; 95 | } else { 96 | return nil; 97 | } 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /Vagrant Manager/VirtualMachineInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualMachineInfo.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "VirtualMachineServiceProvider.h" 10 | 11 | typedef enum {running,suspended,off} PossibleVmStates; 12 | 13 | @interface VirtualMachineInfo : NSObject 14 | 15 | @property (strong, nonatomic) NSString *uuid; 16 | @property (nonatomic) int state; 17 | @property (strong, nonatomic) NSString *stateString; 18 | @property (strong, nonatomic) NSString *name; 19 | @property (strong, nonatomic) NSString *os; 20 | @property (strong, nonatomic) NSDictionary *sharedFolders; 21 | @property (strong, nonatomic) NSDictionary *properties; 22 | @property id provider; 23 | 24 | - (NSString*)getSharedFolderPathWithName:(NSString*)name; 25 | - (BOOL)isState:(PossibleVmStates)state; 26 | - (BOOL)isRunning; 27 | - (BOOL)isSuspended; 28 | - (BOOL)isOff; 29 | - (id)getProvider; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Vagrant Manager/VirtualMachineInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualMachineInfo.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import "VirtualMachineInfo.h" 9 | 10 | @implementation VirtualMachineInfo 11 | 12 | - (NSString*)getSharedFolderPathWithName:(NSString*)name { 13 | NSString *folder = [self.sharedFolders objectForKey:name]; 14 | if(!folder && [[name substringToIndex:1] isEqualToString:@"/"]) { 15 | folder = [self.sharedFolders objectForKey:[name substringFromIndex:1]]; 16 | } 17 | 18 | return folder; 19 | } 20 | 21 | - (BOOL)isState:(PossibleVmStates)state { 22 | return self.state == state; 23 | } 24 | 25 | - (BOOL)isRunning { 26 | return self.state == running; 27 | } 28 | 29 | - (BOOL)isSuspended { 30 | return self.state == suspended; 31 | } 32 | 33 | - (BOOL)isOff { 34 | return self.state == off; 35 | } 36 | 37 | - (id)getProvider { 38 | return self.provider; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Vagrant Manager/VirtualMachineServiceProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualMachineServiceProvider.h 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | @class VirtualMachineInfo; 10 | 11 | @protocol VirtualMachineServiceProvider 12 | 13 | - (NSArray*)getVagrantInstancePaths; 14 | - (NSString*)getProviderIdentifier; 15 | 16 | @end -------------------------------------------------------------------------------- /Vagrant Manager/bm_status_icon_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/bm_status_icon_off.png -------------------------------------------------------------------------------- /Vagrant Manager/bm_status_icon_off@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/bm_status_icon_off@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/bm_status_icon_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/bm_status_icon_on.png -------------------------------------------------------------------------------- /Vagrant Manager/bm_status_icon_on@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/bm_status_icon_on@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/bm_status_icon_suspended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/bm_status_icon_suspended.png -------------------------------------------------------------------------------- /Vagrant Manager/bm_status_icon_suspended@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/bm_status_icon_suspended@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/destroy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/destroy.png -------------------------------------------------------------------------------- /Vagrant Manager/destroy@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/destroy@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/dsa_pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIDOjCCAi0GByqGSM44BAEwggIgAoIBAQDBwdF2jRH4o1VCZLbgmp0zqk5Izxzm 3 | C3MFuI89U9xOlCNffqFfD3ratFdcMaxbb/8IYvfqzrVnrBlY+JoOx7zoeAW1AKcx 4 | Vvimgso3TxUx8D010yJfXQ6bwOZ1Iz4EJqQ72giP7qVMxUE4Kivs+EGKNwOuEq4P 5 | wpZNG/Y/u+gCG93btwQ0XVs675iOaph4bHx/WJvAhTS8uDcxwhGoxaDlNQL8lIzv 6 | AGVI9aM2kjJy10mSatBzLQHgFIXUOYXJku4bDAXfzIgEwmYM25w4ykDcyEGiwqJs 7 | ycuQOIEi2jCbRkdlfEo3xnM/r1R/f2hkFY2FtjeORsHlJsxj17pa7g+rAhUA97Rl 8 | 9EO0uffJMRaZZkhdlaUDExsCggEAX/6JeAS2YDalwZjskKl6BD9/d0HW+jGfgsWq 9 | 5dgjCnzyNjGNNnrZ/9p3UsMwVbzjN7zeODTyA3PakQZ/ifEXJo4szcmbqEdZv9A5 10 | 7yO1k26I3pSeTQFeknELGNfe11x7CZ5Tp9gLPj1PwsxRAah0RBfI9k7FBVGmvYDi 11 | N7ZqtrFetkwBwfohrccPcY/L4vhaY6JOL6VowX+OKxRUWEc00VZLuGbLEqasHNpA 12 | lIBYPJmEw7fQqNCy3hiNAUd6XNziXfX7FYURiPuD4MGtd0o6DTm1OURAi7dpoywz 13 | VXFy7075NYDEOxDZrqjraEUCAdtB64NOuu3rWq1nPQLuhV2GZwOCAQUAAoIBADce 14 | ctrMLcNNCrgKb8ComuSWNsL++ajU9+f+VEULay7HZkQI35g5PvuyORE3Za17RrzG 15 | bYDowvUxVq5Ys4aZS9kSFmW3MusFxgdg38sJYZgFbcIoAIw/2/RqFgdzB2QgNyqQ 16 | 3ghpJCgNXdeXAIjOtsl3QSAt8suPuiLBI4sMvQsfESYkvTkZFZRyJ4soaGd2Hy6c 17 | kkW9zvOTH31W/NSRarzPDw1ty5XeOhj4YcFwXV92OWEMfp2kHhFUyqEaNovZVzAn 18 | h4mxrgA8fSI6LAb4+HDgIlmGVz4vNJq8xn2kyMsksxgMC3WdhxGi3J56/+QtYnmx 19 | gKhPybbir5Tkc+cN3Ys= 20 | -----END PUBLIC KEY----- 21 | -------------------------------------------------------------------------------- /Vagrant Manager/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Vagrant Manager/halt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/halt.png -------------------------------------------------------------------------------- /Vagrant Manager/halt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/halt@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Vagrant Manager 4 | // 5 | // Copyright (c) 2014 Lanayo. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | int main(int argc, const char * argv[]) 11 | { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /Vagrant Manager/provision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/provision.png -------------------------------------------------------------------------------- /Vagrant Manager/provision@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/provision@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/rdp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/rdp.png -------------------------------------------------------------------------------- /Vagrant Manager/rdp@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/rdp@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/reload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/reload.png -------------------------------------------------------------------------------- /Vagrant Manager/reload@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/reload@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/resume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/resume.png -------------------------------------------------------------------------------- /Vagrant Manager/resume@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/resume@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/ssh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/ssh.png -------------------------------------------------------------------------------- /Vagrant Manager/ssh@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/ssh@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/status_icon_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/status_icon_off.png -------------------------------------------------------------------------------- /Vagrant Manager/status_icon_off@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/status_icon_off@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/status_icon_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/status_icon_on.png -------------------------------------------------------------------------------- /Vagrant Manager/status_icon_on@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/status_icon_on@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/status_icon_problem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/status_icon_problem.png -------------------------------------------------------------------------------- /Vagrant Manager/status_icon_problem@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/status_icon_problem@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/status_icon_suspended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/status_icon_suspended.png -------------------------------------------------------------------------------- /Vagrant Manager/status_icon_suspended@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/status_icon_suspended@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/suspend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/suspend.png -------------------------------------------------------------------------------- /Vagrant Manager/suspend@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/suspend@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/up.png -------------------------------------------------------------------------------- /Vagrant Manager/up@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/up@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_off-clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_off-clean.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_off-clean@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_off-clean@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_off-flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_off-flat.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_off-flat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_off-flat@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_on-clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_on-clean.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_on-clean@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_on-clean@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_on-flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_on-flat.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_on-flat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_on-flat@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_1-clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_1-clean.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_1-clean@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_1-clean@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_1-flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_1-flat.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_1-flat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_1-flat@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_2-clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_2-clean.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_2-clean@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_2-clean@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_2-flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_2-flat.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_2-flat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_2-flat@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_3-clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_3-clean.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_3-clean@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_3-clean@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_3-flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_3-flat.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_3-flat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_3-flat@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_4-clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_4-clean.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_4-clean@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_4-clean@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_4-flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_4-flat.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_4-flat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_4-flat@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_5-clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_5-clean.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_5-clean@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_5-clean@2x.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_5-flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_5-flat.png -------------------------------------------------------------------------------- /Vagrant Manager/vagrant_logo_refresh_5-flat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/Vagrant Manager/vagrant_logo_refresh_5-flat@2x.png -------------------------------------------------------------------------------- /dmg/.gitignore: -------------------------------------------------------------------------------- 1 | /Vagrant Manager.app 2 | -------------------------------------------------------------------------------- /dmg/appdmg.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Vagrant Manager", 3 | "background": "background.png", 4 | "icon": "appicon-512x512@2x.png", 5 | "contents": [ 6 | { "x": 236, "y": 160, "type": "file", "path": "Vagrant Manager.app" }, 7 | { "x": 600, "y": 160, "type": "link", "path": "/Applications" }, 8 | 9 | { "x": 250, "y": 500, "type": "position", "path": ".VolumeIcon.icns" }, 10 | { "x": 250, "y": 500, "type": "position", "path": ".background" }, 11 | { "x": 250, "y": 500, "type": "position", "path": ".Trashes" }, 12 | { "x": 250, "y": 500, "type": "position", "path": ".DS_Store" } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /dmg/appicon-512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/dmg/appicon-512x512@2x.png -------------------------------------------------------------------------------- /dmg/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lanayotech/vagrant-manager/f89def11f9b066c5a5e5f4d7f130bd5a94414529/dmg/background.png --------------------------------------------------------------------------------