diff options
| author | Jason Toffaletti <[email protected]> | 2014-01-04 00:40:21 +0000 |
|---|---|---|
| committer | Jason Toffaletti <[email protected]> | 2014-01-04 00:40:21 +0000 |
| commit | e825d66fba2cb4169c7f3b0a43c491cf9e8c0738 (patch) | |
| tree | 406c3436d4912802ad92a413d3ed6b7ed8170325 | |
| parent | 313e1126dd0c974910de74f1b6bbc0fdcbbfd06b (diff) | |
work in progress wrapping git_clone
| -rw-r--r-- | clone.go | 69 | ||||
| -rw-r--r-- | git.go | 2 | ||||
| -rw-r--r-- | remote.go | 85 | ||||
| -rw-r--r-- | wrapper.c | 14 |
4 files changed, 169 insertions, 1 deletions
diff --git a/clone.go b/clone.go new file mode 100644 index 0000000..672c325 --- /dev/null +++ b/clone.go @@ -0,0 +1,69 @@ +package git + +/* +#include <git2.h> +#include <git2/errors.h> + +static git_clone_options git_clone_options_init() { + git_clone_options ret = GIT_CLONE_OPTIONS_INIT; + return ret; +} + +*/ +import "C" +import ( + "runtime" + "unsafe" +) + +type CloneOptions struct { + *CheckoutOpts + *RemoteCallbacks + Bare bool + IgnoreCertErrors bool + RemoteName string + CheckoutBranch string +} + +func Clone(url string, path string, options *CloneOptions) (*Repository, error) { + repo := new(Repository) + + curl := C.CString(url) + defer C.free(unsafe.Pointer(curl)) + + cpath := C.CString(path) + defer C.free(unsafe.Pointer(cpath)) + + var copts C.git_clone_options + populateCloneOptions(&copts, options) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_clone(&repo.ptr, curl, cpath, &copts) + if ret < 0 { + return nil, LastError() + } + + runtime.SetFinalizer(repo, (*Repository).Free) + return repo, nil +} + +func populateCloneOptions(ptr *C.git_clone_options, opts *CloneOptions) { + *ptr = C.git_clone_options_init() + if opts == nil { + return + } + populateCheckoutOpts(&ptr.checkout_opts, opts.CheckoutOpts) + populateRemoteCallbacks(&ptr.remote_callbacks, opts.RemoteCallbacks) + if opts.Bare { + ptr.bare = 1 + } else { + ptr.bare = 0 + } + if opts.IgnoreCertErrors { + ptr.ignore_cert_errors = 1 + } else { + ptr.ignore_cert_errors = 0 + } +} + @@ -1,7 +1,7 @@ package git /* -#cgo pkg-config: libgit2 +#cgo pkg-config: --static libgit2 #include <git2.h> #include <git2/errors.h> */ diff --git a/remote.go b/remote.go new file mode 100644 index 0000000..47866ed --- /dev/null +++ b/remote.go @@ -0,0 +1,85 @@ +package git + +/* +#include <git2.h> +#include <git2/errors.h> + +static git_remote_callbacks git_remote_callbacks_init() { + git_remote_callbacks ret = GIT_REMOTE_CALLBACKS_INIT; + return ret; +} + +extern void _setup_callbacks(git_remote_callbacks *callbacks); + +*/ +import "C" +import ( + "unsafe" +) + +type RemoteCompletion uint +const ( + RemoteCompletionDownload RemoteCompletion = C.GIT_REMOTE_COMPLETION_DOWNLOAD + RemoteCompletionIndexing = C.GIT_REMOTE_COMPLETION_INDEXING + RemoteCompletionError = C.GIT_REMOTE_COMPLETION_ERROR +) + +type ProgressCallback func(str string) int +type CompletionCallback func(RemoteCompletion) int +type CredentialsCallback func(url string, username_from_url string, allowed_types uint) int // FIXME +type TransferProgressCallback func() int // FIXME +type UpdateTipsCallback func(refname string, a *Oid, b *Oid) int + +//export progressCallback +func progressCallback(_str *C.char, _len C.int, data unsafe.Pointer) int { + callbacks := (*RemoteCallbacks)(data) + str := C.GoStringN(_str, _len) + return callbacks.ProgressCallback(str) +} + +//export completionCallback +func completionCallback(completion_type C.git_remote_completion_type, data unsafe.Pointer) int { + callbacks := (*RemoteCallbacks)(data) + return callbacks.CompletionCallback((RemoteCompletion)(completion_type)) +} + +//export credentialsCallback +func credentialsCallback(_cred **C.git_cred, _url *C.char, _username_from_url *C.char, allowed_types uint, data unsafe.Pointer) int { + callbacks := (*RemoteCallbacks)(data) + //cred := C.GoString(_cred) + url := C.GoString(_url) + username_from_url := C.GoString(_username_from_url) + return callbacks.CredentialsCallback(url, username_from_url, allowed_types) +} + +//export transferProgressCallback +func transferProgressCallback(stats C.git_transfer_progress, data unsafe.Pointer) int { + callbacks := (*RemoteCallbacks)(data) + return callbacks.TransferProgressCallback() +} + +//export updateTipsCallback +func updateTipsCallback(_refname *C.char, _a *C.git_oid, _b *C.git_oid, data unsafe.Pointer) int { + callbacks := (*RemoteCallbacks)(data) + refname := C.GoString(_refname) + a := newOidFromC(_a) + b := newOidFromC(_b) + return callbacks.UpdateTipsCallback(refname, a, b) +} + +type RemoteCallbacks struct { + ProgressCallback + CompletionCallback + CredentialsCallback + TransferProgressCallback + UpdateTipsCallback +} + +func populateRemoteCallbacks(ptr *C.git_remote_callbacks, callbacks *RemoteCallbacks) { + *ptr = C.git_remote_callbacks_init() + if callbacks == nil { + return + } + C._setup_callbacks(ptr) + ptr.payload = unsafe.Pointer(callbacks) +} @@ -24,4 +24,18 @@ int _go_git_odb_foreach(git_odb *db, void *payload) { return git_odb_foreach(db, (git_odb_foreach_cb)&odbForEachCb, payload); } + +void _setup_callbacks(git_remote_callbacks *callbacks) { + typedef int (*progress_cb)(const char *str, int len, void *data); + typedef int (*completion_cb)(git_remote_completion_type type, void *data); + typedef int (*credentials_cb)(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *data); + typedef int (*transfer_progress_cb)(const git_transfer_progress *stats, void *data); + typedef int (*update_tips_cb)(const char *refname, const git_oid *a, const git_oid *b, void *data); + callbacks->progress = (progress_cb)progressCallback; + callbacks->completion = (completion_cb)completionCallback; + callbacks->credentials = (credentials_cb)credentialsCallback; + callbacks->transfer_progress = (transfer_progress_cb)transferProgressCallback; + callbacks->update_tips = (update_tips_cb)updateTipsCallback; +} + /* EOF */ |
