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