-- lib-core.git-test/init.lua -- -- Smoke test for lib-core.git v0.1.0. Exercises the synchronous API -- (is_repo, clone, describe, tags) against a real Gitea repo over -- HTTPS, plus the asynchronous start_ls_remote_tags handshake through -- the engine async-pool. -- -- Designed to run under SPOREL_CI=1 (calls engine.exit on completion). -- Interactive run just sits on the polling loop and renders nothing. local git = require("lib-core.git") -- libgit2 sees this as C:\tmp\... on Windows (Win32 path-translation, -- NOT MSYS2's /tmp -> /c/msys64/tmp). For cross-platform smoke runs we -- choose a path that exists in the engine's CWD if possible; falling -- back to the platform tmp is fine because the test runs in CI mode and -- cleans up after itself. local CLONE_DIR = (os.getenv("TEMP") or "/tmp") .. "/sporel-git-smoke-clone" -- Slash normalization for libgit2: it accepts forward slashes on both -- platforms. CLONE_DIR = CLONE_DIR:gsub("\\", "/") -- Public Gitea repo used as the smoke-test target. sporel-meta and -- sporel-engine are private (require token auth which lib-core.git -- v0.1.0 does not yet plumb through), but sporel-lib-core.maps is -- public and conveniently small. local TARGET_URL = "https://git.davoryn.de/sporel/sporel-lib-core.maps.git" -- Cross-platform recursive rmdir via the platform shell. os.execute on -- Windows invokes cmd.exe (NOT MSYS2-bash) so we branch on path-sep. local function rmrf(path) local is_win = package.config:sub(1, 1) == "\\" if is_win then local winpath = path:gsub("/", "\\") os.execute('if exist "' .. winpath .. '" rmdir /S /Q "' .. winpath .. '"') else os.execute("rm -rf '" .. path .. "'") end end -- Module-state for the async leg, populated in init() and polled in update(). local async_handle = nil local async_done = false local frames = 0 function init(ctx) -- Clean state from any previous run. (Done in init() rather than at -- chunk-load so a hot-reload during dev cycles gets a fresh dir.) rmrf(CLONE_DIR) -- --- Synchronous probes ------------------------------------------------- -- is_repo of a non-existent path: must return false. (Avoid using /tmp -- because Windows may have a .git somewhere upstream of it.) assert(git.is_repo(CLONE_DIR .. "-no-such-subdir") == false, "is_repo should reject a non-existent dir") engine.print("git-test: cloning " .. TARGET_URL) local ok, err = git.clone(TARGET_URL, CLONE_DIR, "master") assert(ok, "clone failed: " .. tostring(err)) assert(git.is_repo(CLONE_DIR), "cloned dir should be a repo") engine.print("git-test: clone OK") local desc, derr = git.describe(CLONE_DIR) -- describe can legitimately fail on a repo with no annotated tags; -- treat nil as soft-fail with a marker, not a hard assertion. if desc then engine.print("git-test: describe: " .. desc) else engine.print("git-test: describe (no tag yet): " .. tostring(derr)) end local tags, terr = git.tags(CLONE_DIR) assert(tags ~= nil, "tags failed: " .. tostring(terr)) engine.print("git-test: local tag count = " .. #tags) -- --- Kick off async ls-remote ------------------------------------------ async_handle = git.start_ls_remote_tags(TARGET_URL) engine.print("git-test: async ls_remote_tags dispatched") end function update(ctx, dt) frames = frames + 1 if async_handle and not async_done then if git.is_done(async_handle) then local result = git.take_result(async_handle) async_handle = nil async_done = true if result.tags then engine.print("git-test: async tag count = " .. #result.tags) else engine.print("git-test: async ERROR = " .. tostring(result.error)) end end end -- CI completion: drop out once async finished (or after a generous -- bound — network hiccup safety). if os.getenv("SPOREL_CI") == "1" then if async_done then engine.print("git-test: PASS (CI)") engine.exit(0) elseif frames > 1800 then -- ~30s at 60fps engine.print("git-test: TIMEOUT after " .. frames .. " frames") engine.exit(1) end end end function render() -- No visuals; this is a CI smoke. Interactive runs see a blank window. end