Use getopt_long(3) from <getopt.h> in order to parse command line
[gitlite/.git] / gitlite.c
1 #include <getopt.h>
2 #include <libgen.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <sys/param.h>
7 #include <sysexits.h>
8 #include <unistd.h>
9
10 #include <git2/clone.h>
11 #include <git2/errors.h>
12 #include <git2/global.h>
13
14 // Compile with:
15 // clang90 -o gitlite gitlite.c -lgit2 -I/usr/local/include -L/usr/local/lib -g
16
17 extern char *__progname;
18
19 void
20 git_bail_error(int rc) {
21         const git_error *err = NULL;
22
23         if (rc < 0) {
24                 err = git_error_last();
25                 if (err)
26                         printf("ERROR %d: %s\n", err->klass, err->message);
27                 else
28                         printf("ERROR %d: cannot fetch error info\n", rc);
29         }
30 }
31
32 void
33 util_stripext(char *path) {
34         char *end = path + strlen(path);
35
36         while (end > path && *end != '.') {
37                 --end;
38         }
39
40         if (end > path) {
41                 *end = '\0';
42         }
43 }
44
45 static
46 void usage(void) {
47         fprintf(stderr, "usage: %s --<git-cmd> ...\n", __progname);
48         fprintf(stderr, "usage: %s --clone <git-url> [local-path]\n", __progname);
49 }
50
51 int
52 main(int argc, char *argv[]) {
53         int rc;
54         int ch = 0;
55         int opt_index = -1;
56         int do_clone, do_fetch, do_log = 0;
57         char buff[MAXPATHLEN];
58         char *url = NULL;
59         char *ext = NULL;
60         char *local_path = NULL;
61         git_repository *cloned_repo = NULL;
62
63         static struct option longopts[] = {
64                         {"clone", required_argument, NULL, 'c'},
65                         {"fetch", no_argument, NULL, 'f'},
66                         {"log", no_argument, NULL, 'l'},
67                         {NULL, 0, NULL, 0}
68         };
69
70         if (argc == 1) {
71                 usage();
72                 return (EX_USAGE);
73         }
74
75         while ((ch = getopt_long(argc, argv, "c:fl", longopts, &opt_index)) != -1) {
76                 switch (ch) {
77                 case 'c':
78                         do_clone = 1;
79                         url = optarg;
80                         break;
81                 case 'f':
82                         do_fetch = 1;
83                         break;
84                 case 'l':
85                         do_log = 1;
86                         break;
87                 default:
88                         usage();
89                         return (EX_USAGE);
90                 }
91         }
92         argc -= optind;
93         argv += optind;
94
95         if (do_clone) {
96                 printf("handle git clone command\n");
97
98                 git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
99                 git_checkout_options co_opts = GIT_CHECKOUT_OPTIONS_INIT;
100
101                 co_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
102                 co_opts.progress_cb = NULL;
103                 co_opts.progress_payload = NULL;
104                 clone_opts.checkout_opts = co_opts;
105                 clone_opts.fetch_opts.callbacks.sideband_progress = NULL;
106                 clone_opts.fetch_opts.callbacks.transfer_progress = NULL;
107                 clone_opts.fetch_opts.callbacks.credentials = NULL;
108                 clone_opts.fetch_opts.callbacks.payload = NULL;
109
110                 rc = git_libgit2_init();
111                 git_bail_error(rc);
112
113                 local_path = argv[0];
114                 if (local_path == NULL) {
115                         ext = strdup(basename(__DECONST(char *, url)));
116                         util_stripext(__DECONST(char *, ext));
117                         asprintf(&local_path, "%s/%s", getwd(buff), ext);
118                 }
119
120                 rc = git_clone(&cloned_repo, url, local_path, &clone_opts);
121                 git_bail_error(rc);
122
123         } else if (do_fetch) {
124                 fprintf(stderr, "handle git fetch command\n");
125                 return (-1);
126
127         } else if (do_log) {
128                 fprintf(stderr, "handle git log command\n");
129                 return (-1);
130         }
131
132         if (cloned_repo)
133                 git_repository_free(cloned_repo);
134
135         rc = git_libgit2_shutdown();
136         git_bail_error(rc);
137
138         if (ext != NULL)
139                 free(ext);
140
141         return (rc);
142 }