问题描述
我的目标是创建一个执行 clang-format 的扩展.我的代码看起来像这样:
My goal is to create an extension that executes clang-format. My code looks something like this:
- (void)performCommandWithInvocation:(XCSourceEditorCommandInvocation *)invocation completionHandler:(void (^)(NSError * _Nullable nilOrError))completionHandler
{
NSError *error = nil;
NSURL *executableURL = [[self class] executableURL];
if (!executableURL)
{
NSString *errorDescription = [NSString stringWithFormat:@"Failed to find clang-format. Ensure it is installed at any of these locations\n%@", [[self class] clangFormatUrls]];
completionHandler([NSError errorWithDomain:SourceEditorCommandErrorDomain
code:1
userInfo:@{NSLocalizedDescriptionKey: errorDescription}]);
return;
}
NSMutableArray *args = [NSMutableArray array];
[args addObject:@"-style=LLVM"];
[args addObject:@"someFile.m"];
NSPipe *outputPipe = [NSPipe pipe];
NSPipe *errorPipe = [NSPipe pipe];
NSTask *task = [[NSTask alloc] init];
task.launchPath = executableURL.path;
task.arguments = args;
task.standardOutput = outputPipe;
task.standardError = errorPipe;
@try
{
[task launch];
}
@catch (NSException *exception)
{
completionHandler([NSError errorWithDomain:SourceEditorCommandErrorDomain
code:2
userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Failed to run clang-format: %@", exception.reason]}]);
return;
}
[task waitUntilExit];
NSString *output = [[NSString alloc] initWithData:[[outputPipe fileHandleForReading] readDataToEndOfFile]
encoding:NSUTF8StringEncoding];
NSString *errorOutput = [[NSString alloc] initWithData:[[errorPipe fileHandleForReading] readDataToEndOfFile]
encoding:NSUTF8StringEncoding];
[[outputPipe fileHandleForReading] closeFile];
[[errorPipe fileHandleForReading] closeFile];
int status = [task terminationStatus];
if (status == 0)
{
NSLog(@"Success: %@", output);
}
else
{
error = [NSError errorWithDomain:SourceEditorCommandErrorDomain
code:3
userInfo:@{NSLocalizedDescriptionKey: errorOutput}];
}
completionHandler(error);
}
我需要 try-catch 块的原因是当我尝试运行此代码时抛出异常.异常原因是:
The reason I need that try-catch block is because an exception is thrown when I try to run this code. The exception reason is:
错误:无法访问启动路径
我的 clang-format 的路径是/usr/local/bin/clang-format.我发现它不喜欢我尝试访问/usr/local/bin 中的应用程序,但/bin 是可以的(例如,如果我尝试执行/bin/ls 没有问题).
The path for my clang-format is /usr/local/bin/clang-format. What I discovered is that it doesn't like me trying to access an application in /usr/local/bin, but /bin is ok (e.g. If I try to execute /bin/ls there is no problem).
我尝试的另一个解决方案是通过设置启动路径和参数来运行/bin/bash:
Another solution I tried was to run /bin/bash by setting the launch path and arguments like this:
task.launchPath = [[[NSProcessInfo processInfo] environment] objectForKey:@"SHELL"];
task.arguments = @[@"-l", @"-c", @"/usr/local/bin/clang-format -style=LLVM someFile.m"];
这成功启动了任务,但失败并显示以下错误输出:
This successfully launches the task, but it fails with the following error output:
/bin/bash:/etc/profile: 不允许操作/bin/bash:/usr/local/bin/clang-format: 不允许操作
第一条错误消息是由于尝试在 bash 中调用 -l 参数,该参数尝试以用户身份登录.
The first error message is due to trying to call the -l parameter in bash, which tries to log in as the user.
知道如何启用对其他文件夹的访问吗?是否需要启用某种沙盒环境设置?
Any idea how I can enable access to those other folders? Is there some kind of sandbox environment setting I need to enable?
推荐答案
我猜这是因为沙盒,这是不可能的.您可以捆绑 clang-format 可执行文件并从那里使用它.
I guess that because of the sandboxing this is not possible.You could bundle the clang-format executable and use it from there.
这篇关于Xcode 8 扩展执行 NSTask的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!