1 module libgit2.example.clone; 2 3 4 private static import core.stdc.stdio; 5 private static import libgit2.checkout; 6 private static import libgit2.clone; 7 private static import libgit2.errors; 8 private static import libgit2.example.common; 9 private static import libgit2.indexer; 10 private static import libgit2.repository; 11 private static import libgit2.types; 12 13 extern (C) 14 public struct progress_data 15 { 16 libgit2.indexer.git_indexer_progress fetch_progress; 17 size_t completed_steps; 18 size_t total_steps; 19 const (char)* path; 20 } 21 22 extern (C) 23 nothrow @nogc 24 private void print_progress(const (.progress_data)* pd) 25 26 in 27 { 28 } 29 30 do 31 { 32 int network_percent = (pd.fetch_progress.total_objects > 0) ? ((100 * pd.fetch_progress.received_objects) / pd.fetch_progress.total_objects) : (0); 33 int index_percent = (pd.fetch_progress.total_objects > 0) ? ((100 * pd.fetch_progress.indexed_objects) / pd.fetch_progress.total_objects) : (0); 34 35 int checkout_percent = (pd.total_steps > 0) ? (cast(int)((100 * pd.completed_steps) / pd.total_steps)) : (0); 36 size_t kbytes = pd.fetch_progress.received_bytes / 1024; 37 38 if ((pd.fetch_progress.total_objects) && (pd.fetch_progress.received_objects == pd.fetch_progress.total_objects)) { 39 core.stdc.stdio.printf("Resolving deltas %u/%u\r", pd.fetch_progress.indexed_deltas, pd.fetch_progress.total_deltas); 40 } else { 41 core.stdc.stdio.printf("net %3d%% (%4" ~ libgit2.example.common.PRIuZ ~ " kb, %5u/%5u) / idx %3d%% (%5u/%5u) / chk %3d%% (%4" ~ libgit2.example.common.PRIuZ ~ "/%4" ~ libgit2.example.common.PRIuZ ~ ")%s\n", network_percent, kbytes, pd.fetch_progress.received_objects, pd.fetch_progress.total_objects, index_percent, pd.fetch_progress.indexed_objects, pd.fetch_progress.total_objects, checkout_percent, pd.completed_steps, pd.total_steps, pd.path); 42 } 43 } 44 45 extern (C) 46 nothrow @nogc 47 private int sideband_progress(const (char)* str, int len, void* payload) 48 49 in 50 { 51 } 52 53 do 54 { 55 //cast(void)(payload); 56 57 core.stdc.stdio.printf("remote: %.*s", len, str); 58 core.stdc.stdio.fflush(core.stdc.stdio.stdout); 59 60 return 0; 61 } 62 63 extern (C) 64 nothrow @nogc 65 private int fetch_progress(const (libgit2.indexer.git_indexer_progress)* stats, void* payload) 66 67 in 68 { 69 } 70 71 do 72 { 73 .progress_data* pd = cast(.progress_data*)(payload); 74 pd.fetch_progress = *stats; 75 .print_progress(pd); 76 77 return 0; 78 } 79 80 extern (C) 81 nothrow @nogc 82 private void checkout_progress(const (char)* path, size_t cur, size_t tot, void* payload) 83 84 in 85 { 86 } 87 88 do 89 { 90 .progress_data* pd = cast(.progress_data*)(payload); 91 pd.completed_steps = cur; 92 pd.total_steps = tot; 93 pd.path = path; 94 .print_progress(pd); 95 } 96 97 extern (C) 98 nothrow @nogc 99 public int lg2_clone(libgit2.types.git_repository* repo, int argc, char** argv) 100 101 in 102 { 103 } 104 105 do 106 { 107 //cast(void)(repo); 108 const (char)* url = argv[1]; 109 const (char)* path = argv[2]; 110 111 /* Validate args */ 112 if (argc < 3) { 113 core.stdc.stdio.printf("USAGE: %s <url> <path>\n", argv[0]); 114 115 return -1; 116 } 117 118 /* Set up options */ 119 .progress_data pd = .progress_data.init; 120 libgit2.checkout.git_checkout_options checkout_opts = libgit2.checkout.GIT_CHECKOUT_OPTIONS_INIT(); 121 checkout_opts.checkout_strategy = libgit2.checkout.git_checkout_strategy_t.GIT_CHECKOUT_SAFE; 122 checkout_opts.progress_cb = &.checkout_progress; 123 checkout_opts.progress_payload = &pd; 124 libgit2.clone.git_clone_options clone_opts = libgit2.clone.GIT_CLONE_OPTIONS_INIT(); 125 clone_opts.checkout_opts = checkout_opts; 126 clone_opts.fetch_opts.callbacks.sideband_progress = &.sideband_progress; 127 clone_opts.fetch_opts.callbacks.transfer_progress = &.fetch_progress; 128 clone_opts.fetch_opts.callbacks.credentials = &libgit2.example.common.cred_acquire_cb; 129 clone_opts.fetch_opts.callbacks.payload = &pd; 130 131 /* Do the clone */ 132 libgit2.types.git_repository* cloned_repo = null; 133 int error = libgit2.clone.git_clone(&cloned_repo, url, path, &clone_opts); 134 core.stdc.stdio.printf("\n"); 135 136 if (error != 0) { 137 const (libgit2.errors.git_error)* err = libgit2.errors.git_error_last(); 138 139 if (err != null) { 140 core.stdc.stdio.printf("ERROR %d: %s\n", err.klass, err.message); 141 } else { 142 core.stdc.stdio.printf("ERROR %d: no detailed info\n", error); 143 } 144 } else if (cloned_repo != null) { 145 libgit2.repository.git_repository_free(cloned_repo); 146 } 147 148 return error; 149 }