From 3173567670ddf3a0e17123cead9929ba93bc5411 Mon Sep 17 00:00:00 2001 From: John Holdsworth Date: Sat, 27 Oct 2018 16:27:30 +0100 Subject: [PATCH] Related tests cache. --- InjectionIII/Info.plist | 2 +- InjectionIII/InjectionServer.mm | 79 +++++++++++++++++---------------- README.md | 19 +++++--- 3 files changed, 56 insertions(+), 44 deletions(-) diff --git a/InjectionIII/Info.plist b/InjectionIII/Info.plist index 4653afd6..a642a2ef 100644 --- a/InjectionIII/Info.plist +++ b/InjectionIII/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.2 CFBundleVersion - 1287 + 1302 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/InjectionIII/InjectionServer.mm b/InjectionIII/InjectionServer.mm index c120db56..126b8167 100644 --- a/InjectionIII/InjectionServer.mm +++ b/InjectionIII/InjectionServer.mm @@ -154,15 +154,20 @@ - (void)runInBackground { // start up a file watcher to write generated tmpfile path to client app + NSMutableDictionary *testCache = [NSMutableDictionary new]; + injector = ^(NSArray *changed) { NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; NSMutableArray *changedFiles = [NSMutableArray arrayWithArray:changed]; if ([[NSUserDefaults standardUserDefaults] boolForKey:UserDefaultsTDDEnabled]) { - NSArray *matchedTests = [InjectionServer searchForTestWithFiles:changed - projectRoot:projectFile.stringByDeletingLastPathComponent - fileManager:[NSFileManager defaultManager]]; - [changedFiles addObjectsFromArray:matchedTests]; + for (NSString *injectedFile in changed) { + NSArray *matchedTests = testCache[injectedFile] ?: + (testCache[injectedFile] = [InjectionServer searchForTestWithFile:injectedFile + projectRoot:projectFile.stringByDeletingLastPathComponent + fileManager:[NSFileManager defaultManager]]); + [changedFiles addObjectsFromArray:matchedTests]; + } } for (NSString *swiftSource in changedFiles) @@ -207,43 +212,41 @@ - (void)setProject:(NSString *)project { plugin:injector]; } -+ (NSArray *)searchForTestWithFiles:(NSArray *)injectedFiles projectRoot:(NSString *)projectRoot fileManager:(NSFileManager *)fileManager; ++ (NSArray *)searchForTestWithFile:(NSString *)injectedFile projectRoot:(NSString *)projectRoot fileManager:(NSFileManager *)fileManager; { NSMutableArray *matchedTests = [NSMutableArray array]; - for (NSString *injectedFile in injectedFiles) { - NSString *injectedFileName = [[injectedFile lastPathComponent] stringByDeletingPathExtension]; - NSURL *projectUrl = [NSURL URLWithString:projectRoot]; - NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:projectUrl - includingPropertiesForKeys:@[NSURLNameKey, NSURLIsDirectoryKey] - options:NSDirectoryEnumerationSkipsHiddenFiles - errorHandler:^BOOL(NSURL *url, NSError *error) - { - if (error) { - NSLog(@"[Error] %@ (%@)", error, url); - return NO; - } - - return YES; - }]; - - - for (NSURL *fileURL in enumerator) { - NSString *filename; - NSNumber *isDirectory; - - [fileURL getResourceValue:&filename forKey:NSURLNameKey error:nil]; - [fileURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]; - - if ([filename hasPrefix:@"_"] && [isDirectory boolValue]) { - [enumerator skipDescendants]; - continue; - } + NSString *injectedFileName = [[injectedFile lastPathComponent] stringByDeletingPathExtension]; + NSURL *projectUrl = [NSURL URLWithString:projectRoot]; + NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:projectUrl + includingPropertiesForKeys:@[NSURLNameKey, NSURLIsDirectoryKey] + options:NSDirectoryEnumerationSkipsHiddenFiles + errorHandler:^BOOL(NSURL *url, NSError *error) + { + if (error) { + NSLog(@"[Error] %@ (%@)", error, url); + return NO; + } + + return YES; + }]; + + + for (NSURL *fileURL in enumerator) { + NSString *filename; + NSNumber *isDirectory; + + [fileURL getResourceValue:&filename forKey:NSURLNameKey error:nil]; + [fileURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]; + + if ([filename hasPrefix:@"_"] && [isDirectory boolValue]) { + [enumerator skipDescendants]; + continue; + } - if (![isDirectory boolValue] && - ![[filename lastPathComponent] isEqualToString:[injectedFile lastPathComponent]] && - [[filename lowercaseString] containsString:[injectedFileName lowercaseString]]) { - [matchedTests addObject:fileURL.path]; - } + if (![isDirectory boolValue] && + ![[filename lastPathComponent] isEqualToString:[injectedFile lastPathComponent]] && + [[filename lowercaseString] containsString:[injectedFileName lowercaseString]]) { + [matchedTests addObject:fileURL.path]; } } diff --git a/README.md b/README.md index 639a1700..70e26761 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,17 @@ Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/tvOSInjection.bu Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/macOSInjection.bundle")?.load() #endif ``` +Or, for Xcode 10: + +```Swift +#if DEBUG +Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection10.bundle")?.load() +//for tvOS: +Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/tvOSInjection10.bundle")?.load() +//Or for macOS: +Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/macOSInjection10.bundle")?.load() +#endif +``` Once injection is connected, a file watcher is started in the InjectionIII app and whenever you save a Swift or Objective-C source the target app is messaged to update the implementation. @@ -47,11 +58,9 @@ from source you'll need to use: ### Available downloads -| Xcode 9 | Xcode 10 | -| ------------- | ------------- | -| [Mac app store](https://itunes.apple.com/app/injectioniii/id1380446739?mt=12) | [Direct download](http://johnholdsworth.com/InjectionX.app.zip) | - -The reason for multiple versions is routed in Swift not being AB stable yet, this means that there will be one version per Xcode release, hence numerous versions being available for download. +| Xcode 9.3/4, Xcode 10 | +| ------------- | +| [Mac app store](https://itunes.apple.com/app/injectioniii/id1380446739?mt=12) | ### Limitations