From 439f7acf2865af07f970b8bfe2691b70eca7c973 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Tue, 5 Mar 2013 21:05:19 +0100 Subject: [PATCH] Submodule wrapping courtesy of @sbinet --- submodule.go | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++ wrapper.c | 8 ++ 2 files changed, 271 insertions(+) create mode 100644 submodule.go diff --git a/submodule.go b/submodule.go new file mode 100644 index 0000000..e1e031b --- /dev/null +++ b/submodule.go @@ -0,0 +1,263 @@ +package git + +/* +#cgo pkg-config: libgit2 +#include +#include + +extern int _go_git_visit_submodule(git_repository *repo, void *fct); +*/ +import "C" +import ( + "unsafe" +) + +// Submodule +type Submodule struct { + ptr *C.git_submodule +} + +type SubmoduleUpdate int + +const ( + SubmoduleUpdateDefault SubmoduleUpdate = C.GIT_SUBMODULE_UPDATE_DEFAULT + SubmoduleUpdateCheckout = C.GIT_SUBMODULE_UPDATE_CHECKOUT + SubmoduleUpdateRebase = C.GIT_SUBMODULE_UPDATE_REBASE + SubmoduleUpdateMerge = C.GIT_SUBMODULE_UPDATE_MERGE + SubmoduleUpdateNone = C.GIT_SUBMODULE_UPDATE_NONE +) + +type SubmoduleIgnore int + +const ( + SubmoduleIgnoreDefault SubmoduleIgnore = C.GIT_SUBMODULE_IGNORE_DEFAULT + SubmoduleIgnoreNone = C.GIT_SUBMODULE_IGNORE_NONE + SubmoduleIgnoreUntracked = C.GIT_SUBMODULE_IGNORE_UNTRACKED + SubmoduleIgnoreDirty = C.GIT_SUBMODULE_IGNORE_DIRTY + SubmoduleIgnoreAll = C.GIT_SUBMODULE_IGNORE_ALL +) + +type SubmoduleStatus int + +const ( + SubmoduleStatusInHead SubmoduleStatus = C.GIT_SUBMODULE_STATUS_IN_HEAD + SubmoduleStatusInIndex = C.GIT_SUBMODULE_STATUS_IN_INDEX + SubmoduleStatusInConfig = C.GIT_SUBMODULE_STATUS_IN_CONFIG + SubmoduleStatusInWd = C.GIT_SUBMODULE_STATUS_IN_WD + SubmoduleStatusIndexAdded = C.GIT_SUBMODULE_STATUS_INDEX_ADDED + SubmoduleStatusIndexDeleted = C.GIT_SUBMODULE_STATUS_INDEX_DELETED + SubmoduleStatusIndexModified = C.GIT_SUBMODULE_STATUS_INDEX_MODIFIED + SubmoduleStatusWdUninitialized = C.GIT_SUBMODULE_STATUS_WD_UNINITIALIZED + SubmoduleStatusWdAdded = C.GIT_SUBMODULE_STATUS_WD_ADDED + SubmoduleStatusWdDeleted = C.GIT_SUBMODULE_STATUS_WD_DELETED + SubmoduleStatusWdModified = C.GIT_SUBMODULE_STATUS_WD_MODIFIED + SubmoduleStatusWdIndexModified = C.GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED + SubmoduleStatusWdWdModified = C.GIT_SUBMODULE_STATUS_WD_WD_MODIFIED + SubmoduleStatusWdUntracked = C.GIT_SUBMODULE_STATUS_WD_UNTRACKED +) + +func SubmoduleStatusIsUnmodified(status int) bool { + o := SubmoduleStatus(status) & ^(SubmoduleStatusInHead | SubmoduleStatusInIndex | + SubmoduleStatusInConfig | SubmoduleStatusInWd) + return o == 0 +} + +func (repo *Repository) LookupSubmodule(name string) (*Submodule, error) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + sub := new(Submodule) + ret := C.git_submodule_lookup(&sub.ptr, repo.ptr, cname) + if ret < 0 { + return nil, LastError() + } + + return sub, nil +} + +type SubmoduleCbk func(sub *Submodule, name string) int + +//export SubmoduleVisitor +func SubmoduleVisitor(csub unsafe.Pointer, name string, cfct unsafe.Pointer) int { + sub := &Submodule{(*C.git_submodule)(csub)} + fct := *(*SubmoduleCbk)(cfct) + return fct(sub, name) +} + +func (repo *Repository) ForeachSubmodule(cbk SubmoduleCbk) error { + ret := C._go_git_visit_submodule(repo.ptr, unsafe.Pointer(&cbk)) + if ret < 0 { + return LastError() + } + return nil +} + +func (repo *Repository) AddSubmodule(url, path string, use_git_link bool) (*Submodule, error) { + curl := C.CString(url) + defer C.free(unsafe.Pointer(curl)) + cpath := C.CString(path) + defer C.free(unsafe.Pointer(cpath)) + + sub := new(Submodule) + ret := C.git_submodule_add_setup(&sub.ptr, repo.ptr, curl, cpath, cbool(use_git_link)) + if ret < 0 { + return nil, LastError() + } + return sub, nil +} + +func (sub *Submodule) FinalizeAdd() error { + ret := C.git_submodule_add_finalize(sub.ptr) + if ret < 0 { + return LastError() + } + return nil +} + +func (sub *Submodule) AddToIndex(write_index bool) error { + ret := C.git_submodule_add_to_index(sub.ptr, cbool(write_index)) + if ret < 0 { + return LastError() + } + return nil +} + +func (sub *Submodule) Save() error { + ret := C.git_submodule_save(sub.ptr) + if ret < 0 { + return LastError() + } + return nil +} + +func (sub *Submodule) Owner() *Repository { + repo := C.git_submodule_owner(sub.ptr) + //FIXME: how to handle dangling references ? + return &Repository{repo} +} + +func (sub *Submodule) Name() string { + n := C.git_submodule_name(sub.ptr) + return C.GoString(n) +} + +func (sub *Submodule) Path() string { + n := C.git_submodule_path(sub.ptr) + return C.GoString(n) +} + +func (sub *Submodule) Url() string { + n := C.git_submodule_url(sub.ptr) + return C.GoString(n) +} + +func (sub *Submodule) SetUrl(url string) error { + curl := C.CString(url) + defer C.free(unsafe.Pointer(curl)) + + ret := C.git_submodule_set_url(sub.ptr, curl) + if ret < 0 { + return LastError() + } + return nil +} + +func (sub *Submodule) IndexId() *Oid { + idx := C.git_submodule_index_id(sub.ptr) + if idx == nil { + return nil + } + return newOidFromC(idx) +} + +func (sub *Submodule) HeadId() *Oid { + idx := C.git_submodule_head_id(sub.ptr) + if idx == nil { + return nil + } + return newOidFromC(idx) +} + +func (sub *Submodule) WdId() *Oid { + idx := C.git_submodule_wd_id(sub.ptr) + if idx == nil { + return nil + } + return newOidFromC(idx) +} + +func (sub *Submodule) Ignore() SubmoduleIgnore { + o := C.git_submodule_ignore(sub.ptr) + return SubmoduleIgnore(o) +} + +func (sub *Submodule) SetIgnore(ignore SubmoduleIgnore) SubmoduleIgnore { + o := C.git_submodule_set_ignore(sub.ptr, C.git_submodule_ignore_t(ignore)) + return SubmoduleIgnore(o) +} + +func (sub *Submodule) Update() SubmoduleUpdate { + o := C.git_submodule_update(sub.ptr) + return SubmoduleUpdate(o) +} + +func (sub *Submodule) SetUpdate(update SubmoduleUpdate) SubmoduleUpdate { + o := C.git_submodule_set_update(sub.ptr, C.git_submodule_update_t(update)) + return SubmoduleUpdate(o) +} + +func (sub *Submodule) FetchRecurseSubmodules() bool { + if 0 == C.git_submodule_fetch_recurse_submodules(sub.ptr) { + return false + } + return true +} + +func (sub *Submodule) SetFetchRecurseSubmodules(v bool) error { + ret := C.git_submodule_set_fetch_recurse_submodules(sub.ptr, cbool(v)) + if ret < 0 { + return LastError() + } + return nil +} + +func (sub *Submodule) Init(overwrite bool) error { + ret := C.git_submodule_init(sub.ptr, cbool(overwrite)) + if ret < 0 { + return LastError() + } + return nil +} + +func (sub *Submodule) Sync() error { + ret := C.git_submodule_sync(sub.ptr) + if ret < 0 { + return LastError() + } + return nil +} + +func (sub *Submodule) Open() (*Repository, error) { + repo := new(Repository) + ret := C.git_submodule_open(&repo.ptr, sub.ptr) + if ret < 0 { + return nil, LastError() + } + return repo, nil +} + +func (sub *Submodule) Reload() error { + ret := C.git_submodule_reload(sub.ptr) + if ret < 0 { + return LastError() + } + return nil +} + +func (repo *Repository) ReloadAllSubmodules() error { + ret := C.git_submodule_reload_all(repo.ptr) + if ret < 0 { + return LastError() + } + return nil +} diff --git a/wrapper.c b/wrapper.c index 4e1304e..13478cb 100644 --- a/wrapper.c +++ b/wrapper.c @@ -1,5 +1,13 @@ #include "_cgo_export.h" #include "git2.h" +#include "git2/submodule.h" + +typedef int (*gogit_submodule_cbk)(git_submodule *sm, const char *name, void *payload); + +int _go_git_visit_submodule(git_repository *repo, void *fct) +{ + return git_submodule_foreach(repo, (gogit_submodule_cbk)&SubmoduleVisitor, fct); +} int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr) {