From 88b58523487d4d87e828c82df3a35ee55cd8767c Mon Sep 17 00:00:00 2001 From: Smooth Operator Date: Sat, 4 Nov 2023 19:35:45 -0400 Subject: [PATCH 1/8] rework init()/shutdown() --- gittyup.nim | 54 ++++++++++++++++++++------------------------------ gittyup.nimble | 2 +- tests/test.nim | 5 ++--- 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/gittyup.nim b/gittyup.nim index 3f7124a..1f033a4 100644 --- a/gittyup.nim +++ b/gittyup.nim @@ -267,6 +267,8 @@ proc loadCerts(): bool = if (file, dir) == ("", ""): file = "/etc/ssl/certs/ca-certificates.crt" if not fileExists(file): + when defined(debugGit): + debug "skipped loading certs" return true # this seems to be helpful for git builds on linux, at least if file != "" and dir == "": @@ -278,44 +280,32 @@ proc loadCerts(): bool = if not result: dumpError() -proc initGit(): bool = - let code = git_libgit2_init() - result = code > 0 - when defined(debugGit): - debug "git init" - when not defined(windows): - result = result and loadCerts() - -proc init*(): bool = +proc init*(): int = ## initialize the library to prepare for git operations; - ## returns true if libgit2 was initialized - when defined(gitShutsDown): - return initGit() + ## returns the number of outstanding initializations. + result = git_libgit2_init() + if result <= 0: + raise newException(OSError, "unable to init git") else: - block: - once: - return initGit() - - result = true - -proc shutdown*(): bool = - ## shutdown the library, freeing any libgit2 data; - ## returns true if shutdown was successful - when defined(gitShutsDown): - result = git_libgit2_shutdown() >= 0 when defined(debugGit): - debug "git shut" - else: - result = true + debug "git init" + when not defined(windows): + # let it at least try to work if certs are not found + discard loadCerts() + +proc shutdown*(): int = + ## decrement the initialization counter. when the counter is zero, + ## no outstanding resources are allocated by the underlying libgit2. + result = git_libgit2_shutdown() + when defined(debugGit): + debug "git shut" template withGit(body: untyped) = ## convenience to ensure git is initialized and shutdown - if not init(): - raise newException(OSError, "unable to init git") - defer: - if not shutdown(): - raise newException(OSError, "unable to shut git") - body + if init() > 0: + defer: + discard shutdown() + body template setResultAsError(result: typed; code: cint | GitResultCode) = ## given a git result code, assign it to the result to indicate error; diff --git a/gittyup.nimble b/gittyup.nimble index bae0593..0f6d3de 100644 --- a/gittyup.nimble +++ b/gittyup.nimble @@ -1,4 +1,4 @@ -version = "3.2.1" +version = "4.0.0" author = "disruptek" description = "higher-level libgit2 bindings" license = "MIT" diff --git a/tests/test.nim b/tests/test.nim index 68ca86e..3209992 100644 --- a/tests/test.nim +++ b/tests/test.nim @@ -25,8 +25,7 @@ let tmpdir = getTempDir() / "gittyup-" & $getCurrentProcessId() / "" template setup(): GitRepository = ## setup a repo for a test - if not init(): - fail dumpError(GIT_OK) + check init() > 0 cleanup tmpdir let open = repositoryOpen getCurrentDir() check open.isOk @@ -35,7 +34,7 @@ template setup(): GitRepository = template teardown() {.dirty.} = ## tear down a test repo free repo - check shutdown() + check shutdown() == 0 cleanup tmpdir template test(body: untyped) = From 249a0ea44c1d735dfcc260d51fbd24478b1da862 Mon Sep 17 00:00:00 2001 From: Smooth Operator Date: Sat, 4 Nov 2023 22:03:57 -0400 Subject: [PATCH 2/8] shorten ci --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69b02a6..e7beca9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,10 +84,10 @@ jobs: cmake --build . -- --quiet cd ../.. nimble -y develop - if [ "${{ matrix.os }}" == "macos-latest" ]; then - balls --path="." --backend:c --backend:cpp --mm:arc --mm:orc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.dylib" --passc:"-I$(pwd)/libgit2/include" + if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then + balls --path="." --define:useMalloc --backend:c --mm:arc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.dylib" --passc:"-I$(pwd)/libgit2/include" else - balls --path="." --backend:c --backend:cpp --mm:arc --mm:orc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.so" --passc:"-I$(pwd)/libgit2/include" + balls --path="." --define:useMalloc --backend:c --mm:arc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.so" --passc:"-I$(pwd)/libgit2/include" fi - name: Build docs From df9304b4db68bbc2fd19a5152e984bb4eea43b3a Mon Sep 17 00:00:00 2001 From: Smooth Operator Date: Sat, 4 Nov 2023 22:07:41 -0400 Subject: [PATCH 3/8] oops --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e7beca9..1a638f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,9 +85,9 @@ jobs: cd ../.. nimble -y develop if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then - balls --path="." --define:useMalloc --backend:c --mm:arc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.dylib" --passc:"-I$(pwd)/libgit2/include" - else balls --path="." --define:useMalloc --backend:c --mm:arc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.so" --passc:"-I$(pwd)/libgit2/include" + else + balls --path="." --define:useMalloc --backend:c --mm:arc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.dylib" --passc:"-I$(pwd)/libgit2/include" fi - name: Build docs From a211671408cd048b54b95d400e9a0f0aab48286e Mon Sep 17 00:00:00 2001 From: Smooth Operator Date: Sun, 5 Nov 2023 08:50:40 -0500 Subject: [PATCH 4/8] check speed of sanitizers --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a638f7..ea592b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,7 +71,7 @@ jobs: shell: bash run: | sudo apt-get update - sudo apt install --fix-missing valgrind + #sudo apt install --fix-missing valgrind cd project git fetch --unshallow nimble --accept develop From e0e1a51e51e2976acfbf4d3c890a045f48ce3333 Mon Sep 17 00:00:00 2001 From: Smooth Operator Date: Sun, 5 Nov 2023 09:12:49 -0500 Subject: [PATCH 5/8] make it official and restore cpp/orc --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea592b5..b8e359a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,6 +71,7 @@ jobs: shell: bash run: | sudo apt-get update + # using compiler santizers for speed #sudo apt install --fix-missing valgrind cd project git fetch --unshallow @@ -85,9 +86,9 @@ jobs: cd ../.. nimble -y develop if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then - balls --path="." --define:useMalloc --backend:c --mm:arc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.so" --passc:"-I$(pwd)/libgit2/include" + balls --path="." --define:useMalloc --backend:c --backend:cpp --mm:orc --mm:arc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.so" --passc:"-I$(pwd)/libgit2/include" else - balls --path="." --define:useMalloc --backend:c --mm:arc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.dylib" --passc:"-I$(pwd)/libgit2/include" + balls --path="." --define:useMalloc --backend:c --backend:cpp --mm:orc --mm:arc -d:libgit2Lib="$(pwd)/libgit2/build/libgit2.dylib" --passc:"-I$(pwd)/libgit2/include" fi - name: Build docs From 34fa4a8eefc5a0e3343e95e6f396c5f55e6a9585 Mon Sep 17 00:00:00 2001 From: Smooth Operator Date: Sun, 5 Nov 2023 16:43:16 -0500 Subject: [PATCH 6/8] simplify --- gittyup.nim | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/gittyup.nim b/gittyup.nim index 1f033a4..656fa77 100644 --- a/gittyup.nim +++ b/gittyup.nim @@ -254,28 +254,18 @@ proc normalizeUrl(uri: Uri): Uri = result.scheme = "ssh" proc loadCerts(): bool = + ## true if we informed libgit2 of the system certs (posix only) # https://github.com/wildart/julia/commit/2a59c5fcb579c76715f0015784b6a0a8ebda0c0c - var - file = getEnv("SSL_CERT_FILE") - dir = getEnv("SSL_CERT_DIR") - if not fileExists(file): - file = "" - if not dirExists(dir): - dir = "" - # try to set a default for linux - when defined(posix): - if (file, dir) == ("", ""): - file = "/etc/ssl/certs/ca-certificates.crt" - if not fileExists(file): - when defined(debugGit): - debug "skipped loading certs" - return true - # this seems to be helpful for git builds on linux, at least - if file != "" and dir == "": - dir = parentDir file - result = git_libgit2_opts( - GIT_OPT_SET_SSL_CERT_LOCATIONS.cint, - file.cstring, dir.cstring) >= 0 + when not defined(posix): return false + var file = getEnv("SSL_CERT_FILE", "/etc/ssl/certs/ca-certificates.crt") + var dir = getEnv("SSL_CERT_DIR", "") + if dir == "" or not dir.dirExists: + if file == "" or not file.fileExists: + return false + else: + dir = parentDir file + result = 0 <= git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS.cint, + file.cstring, dir.cstring) # this is a little heavy-handed, but it might save someone some time if not result: dumpError() @@ -289,9 +279,8 @@ proc init*(): int = else: when defined(debugGit): debug "git init" - when not defined(windows): - # let it at least try to work if certs are not found - discard loadCerts() + # let it at least try to work if certs are not found + discard loadCerts() proc shutdown*(): int = ## decrement the initialization counter. when the counter is zero, From 34a8fcb463506723c6bfe4d50487d786dad7c1f5 Mon Sep 17 00:00:00 2001 From: Smooth Operator Date: Mon, 6 Nov 2023 12:39:06 -0500 Subject: [PATCH 7/8] simplify and rm strarray leak --- gittyup.nim | 18 +++++++----------- tests/test.nim | 4 +++- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/gittyup.nim b/gittyup.nim index 656fa77..7205888 100644 --- a/gittyup.nim +++ b/gittyup.nim @@ -222,7 +222,7 @@ template err*[T](self: var Result[T, GitResultCode]; x: GitResultCode): auto = # create a new result (eg. for an iterator) template ok*[T](x: T): auto = #results.ok(Result[T, GitResultCode], x) - results.ok(GitResult[T], x) + badresults.ok(GitResult[T], x) template err*[T](x: GitResultCode): auto = #results.err(Result[T, GitResultCode], x) badresults.err(Result[T, GitResultCode], x) @@ -409,14 +409,14 @@ proc free*(gstrings: var GitStrArray) = template gstrs: git_strarray = cast[git_strarray](gstrings) if not gstrs.strings.isNil: git_strarray_dispose(addr gstrings) - assert gstrs.strings.isNil proc free*(gstrings: var GittyStrArray) = ## free a git_strarray allocated by nim template gstrs: git_strarray = gstrings.git_strarray if not gstrs.strings.isNil: - dealloc gstrs.strings + deallocCStringArray cast[cstringArray](gstrs.strings) gstrs.strings = nil + gstrs.count = 0 iterator items(gstrings: GitStrArray | GittyStrArray): string = ## emit the members of a string array @@ -1542,23 +1542,19 @@ iterator commitsForSpec*(repo: GitRepository; for rev in repo.revWalk(walker): # if there's an error, yield it if rev.isErr: - #yield ok[GitThing](rev.get) - yield Result[GitThing, GitResultCode].ok rev.get + yield err[GitThing](rev.error) break complete else: - let - matched = rev.get.commit.parentsMatch(options, ps) + let matched = rev.get.commit.parentsMatch(options, ps) if matched.isOk and matched.get: # all the parents matched, so yield this revision - #yield ok[GitThing](rev.get) - yield Result[GitThing, GitResultCode].ok rev.get + yield ok[GitThing](get rev) else: # we're not going to emit this revision, so free it free rev.get if matched.isErr: # the matching process produced an error - #yield err[GitThing](matched.error) - yield Result[GitThing, GitResultCode].err matched.error + yield err[GitThing](matched.error) break complete proc tagCreateLightweight*(repo: GitRepository; target: GitThing; diff --git a/tests/test.nim b/tests/test.nim index 3209992..502df63 100644 --- a/tests/test.nim +++ b/tests/test.nim @@ -50,7 +50,7 @@ template gitTrap*(code: GitResultCode) = if code != GIT_OK: fail dumpError(code) -suite "giddy up, pardner": +when false: ## open the local repo test: if fileExists(getEnv"HOME" / ".gitconfig"): @@ -138,6 +138,7 @@ suite "giddy up, pardner": check rev.isOk free rev.get +suite "giddy up, pardner": ## commits for spec test: cloned := cloneme.clone(tmpdir): @@ -168,6 +169,7 @@ suite "giddy up, pardner": break found fail "unable to find v102" +when false: ## fetchRemote test: cloned := cloneme.clone(tmpdir): From 0f82418b7e69047a9c5f48314876b51d6faa4df8 Mon Sep 17 00:00:00 2001 From: Smooth Operator Date: Mon, 6 Nov 2023 12:40:58 -0500 Subject: [PATCH 8/8] restore tests --- tests/test.nim | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test.nim b/tests/test.nim index 502df63..3209992 100644 --- a/tests/test.nim +++ b/tests/test.nim @@ -50,7 +50,7 @@ template gitTrap*(code: GitResultCode) = if code != GIT_OK: fail dumpError(code) -when false: +suite "giddy up, pardner": ## open the local repo test: if fileExists(getEnv"HOME" / ".gitconfig"): @@ -138,7 +138,6 @@ when false: check rev.isOk free rev.get -suite "giddy up, pardner": ## commits for spec test: cloned := cloneme.clone(tmpdir): @@ -169,7 +168,6 @@ suite "giddy up, pardner": break found fail "unable to find v102" -when false: ## fetchRemote test: cloned := cloneme.clone(tmpdir):