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 	}