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