Files
cappuccino/Tools/XcodeCapp/XcodeCapp/ProcessSourceOperation.m
T
Aparajita Fishman 668eb1f8c4 Fixed: in some cases nib2cib would write to stdout, which wasn't captured by XcodeCapp.
Previously, only stderr was checked for response text. In some edge cases it would write an error message to stdout. In addition, the default error message provided when the return status was non-zero and the output was empty was implemented incorrectly.

Now all output from nib2cib is correctly captured.

Also updated help to indicate how to enable debug logging.
2013-05-25 19:23:10 -04:00

201 lines
6.4 KiB
Objective-C

//
// ProcessSourceOperation.m
// XcodeCapp
//
// Created by Aparajita on 4/27/13.
// Copyright (c) 2013 Cappuccino Project. All rights reserved.
//
#import "ProcessSourceOperation.h"
#import "Notifications.h"
#import "XcodeCapp.h"
@interface ProcessSourceOperation ()
@property XcodeCapp *xcc;
@property NSNumber *projectId;
@property NSString *sourcePath;
@property NSString *projectPath;
@end
@implementation ProcessSourceOperation
- (id)initWithXCC:(XcodeCapp *)xcc projectId:(NSNumber *)projectId sourcePath:(NSString *)sourcePath
{
self = [super init];
if (self)
{
self.xcc = xcc;
self.projectId = projectId;
self.sourcePath = sourcePath;
self.projectPath = xcc.projectPath;
}
return self;
}
- (void)main
{
if (self.isCancelled)
return;
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
NSDictionary *info = @{ @"projectId":self.projectId, @"path":self.sourcePath };
[center postNotificationName:XCCConversionDidStartNotification object:self userInfo:info];
DDLogVerbose(@"Conversion started: %@", self.sourcePath);
NSString *launchPath = nil;
NSArray *arguments = nil;
NSString *response = nil;
NSString *projectRelativePath = [self.sourcePath substringFromIndex:self.projectPath.length + 1];
NSString *notificationTitle = nil;
NSString *notificationMessage = projectRelativePath.lastPathComponent;
if ([self.xcc isXibFile:self.sourcePath])
{
launchPath = self.xcc.executablePaths[@"nib2cib"];
arguments = @[
@"--no-colors",
self.sourcePath
];
notificationTitle = @"Xib converted";
}
else if ([self.xcc isObjjFile:self.sourcePath])
{
launchPath = self.xcc.executablePaths[@"objj"];
arguments = @[
self.xcc.parserPath,
self.projectPath,
self.sourcePath
];
notificationTitle = @"Objective-J source processed";
}
else if ([self.xcc isXCCIgnoreFile:self.sourcePath])
{
if (self.isCancelled)
return;
[self.xcc performSelectorOnMainThread:@selector(computeIgnoredPaths) withObject:nil waitUntilDone:NO];
notificationTitle = @"Parsed .xcodecapp-ignore";
notificationMessage = @"Ignored paths updated";
}
// Run the task and get the response if needed
NSInteger status = 0;
if (arguments)
{
if (self.isCancelled)
return;
DDLogVerbose(@"Running processing task: %@", launchPath);
NSDictionary *taskResult = [self.xcc runTaskWithLaunchPath:launchPath
arguments:arguments
returnType:kTaskReturnTypeAny];
status = [taskResult[@"status"] intValue];
response = taskResult[@"response"];
DDLogInfo(@"Processed %@: [%ld, %@]", self.sourcePath, status, status ? response : @"");
if (self.isCancelled)
return;
if (status != 0)
{
if ([self.xcc isXibFile:self.sourcePath])
{
if (response.length == 0)
response = @"An unspecified error occurred";
notificationTitle = @"Error converting xib";
NSString *message = [NSString stringWithFormat:@"%@\n%@", self.sourcePath.lastPathComponent, response];
NSDictionary *info =
@{
@"projectId":self.projectId,
@"message":message,
@"path":self.sourcePath,
@"status":taskResult[@"status"]
};
if (self.isCancelled)
return;
[center postNotificationName:XCCConversionDidGenerateErrorNotification object:self userInfo:info];
}
else
{
notificationTitle = [(status == XCCStatusCodeError ? @"Error" : @"Warning") stringByAppendingString:@" parsing Objective-J source"];
@try
{
NSArray *errors = [response propertyList];
for (NSDictionary *error in errors)
{
[self postErrorNotificationForPath:error[@"path"] line:[error[@"line"] intValue] message:error[@"message"] status:status];
}
}
@catch (NSException *exception)
{
[self postErrorNotificationForPath:self.sourcePath line:0 message:response status:status];
}
}
[self notifyUserWithTitle:notificationTitle message:notificationMessage];
}
else if (!self.xcc.isLoadingProject)
{
[self notifyUserWithTitle:notificationTitle message:notificationMessage];
}
}
if (!self.isCancelled)
{
DDLogVerbose(@"Conversion ended: %@", self.sourcePath);
[center postNotificationName:XCCConversionDidEndNotification object:self userInfo:@{ @"projectId":self.projectId, @"path":self.sourcePath }];
}
}
- (void)postErrorNotificationForPath:(NSString *)path line:(int)line message:(NSString *)message status:(NSInteger)status
{
NSMutableDictionary *info = [NSMutableDictionary dictionaryWithObjectsAndKeys:
path, @"path",
[NSNumber numberWithInt:line], @"line",
[NSNumber numberWithInteger:status], @"status",
nil];
info[@"projectId"] = self.projectId;
info[@"message"] = [NSString stringWithFormat:@"%@, line %d\n%@", [self.sourcePath lastPathComponent], 0, message];
if (self.isCancelled)
return;
[[NSNotificationCenter defaultCenter] postNotificationName:XCCConversionDidGenerateErrorNotification object:self userInfo:info];
}
- (void)notifyUserWithTitle:(NSString *)title message:(NSString *)message
{
NSDictionary *info = @{ @"projectId":self.projectId, @"title":title, @"message":message };
if (self.isCancelled)
return;
// nib2cib can take a while to run, show a message while the conversion is happening
[self.xcc wantUserNotificationWithInfo:info];
}
@end