From d59ca46212f1affa681a4fec92dc1b2f3256f9d4 Mon Sep 17 00:00:00 2001 From: David Cruz Date: Sun, 26 Apr 2026 14:01:53 -0700 Subject: [PATCH] refactor: use git2-sys directly instead of git package --- packages/git/lde.json | 10 -- packages/git/src/init.lua | 115 ------------------ packages/lde-core/lde.json | 2 +- packages/lde-core/src/global/init.lua | 24 ++-- packages/lde-core/src/package/initialize.lua | 13 +- packages/lde-core/src/package/install/git.lua | 14 ++- packages/lde-core/src/package/update.lua | 13 +- packages/lde-core/src/util/init.lua | 6 +- packages/lde-core/tests/main.test.lua | 1 - packages/lde/lde.json | 2 +- packages/lde/src/commands/publish.lua | 22 ++-- packages/lde/tests/main.test.lua | 4 +- 12 files changed, 60 insertions(+), 166 deletions(-) delete mode 100644 packages/git/lde.json delete mode 100644 packages/git/src/init.lua diff --git a/packages/git/lde.json b/packages/git/lde.json deleted file mode 100644 index f93b00c4..00000000 --- a/packages/git/lde.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "git", - "description": "Provides git command execution in a nice API. Requires git cli to be available.", - "version": "0.1.0", - "dependencies": { - "git2-sys": { - "git": "https://github.com/lde-org/git2-sys" - } - } -} diff --git a/packages/git/src/init.lua b/packages/git/src/init.lua deleted file mode 100644 index 83d15a38..00000000 --- a/packages/git/src/init.lua +++ /dev/null @@ -1,115 +0,0 @@ -local git2 = require("git2-sys") - -local git = {} - ----@param url string ----@param dir string ----@param branch string? ----@param commit string? -function git.clone(url, dir, branch, commit) - local ok, err = pcall(function() - local repo = git2.clone(url, dir, branch) - repo:updateSubmodules() - if commit then - repo:checkout(commit) - end - repo:free() - end) - if not ok then - return nil, err - end - return true -end - ----@param cwd string? ----@param ref "HEAD" | string? -function git.getCommitHash(cwd, ref) - local ok, result = pcall(function() - local repo = git2.open(cwd or ".") - local sha = repo:revparse(ref or "HEAD") - repo:free() - return sha - end) - if not ok then - return nil, result - end - return true, result -end - ----@param repoDir string? -function git.pull(repoDir) - local ok, err = pcall(function() - local repo = git2.open(repoDir or ".") - repo:pull() - repo:free() - end) - return ok, ok and nil or err -end - ----@param dir string? ----@param bare boolean? -function git.init(dir, bare) - local ok, err = pcall(function() - local repo = git2.init(dir or ".", bare) - repo:free() - end) - return ok, ok and nil or err -end - ----@param commit string ----@param repoDir string? -function git.checkout(commit, repoDir) - local ok, err = pcall(function() - local repo = git2.open(repoDir or ".") - repo:checkout(commit) - repo:free() - end) - return ok, ok and nil or err -end - -function git.version() - local ok, v = pcall(git2.version) - return ok, ok and ("libgit2 " .. v) or v -end - ----@param dir string? -function git.isInsideWorkTree(dir) - local ok, repo = pcall(git2.open, dir or ".") - if not ok then - return false - end - local wd = repo:workdir() - repo:free() - return wd ~= nil -end - ----@param remoteName string ----@param cwd string? -function git.remoteGetUrl(remoteName, cwd) - local ok, result = pcall(function() - local repo = git2.open(cwd or ".") - local url = repo:remoteUrl(remoteName) - repo:free() - return url - end) - if not ok then - return nil, result - end - return true, result -end - ----@param cwd string? -function git.getCurrentBranch(cwd) - local ok, result = pcall(function() - local repo = git2.open(cwd or ".") - local branch = repo:currentBranch() - repo:free() - return branch - end) - if not ok then - return nil, result - end - return true, result -end - -return git diff --git a/packages/lde-core/lde.json b/packages/lde-core/lde.json index 134ed49b..2aca0424 100644 --- a/packages/lde-core/lde.json +++ b/packages/lde-core/lde.json @@ -14,7 +14,7 @@ "curl-sys": { "git": "https://github.com/lde-org/curl-sys" }, "semver": { "path": "../semver" }, "lde-test": { "path": "../lde-test" }, - "git": { "path": "../git" }, + "git2-sys": { "git": "https://github.com/lde-org/git2-sys" }, "rocked": { "path": "../rocked" }, "luarocks": { "path": "../luarocks" }, "archive": { "git": "https://github.com/lde-org/archive" }, diff --git a/packages/lde-core/src/global/init.lua b/packages/lde-core/src/global/init.lua index a2934217..9cbf1102 100644 --- a/packages/lde-core/src/global/init.lua +++ b/packages/lde-core/src/global/init.lua @@ -1,5 +1,5 @@ local fs = require("fs") -local git = require("git") +local git2 = require("git2-sys") local json = require("json") local path = require("path") local process = require("process") @@ -100,12 +100,14 @@ function global.syncRegistry() local registryDir = global.getRegistryDir() if not fs.exists(registryDir) then - local ok, err = git.clone(global.getConfig().registry, registryDir) - if not ok then + local repo, err = git2.clone(global.getConfig().registry, registryDir) + if not repo then error("Failed to clone lde registry: " .. (err or "unknown error")) end + repo:updateSubmodules() else - git.pull(registryDir) + local repo = git2.open(registryDir) + if repo then repo:pull() end end end @@ -182,7 +184,14 @@ end ---@param commit string? function global.cloneDir(repoName, repoUrl, branch, commit) local repoDir = global.getGitRepoDir(repoName, branch, commit) - return git.clone(repoUrl, repoDir, branch, commit) + local repo, err = git2.clone(repoUrl, repoDir, branch) + if not repo then return nil, err end + repo:updateSubmodules() + if commit then + local ok, cerr = repo:checkout(commit) + if not ok then return nil, cerr end + end + return true end ---@param repoName string @@ -278,10 +287,11 @@ function global.getOrCloneRepo(repoName, cloneUrl, branch) local safeName = branch and (repoName .. "-" .. branch) or repoName local repoDir = global.getGitRepoDir(safeName) if not fs.exists(repoDir) then - local ok, err = git.clone(cloneUrl, repoDir, branch) - if not ok then + local repo, err = git2.clone(cloneUrl, repoDir, branch) + if not repo then error("Failed to clone git repository: " .. (err or "unknown error")) end + repo:updateSubmodules() end return repoDir end diff --git a/packages/lde-core/src/package/initialize.lua b/packages/lde-core/src/package/initialize.lua index 3acbe031..c6fa887f 100644 --- a/packages/lde-core/src/package/initialize.lua +++ b/packages/lde-core/src/package/initialize.lua @@ -2,18 +2,19 @@ local path = require("path") local fs = require("fs") local util = require("util") local ansi = require("ansi") -local git = require("git") +local git2 = require("git2-sys") local Package = require("lde-core.package") local function hasGit() - return git.version() == true + return true end ---@param dir string local function isInsideGitRepo(dir) - local ok = git.isInsideWorkTree(dir) - return ok == true + local repo = git2.open(dir) + if not repo then return false end + return repo:workdir() ~= nil end --- Initializes a package at the given directory. @@ -79,8 +80,8 @@ local function initPackage(dir) end if hasGit() and not isInsideGitRepo(dir) then - local ok = git.init(dir) - if not ok then + local repo = git2.init(dir) + if not repo then ansi.printf("{yellow}Warning: failed to initialize git repository") end end diff --git a/packages/lde-core/src/package/install/git.lua b/packages/lde-core/src/package/install/git.lua index f7fca99f..2b0d97bc 100644 --- a/packages/lde-core/src/package/install/git.lua +++ b/packages/lde-core/src/package/install/git.lua @@ -1,6 +1,6 @@ local fs = require("fs") local path = require("path") -local git = require("git") +local git2 = require("git2-sys") local lde = require("lde-core") ---@param packageName string @@ -11,11 +11,15 @@ local function resolve(packageName, depInfo) local resolvedCommit = depInfo.commit if not resolvedCommit then - local ok, output = git.getCommitHash(repoDir) - resolvedCommit = (ok and output) and string.gsub(output, "%s+$", "") or nil - if not resolvedCommit then - error("Failed to resolve HEAD commit for git dependency") + local repo, openErr = git2.open(repoDir) + if not repo then + error("Failed to resolve HEAD commit for git dependency: " .. (openErr or "")) end + local sha, revErr = repo:revparse("HEAD") + if not sha then + error("Failed to resolve HEAD commit for git dependency: " .. (revErr or "")) + end + resolvedCommit = sha end ---@type lde.Lockfile.GitDependency diff --git a/packages/lde-core/src/package/update.lua b/packages/lde-core/src/package/update.lua index f542d9a5..cef28abb 100644 --- a/packages/lde-core/src/package/update.lua +++ b/packages/lde-core/src/package/update.lua @@ -1,6 +1,6 @@ local fs = require("fs") local json = require("json") -local git = require("git") +local git2 = require("git2-sys") local semver = require("semver") local luarocks = require("luarocks") @@ -23,12 +23,17 @@ local function updateGitDependency(name, depInfo) return false, "skipped (not installed)" end - local ok, output = git.pull(repoDir) + local repo, openErr = git2.open(repoDir) + if not repo then + return false, "failed: " .. (openErr or "unknown error") + end + + local ok, pullErr = repo:pull() if not ok then - return false, "failed: " .. (output or "unknown error") + return false, "failed: " .. (pullErr or "unknown error") end - return true, (string.gsub(output or "updated", "%s+$", "")) + return true, "updated" end --- Updates a registry dependency to the latest compatible version (same major). diff --git a/packages/lde-core/src/util/init.lua b/packages/lde-core/src/util/init.lua index 8f89750d..532d2f29 100644 --- a/packages/lde-core/src/util/init.lua +++ b/packages/lde-core/src/util/init.lua @@ -2,7 +2,7 @@ local util = {} local fs = require("fs") local path = require("path") -local git = require("git") +local git2 = require("git2-sys") local json = require("json") local rocked = require("rocked") local ansi = require("ansi") @@ -127,7 +127,9 @@ function util.openRockspecUrl(name, url, branch, commit) if sourceUrl:match("^git") then sourceUrl = util.normalizeGitUrl(sourceUrl) dir = lde.global.getOrInitGitRepo(name, sourceUrl, branch or sourceTag, commit) - lockEntry = { git = sourceUrl, commit = select(2, git.getCommitHash(dir)) or commit, rockspec = url } + local repo = git2.open(dir) + local sha = repo and repo:revparse("HEAD") + lockEntry = { git = sourceUrl, commit = sha or commit, rockspec = url } elseif sourceUrl:match("^https?://") then dir = lde.global.getOrInitArchive(sourceUrl) lockEntry = { archive = sourceUrl, rockspec = url } diff --git a/packages/lde-core/tests/main.test.lua b/packages/lde-core/tests/main.test.lua index d210af9a..01fb52cc 100644 --- a/packages/lde-core/tests/main.test.lua +++ b/packages/lde-core/tests/main.test.lua @@ -4,7 +4,6 @@ local fs = require("fs") local env = require("env") local path = require("path") local json = require("json") -local git = require("git") local lde = require("lde-core") diff --git a/packages/lde/lde.json b/packages/lde/lde.json index c4f3d225..b9b25961 100644 --- a/packages/lde/lde.json +++ b/packages/lde/lde.json @@ -16,7 +16,7 @@ "git": "https://github.com/codebycruz/winapi", "optional": true }, - "git": { "path": "../git" }, + "git2-sys": { "git": "https://github.com/lde-org/git2-sys" }, "luarocks": { "path": "../luarocks" }, "readline": { "path": "../readline" } }, diff --git a/packages/lde/src/commands/publish.lua b/packages/lde/src/commands/publish.lua index a06b8a4a..ed1de45e 100644 --- a/packages/lde/src/commands/publish.lua +++ b/packages/lde/src/commands/publish.lua @@ -1,5 +1,5 @@ local ansi = require("ansi") -local git = require("git") +local git2 = require("git2-sys") local json = require("json") local process = require("process") @@ -28,14 +28,6 @@ local function openBrowser(url) end end ----@param ok boolean ----@param output string? ----@return string? -local function trimOutput(ok, output) - if not ok or not output then return nil end - return (string.gsub(output, "%s+$", "")) -end - ---@param args clap.Args local function publish(args) local pkg, err = lde.Package.open() @@ -47,19 +39,25 @@ local function publish(args) local config = pkg:readConfig() local pkgDir = pkg:getDir() - local gitUrl = trimOutput(git.remoteGetUrl("origin", pkgDir)) + local repo, repoErr = git2.open(pkgDir) + if not repo then + ansi.printf("{red}Could not open git repository: %s", repoErr or "unknown error") + return + end + + local gitUrl, urlErr = repo:remoteUrl("origin") if not gitUrl then ansi.printf("{red}Could not get git remote URL. Is this a git repo with an 'origin' remote?") return end - local commit = trimOutput(git.getCommitHash(pkgDir)) + local commit, commitErr = repo:revparse("HEAD") if not commit then ansi.printf("{red}Could not get current commit. Does this repo have any commits?") return end - local branch = trimOutput(git.getCurrentBranch(pkgDir)) or "master" + local branch = repo:currentBranch() or "master" local versions = {} json.addField(versions, config.version, commit) diff --git a/packages/lde/tests/main.test.lua b/packages/lde/tests/main.test.lua index 409999cc..c210a46f 100644 --- a/packages/lde/tests/main.test.lua +++ b/packages/lde/tests/main.test.lua @@ -4,7 +4,7 @@ local fs = require("fs") local env = require("env") local path = require("path") local json = require("json") -local git = require("git") +local git2 = require("git2-sys") local lde = require("lde-core") @@ -15,7 +15,7 @@ test.it("should not ignore --git in ldx", function() local repoDir = lde.global.getGitRepoDir("hood") fs.rmdir(repoDir) fs.mkdir(repoDir) - git.init(repoDir, true) + git2.init(repoDir, true) fs.write(path.join(repoDir, "lde.json"), json.encode({ name = "hood", version = "1.0.0",