diff --git a/Cakebrew.xcodeproj/project.pbxproj b/Cakebrew.xcodeproj/project.pbxproj index a4f0a978..9341a769 100644 --- a/Cakebrew.xcodeproj/project.pbxproj +++ b/Cakebrew.xcodeproj/project.pbxproj @@ -60,6 +60,7 @@ 1FE4FE6C148E4CDD008EDE8B /* BPAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FE4FE6B148E4CDD008EDE8B /* BPAppDelegate.m */; }; 1FE4FE6F148E4CDD008EDE8B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1FE4FE6D148E4CDD008EDE8B /* MainMenu.xib */; }; 1FE4FE77148E4D43008EDE8B /* BPHomebrewInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FE4FE76148E4D43008EDE8B /* BPHomebrewInterface.m */; }; + 222DC89E284CE05B0094E825 /* BPCasksDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 222DC89D284CE05B0094E825 /* BPCasksDataSource.m */; }; D212A5881B853069003000ED /* BPFormulaTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D212A5871B853069003000ED /* BPFormulaTests.m */; }; D212A5891B853132003000ED /* BPFormula.m in Sources */ = {isa = PBXBuildFile; fileRef = 1570BA5518EE50BD001C3C5C /* BPFormula.m */; }; D228335A1BA71B9900E44C82 /* BPTask.m in Sources */ = {isa = PBXBuildFile; fileRef = D23620E01B8B3094006D293D /* BPTask.m */; }; @@ -92,6 +93,51 @@ D2F732F119190B75002B2512 /* NSString+URLValidation.m in Sources */ = {isa = PBXBuildFile; fileRef = D2F732F019190B75002B2512 /* NSString+URLValidation.m */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 228C518A284CD267004E87EA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 228C5183284CD267004E87EA /* PXSourceList.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8D1107320486CEB800E47090; + remoteInfo = CellBasedSourceList; + }; + 228C518C284CD267004E87EA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 228C5183284CD267004E87EA /* PXSourceList.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D263123B186EF9F00036501C; + remoteInfo = ViewBasedSourceList; + }; + 228C518E284CD267004E87EA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 228C5183284CD267004E87EA /* PXSourceList.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 4CC5EA2A12DC81ED001F282E; + remoteInfo = PXSourceList; + }; + 228C5197284CD26D004E87EA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 228C5190284CD26D004E87EA /* PXSourceList.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8D1107320486CEB800E47090; + remoteInfo = CellBasedSourceList; + }; + 228C5199284CD26D004E87EA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 228C5190284CD26D004E87EA /* PXSourceList.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D263123B186EF9F00036501C; + remoteInfo = ViewBasedSourceList; + }; + 228C519B284CD26D004E87EA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 228C5190284CD26D004E87EA /* PXSourceList.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 4CC5EA2A12DC81ED001F282E; + remoteInfo = PXSourceList; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ 1570BA6018EF9B0F001C3C5C /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; @@ -235,6 +281,11 @@ 1FE4FE6B148E4CDD008EDE8B /* BPAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BPAppDelegate.m; sourceTree = ""; }; 1FE4FE75148E4D43008EDE8B /* BPHomebrewInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BPHomebrewInterface.h; sourceTree = ""; }; 1FE4FE76148E4D43008EDE8B /* BPHomebrewInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BPHomebrewInterface.m; sourceTree = ""; }; + 222DC894284CDF900094E825 /* BPCasksDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BPCasksDataSource.h; sourceTree = ""; }; + 222DC89D284CE05B0094E825 /* BPCasksDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = BPCasksDataSource.m; path = Controllers/BPCasksDataSource.m; sourceTree = ""; }; + 228C5183284CD267004E87EA /* PXSourceList.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PXSourceList.xcodeproj; path = Dependencies/PXSourceList/PXSourceList.xcodeproj; sourceTree = ""; }; + 228C5190284CD26D004E87EA /* PXSourceList.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PXSourceList.xcodeproj; path = Dependencies/PXSourceList/PXSourceList.xcodeproj; sourceTree = ""; }; + 228C519D284CD322004E87EA /* PXSourceList */ = {isa = PBXFileReference; lastKnownFileType = folder; name = PXSourceList; path = Dependencies/PXSourceList; sourceTree = ""; }; D212A5871B853069003000ED /* BPFormulaTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BPFormulaTests.m; sourceTree = ""; }; D23620DF1B8B3094006D293D /* BPTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BPTask.h; sourceTree = ""; }; D23620E01B8B3094006D293D /* BPTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BPTask.m; sourceTree = ""; }; @@ -363,6 +414,8 @@ 150AEC4B1B3F999A00163767 /* BPUpdateViewController.m */, 15EC1B0A25CEE4C200C93861 /* BPMainWindowController.h */, 15EC1B0B25CEE4C200C93861 /* BPMainWindowController.m */, + 222DC894284CDF900094E825 /* BPCasksDataSource.h */, + 222DC89D284CE05B0094E825 /* BPCasksDataSource.m */, ); name = Controllers; sourceTree = ""; @@ -436,6 +489,9 @@ 1FE4FE49148E4CDD008EDE8B = { isa = PBXGroup; children = ( + 228C519D284CD322004E87EA /* PXSourceList */, + 228C5183284CD267004E87EA /* PXSourceList.xcodeproj */, + 228C5190284CD26D004E87EA /* PXSourceList.xcodeproj */, 1FE4FE5E148E4CDD008EDE8B /* Cakebrew */, D261C9C11B852FA300409803 /* CakebrewTests */, 1FE4FE57148E4CDD008EDE8B /* Frameworks */, @@ -520,6 +576,26 @@ name = "Supporting Files"; sourceTree = ""; }; + 228C5184284CD267004E87EA /* Products */ = { + isa = PBXGroup; + children = ( + 228C518B284CD267004E87EA /* PXSourceList.app */, + 228C518D284CD267004E87EA /* ViewBasedSourceList.app */, + 228C518F284CD267004E87EA /* PXSourceList.framework */, + ); + name = Products; + sourceTree = ""; + }; + 228C5191284CD26D004E87EA /* Products */ = { + isa = PBXGroup; + children = ( + 228C5198284CD26D004E87EA /* PXSourceList.app */, + 228C519A284CD26D004E87EA /* ViewBasedSourceList.app */, + 228C519C284CD26D004E87EA /* PXSourceList.framework */, + ); + name = Products; + sourceTree = ""; + }; D261C9C11B852FA300409803 /* CakebrewTests */ = { isa = PBXGroup; children = ( @@ -607,7 +683,7 @@ ORGANIZATIONNAME = "Bruno Philipe"; TargetAttributes = { 1FE4FE53148E4CDD008EDE8B = { - DevelopmentTeam = R85D3K8ATT; + DevelopmentTeam = NCC257H8F7; ProvisioningStyle = Automatic; }; D261C9BF1B852FA300409803 = { @@ -631,6 +707,16 @@ mainGroup = 1FE4FE49148E4CDD008EDE8B; productRefGroup = 1FE4FE55148E4CDD008EDE8B /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 228C5191284CD26D004E87EA /* Products */; + ProjectRef = 228C5190284CD26D004E87EA /* PXSourceList.xcodeproj */; + }, + { + ProductGroup = 228C5184284CD267004E87EA /* Products */; + ProjectRef = 228C5183284CD267004E87EA /* PXSourceList.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 1FE4FE53148E4CDD008EDE8B /* Cakebrew */, @@ -639,6 +725,51 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + 228C518B284CD267004E87EA /* PXSourceList.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = PXSourceList.app; + remoteRef = 228C518A284CD267004E87EA /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 228C518D284CD267004E87EA /* ViewBasedSourceList.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = ViewBasedSourceList.app; + remoteRef = 228C518C284CD267004E87EA /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 228C518F284CD267004E87EA /* PXSourceList.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = PXSourceList.framework; + remoteRef = 228C518E284CD267004E87EA /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 228C5198284CD26D004E87EA /* PXSourceList.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = PXSourceList.app; + remoteRef = 228C5197284CD26D004E87EA /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 228C519A284CD26D004E87EA /* ViewBasedSourceList.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = ViewBasedSourceList.app; + remoteRef = 228C5199284CD26D004E87EA /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 228C519C284CD26D004E87EA /* PXSourceList.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = PXSourceList.framework; + remoteRef = 228C519B284CD26D004E87EA /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 1FE4FE52148E4CDD008EDE8B /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -716,6 +847,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 222DC89E284CE05B0094E825 /* BPCasksDataSource.m in Sources */, 15BBA18E1BD031C9002C0127 /* BPBackgroundView.m in Sources */, 15D28A121AE1BD27005C8A3E /* BPTimedDispatch.m in Sources */, D2A3A82F1B8C9F5200D05469 /* BPUtilities.m in Sources */, @@ -1047,8 +1179,8 @@ CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 594; - DEVELOPMENT_TEAM = R85D3K8ATT; + CURRENT_PROJECT_VERSION = 595; + DEVELOPMENT_TEAM = NCC257H8F7; ENABLE_HARDENED_RUNTIME = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1059,6 +1191,8 @@ GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; INFOPLIST_FILE = "Cakebrew/Cakebrew-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 11.3; + MARKETING_VERSION = 1.4; ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.brunophilipe.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = Cakebrew; @@ -1078,8 +1212,8 @@ CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 594; - DEVELOPMENT_TEAM = R85D3K8ATT; + CURRENT_PROJECT_VERSION = 595; + DEVELOPMENT_TEAM = NCC257H8F7; ENABLE_HARDENED_RUNTIME = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1089,6 +1223,8 @@ GCC_PREFIX_HEADER = "Cakebrew/Cakebrew-Prefix.pch"; INFOPLIST_FILE = "Cakebrew/Cakebrew-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 11.3; + MARKETING_VERSION = 1.4; ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.brunophilipe.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = Cakebrew; diff --git a/Cakebrew/BPCasksDataSource.h b/Cakebrew/BPCasksDataSource.h new file mode 100644 index 00000000..a8b7cfbf --- /dev/null +++ b/Cakebrew/BPCasksDataSource.h @@ -0,0 +1,18 @@ +// +// BPCasksDataSource.h +// Cakebrew +// + +#import +#import "BPHomebrewInterface.h" +#import "BPFormula.h" + +@interface BPCasksDataSource : NSObject + +@property (nonatomic, assign) BPListMode mode; + +- (instancetype)initWithMode:(BPListMode)aMode; +- (BPFormula *)caskAtIndex:(NSInteger)index; +- (NSArray *)casksAtIndexSet:(NSIndexSet *)indexSet; +- (void)refreshBackingArray; +@end diff --git a/Cakebrew/BPFormulaeDataSource.m b/Cakebrew/BPFormulaeDataSource.m index 69f81951..5819d5b7 100644 --- a/Cakebrew/BPFormulaeDataSource.m +++ b/Cakebrew/BPFormulaeDataSource.m @@ -18,7 +18,7 @@ @implementation BPFormulaeDataSource - (instancetype)init { - return [self initWithMode:kBPListAll]; + return [self initWithMode:kBPListAllFormulae]; } - (instancetype)initWithMode:(BPListMode)aMode @@ -40,11 +40,11 @@ - (void)setMode:(BPListMode)mode - (void)refreshBackingArray { switch (self.mode) { - case kBPListAll: + case kBPListAllFormulae: _formulaeArray = [[BPHomebrewManager sharedManager] allFormulae]; break; - case kBPListInstalled: + case kBPListInstalledFormulae: _formulaeArray = [[BPHomebrewManager sharedManager] installedFormulae]; break; @@ -52,11 +52,11 @@ - (void)refreshBackingArray _formulaeArray = [[BPHomebrewManager sharedManager] leavesFormulae]; break; - case kBPListOutdated: + case kBPListOutdatedFormulae: _formulaeArray = [[BPHomebrewManager sharedManager] outdatedFormulae]; break; - case kBPListSearch: + case kBPListSearchFormulae: _formulaeArray = [[BPHomebrewManager sharedManager] searchFormulae]; break; diff --git a/Cakebrew/BPFormulaeTableView.m b/Cakebrew/BPFormulaeTableView.m index ec6552d9..acd4ef3b 100644 --- a/Cakebrew/BPFormulaeTableView.m +++ b/Cakebrew/BPFormulaeTableView.m @@ -29,7 +29,7 @@ - (instancetype)initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; if (self) { - _mode = kBPListAll; + _mode = kBPListAllFormulae; } return self; } @@ -48,7 +48,7 @@ - (void)configureTableForListing } switch (self.mode) { - case kBPListAll: + case kBPListAllFormulae: titleWidth = (NSInteger)(totalWidth - 125); [[self tableColumnWithIdentifier:kColumnIdentifierVersion] setHidden:YES]; [[self tableColumnWithIdentifier:kColumnIdentifierLatestVersion] setHidden:YES]; @@ -57,7 +57,7 @@ - (void)configureTableForListing [self setAllowsMultipleSelection:NO]; break; - case kBPListInstalled: + case kBPListInstalledFormulae: titleWidth = (NSInteger)(totalWidth * 0.4); [[self tableColumnWithIdentifier:kColumnIdentifierLatestVersion] setHidden:YES]; [[self tableColumnWithIdentifier:kColumnIdentifierStatus] setHidden:YES]; @@ -74,7 +74,7 @@ - (void)configureTableForListing [self setAllowsMultipleSelection:NO]; break; - case kBPListOutdated: + case kBPListOutdatedFormulae: titleWidth = (NSInteger)(totalWidth * 0.4); [[self tableColumnWithIdentifier:kColumnIdentifierStatus] setHidden:YES]; [[self tableColumnWithIdentifier:kColumnIdentifierVersion] setHidden:NO]; @@ -84,7 +84,7 @@ - (void)configureTableForListing [self setAllowsMultipleSelection:YES]; break; - case kBPListSearch: + case kBPListSearchFormulae: titleWidth = (NSInteger)(totalWidth - 90); [[self tableColumnWithIdentifier:kColumnIdentifierVersion] setHidden:YES]; [[self tableColumnWithIdentifier:kColumnIdentifierLatestVersion] setHidden:YES]; @@ -101,6 +101,43 @@ - (void)configureTableForListing [self setAllowsMultipleSelection:NO]; break; + case kBPListAllCasks: + titleWidth = (NSInteger)(totalWidth - 125); + [[self tableColumnWithIdentifier:kColumnIdentifierVersion] setHidden:YES]; + [[self tableColumnWithIdentifier:kColumnIdentifierLatestVersion] setHidden:YES]; + [[self tableColumnWithIdentifier:kColumnIdentifierStatus] setHidden:NO]; + [[self tableColumnWithIdentifier:kColumnIdentifierStatus] setWidth:(NSInteger)((totalWidth-titleWidth)*0.90)]; + [self setAllowsMultipleSelection:NO]; + break; + + case kBPListInstalledCasks: + titleWidth = (NSInteger)(totalWidth * 0.4); + [[self tableColumnWithIdentifier:kColumnIdentifierLatestVersion] setHidden:YES]; + [[self tableColumnWithIdentifier:kColumnIdentifierStatus] setHidden:YES]; + [[self tableColumnWithIdentifier:kColumnIdentifierVersion] setHidden:NO]; + [[self tableColumnWithIdentifier:kColumnIdentifierVersion] setWidth:(NSInteger)totalWidth*0.55]; + [self setAllowsMultipleSelection:NO]; + break; + + case kBPListOutdatedCasks: + titleWidth = (NSInteger)(totalWidth * 0.4); + [[self tableColumnWithIdentifier:kColumnIdentifierStatus] setHidden:YES]; + [[self tableColumnWithIdentifier:kColumnIdentifierVersion] setHidden:NO]; + [[self tableColumnWithIdentifier:kColumnIdentifierVersion] setWidth:(totalWidth-titleWidth)*0.48]; + [[self tableColumnWithIdentifier:kColumnIdentifierLatestVersion] setHidden:NO]; + [[self tableColumnWithIdentifier:kColumnIdentifierLatestVersion] setWidth:(totalWidth-titleWidth)*0.48]; + [self setAllowsMultipleSelection:YES]; + break; + + case kBPListSearchCasks: + titleWidth = (NSInteger)(totalWidth - 90); + [[self tableColumnWithIdentifier:kColumnIdentifierVersion] setHidden:YES]; + [[self tableColumnWithIdentifier:kColumnIdentifierLatestVersion] setHidden:YES]; + [[self tableColumnWithIdentifier:kColumnIdentifierStatus] setHidden:NO]; + [[self tableColumnWithIdentifier:kColumnIdentifierStatus] setWidth:(totalWidth-titleWidth)*0.90]; + [self setAllowsMultipleSelection:NO]; + break; + default: break; } diff --git a/Cakebrew/BPHomebrewInterface.h b/Cakebrew/BPHomebrewInterface.h index 88397997..d6d1b9eb 100644 --- a/Cakebrew/BPHomebrewInterface.h +++ b/Cakebrew/BPHomebrewInterface.h @@ -24,12 +24,18 @@ #import "BPFormula.h" typedef NS_ENUM(NSInteger, BPListMode) { - kBPListAll, - kBPListInstalled, + kBPListAllFormulae, + kBPListInstalledFormulae, kBPListLeaves, - kBPListOutdated, - kBPListSearch, /* Don't call -[BPHomebrewInterface listMode:] with this parameter. */ - kBPListRepositories + kBPListOutdatedFormulae, + kBPListSearchFormulae, /* Don't call -[BPHomebrewInterface listMode:] with this parameter. */ + kBPListRepositories, + + kBPListAllCasks, + kBPListInstalledCasks, + kBPListOutdatedCasks, + kBPListSearchCasks + }; @protocol BPHomebrewInterfaceDelegate diff --git a/Cakebrew/BPHomebrewInterface.m b/Cakebrew/BPHomebrewInterface.m index b0051baf..ed9783a3 100644 --- a/Cakebrew/BPHomebrewInterface.m +++ b/Cakebrew/BPHomebrewInterface.m @@ -22,6 +22,8 @@ #import "BPHomebrewInterface.h" #import "BPTask.h" +NSString *brewPath = @""; + #define kDEBUG_WARNING @"\ User Shell: %@\n\ Command: %@\n\ @@ -41,18 +43,28 @@ - (BPFormula *)parseFormulaItem:(NSString *)item; @end -@interface BPHomebrewInterfaceListCallInstalled : BPHomebrewInterfaceListCall +@interface BPHomebrewInterfaceListCallInstalledFormulae : BPHomebrewInterfaceListCall @end -@interface BPHomebrewInterfaceListCallAll : BPHomebrewInterfaceListCall +@interface BPHomebrewInterfaceListCallInstalledCasks : BPHomebrewInterfaceListCall @end -@interface BPHomebrewInterfaceListCallLeaves : BPHomebrewInterfaceListCall +@interface BPHomebrewInterfaceListCallAllFormulae : BPHomebrewInterfaceListCall +@end + +@interface BPHomebrewInterfaceListCallAllCasks : BPHomebrewInterfaceListCall @end -@interface BPHomebrewInterfaceListCallUpgradeable : BPHomebrewInterfaceListCall +@interface BPHomebrewInterfaceListCallUpgradeableFormulae : BPHomebrewInterfaceListCall @end +@interface BPHomebrewInterfaceListCallUpgradeableCasks : BPHomebrewInterfaceListCall +@end + +@interface BPHomebrewInterfaceListCallLeaves : BPHomebrewInterfaceListCall +@end + + @interface BPHomebrewInterfaceListCallRepositories: BPHomebrewInterfaceListCall @end @@ -116,10 +128,11 @@ - (BOOL)checkForHomebrew NSString *output = [task output]; output = [self removeLoginShellOutputFromString:output]; -#ifdef DEBUG - NSLog(@"brew: %@", output); -#endif - + output = [self removeNewLineFromString:output]; + brewPath = output; +// #ifdef DEBUG +// NSLog(@"brew: %@", output); +// #endif return output.length != 0; } @@ -135,8 +148,7 @@ - (void)setDelegate:(id)delegate else { [self setPath_cellar:[self getUserCellarPath]]; - - NSLog(@"cellar: %@", self.path_cellar); +// NSLog(@"cellar: %@", self.path_cellar); } } } @@ -172,11 +184,9 @@ - (NSString *)getValidUserShellPath NSLog(@"No valid shell found..."); return nil; } - -#ifdef DEBUG - NSLog(@"shell: %@", userShell); -#endif - +// #ifdef DEBUG +// NSLog(@"shell: %@", userShell); +// #endif return userShell; } @@ -203,12 +213,11 @@ - (NSArray *)formatArguments:(NSArray *)extraArguments sendOutputId:(BOOL)sendOu { NSString *command = nil; if (sendOutputID) { - command = [NSString stringWithFormat:@"echo \"%@\";brew %@", cakebrewOutputIdentifier, [extraArguments componentsJoinedByString:@" "]]; + command = [NSString stringWithFormat:@"echo \"%@\";%@ %@", cakebrewOutputIdentifier, brewPath, [extraArguments componentsJoinedByString:@" "]]; } else { - command = [NSString stringWithFormat:@"brew %@", [extraArguments componentsJoinedByString:@" "]]; + command = [NSString stringWithFormat:@"%@ %@", brewPath, [extraArguments componentsJoinedByString:@" "]]; } NSArray *arguments = @[@"-l", @"-c", command]; - return arguments; } @@ -233,7 +242,8 @@ - (void)task:(BPTask *)task didFinishWithOutput:(NSString *)output error:(NSStri - (BOOL)performBrewCommandWithArguments:(NSArray*)arguments dataReturnBlock:(void (^)(NSString*))block { - return [self performAsyncBrewCommandWithArguments:arguments wrapsSynchronousRequest:NO queue:nil dataReturnBlock:block]; + return [self performSyncBrewCommandWithArguments:arguments dataReturnBlock:block wrapRequest:false]; + //return [self performAsyncBrewCommandWithArguments:arguments wrapsSynchronousRequest:NO queue:nil dataReturnBlock:block]; } - (BOOL)performAsyncBrewCommandWithArguments:(NSArray*)arguments @@ -281,39 +291,39 @@ - (BOOL)performAsyncBrewCommandWithArguments:(NSArray*)arguments return status == 0; } +- (BOOL)performSyncBrewCommandWithArguments:(NSArray*)arguments + dataReturnBlock:(void (^)(NSString*))block + wrapRequest:(BOOL)wrap +{ + arguments = [self formatArguments:arguments sendOutputId:wrap]; + BPTask *task = [[BPTask alloc] initWithPath:self.path_shell arguments:arguments]; + int status = [task execute]; + NSString *output = [task output]; + if (wrap) { + output = [self removeLoginShellOutputFromString:output]; + } + block(output); + return status == 0; +} + - (BOOL)isRunningBackgroundTask { return [[self.tasks allKeys] count] > 0; } -/** - * This method performs a brew command in an asynchronous mode so that long chunks of data can be returned, - * but to the callee it behaves like a synchronous call. - * - * Note: Synchronous tasks were deprecated and removed completely in Nov 1st, 2016 due to numerous bugs. All - * "synchronous" tasks should use this method instead. - */ + - (NSString*)performSyncBrewCommandWithArguments:(NSArray*)arguments { - NSString __block *finalOutput = nil; - - dispatch_queue_t queue = _taskOperationsQueue; - - dispatch_sync(queue, ^{ - NSMutableString *output = [NSMutableString new]; - - [self performAsyncBrewCommandWithArguments:arguments - wrapsSynchronousRequest:YES - queue:queue - dataReturnBlock:^(NSString *partialOutput) - { - [output appendString:partialOutput]; - }]; - - finalOutput = [output copy]; - }); - - return [self removeLoginShellOutputFromString:finalOutput]; + NSString __block *outputValue; + void (^displayTerminalOutput)(NSString *outputValue) = ^(NSString *output) { + if (outputValue) { + outputValue = [outputValue stringByAppendingString:output]; + } else { + outputValue = output; + } + }; + [self performBrewCommandWithArguments:arguments dataReturnBlock:displayTerminalOutput]; + return [self removeLoginShellOutputFromString:outputValue]; } #pragma mark - Operations that return on finish @@ -323,22 +333,34 @@ - (NSString*)performSyncBrewCommandWithArguments:(NSArray*)arguments BPHomebrewInterfaceListCall *listCall = nil; switch (mode) { - case kBPListInstalled: - listCall = [[BPHomebrewInterfaceListCallInstalled alloc] init]; + case kBPListInstalledFormulae: + listCall = [[BPHomebrewInterfaceListCallInstalledFormulae alloc] init]; break; - - case kBPListAll: - listCall = [[BPHomebrewInterfaceListCallAll alloc] init]; + + case kBPListInstalledCasks: + listCall = [[BPHomebrewInterfaceListCallInstalledCasks alloc] init]; + break; + + case kBPListAllFormulae: + listCall = [[BPHomebrewInterfaceListCallAllFormulae alloc] init]; + break; + + case kBPListAllCasks: + listCall = [[BPHomebrewInterfaceListCallAllCasks alloc] init]; break; + case kBPListOutdatedFormulae: + listCall = [[BPHomebrewInterfaceListCallUpgradeableFormulae alloc] init]; + break; + + case kBPListOutdatedCasks: + listCall = [[BPHomebrewInterfaceListCallUpgradeableCasks alloc] init]; + break; + case kBPListLeaves: listCall = [[BPHomebrewInterfaceListCallLeaves alloc] init]; break; - case kBPListOutdated: - listCall = [[BPHomebrewInterfaceListCallUpgradeable alloc] init]; - break; - case kBPListRepositories: listCall = [[BPHomebrewInterfaceListCallRepositories alloc] init]; break; @@ -387,7 +409,13 @@ - (NSString*)removeLoginShellOutputFromString:(NSString*)string { return string; } } - //If all else fails... + return nil; +} + +- (NSString*)removeNewLineFromString:(NSString*)string { + if (string) { + return [string stringByReplacingOccurrencesOfString:@"\n" withString:@""]; + } return nil; } @@ -539,11 +567,11 @@ - (BPFormula *)parseFormulaItem:(NSString *)item @end -@implementation BPHomebrewInterfaceListCallInstalled +@implementation BPHomebrewInterfaceListCallInstalledFormulae - (instancetype)init { - return (BPHomebrewInterfaceListCallInstalled *)[super initWithArguments:@[@"list", @"--versions"]]; + return (BPHomebrewInterfaceListCallInstalledFormulae *)[super initWithArguments:@[@"list", @"--versions", @"--formulae"]]; } - (BPFormula *)parseFormulaItem:(NSString *)item @@ -554,29 +582,84 @@ - (BPFormula *)parseFormulaItem:(NSString *)item @end -@implementation BPHomebrewInterfaceListCallAll +@implementation BPHomebrewInterfaceListCallInstalledCasks - (instancetype)init { - return (BPHomebrewInterfaceListCallAll *)[super initWithArguments:@[@"formulae"]]; + return (BPHomebrewInterfaceListCallInstalledCasks *)[super initWithArguments:@[@"list", @"--versions", @"--casks"]]; +} + +- (BPFormula *)parseFormulaItem:(NSString *)item +{ + NSArray *aux = [item componentsSeparatedByString:@" "]; + return [BPFormula formulaWithName:[aux firstObject] andVersion:[aux lastObject]]; } @end -@implementation BPHomebrewInterfaceListCallLeaves +@implementation BPHomebrewInterfaceListCallAllFormulae - (instancetype)init { - return (BPHomebrewInterfaceListCallLeaves *)[super initWithArguments:@[@"leaves"]]; + return (BPHomebrewInterfaceListCallAllFormulae *)[super initWithArguments:@[@"formulae"]]; +} + +@end + +@implementation BPHomebrewInterfaceListCallAllCasks + +- (instancetype)init +{ + return (BPHomebrewInterfaceListCallAllCasks *)[super initWithArguments:@[@"casks"]]; +} + +@end + +@implementation BPHomebrewInterfaceListCallUpgradeableFormulae + +- (instancetype)init +{ + return (BPHomebrewInterfaceListCallUpgradeableFormulae *)[super initWithArguments:@[@"outdated", @"--verbose", @"--formulae"]]; +} + +- (BPFormula *)parseFormulaItem:(NSString *)item +{ + static NSString *regexString = @"(\\S+)\\s\\(((.*, )*(.*))\\) < (\\S+)"; + + BPFormula __block *formula = nil; + NSError *error = nil; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:NSRegularExpressionCaseInsensitive error:&error]; + + [regex enumerateMatchesInString:item options:0 range:NSMakeRange(0, [item length]) usingBlock: + ^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) + { + if (result.resultType == NSTextCheckingTypeRegularExpression && [result numberOfRanges] >= 4) + { + NSString *formulaName = [item substringWithRange:[result rangeAtIndex:1]]; + NSString *installedVersion = [item substringWithRange:[result rangeAtIndex:[result numberOfRanges] - 2]]; + NSString *latestVersion = [item substringWithRange:[result rangeAtIndex:[result numberOfRanges] - 1]]; + + formula = [BPFormula formulaWithName:formulaName + version:installedVersion + andLatestVersion:latestVersion]; + } + }]; + + if (!formula) { + formula = [BPFormula formulaWithName:item]; + } + + return formula; } @end -@implementation BPHomebrewInterfaceListCallUpgradeable + +@implementation BPHomebrewInterfaceListCallUpgradeableCasks - (instancetype)init { - return (BPHomebrewInterfaceListCallUpgradeable *)[super initWithArguments:@[@"outdated", @"--verbose"]]; + return (BPHomebrewInterfaceListCallUpgradeableCasks *)[super initWithArguments:@[@"outdated", @"--verbose", @"--casks"]]; } - (BPFormula *)parseFormulaItem:(NSString *)item @@ -611,6 +694,17 @@ - (BPFormula *)parseFormulaItem:(NSString *)item @end + +@implementation BPHomebrewInterfaceListCallLeaves + +- (instancetype)init +{ + return (BPHomebrewInterfaceListCallLeaves *)[super initWithArguments:@[@"leaves"]]; +} + +@end + + @implementation BPHomebrewInterfaceListCallRepositories - (instancetype)init diff --git a/Cakebrew/BPHomebrewManager.h b/Cakebrew/BPHomebrewManager.h index 30ab4499..49202ae1 100644 --- a/Cakebrew/BPHomebrewManager.h +++ b/Cakebrew/BPHomebrewManager.h @@ -27,7 +27,7 @@ typedef NS_ENUM(NSInteger, BPFormulaStatus) { kBPFormulaNotInstalled, kBPFormulaInstalled, - kBPFormulaOutdated, + kBPFormulaOutdated }; @protocol BPHomebrewManagerDelegate @@ -47,6 +47,11 @@ typedef NS_ENUM(NSInteger, BPFormulaStatus) { @property (strong) NSArray *searchFormulae; @property (strong) NSArray *repositoriesFormulae; +@property (strong) NSArray *installedCasks; +@property (strong) NSArray *outdatedCasks; +@property (strong) NSArray *allCasks; +@property (strong) NSArray *searchCasks; + @property (weak) id delegate; + (instancetype)sharedManager; @@ -58,6 +63,7 @@ typedef NS_ENUM(NSInteger, BPFormulaStatus) { - (void)updateSearchWithName:(NSString *)name; - (BPFormulaStatus)statusForFormula:(BPFormula*)formula; +- (BPFormulaStatus)statusForCask:(BPFormula*)formula; - (void)cleanUp; diff --git a/Cakebrew/BPHomebrewManager.m b/Cakebrew/BPHomebrewManager.m index 556a1b02..b67123d7 100644 --- a/Cakebrew/BPHomebrewManager.m +++ b/Cakebrew/BPHomebrewManager.m @@ -72,32 +72,45 @@ - (void)dealloc - (void)reloadFromInterfaceRebuildingCache:(BOOL)shouldRebuildCache; { NSUInteger previousCountOfAllFormulae = [self allFormulae].count; + NSUInteger previousCountOfAllCasks = [self allCasks].count; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ [[BPHomebrewInterface sharedInterface] setDelegate:self]; - NSArray *installedFormulae = [[BPHomebrewInterface sharedInterface] listMode:kBPListInstalled]; + NSArray *installedFormulae = [[BPHomebrewInterface sharedInterface] listMode:kBPListInstalledFormulae]; NSArray *leavesFormulae = [[BPHomebrewInterface sharedInterface] listMode:kBPListLeaves]; - NSArray *outdatedFormulae = [[BPHomebrewInterface sharedInterface] listMode:kBPListOutdated]; + NSArray *outdatedFormulae = [[BPHomebrewInterface sharedInterface] listMode:kBPListOutdatedFormulae]; NSArray *repositoriesFormulae = [[BPHomebrewInterface sharedInterface] listMode:kBPListRepositories]; + + NSArray *installedCasks = [[BPHomebrewInterface sharedInterface] listMode:kBPListInstalledCasks]; + NSArray *outdatedCasks = [[BPHomebrewInterface sharedInterface] listMode:kBPListOutdatedCasks]; + NSArray *allFormulae = nil; + NSArray *allCasks = nil; if (![self loadAllFormulaeCaches] || previousCountOfAllFormulae <= 100 || shouldRebuildCache) { - allFormulae = [[BPHomebrewInterface sharedInterface] listMode:kBPListAll]; + allFormulae = [[BPHomebrewInterface sharedInterface] listMode:kBPListAllFormulae]; } - dispatch_async(dispatch_get_main_queue(), ^{ + if (![self loadAllCasksCaches] || previousCountOfAllCasks <= 10 || shouldRebuildCache) { + allCasks = [[BPHomebrewInterface sharedInterface] listMode:kBPListAllCasks]; + } + dispatch_async(dispatch_get_main_queue(), ^{ if (allFormulae != nil) { [self setAllFormulae:allFormulae]; [self storeAllFormulaeCaches]; } - + if (allCasks != nil) { + [self setAllCasks:allCasks]; + [self storeAllCasksCaches]; + } [self setInstalledFormulae:installedFormulae]; [self setLeavesFormulae:leavesFormulae]; [self setOutdatedFormulae:outdatedFormulae]; [self setRepositoriesFormulae:repositoriesFormulae]; - + [self setInstalledCasks:installedCasks]; + [self setOutdatedCasks:outdatedCasks]; [self.delegate homebrewManagerFinishedUpdating:self]; }); }); @@ -122,65 +135,82 @@ - (void)updateSearchWithName:(NSString *)name }); } +- (BOOL)loadAllFormulaeCaches +{ + return [self loadCache:@"allFormulae.cache.bin" array:self.allFormulae]; +} + +- (BOOL)loadAllCasksCaches +{ + return [self loadCache:@"allCasks.cache.bin" array:self.allCasks]; +} + /** Returns `YES` if cache exists, was created less than 24 hours ago and was loaded successfully. Otherwise returns `NO`. */ -- (BOOL)loadAllFormulaeCaches +- (BOOL)loadCache:(NSString*)fileName array:(NSArray*)cache { - NSURL *cachesFolder = [BPAppDelegate urlForApplicationCachesFolder]; - NSURL *allFormulaeFile = [cachesFolder URLByAppendingPathComponent:@"allFormulae.cache.bin"]; - BOOL shouldLoadCache = NO; - - if ([[NSUserDefaults standardUserDefaults] objectForKey:kBPCacheLastUpdateKey]) - { - NSDate *storageDate = [NSDate dateWithTimeIntervalSince1970:[[NSUserDefaults standardUserDefaults] - integerForKey:kBPCacheLastUpdateKey]]; - - if ([[NSDate date] timeIntervalSinceDate:storageDate] <= 3600*24) - { - shouldLoadCache = YES; - } - } - - if (shouldLoadCache && allFormulaeFile) - { - NSDictionary *cacheDict = nil; - - if ([[NSFileManager defaultManager] fileExistsAtPath:allFormulaeFile.relativePath]) - { - NSData *data = [NSData dataWithContentsOfFile:allFormulaeFile.relativePath]; - NSError *error = nil; + NSURL *cachesFolder = [BPAppDelegate urlForApplicationCachesFolder]; + NSURL *allFile = [cachesFolder URLByAppendingPathComponent:fileName]; + BOOL shouldLoadCache = NO; + + if ([[NSUserDefaults standardUserDefaults] objectForKey:kBPCacheLastUpdateKey]) + { + NSDate *storageDate = [NSDate dateWithTimeIntervalSince1970:[[NSUserDefaults standardUserDefaults] + integerForKey:kBPCacheLastUpdateKey]]; + + if ([[NSDate date] timeIntervalSinceDate:storageDate] <= 3600*24) + { + shouldLoadCache = YES; + } + } + + if (shouldLoadCache && allFile) + { + NSDictionary *cacheDict = nil; + + if ([[NSFileManager defaultManager] fileExistsAtPath:allFile.relativePath]) + { + NSData *data = [NSData dataWithContentsOfFile:allFile.relativePath]; + NSError *error = nil; - if (@available(macOS 10.13, *)) { - NSSet *classes = [NSSet setWithArray:@[[NSDictionary class], [NSMutableArray class], [BPFormula class]]]; - cacheDict = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:data error:&error]; - if (error) { - NSLog(@"Failed decoding data: %@", [error localizedDescription]); - } - } else { - cacheDict = [NSKeyedUnarchiver unarchiveObjectWithFile:allFormulaeFile.relativePath]; - } - self.allFormulae = [cacheDict objectForKey:kBPCacheDataKey]; - } - } - else - { - // Delete all cache data - [[NSFileManager defaultManager] removeItemAtURL:allFormulaeFile error:nil]; - [[NSUserDefaults standardUserDefaults] removeObjectForKey:kBPCacheLastUpdateKey]; - } - - return self.allFormulae != nil; + if (@available(macOS 10.13, *)) { + NSSet *classes = [NSSet setWithArray:@[[NSDictionary class], [NSMutableArray class], [BPFormula class]]]; + cacheDict = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:data error:&error]; + if (error) { + NSLog(@"Failed decoding data: %@", [error localizedDescription]); + } + } else { + cacheDict = [NSKeyedUnarchiver unarchiveObjectWithFile:allFile.relativePath]; + } + cache = [cacheDict objectForKey:kBPCacheDataKey]; + } + } else { + // Delete all cache data + [[NSFileManager defaultManager] removeItemAtURL:allFile error:nil]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:kBPCacheLastUpdateKey]; + } + return cache != nil; } - (void)storeAllFormulaeCaches { - if (self.allFormulae) + [self storeCache:@"allFormulae.cache.bin" array:self.allFormulae]; +} + +- (void)storeAllCasksCaches +{ + [self storeCache:@"allCasks.cache.bin" array:self.allCasks]; +} + +- (void)storeCache:(NSString*)fileName array:(NSArray*)cache +{ + if (self.allCasks) { NSURL *cachesFolder = [BPAppDelegate urlForApplicationCachesFolder]; if (cachesFolder) { - NSURL *allFormulaeFile = [cachesFolder URLByAppendingPathComponent:@"allFormulae.cache.bin"]; + NSURL *allFile = [cachesFolder URLByAppendingPathComponent:fileName]; NSDate *storageDate = [NSDate date]; if ([[NSUserDefaults standardUserDefaults] objectForKey:kBPCacheLastUpdateKey]) @@ -189,7 +219,7 @@ - (void)storeAllFormulaeCaches integerForKey:kBPCacheLastUpdateKey]]; } - NSDictionary *cacheDict = @{kBPCacheDataKey: self.allFormulae}; + NSDictionary *cacheDict = @{kBPCacheDataKey: cache}; NSData *cacheData; if (@available(macOS 10.13, *)) { @@ -205,21 +235,19 @@ - (void)storeAllFormulaeCaches cacheData = [NSKeyedArchiver archivedDataWithRootObject:cacheDict]; } - if ([[NSFileManager defaultManager] fileExistsAtPath:allFormulaeFile.relativePath]) + if ([[NSFileManager defaultManager] fileExistsAtPath:allFile.relativePath]) { - [cacheData writeToURL:allFormulaeFile atomically:YES]; + [cacheData writeToURL:allFile atomically:YES]; } else { - [[NSFileManager defaultManager] createFileAtPath:allFormulaeFile.relativePath + [[NSFileManager defaultManager] createFileAtPath:allFile.relativePath contents:cacheData attributes:nil]; } [[NSUserDefaults standardUserDefaults] setInteger:[storageDate timeIntervalSince1970] forKey:kBPCacheLastUpdateKey]; - } - else - { + } else { NSLog(@"Could not store cache file. BPAppDelegate function returned nil!"); } } @@ -242,21 +270,27 @@ - (NSInteger)searchForFormula:(BPFormula*)formula inArray:(NSArray*)array return -1; } -- (BPFormulaStatus)statusForFormula:(BPFormula*)formula -{ - if ([self searchForFormula:formula inArray:self.installedFormulae] >= 0) - { +- (BPFormulaStatus)statusForFormula:(BPFormula*)formula { + if ([self searchForFormula:formula inArray:self.installedFormulae] >= 0) { if ([self searchForFormula:formula inArray:self.outdatedFormulae] >= 0) { return kBPFormulaOutdated; - } - else - { + } else { return kBPFormulaInstalled; } + } else { + return kBPFormulaNotInstalled; } - else - { +} + +- (BPFormulaStatus)statusForCask:(BPFormula*)formula { + if ([self searchForFormula:formula inArray:self.installedCasks] >= 0) { + if ([self searchForFormula:formula inArray:self.outdatedCasks] >= 0) { + return kBPFormulaOutdated; + } else { + return kBPFormulaInstalled; + } + } else { return kBPFormulaNotInstalled; } } diff --git a/Cakebrew/BPTask.m b/Cakebrew/BPTask.m index b2a4c8c9..02bff67d 100644 --- a/Cakebrew/BPTask.m +++ b/Cakebrew/BPTask.m @@ -36,6 +36,8 @@ @interface BPTask() NSFileHandle *errorFileHandle; NSMutableData *outputData; NSMutableData *errorData; + int someAsyncOut; + int someAsyncErr; NSObject *outputHandlerObserver; NSObject *errorHandlerObserver; void (^operationUpdateBlock)(NSString*); @@ -59,6 +61,13 @@ - (instancetype)initWithPath:(NSString *)path arguments:(NSArray *)arguments self = [super init]; if (self) { + someAsyncOut = 0; + someAsyncErr = 0; + #ifdef DEBUG + if (![self shouldUsePartialUpdates]) { + NSLog(@"cmd: %@ %@", path, [arguments componentsJoinedByString:@" "]); + } + #endif _task = [self taskWithPath:path arguments:arguments]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidTerminate:) @@ -157,24 +166,33 @@ - (void)processStandardError } } } - +/** + * waitUntilExit makes sure that we stay in the same run loop (thread); needed for notifications + */ - (int)execute { [self configureStandardOutput]; - [self configureStandardError]; [self configureOutputFileHandle]; + [self configureStandardError]; [self configureErrorFileHandle]; [self beginActivity]; @try { [self.task launch]; - [self.task waitUntilExit]; //this makes sure that we stay in the same run loop (thread); needed for notifications - - return [self.task terminationStatus]; + [self.task waitUntilExit]; + if (![self shouldUsePartialUpdates]) { +// #ifdef DEBUG +// NSLog(@"\tcode = %d", [self.task terminationStatus]); +// NSLog(@"\tout = %@", self.output); +// NSLog(@"\terr = %@", self.error); +// #endif + return [self.task terminationStatus]; + } else { + return 0; + } } @catch (NSException *exception) { NSLog(@"Exception: %@", exception); [self cleanup]; - return -1; } } @@ -183,35 +201,53 @@ - (void)updatedFileHandle:(NSNotification*)notification { NSFileHandle *fileHandle = [notification object]; NSData *data = [fileHandle readDataToEndOfFile]; - + if (fileHandle == outputFileHandle) { [outputData appendData:data]; + someAsyncOut += data.length + 1; } if (fileHandle == errorFileHandle) { [errorData appendData:data]; + someAsyncErr += data.length + 1; } - [fileHandle waitForDataInBackgroundAndNotify]; - - if (data && data.length > 0) { + if (someAsyncOut > 0 && someAsyncErr > 0 ) { dispatch_queue_t queue = [self updateBlockQueue]; if (queue == nil) { queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); } + [self processStandardOutput]; + [self processStandardError]; + #ifdef DEBUG + NSLog(@"async cmd: %@ %@", [self.task launchPath], [[self.task arguments] componentsJoinedByString:@" "]); + NSLog(@"\tcode = %d", [self.task terminationStatus]); + NSLog(@"\tout = %@", self.output); + NSLog(@"\terr = %@", self.error); + #endif dispatch_async(queue, ^{ - self.updateBlock([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); + self.updateBlock(self.output); }); + [self taskDidTerminateH]; } } - (void)taskDidTerminate:(NSNotification *)notification { + if ([self shouldUsePartialUpdates]) { + if (someAsyncOut < 1 || someAsyncErr < 1) { + return; + } + } [self processStandardOutput]; [self processStandardError]; + [self taskDidTerminateH]; +} +- (void)taskDidTerminateH +{ [[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:outputHandlerObserver]; [[NSNotificationCenter defaultCenter] removeObserver:errorHandlerObserver]; diff --git a/Cakebrew/Base.lproj/MainMenu.xib b/Cakebrew/Base.lproj/MainMenu.xib index 37877c54..fe18eec0 100644 --- a/Cakebrew/Base.lproj/MainMenu.xib +++ b/Cakebrew/Base.lproj/MainMenu.xib @@ -1,8 +1,8 @@ - + - + @@ -587,7 +587,7 @@ CA - + @@ -780,11 +780,11 @@ CA - + - + @@ -846,7 +846,7 @@ CA - +