1 /** 2 * This part is not strictly libgit2-dependent, but you can use this 3 * as a starting point for a git-like tool 4 */ 5 module libgit2.example.lg2; 6 7 8 private static import core.stdc.stdio; 9 private static import core.stdc.stdlib; 10 private static import core.stdc.string; 11 private static import libgit2.errors; 12 private static import libgit2.example.add; 13 private static import libgit2.example.args; 14 private static import libgit2.example.blame; 15 private static import libgit2.example.cat_file; 16 private static import libgit2.example.checkout; 17 private static import libgit2.example.clone; 18 private static import libgit2.example.commit; 19 private static import libgit2.example.common; 20 private static import libgit2.example.config; 21 private static import libgit2.example.describe; 22 private static import libgit2.example.diff; 23 private static import libgit2.example.fetch; 24 private static import libgit2.example.for_each_ref; 25 private static import libgit2.example.general; 26 private static import libgit2.example.index_pack; 27 private static import libgit2.example.init; 28 private static import libgit2.example.log; 29 private static import libgit2.example.ls_files; 30 private static import libgit2.example.ls_remote; 31 private static import libgit2.example.merge; 32 private static import libgit2.example.push; 33 private static import libgit2.example.remote; 34 private static import libgit2.example.rev_list; 35 private static import libgit2.example.rev_parse; 36 private static import libgit2.example.show_index; 37 private static import libgit2.example.stash; 38 private static import libgit2.example.status; 39 private static import libgit2.example.tag; 40 private static import libgit2.global; 41 private static import libgit2.repository; 42 private static import libgit2.types; 43 44 45 public alias git_command_fn = extern (C) nothrow @nogc int function(libgit2.types.git_repository*, int, char**); 46 47 extern (C) 48 public struct commands_t 49 { 50 immutable (char)* name; 51 .git_command_fn fn; 52 char requires_repo; 53 } 54 55 public static immutable .commands_t[] commands = 56 [ 57 {"add".ptr, &libgit2.example.add.lg2_add, 1}, 58 {"blame".ptr, &libgit2.example.blame.lg2_blame, 1}, 59 {"cat-file".ptr, &libgit2.example.cat_file.lg2_cat_file, 1}, 60 {"checkout".ptr, &libgit2.example.checkout.lg2_checkout, 1}, 61 {"clone".ptr, &libgit2.example.clone.lg2_clone, 0}, 62 {"commit".ptr, &libgit2.example.commit.lg2_commit, 1}, 63 {"config".ptr, &libgit2.example.config.lg2_config, 1}, 64 {"describe".ptr, &libgit2.example.describe.lg2_describe, 1}, 65 {"diff".ptr, &libgit2.example.diff.lg2_diff, 1}, 66 {"fetch".ptr, &libgit2.example.fetch.lg2_fetch, 1}, 67 {"for-each-ref".ptr, &libgit2.example.for_each_ref.lg2_for_each_ref, 1}, 68 {"general".ptr, &libgit2.example.general.lg2_general, 0}, 69 {"index-pack".ptr, &libgit2.example.index_pack.lg2_index_pack, 1}, 70 {"init".ptr, &libgit2.example.init.lg2_init, 0}, 71 {"log".ptr, &libgit2.example.log.lg2_log, 1}, 72 {"ls-files".ptr, &libgit2.example.ls_files.lg2_ls_files, 1}, 73 {"ls-remote".ptr, &libgit2.example.ls_remote.lg2_ls_remote, 1}, 74 {"merge".ptr, &libgit2.example.merge.lg2_merge, 1}, 75 {"push".ptr, &libgit2.example.push.lg2_push, 1}, 76 {"remote".ptr, &libgit2.example.remote.lg2_remote, 1}, 77 {"rev-list".ptr, &libgit2.example.rev_list.lg2_rev_list, 1}, 78 {"rev-parse".ptr, &libgit2.example.rev_parse.lg2_rev_parse, 1}, 79 {"show-index".ptr, &libgit2.example.show_index.lg2_show_index, 0}, 80 {"stash".ptr, &libgit2.example.stash.lg2_stash, 1}, 81 {"status".ptr, &libgit2.example.status.lg2_status, 1}, 82 {"tag".ptr, &libgit2.example.tag.lg2_tag, 1}, 83 ]; 84 85 nothrow @nogc 86 private int run_command(.git_command_fn fn, libgit2.types.git_repository* repo, libgit2.example.args.args_info args) 87 88 in 89 { 90 } 91 92 do 93 { 94 /* Run the command. If something goes wrong, print the error message to stderr */ 95 int error = fn(repo, args.argc - args.pos, &args.argv[args.pos]); 96 97 if (error < 0) { 98 if (libgit2.errors.git_error_last() == null) { 99 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "Error without message"); 100 } else { 101 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "Bad news:\n %s\n", libgit2.errors.git_error_last().message); 102 } 103 } 104 105 return !!error; 106 } 107 108 nothrow @nogc 109 private void usage(const (char)* prog) 110 111 in 112 { 113 } 114 115 do 116 { 117 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "usage: %s <cmd>...\n\nAvailable commands:\n\n", prog); 118 119 for (size_t i = 0; i < commands.length; i++) { 120 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "\t%s\n", commands[i].name); 121 } 122 123 core.stdc.stdlib.exit(core.stdc.stdlib.EXIT_FAILURE); 124 } 125 126 version (LIBGIT2_EXAMPLE) 127 extern (C) 128 nothrow @nogc 129 public int main(int argc, char** argv) 130 131 do 132 { 133 if (argc < 2) { 134 .usage(argv[0]); 135 } 136 137 libgit2.example.args.args_info args = libgit2.example.args.ARGS_INFO_INIT(argc, argv); 138 libgit2.global.git_libgit2_init(); 139 140 const (char)* git_dir = null; 141 142 for (args.pos = 1; args.pos < args.argc; ++args.pos) { 143 char* a = args.argv[args.pos]; 144 145 if (a[0] != '-') { 146 /* non-arg */ 147 break; 148 } else if (libgit2.example.args.optional_str_arg(&git_dir, &args, "--git-dir", ".git")) { 149 continue; 150 } else if (libgit2.example.args.match_arg_separator(&args)) { 151 break; 152 } 153 } 154 155 if (args.pos == args.argc) { 156 .usage(argv[0]); 157 } 158 159 if (git_dir == null) { 160 git_dir = "."; 161 } 162 163 libgit2.types.git_repository* repo = null; 164 int return_code = 1; 165 166 scope (exit) { 167 libgit2.repository.git_repository_free(repo); 168 libgit2.global.git_libgit2_shutdown(); 169 } 170 171 for (size_t i = 0; i < commands.length; ++i) { 172 if (core.stdc..string.strcmp(args.argv[args.pos], commands[i].name)) { 173 continue; 174 } 175 176 /* 177 * Before running the actual command, create an instance 178 * of the local repository and pass it to the function. 179 */ 180 if (commands[i].requires_repo) { 181 libgit2.example.common.check_lg2(libgit2.repository.git_repository_open_ext(&repo, git_dir, 0, null), "Unable to open repository '%s'", git_dir); 182 } 183 184 return_code = run_command(commands[i].fn, repo, args); 185 186 return return_code; 187 } 188 189 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "Command not found: %s\n", argv[1]); 190 191 return return_code; 192 }