1 /* 2 * libgit2 "ls-files" example - shows how to view all files currently in the index 3 * 4 * Written by the libgit2 contributors 5 * 6 * To the extent possible under law, the author(s) have dedicated all copyright 7 * and related and neighboring rights to this software to the public domain 8 * worldwide. This software is distributed without any warranty. 9 * 10 * You should have received a copy of the CC0 Public Domain Dedication along 11 * with this software. If not, see 12 * <http://creativecommons.org/publicdomain/zero/1.0/>. 13 */ 14 module libgit2_d.example.ls_files; 15 16 17 private static import core.stdc.stdio; 18 private static import core.stdc.stdlib; 19 private static import core.stdc..string; 20 private static import libgit2_d.index; 21 private static import libgit2_d.repository; 22 private static import libgit2_d.types; 23 24 package: 25 26 /** 27 * This example demonstrates the libgit2 index APIs to roughly 28 * simulate the output of `git ls-files`. 29 * `git ls-files` has many options and this currently does not show them. 30 * 31 * `git ls-files` base command shows all paths in the index at that time. 32 * This includes staged and committed files, but unstaged files will not display. 33 * 34 * This currently supports the default behavior and the `--error-unmatch` option. 35 */ 36 37 public struct ls_options 38 { 39 int error_unmatch; 40 char*[1024] files; 41 size_t file_count; 42 } 43 44 nothrow @nogc 45 private void usage(const (char)* message, const (char)* arg) 46 47 in 48 { 49 } 50 51 do 52 { 53 if ((message != null) && (arg != null)) { 54 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "%s: %s\n", message, arg); 55 } else if (message != null) { 56 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "%s\n", message); 57 } 58 59 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "usage: ls-files [--error-unmatch] [--] [<file>...]\n"); 60 core.stdc.stdlib.exit(1); 61 } 62 63 nothrow @nogc 64 private int parse_options(.ls_options* opts, int argc, char** argv) 65 66 in 67 { 68 } 69 70 do 71 { 72 core.stdc..string.memset(opts, 0, .ls_options.sizeof); 73 74 if (argc < 2) { 75 return 0; 76 } 77 78 int parsing_files = 0; 79 80 for (int i = 1; i < argc; ++i) { 81 char* a = argv[i]; 82 83 /* if it doesn't start with a '-' or is after the '--' then it is a file */ 84 if ((a[0] != '-') || (parsing_files)) { 85 parsing_files = 1; 86 87 /* watch for overflows (just in case) */ 88 if (opts.file_count == 1024) { 89 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "ls-files can only support 1024 files at this time.\n"); 90 91 return -1; 92 } 93 94 opts.files[opts.file_count++] = a; 95 } else if (!core.stdc..string.strcmp(a, "--")) { 96 parsing_files = 1; 97 } else if (!core.stdc..string.strcmp(a, "--error-unmatch")) { 98 opts.error_unmatch = 1; 99 } else { 100 .usage("Unsupported argument", a); 101 102 return -1; 103 } 104 } 105 106 return 0; 107 } 108 109 nothrow @nogc 110 private int print_paths(.ls_options* opts, libgit2_d.types.git_index* index) 111 112 in 113 { 114 } 115 116 do 117 { 118 const (libgit2_d.index.git_index_entry)* entry; 119 120 /* if there are no files explicitly listed by the user print all entries in the index */ 121 if (opts.file_count == 0) { 122 size_t entry_count = libgit2_d.index.git_index_entrycount(index); 123 124 for (size_t i = 0; i < entry_count; i++) { 125 entry = libgit2_d.index.git_index_get_byindex(index, i); 126 core.stdc.stdio.puts(entry.path); 127 } 128 129 return 0; 130 } 131 132 /* loop through the files found in the args and print them if they exist */ 133 for (size_t i = 0; i < opts.file_count; ++i) { 134 const (char)* path = opts.files[i]; 135 entry = libgit2_d.index.git_index_get_bypath(index, path, libgit2_d.index.git_index_stage_t.GIT_INDEX_STAGE_NORMAL); 136 137 if (entry != null) { 138 core.stdc.stdio.puts(path); 139 } else if (opts.error_unmatch) { 140 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "error: pathspec '%s' did not match any file(s) known to git.\n", path); 141 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "Did you forget to 'git add'?\n"); 142 143 return -1; 144 } 145 } 146 147 return 0; 148 } 149 150 extern (C) 151 nothrow @nogc 152 //int lg2_ls_files(libgit2_d.types.git_repository* repo, int argc, char*[] argv) 153 public int lg2_ls_files(libgit2_d.types.git_repository* repo, int argc, char** argv) 154 155 in 156 { 157 } 158 159 do 160 { 161 .ls_options opts; 162 int error = .parse_options(&opts, argc, argv); 163 164 if (error < 0) { 165 return error; 166 } 167 168 libgit2_d.types.git_index* index = null; 169 170 scope (exit) { 171 libgit2_d.index.git_index_free(index); 172 } 173 174 error = libgit2_d.repository.git_repository_index(&index, repo); 175 176 if (error < 0) { 177 return error; 178 } 179 180 error = .print_paths(&opts, index); 181 182 return error; 183 }