Inna Palant | ff3f07a | 2019-07-11 16:15:26 -0700 | [diff] [blame] | 1 | #include <stdlib.h> |
| 2 | #include <stdio.h> |
| 3 | #include <string.h> |
| 4 | |
| 5 | #include "../common.h" |
| 6 | #include "common.h" |
| 7 | |
| 8 | /* This part is not strictly libgit2-dependent, but you can use this |
| 9 | * as a starting point for a git-like tool */ |
| 10 | |
| 11 | struct { |
| 12 | char *name; |
| 13 | git_cb fn; |
| 14 | } commands[] = { |
| 15 | {"ls-remote", ls_remote}, |
| 16 | {"fetch", fetch}, |
| 17 | {"clone", do_clone}, |
| 18 | {"index-pack", index_pack}, |
| 19 | { NULL, NULL} |
| 20 | }; |
| 21 | |
| 22 | static int run_command(git_cb fn, git_repository *repo, struct args_info args) |
| 23 | { |
| 24 | int error; |
| 25 | |
| 26 | /* Run the command. If something goes wrong, print the error message to stderr */ |
| 27 | error = fn(repo, args.argc - args.pos, &args.argv[args.pos]); |
| 28 | if (error < 0) { |
Chih-Hung Hsieh | da60c85 | 2019-12-19 14:56:55 -0800 | [diff] [blame^] | 29 | if (git_error_last() == NULL) |
Inna Palant | ff3f07a | 2019-07-11 16:15:26 -0700 | [diff] [blame] | 30 | fprintf(stderr, "Error without message"); |
| 31 | else |
Chih-Hung Hsieh | da60c85 | 2019-12-19 14:56:55 -0800 | [diff] [blame^] | 32 | fprintf(stderr, "Bad news:\n %s\n", git_error_last()->message); |
Inna Palant | ff3f07a | 2019-07-11 16:15:26 -0700 | [diff] [blame] | 33 | } |
| 34 | |
| 35 | return !!error; |
| 36 | } |
| 37 | |
| 38 | int main(int argc, char **argv) |
| 39 | { |
| 40 | int i; |
| 41 | int return_code = 1; |
| 42 | int error; |
| 43 | git_repository *repo; |
| 44 | struct args_info args = ARGS_INFO_INIT; |
| 45 | const char *git_dir = NULL; |
| 46 | |
| 47 | if (argc < 2) { |
| 48 | fprintf(stderr, "usage: %s <cmd> [repo]\n", argv[0]); |
| 49 | exit(EXIT_FAILURE); |
| 50 | } |
| 51 | |
| 52 | git_libgit2_init(); |
| 53 | |
| 54 | for (args.pos = 1; args.pos < args.argc; ++args.pos) { |
| 55 | char *a = args.argv[args.pos]; |
| 56 | |
| 57 | if (a[0] != '-') { |
| 58 | /* non-arg */ |
| 59 | break; |
| 60 | } else if (optional_str_arg(&git_dir, &args, "--git-dir", ".git")) { |
| 61 | continue; |
| 62 | } else if (!strcmp(a, "--")) { |
| 63 | /* arg separator */ |
| 64 | break; |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | /* Before running the actual command, create an instance of the local |
| 69 | * repository and pass it to the function. */ |
| 70 | |
| 71 | error = git_repository_open(&repo, git_dir); |
| 72 | if (error < 0) |
| 73 | repo = NULL; |
| 74 | |
| 75 | for (i = 0; commands[i].name != NULL; ++i) { |
| 76 | if (!strcmp(args.argv[args.pos], commands[i].name)) { |
| 77 | return_code = run_command(commands[i].fn, repo, args); |
| 78 | goto shutdown; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | fprintf(stderr, "Command not found: %s\n", argv[1]); |
| 83 | |
| 84 | shutdown: |
| 85 | git_repository_free(repo); |
| 86 | |
| 87 | git_libgit2_shutdown(); |
| 88 | |
| 89 | return return_code; |
| 90 | } |