1 /* 2 * libgit2 "remote" example - shows how to modify remotes for a repo 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.remote; 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.example.common; 21 private static import libgit2_d.remote; 22 private static import libgit2_d.strarray; 23 private static import libgit2_d.types; 24 25 package: 26 27 /** 28 * This is a sample program that is similar to "git remote". See the 29 * documentation for that (try "git help remote") to understand what this 30 * program is emulating. 31 * 32 * This demonstrates using the libgit2 APIs to modify remotes of a repository. 33 */ 34 35 public enum subcmd 36 { 37 subcmd_add, 38 subcmd_remove, 39 subcmd_rename, 40 subcmd_seturl, 41 subcmd_show, 42 } 43 44 //Declaration name in C language 45 public enum 46 { 47 subcmd_add = .subcmd.subcmd_add, 48 subcmd_remove = .subcmd.subcmd_remove, 49 subcmd_rename = .subcmd.subcmd_rename, 50 subcmd_seturl = .subcmd.subcmd_seturl, 51 subcmd_show = .subcmd.subcmd_show, 52 } 53 54 public struct remote_opts 55 { 56 .subcmd cmd; 57 58 /* for command-specific args */ 59 int argc; 60 char** argv; 61 } 62 63 extern (C) 64 nothrow @nogc 65 //int lg2_remote(libgit2_d.types.git_repository* repo, int argc, char*[] argv) 66 public int lg2_remote(libgit2_d.types.git_repository* repo, int argc, char** argv) 67 68 in 69 { 70 } 71 72 do 73 { 74 int retval = 0; 75 .remote_opts opt = .remote_opts.init; 76 77 .parse_subcmd(&opt, argc, argv); 78 79 switch (opt.cmd) { 80 case .subcmd.subcmd_add: 81 retval = .cmd_add(repo, &opt); 82 83 break; 84 85 case .subcmd.subcmd_remove: 86 retval = .cmd_remove(repo, &opt); 87 88 break; 89 90 case .subcmd.subcmd_rename: 91 retval = .cmd_rename(repo, &opt); 92 93 break; 94 95 case .subcmd.subcmd_seturl: 96 retval = .cmd_seturl(repo, &opt); 97 98 break; 99 100 case .subcmd.subcmd_show: 101 retval = .cmd_show(repo, &opt); 102 103 break; 104 105 default: 106 break; 107 } 108 109 return retval; 110 } 111 112 nothrow @nogc 113 private int cmd_add(libgit2_d.types.git_repository* repo, .remote_opts* o) 114 115 in 116 { 117 } 118 119 do 120 { 121 libgit2_d.types.git_remote* remote = null; 122 123 if (o.argc != 2) { 124 .usage("you need to specify a name and URL", null); 125 } 126 127 char* name = o.argv[0]; 128 char* url = o.argv[1]; 129 130 libgit2_d.example.common.check_lg2(libgit2_d.remote.git_remote_create(&remote, repo, name, url), "could not create remote", null); 131 132 return 0; 133 } 134 135 nothrow @nogc 136 private int cmd_remove(libgit2_d.types.git_repository* repo, .remote_opts* o) 137 138 in 139 { 140 } 141 142 do 143 { 144 if (o.argc != 1) { 145 .usage("you need to specify a name", null); 146 } 147 148 char* name = o.argv[0]; 149 150 libgit2_d.example.common.check_lg2(libgit2_d.remote.git_remote_delete(repo, name), "could not delete remote", name); 151 152 return 0; 153 } 154 155 nothrow @nogc 156 private int cmd_rename(libgit2_d.types.git_repository* repo, .remote_opts* o) 157 158 in 159 { 160 } 161 162 do 163 { 164 libgit2_d.strarray.git_strarray problems = libgit2_d.strarray.git_strarray.init; 165 166 if (o.argc != 2) { 167 .usage("you need to specify old and new remote name", null); 168 } 169 170 char* old = o.argv[0]; 171 char* new_ = o.argv[1]; 172 173 int retval = libgit2_d.remote.git_remote_rename(&problems, repo, old, new_); 174 175 if (!retval) { 176 return 0; 177 } 178 179 for (int i = 0; i < cast(int)(problems.count); i++) { 180 core.stdc.stdio.puts(problems.strings[0]); 181 } 182 183 libgit2_d.strarray.git_strarray_dispose(&problems); 184 185 return retval; 186 } 187 188 nothrow @nogc 189 private int cmd_seturl(libgit2_d.types.git_repository* repo, .remote_opts* o) 190 191 in 192 { 193 } 194 195 do 196 { 197 int push = 0; 198 char* name = null; 199 char* url = null; 200 201 for (int i = 0; i < o.argc; i++) { 202 char* arg = o.argv[i]; 203 204 if (!core.stdc..string.strcmp(arg, "--push")) { 205 push = 1; 206 } else if ((arg[0] != '-') && (name == null)) { 207 name = arg; 208 } else if ((arg[0] != '-') && (url == null)) { 209 url = arg; 210 } else { 211 .usage("invalid argument to set-url", arg); 212 } 213 } 214 215 if ((name == null) || (url == null)) { 216 .usage("you need to specify remote and the new URL", null); 217 } 218 219 int retval; 220 221 if (push) { 222 retval = libgit2_d.remote.git_remote_set_pushurl(repo, name, url); 223 } else { 224 retval = libgit2_d.remote.git_remote_set_url(repo, name, url); 225 } 226 227 libgit2_d.example.common.check_lg2(retval, "could not set URL", url); 228 229 return 0; 230 } 231 232 nothrow @nogc 233 private int cmd_show(libgit2_d.types.git_repository* repo, .remote_opts* o) 234 235 in 236 { 237 } 238 239 do 240 { 241 int verbose = 0; 242 libgit2_d.strarray.git_strarray remotes = libgit2_d.strarray.git_strarray.init; 243 libgit2_d.types.git_remote* remote = null; 244 245 for (int i = 0; i < o.argc; i++) { 246 const (char)* arg = o.argv[i]; 247 248 if ((!core.stdc..string.strcmp(arg, "-v")) || (!core.stdc..string.strcmp(arg, "--verbose"))) { 249 verbose = 1; 250 } 251 } 252 253 libgit2_d.example.common.check_lg2(libgit2_d.remote.git_remote_list(&remotes, repo), "could not retrieve remotes", null); 254 255 for (int i = 0; i < cast(int)(remotes.count); i++) { 256 const (char)* name = remotes.strings[i]; 257 258 if (!verbose) { 259 core.stdc.stdio.puts(name); 260 261 continue; 262 } 263 264 libgit2_d.example.common.check_lg2(libgit2_d.remote.git_remote_lookup(&remote, repo, name), "could not look up remote", name); 265 266 const (char)* fetch = libgit2_d.remote.git_remote_url(remote); 267 268 if (fetch != null) { 269 core.stdc.stdio.printf("%s\t%s (fetch)\n", name, fetch); 270 } 271 272 const (char)* push = libgit2_d.remote.git_remote_pushurl(remote); 273 274 /* use fetch URL if no distinct push URL has been set */ 275 push = (push != null) ? (push) : (fetch); 276 277 if (push != null) { 278 core.stdc.stdio.printf("%s\t%s (push)\n", name, push); 279 } 280 281 libgit2_d.remote.git_remote_free(remote); 282 } 283 284 libgit2_d.strarray.git_strarray_dispose(&remotes); 285 286 return 0; 287 } 288 289 nothrow @nogc 290 private void parse_subcmd(.remote_opts* opt, int argc, char** argv) 291 292 in 293 { 294 } 295 296 do 297 { 298 char* arg = argv[1]; 299 .subcmd cmd = cast(.subcmd)(0); 300 301 if (argc < 2) { 302 .usage("no command specified", null); 303 } 304 305 if (!core.stdc..string.strcmp(arg, "add")) { 306 cmd = .subcmd.subcmd_add; 307 } else if (!core.stdc..string.strcmp(arg, "remove")) { 308 cmd = .subcmd.subcmd_remove; 309 } else if (!core.stdc..string.strcmp(arg, "rename")) { 310 cmd = .subcmd.subcmd_rename; 311 } else if (!core.stdc..string.strcmp(arg, "set-url")) { 312 cmd = .subcmd.subcmd_seturl; 313 } else if (!core.stdc..string.strcmp(arg, "show")) { 314 cmd = .subcmd.subcmd_show; 315 } else { 316 .usage("command is not valid", arg); 317 } 318 319 opt.cmd = cmd; 320 321 /* executable and subcommand are removed */ 322 opt.argc = argc - 2; 323 324 opt.argv = argv + 2; 325 } 326 327 nothrow @nogc 328 private void usage(const (char)* msg, const (char)* arg) 329 330 in 331 { 332 } 333 334 do 335 { 336 core.stdc.stdio.fputs("usage: remote add <name> <url>\n", core.stdc.stdio.stderr); 337 core.stdc.stdio.fputs(" remote remove <name>\n", core.stdc.stdio.stderr); 338 core.stdc.stdio.fputs(" remote rename <old> <new>\n", core.stdc.stdio.stderr); 339 core.stdc.stdio.fputs(" remote set-url [--push] <name> <newurl>\n", core.stdc.stdio.stderr); 340 core.stdc.stdio.fputs(" remote show [-v|--verbose]\n", core.stdc.stdio.stderr); 341 342 if ((msg != null) && (arg == null)) { 343 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "\n%s\n", msg); 344 } else if ((msg != null) && (arg != null)) { 345 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "\n%s: %s\n", msg, arg); 346 } 347 348 core.stdc.stdlib.exit(1); 349 }