commit 300a9f8364b032e7f4a3b6b01a6008428ec3ca17
Author: Leah (ctucx) <leah@ctu.cx>
Date: Tue, 16 Mar 2021 11:34:42 +0100
Author: Leah (ctucx) <leah@ctu.cx>
Date: Tue, 16 Mar 2021 11:34:42 +0100
init
14 files changed, 408 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -0,0 +1,4 @@ +libgit2.so +listAllCommits +listAllRefs +showLastCommit
diff --git a/listAllCommits.nim b/listAllCommits.nim @@ -0,0 +1,32 @@ +import os, times +import nimgit + +if paramCount() == 0: + echo "No git-repo given." + quit(QuitFailure) + +discard git_libgit2_init() + +try: + let gitRepository = openGitRepository(paramStr(1)) + let gitRevisionWalker = gitRepository.createRevisionWalker("HEAD") + + for gitOid in gitRevisionWalker.walk(): + let gitCommit = gitRepository.lookupCommit(gitOid) + + let author = gitCommit.getAuthor() + + echo "===================" + echo "hash: " & $gitOid + echo "author: " & author.name & " <" & author.email & ">" + echo "when: " & $author.when.time + echo "message: " & gitCommit.getSummary() + echo "" + + free(gitCommit) + + free(gitRevisionWalker) + free(gitRepository) + +except: + echo "Error:\n", getCurrentExceptionMsg()+ \ No newline at end of file
diff --git a/listAllRefs.nim b/listAllRefs.nim @@ -0,0 +1,33 @@ +import os +import nimgit + +if paramCount() == 0: + echo "No git-repo given." + quit(QuitFailure) + +discard git_libgit2_init() + +try: + let gitRepository = openGitRepository(paramStr(1)) + let gitRefNames = gitRepository.getGitReferenceNames() + + for gitRefName in gitRefNames: + let gitReference = gitRepository.lookupGitReference(gitRefName) + + case git_reference_type(gitReference): + of GIT_REFERENCE_DIRECT: + echo gitRefName & ": " & $git_oid_tostr_s(git_reference_target(gitReference)) + + of GIT_REFERENCE_SYMBOLIC: + echo gitRefName & " => " & $git_reference_symbolic_target(gitReference) + + else: + echo "Unexpected reference type" + quit(QuitFailure) + + free(gitReference) + + free(gitRepository) + +except: + echo "Error:\n", getCurrentExceptionMsg()+ \ No newline at end of file
diff --git a/nim.cfg b/nim.cfg @@ -0,0 +1 @@ +-d:git2Git
diff --git a/nimgit.nim b/nimgit.nim @@ -0,0 +1,6 @@ +import nimgit2 +import nimgit/[types, free, repository, objects, reference, commit] + +export nimgit2 +export types, free, objects, repository, reference, commit +
diff --git a/nimgit.nimble b/nimgit.nimble @@ -0,0 +1,16 @@ +# Package + +version = "0.1.0" +author = "Leah (ctucx)" +description = "libgit2 wrapper for nim" +license = "MIT" +srcDir = "./" +installDirs = @["nimgit"] +installFiles = @["nimgit.nim"] +bin = @["showLastCommit", "listAllCommits", "listAllFiles", "listAllRefs"] + + +# Dependencies + +requires "nim >= 1.4.2" +requires "nimgit2"
diff --git a/nimgit/commit.nim b/nimgit/commit.nim @@ -0,0 +1,26 @@ +import nimgit2 +import types, utils + +proc lookupCommit* (repo: GitRepository, oid: ptr git_oid): GitCommit = + let error = git_commit_lookup(addr result, repo, oid) + + if error != 0: + raise newException(CatchableError, "Commit lookup failed: " & $error.getResultCode) + +proc getObjectId* (commit: GitCommit): GitObjectId = + result = git_commit_id(commit) + +proc getSummary* (commit: GitCommit): string = + result = $git_commit_summary(commit) + +proc getMessage* (commit: GitCommit): string = + result = $git_commit_message(commit) + +proc getShortMessage* (commit: GitCommit): string = commit.getSummary() + +proc getAuthor* (commit: GitCommit): GitSignature = + let author = git_commit_author(commit) + + result.name = $author.name + result.email = $author.email + result.when = parseGitTime(author.when)
diff --git a/nimgit/free.nim b/nimgit/free.nim @@ -0,0 +1,53 @@ +import nimgit2 + +type + NimGitTypes = git_clone_options | git_status_options | git_checkout_options | + git_oid | git_diff_options + + GitTypes = git_repository | git_reference | git_remote | git_tag | + git_strarray | git_object | git_commit | git_status_list | + git_annotated_commit | git_tree_entry | git_revwalk | git_buf | + git_pathspec | git_tree | git_diff | git_pathspec_match_list | + git_branch_iterator | git_signature + + +proc free* [T: NimGitTypes] (point: ptr T) = dealloc(point) + +proc free* [T: GitTypes] (point: ptr T) = + ## perform a free of a git-managed pointer + when T is git_repository: + git_repository_free(point) + elif T is git_reference: + git_reference_free(point) + elif T is git_remote: + git_remote_free(point) + elif T is git_strarray: + git_strarray_dispose(point) + elif T is git_tag: + git_tag_free(point) + elif T is git_commit: + git_commit_free(point) + elif T is git_object: + git_object_free(point) + elif T is git_tree: + git_tree_free(point) + elif T is git_tree_entry: + git_tree_entry_free(point) + elif T is git_revwalk: + git_revwalk_free(point) + elif T is git_status_list: + git_status_list_free(point) + elif T is git_annotated_commit: + git_annotated_commit_free(point) + elif T is git_pathspec: + git_pathspec_free(point) + elif T is git_pathspec_match_list: + git_pathspec_match_list_free(point) + elif T is git_diff: + git_diff_free(point) + elif T is git_buf: + git_buf_dispose(point) + elif T is git_branch_iterator: + git_branch_iterator_free(point) + elif T is git_signature: + git_signature_free(point)+ \ No newline at end of file
diff --git a/nimgit/objects.nim b/nimgit/objects.nim @@ -0,0 +1,15 @@ +import nimgit2 +import types + +proc initGitObjectId* (): GitObjectId = cast[GitObjectId](sizeof(git_oid).alloc) + +proc lookupObject* (repo: GitRepository, name: string): GitObject = + let error = git_revparse_single(addr result, repo, cstring(name)) + + if error != 0: + raise newException(CatchableError, "Object lookup failed: " & $error.getResultCode) + +proc getSha* (obj: GitObjectId): string = + result = $git_oid_tostr_s(obj) + +proc `$`* (obj: GitObjectId): string = obj.getSha()+ \ No newline at end of file
diff --git a/nimgit/reference.nim b/nimgit/reference.nim @@ -0,0 +1,69 @@ +import nimgit2 +import types, free, objects + +proc getGitReferenceNames* (repo: GitRepository): seq[string] = + var gitRefsArr: git_strarray + + let error = git_reference_list(addr gitRefsArr, repo) + + if error != 0: + raise newException(CatchableError, "Cannot get reference-names: " & $error.getResultCode) + + result = cstringArrayToSeq(cast[cstringArray](gitRefsArr.strings), gitRefsArr.count) + + git_strarray_dispose(addr gitRefsArr); + +proc lookupGitReference* (repo: GitRepository, refName: string): GitReference = + let error = git_reference_lookup(addr result, repo, cstring(refName)) + + if error != 0: + raise newException(CatchableError, "Lookup failed: " & $error.getResultCode) + +proc createRevisionWalker* (repo: GitRepository, sort: git_sort_t = GIT_SORT_TOPOLOGICAL): GitRevisionWalker = + var error: cint + + error = git_revwalk_new(addr result, repo) + + if error != 0: + raise newException(CatchableError, "Cannot create RevWalker: " & $error.getResultCode) + + error = git_revwalk_sorting(result, cast[cuint](sort)) + + if error != 0: + raise newException(CatchableError, "Cannot set sorting: " & $error.getResultCode) + +proc createRevisionWalker* (repo: GitRepository, reference: string, sort: git_sort_t = GIT_SORT_TOPOLOGICAL): GitRevisionWalker = + var error: cint + var gitWalker = repo.createRevisionWalker(sort) + + error = git_revwalk_push_ref(gitWalker, "HEAD") + + if error != 0: + raise newException(CatchableError, "Cannot push: " & $error.getResultCode) + + result = gitWalker + +proc next* (walker: GitRevisionWalker): GitObjectId = + var error: cint + var objectId = initGitObjectId() + + error = git_revwalk_next(objectId, walker) + + if error != 0: + free(objectId) + raise newException(CatchableError, "Cannot get next: " & $error.getResultCode) + + result = objectId + + + +iterator walk* (walker: GitRevisionWalker): GitObjectId = + block: + try: + while true: + yield walker.next() + except: + if getCurrentExceptionMsg() == "Cannot get next: end of iteration": + break + else: + raise newException(CatchableError, getCurrentExceptionMsg())
diff --git a/nimgit/repository.nim b/nimgit/repository.nim @@ -0,0 +1,19 @@ +import nimgit2 +import types + +proc openGitRepository* (path: string): GitRepository = + let error = git_repository_open(addr result, path) + + if error != 0: + raise newException(CatchableError, "Cannot open repository: " & $error.getResultCode) + +proc getHead* (repo: GitRepository): GitReference = + let error = git_repository_head(addr result, repo) + + if error != 0: + raise newException(CatchableError, "Cannot get HEAD: " & $error.getResultCode) + +proc getPath* (repo: GitRepository): string = + return $git_repository_path(repo) + +proc `$`* (repo: GitRepository): string = repo.getPath()+ \ No newline at end of file
diff --git a/nimgit/types.nim b/nimgit/types.nim @@ -0,0 +1,90 @@ +import times +import nimgit2 + +type + GitRepository* = ptr git_repository + GitObject* = ptr git_object + GitObjectId* = ptr git_oid + GitCommit* = ptr git_commit + GitReference* = ptr git_reference + GitRevisionWalker* = ptr git_revwalk + + GitTime* = object + time* : Time + offset* : int + isSigned* : bool + + GitSignature* = object + name* : string + email* : string + `when`* : GitTime + + GitReturnCode* = enum + grcApplyFail = (GIT_EAPPLYFAIL, "patch failed") + grcIndexDirty = (GIT_EINDEXDIRTY, "dirty index") + grcMismatch = (GIT_EMISMATCH, "hash mismatch") + grcRetry = (GIT_RETRY, "retry") + grcIterOver = (GIT_ITEROVER, "end of iteration") + grcPassThrough = (GIT_PASSTHROUGH, "pass-through") + grcMergeConflict = (GIT_EMERGE_CONFLICT, "merge conflict") + grcDirectory = (GIT_EDIRECTORY, "directory") + grcUncommitted = (GIT_EUNCOMMITTED, "uncommitted") + grcInvalid = (GIT_EINVALID, "invalid") + grcEndOfFile = (GIT_EEOF, "end-of-file") + grcPeel = (GIT_EPEEL, "peel") + grcApplied = (GIT_EAPPLIED, "applied") + grcCertificate = (GIT_ECERTIFICATE, "certificate") + grcAuthentication = (GIT_EAUTH, "authentication") + grcModified = (GIT_EMODIFIED, "modified") + grcLocked = (GIT_ELOCKED, "locked") + grcConflict = (GIT_ECONFLICT, "conflict") + grcInvalidSpec = (GIT_EINVALIDSPEC, "invalid spec") + grcNonFastForward = (GIT_ENONFASTFORWARD, "not fast-forward") + grcUnmerged = (GIT_EUNMERGED, "unmerged") + grcUnbornBranch = (GIT_EUNBORNBRANCH, "unborn branch") + grcBareRepo = (GIT_EBAREREPO, "bare repository") + grcUser = (GIT_EUSER, "user-specified") + grcBuffer = (GIT_EBUFS, "buffer overflow") + grcAmbiguous = (GIT_EAMBIGUOUS, "ambiguous match") + grcExists = (GIT_EEXISTS, "object exists") + grcNotFound = (GIT_ENOTFOUND, "not found") + grcError = (GIT_ERROR, "generic error") + grcOk = (GIT_OK, "ok") + + GitErrorClass* = enum + gecNone = (GIT_ERROR_NONE, "none") + gecNoMemory = (GIT_ERROR_NOMEMORY, "no memory") + gecOS = (GIT_ERROR_OS, "os") + gecInvalid = (GIT_ERROR_INVALID, "invalid") + gecReference = (GIT_ERROR_REFERENCE, "reference") + gecZlib = (GIT_ERROR_ZLIB, "zlib") + gecRepository = (GIT_ERROR_REPOSITORY, "repository") + gecConfig = (GIT_ERROR_CONFIG, "config") + gecRegEx = (GIT_ERROR_REGEX, "regex") + gecODB = (GIT_ERROR_ODB, "odb") + gecIndex = (GIT_ERROR_INDEX, "index") + gecObject = (GIT_ERROR_OBJECT, "object") + gecNet = (GIT_ERROR_NET, "network") + gecTag = (GIT_ERROR_TAG, "tag") + gecTree = (GIT_ERROR_TREE, "tree") + gecIndexer = (GIT_ERROR_INDEXER, "indexer") + gecSSL = (GIT_ERROR_SSL, "ssl") + gecSubModule = (GIT_ERROR_SUBMODULE, "submodule") + gecThread = (GIT_ERROR_THREAD, "thread") + gecStash = (GIT_ERROR_STASH, "stash") + gecCheckOut = (GIT_ERROR_CHECKOUT, "check out") + gecFetchHead = (GIT_ERROR_FETCHHEAD, "fetch head") + gecMerge = (GIT_ERROR_MERGE, "merge") + gecSSH = (GIT_ERROR_SSH, "ssh") + gecFilter = (GIT_ERROR_FILTER, "filter") + gecRevert = (GIT_ERROR_REVERT, "revert") + gecCallBack = (GIT_ERROR_CALLBACK, "call back") + gecCherryPick = (GIT_ERROR_CHERRYPICK, "cherry pick") + gecDescribe = (GIT_ERROR_DESCRIBE, "describe") + gecReBase = (GIT_ERROR_REBASE, "re-base") + gecFileSystem = (GIT_ERROR_FILESYSTEM, "filesystem") + gecPatch = (GIT_ERROR_PATCH, "patch") + gecWorkTree = (GIT_ERROR_WORKTREE, "work tree") + gecSHA1 = (GIT_ERROR_SHA1, "sha1") + +template getResultCode* (code: cint): GitReturnCode = cast[GitReturnCode](code.ord)+ \ No newline at end of file
diff --git a/nimgit/utils.nim b/nimgit/utils.nim @@ -0,0 +1,8 @@ +import times +import nimgit2 +import types + +proc parseGitTime* (time: git_time): GitTime = + result.time = fromUnix(time.time) + result.offset = time.offset + result.isSigned = (time.sign == '+')+ \ No newline at end of file
diff --git a/showLastCommit.nim b/showLastCommit.nim @@ -0,0 +1,28 @@ +import os, times +import nimgit + +if paramCount() == 0: + echo "No git-repo given." + quit(QuitFailure) + +discard git_libgit2_init() + +try: + let gitRepository = openGitRepository(paramStr(1)) + let headCommit = cast[GitCommit](gitRepository.lookupObject("HEAD^{commit}")) + + echo "Last commit on HEAD in repo: " & $gitRepository + + let commit = cast[GitCommit](headCommit) + let author = commit.getAuthor() + + echo "hash: " & $commit.getObjectId() + echo "author: " & author.name & " <" & author.email & ">" + echo "when: " & $author.when.time + echo "message: " & commit.getSummary() + + free(commit); + free(gitRepository) + +except: + echo "Error:\n", getCurrentExceptionMsg()+ \ No newline at end of file