Merge branch 'pu/pb/index_quick_fix' into stable
[GitX.git] / gitx.m
blob6449556b26aaf11b00f9abf731256a2579ab13ae
1 //
2 //  gitx.m
3 //  GitX
4 //
5 //  Created by CiarĂ¡n Walsh on 15/08/2008.
6 //  Copyright 2008 __MyCompanyName__. All rights reserved.
7 //
9 #import "PBCLIProxy.h"
10 #import "PBGitBinary.h"
11 #import "PBEasyPipe.h"
13 NSDistantObject* connect()
15         id proxy = [NSConnection rootProxyForConnectionWithRegisteredName:ConnectionName host:nil];
16         [proxy setProtocolForProxy:@protocol(GitXCliToolProtocol)];
17         return proxy;
20 NSDistantObject *createProxy()
22         NSDistantObject *proxy = connect();
24         if (proxy)
25                 return proxy;
27         // The connection failed, so try to launch the app
28         [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier: @"nl.frim.GitX"
29                                                                                                                  options: NSWorkspaceLaunchWithoutActivation
30                                                                   additionalEventParamDescriptor: nil
31                                                                                                 launchIdentifier: nil];
33         // Now attempt to connect, allowing the app time to startup
34         int attempt;
35         for (attempt = 0; proxy == nil && attempt < 50; ++attempt) {
36                 if (proxy = connect())
37                         return proxy;
39                 usleep(15000);
40         }
42         // not succesful!
43         fprintf(stderr, "Couldn't connect to app server!\n");
44         exit(1);
45         return nil;
48 void usage(char const *programName)
51         printf("Usage: %s (--help|--version)\n", programName);
52         printf("   or: %s (--commit|-h)\n", programName);
53         printf("   or: %s <revlist options>\n", programName);
54         printf("\n");
55         printf("\t-h, --help          print this help\n");
56         printf("\t--commit, -c        start GitX in commit mode\n");
57         printf("\n");
58         printf("RevList options\n");
59         printf("\tSee 'man git-log' and 'man git-rev-list' for options you can pass to gitx\n");
60         printf("\n");
61         printf("\t--all                  show all branches\n");
62         printf("\t<branch>               show specific branch\n");
63         printf("\t -- <path>             show commits touching paths\n");
64         exit(1);
67 void version_info()
69         NSString *version = [[[NSBundle bundleForClass:[PBGitBinary class]] infoDictionary] valueForKey:@"CFBundleVersion"];
70         printf("This is GitX version %s\n", [version UTF8String]);
71         if ([PBGitBinary path])
72                 printf("Using git found at %s, version %s\n", [[PBGitBinary path] UTF8String], [[PBGitBinary version] UTF8String]);
73         else
74                 printf("GitX cannot find a git binary\n");
75         exit(1);
78 void git_path()
80         if (![PBGitBinary path])
81                 exit(101);
83         NSString *path = [[PBGitBinary path] stringByDeletingLastPathComponent];
84         printf("%s", [path UTF8String]);
85         exit(0);
88 void handleSTDINDiff(id<GitXCliToolProtocol> proxy)
90         NSFileHandle *handle = [NSFileHandle fileHandleWithStandardInput];
91         NSData *data = [handle readDataToEndOfFile];
92         NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
94         if (string && [string length] > 0) {
95                 [proxy openDiffWindowWithDiff:string];
96                 exit(0);
97         }
100 void handleDiffWithArguments(NSArray *arguments, NSString *directory, id<GitXCliToolProtocol> proxy)
102         int ret;
103         arguments = [[NSArray arrayWithObject:@"diff"] arrayByAddingObjectsFromArray:arguments];
104         NSString *diff = [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir:directory retValue:&ret];
105         if (ret) {
106                 printf("Invalid diff command\n");
107                 exit(3);
108         }
110         [proxy openDiffWindowWithDiff:diff];
111         exit(0);
114 int main(int argc, const char** argv)
116         if (argc >= 2 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
117                 usage(argv[0]);
118         if (argc >= 2 && (!strcmp(argv[1], "--version") || !strcmp(argv[1], "-v")))
119                 version_info();
120         if (argc >= 2 && !strcmp(argv[1], "--git-path"))
121                 git_path();
123         if (![PBGitBinary path]) {
124                 printf("%s\n", [[PBGitBinary notFoundError] cStringUsingEncoding:NSUTF8StringEncoding]);
125                 exit(2);
126         }
128         // Attempt to connect to the app
129         id proxy = createProxy();
131         // Create arguments
132         argv++; argc--;
133         NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:argc];
134         int i = 0;
135         for (i = 0; i < argc; i++)
136                 [arguments addObject: [NSString stringWithUTF8String:argv[i]]];
138         if (!isatty(STDIN_FILENO) && fdopen(STDIN_FILENO, "r"))
139                 handleSTDINDiff(proxy);
141         // From this point, we require a working directory
142         NSString *pwd = [[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"];
143         if (!pwd)
144                 exit(2);
146         if ([arguments count] > 0 && ([[arguments objectAtIndex:0] isEqualToString:@"--diff"] ||
147                 [[arguments objectAtIndex:0] isEqualToString:@"-d"]))
148                 handleDiffWithArguments([arguments subarrayWithRange:NSMakeRange(1, [arguments count] - 1)], pwd, proxy);
150         // No diff, just open the current dir
151         NSURL* url = [NSURL fileURLWithPath:pwd];
152         NSError* error = nil;
154         if (![proxy openRepository:url arguments: arguments error:&error]) {
155                 fprintf(stderr, "Error opening repository at %s\n", [[url path] UTF8String]);
156                 if (error)
157                         fprintf(stderr, "\t%s\n", [[error localizedFailureReason] UTF8String]);
158         }
160         return 0;