Skip to content

Commit

Permalink
test: add git ops tests
Browse files Browse the repository at this point in the history
  • Loading branch information
polarmutex committed Nov 9, 2023
1 parent d54e015 commit cf8cb15
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .busted
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
return {
_all = {
coverage = false,
lpath = "lua/?.lua;lua/?/init.lua",
lpath = "lua/?.lua;lua/?/init.lua;spec/?.lua;spec/?/init.lua",
},
default = {
verbose = true
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
.direnv
.pre-commit-config.yaml
/luarocks
/lua
/lua_modules
/.luarocks
7 changes: 6 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@
devShells = {
default = pkgs.mkShell {
name = "haskell-tools.nvim-shell";
inherit (pre-commit-check) shellHook;
shellHook =
pre-commit-check.shellHook
+ ''
export RT_LIBDIR=${pkgs.glibc}
'';
buildInputs =
(with pkgs; [
neorocks
Expand All @@ -75,6 +79,7 @@
#luacheck
#markdownlint-cli
]);
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [];
};
};

Expand Down
1 change: 0 additions & 1 deletion git-worktree.nvim-scm-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,5 @@ build = {
type = 'builtin',
copy_directories = {
'doc',
'tests'
},
}
86 changes: 46 additions & 40 deletions lua/git-worktree/git.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local Job = require("plenary.job")
local Job = require("plenary").job
local Path = require("plenary.path")
local Status = require("git-worktree.status")

Expand Down Expand Up @@ -57,53 +57,59 @@ end

--- @param is_worktree boolean
--- @return string|nil
function M.find_git_dir(is_worktree)
local find_git_dir_job = Job:new({
function M.find_git_dir()
local job = Job:new {
'git',
'rev-parse',
'--absolute-git-dir',
'--show-toplevel',
cwd = vim.loop.cwd(),
})
on_stderr = function(_, data)
status:log().info("ERROR: " .. data)
end,
}

local stdout, code = find_git_dir_job:sync()
local stdout, code = job:sync()
if code ~= 0 then
status:log().error("Error in determining the git root dir")
status:log().error("Error in determining the git root dir: code:" ..
tostring(code) .. " out: " .. table.concat(stdout, "") .. ".")
return nil
end

stdout = table.concat(stdout, "")

if is_worktree then
-- if in worktree git dir returns absolute path

-- try to find the dot git folder (non-bare repo)
local git_dir = Path:new(stdout)
local has_dot_git = false
for _, dir in ipairs(git_dir:_split()) do
if dir == ".git" then
has_dot_git = true
break
end
end

if has_dot_git then
if stdout == ".git" then
return vim.loop.cwd()
else
local start = stdout:find("%.git")
return stdout:sub(1, start - 2)
end
else
local start = stdout:find("/worktrees/")
return stdout:sub(0, start - 1)
end
elseif stdout == "." then
-- we are in the root git dir
return vim.loop.cwd()
else
-- if not in worktree git dir should be absolute
return stdout
end
status:log().info("cwd: " .. vim.loop.cwd())
status:log().info("git root dir: " .. stdout)

-- if is_worktree then
-- -- if in worktree git dir returns absolute path
--
-- -- try to find the dot git folder (non-bare repo)
-- local git_dir = Path:new(stdout)
-- local has_dot_git = false
-- for _, dir in ipairs(git_dir:_split()) do
-- if dir == ".git" then
-- has_dot_git = true
-- break
-- end
-- end
--
-- if has_dot_git then
-- if stdout == ".git" then
-- return vim.loop.cwd()
-- else
-- local start = stdout:find("%.git")
-- return stdout:sub(1, start - 2)
-- end
-- else
-- local start = stdout:find("/worktrees/")
-- return stdout:sub(0, start - 1)
-- end
-- elseif stdout == "." then
-- -- we are in the root git dir
-- return vim.loop.cwd()
-- else
-- if not in worktree git dir should be absolute
return stdout
-- end
end

--- @return string|nil
Expand All @@ -112,7 +118,7 @@ function M.find_git_toplevel()
'git',
'rev-parse',
'--show-toplevel',
cwd = cwd,
cwd = vim.loop.cwd(),
})
local stdout, code = find_toplevel_job:sync()
if code == 0 then
Expand Down
40 changes: 40 additions & 0 deletions spec/git_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
local git_harness = require('util.git_harness')
local gwt_git = require('git-worktree.git')
local Status = require("git-worktree.status")

local status = Status:new()


describe('git-worktree git operations', function()
describe('finds git toplevel in normal repo', function()
before_each(function()
repo_dir = git_harness.prepare_repo()
end)
it('Public API is available after setup.', function()
local ret_git_dir = gwt_git.find_git_dir()
assert.are.same(ret_git_dir, repo_dir)
end)
end)

describe('finds git toplevel in bare repo', function()
before_each(function()
repo_dir = git_harness.prepare_repo_bare()
end)
it('no toplevel in a bare repo', function()
local ret_git_dir = gwt_git.find_git_dir()
assert.are.same(ret_git_dir, nil)
end)
end)

describe('finds git toplevel in worktree repo', function()
before_each(function()
repo_dir = git_harness.prepare_repo_worktree()
end)
it('Public API is available after setup.', function()
local ret_git_dir = gwt_git.find_git_dir()
status:log().info("ret_git_dir: " .. ret_git_dir .. ".")
status:log().info("repo_dir : " .. repo_dir .. ".")
assert.are.same(ret_git_dir, repo_dir)
end)
end)
end)
64 changes: 64 additions & 0 deletions spec/util/git_harness.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
local system = require('util.system')

local M = {}

local origin_repo_path = nil

function M.setup_origin_repo()
if origin_repo_path ~= nil then
return origin_repo_path
end

local workspace_dir = system.create_temp_dir("workspace-dir")
vim.api.nvim_set_current_dir(vim.fn.getcwd())
system.run("cp -r spec/.repo " .. workspace_dir)
vim.api.nvim_set_current_dir(workspace_dir)
system.run([[
mv .repo/.git-orig ./.git
mv .repo/* .
git config user.email "[email protected]"
git config user.name "Test User"
]])

origin_repo_path = system.create_temp_dir("origin-repo")
system.run(string.format("git clone --bare %s %s", workspace_dir, origin_repo_path))

return origin_repo_path
end

function M.prepare_repo()
M.setup_origin_repo()

local working_dir = system.create_temp_dir("working-dir")
vim.api.nvim_set_current_dir(working_dir)
system.run(string.format("git clone %s %s", origin_repo_path, working_dir))
system.run([[
git config remote.origin.url [email protected]:test/test.git
git config user.email "[email protected]"
git config user.name "Test User"
]])
return working_dir
end

function M.prepare_repo_bare()
M.setup_origin_repo()

local working_dir = system.create_temp_dir("working-bare-dir")
vim.api.nvim_set_current_dir(working_dir)
system.run(string.format("git clone --bare %s %s", origin_repo_path, working_dir))
return working_dir
end

function M.prepare_repo_worktree()
M.setup_origin_repo()

local working_dir = system.create_temp_dir("working-worktree-dir")
vim.api.nvim_set_current_dir(working_dir)
system.run(string.format("git clone --bare %s %s", origin_repo_path, working_dir))
system.run("git worktree add wt master")
local worktree_dir = working_dir .. "/wt"
vim.api.nvim_set_current_dir(worktree_dir)
return worktree_dir
end

return M
41 changes: 41 additions & 0 deletions spec/util/system.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
local M = {}

---Runs a system command and errors if it fails
---@param cmd string | table Command to be ran
---@param ignore_err boolean? Whether the error should be ignored
---@param error_msg string? The error message to be emitted on command failure
---@return string The output of the system command
function M.run(cmd, ignore_err, error_msg)
if ignore_err == nil then
ignore_err = false
end

local output = vim.fn.system(cmd)
if vim.v.shell_error ~= 0 and not ignore_err then
error(error_msg or ("Command failed: ↓\n" .. cmd .. "\nOutput from command: ↓\n" .. output))
end
return output
end

local function is_macos()
return vim.loop.os_uname().sysname == "Darwin"
end

---Create a temporary directory for use
---@param suffix string? The suffix to be appended to the temp directory, ideally avoid spaces in your suffix
---@return string The path to the temporary directory
function M.create_temp_dir(suffix)
suffix = "git-worktree-" .. (suffix or "")

local cmd
if is_macos() then
cmd = string.format("mktemp -d -t %s", suffix)
else
cmd = string.format("mktemp -d --suffix=%s", suffix)
end

local prefix = is_macos() and "/private" or ""
return prefix .. vim.trim(M.run(cmd))
end

return M

0 comments on commit cf8cb15

Please sign in to comment.