1 /* 2 * Copyright David Nadlinger 2014. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 module git.clone; 8 9 import git.checkout; 10 import git.credentials; 11 import git.remote; 12 import git.repository; 13 import git.transport; 14 import git.types; 15 import git.util; 16 import git.version_; 17 18 import deimos.git2.clone; 19 import deimos.git2.remote; 20 import deimos.git2.transport; 21 import deimos.git2.types; 22 23 /// 24 struct GitCloneOptions 25 { 26 uint version_ = git_clone_options.init.version_; 27 28 GitCheckoutOptions checkoutOptions; 29 30 bool cloneBare; 31 32 static if (targetLibGitVersion == VersionInfo(0, 19, 0)) TransferCallbackDelegate fetchProgessCallback; 33 34 string remoteName; 35 static if (targetLibGitVersion == VersionInfo(0, 19, 0)) { 36 string pushURL; 37 string fetchSpec; 38 string pushSpec; 39 40 GitCredAcquireDelegate credAcquireCallback; 41 42 GitTransportFlags transportFlags; 43 // GitTransport transport; // TODO: translate 44 // GitRemoteCallback[] remoteCallbacks; // TODO: implement translation 45 GitRemoteAutotagOption remoteAutotag; 46 } 47 string checkoutBranch; 48 } 49 50 51 static if (targetLibGitVersion == VersionInfo(0, 19, 0)) { 52 extern(C) nothrow int cFetchProgessCallback( 53 const(git_transfer_progress)* stats, 54 void* payload) 55 { 56 auto dg = (cast(GitCloneOptions*)payload).fetchProgessCallback; 57 if (dg) { 58 try { 59 auto tp = GitTransferProgress(stats); 60 dg(tp); 61 } catch (Exception e) { 62 return -1; 63 } 64 } 65 return 0; 66 } 67 68 extern(C) int cCredAcquireCallback( 69 git_cred** cred, 70 const(char)* url, 71 const(char)* username_from_url, 72 uint allowed_types, 73 void* payload) 74 { 75 auto dg = (cast(GitCloneOptions*)payload).credAcquireCallback; 76 if (dg) 77 { 78 auto dCred = dg(toSlice(url), toSlice(username_from_url), allowed_types); 79 // FIXME: cred will probably be immediately freed. 80 *cred = dCred.cHandle; 81 return 0; 82 } 83 84 // FIXME: Use real error code here. 85 return 1; 86 } 87 } 88 89 GitRepo cloneRepo(in char[] url, in char[] localPath, GitCloneOptions options = GitCloneOptions.init) 90 { 91 git_clone_options cOpts; 92 with (options) 93 { 94 cOpts.version_ = version_; 95 checkoutOptions.toCCheckoutOpts(cOpts.checkout_opts); 96 cOpts.bare = cloneBare; 97 static if (targetLibGitVersion == VersionInfo(0, 19, 0)) { 98 if (fetchProgessCallback) 99 { 100 cOpts.fetch_progress_cb = &cFetchProgessCallback; 101 cOpts.fetch_progress_payload = &cOpts; 102 } 103 } 104 cOpts.remote_name = remoteName.gitStr; 105 static if (targetLibGitVersion == VersionInfo(0, 19, 0)) { 106 cOpts.pushurl = pushURL.gitStr; 107 cOpts.fetch_spec = fetchSpec.gitStr; 108 cOpts.push_spec = pushSpec.gitStr; 109 if (credAcquireCallback) 110 { 111 cOpts.cred_acquire_cb = &cCredAcquireCallback; 112 cOpts.cred_acquire_payload = &cOpts; 113 } 114 cOpts.transport_flags = transportFlags; 115 // cOpts.transport = // TODO: Translate. 116 cOpts.remote_autotag = cast(git_remote_autotag_option_t)remoteAutotag; 117 } 118 cOpts.checkout_branch = checkoutBranch.gitStr; 119 } 120 121 git_repository* repo; 122 auto errc = git_clone(&repo, url.gitStr, localPath.gitStr, &cOpts); 123 require(errc == 0); 124 return GitRepo(repo); 125 }