lazy.nvim/lua/lazy/manage/task/git.lua

252 lines
6.2 KiB
Lua
Raw Normal View History

local Git = require("lazy.manage.git")
2022-11-29 07:15:13 +08:00
local Lock = require("lazy.manage.lock")
2022-11-29 22:25:09 +08:00
local Config = require("lazy.core.config")
2022-11-28 18:04:32 +08:00
---@type table<string, LazyTaskDef>
local M = {}
M.log = {
2022-11-29 22:25:09 +08:00
---@param opts {updated?:boolean, check?: boolean}
skip = function(plugin, opts)
if opts.check and plugin.pin then
return true
end
if opts.updated and not (plugin._.updated and plugin._.updated.from ~= plugin._.updated.to) then
return true
2022-11-28 18:04:32 +08:00
end
local stat = vim.loop.fs_stat(plugin.dir .. "/.git")
return not (stat and stat.type == "directory")
2022-11-28 18:04:32 +08:00
end,
2022-11-29 22:25:09 +08:00
---@param opts {args?: string[], updated?:boolean, check?:boolean}
run = function(self, opts)
2022-11-28 18:04:32 +08:00
local args = {
"log",
"--pretty=format:%h %s (%cr)",
"--abbrev-commit",
"--decorate",
"--date=short",
"--color=never",
"--no-show-signature",
2022-11-28 18:04:32 +08:00
}
if opts.updated then
table.insert(args, self.plugin._.updated.from .. ".." .. (self.plugin._.updated.to or "HEAD"))
elseif opts.check then
local info = assert(Git.info(self.plugin.dir))
local target = assert(Git.get_target(self.plugin))
if not target.commit then
for k, v in pairs(target) do
error(k .. " '" .. v .. "' not found")
end
error("no target commit found")
end
assert(target.commit, self.plugin.name .. " " .. target.branch)
if not Git.eq(info, target) then
self.plugin._.updates = { from = info, to = target }
end
table.insert(args, info.commit .. ".." .. target.commit)
2022-11-29 17:55:49 +08:00
else
2022-11-29 22:25:09 +08:00
vim.list_extend(args, opts.args or Config.options.git.log)
2022-11-28 18:04:32 +08:00
end
self:spawn("git", {
args = args,
cwd = self.plugin.dir,
})
end,
}
M.clone = {
skip = function(plugin)
return plugin._.installed or plugin._.is_local
end,
2022-11-28 18:04:32 +08:00
run = function(self)
local args = {
"clone",
2022-12-06 18:12:54 +08:00
self.plugin.url,
}
if Config.options.git.filter then
args[#args + 1] = "--filter=blob:none"
end
if self.plugin.submodules ~= false then
args[#args + 1] = "--recurse-submodules"
end
args[#args + 1] = "--progress"
if self.plugin.branch then
vim.list_extend(args, { "-b", self.plugin.branch })
end
table.insert(args, self.plugin.dir)
self:spawn("git", {
args = args,
on_exit = function(ok)
if ok then
self.plugin._.cloned = true
self.plugin._.installed = true
self.plugin._.dirty = true
end
end,
})
end,
}
-- setup origin branches if needed
-- fetch will retrieve the data
M.branch = {
skip = function(plugin)
if not plugin._.installed or plugin._.is_local then
return true
2022-11-28 18:04:32 +08:00
end
local branch = assert(Git.get_branch(plugin))
return Git.get_commit(plugin.dir, branch)
end,
run = function(self)
local args = {
"remote",
"set-branches",
"--add",
"origin",
assert(Git.get_branch(self.plugin)),
}
self:spawn("git", {
args = args,
cwd = self.plugin.dir,
})
2022-11-28 18:04:32 +08:00
end,
}
-- check and switch origin
M.origin = {
skip = function(plugin)
if not plugin._.installed or plugin._.is_local then
return true
end
local origin = Git.get_origin(plugin.dir)
return origin == plugin.url
end,
---@param opts {check?:boolean}
run = function(self, opts)
if opts.check then
local origin = Git.get_origin(self.plugin.dir)
self.error = "Origin has changed:\n"
self.error = self.error .. " * old: " .. origin .. "\n"
self.error = self.error .. " * new: " .. self.plugin.url .. "\n"
self.error = self.error .. "Please run update to fix"
return
end
require("lazy.manage.task.fs").clean.run(self, opts)
M.clone.run(self, opts)
end,
}
-- fetches all needed origin branches
M.fetch = {
skip = function(plugin)
return not plugin._.installed or plugin._.is_local
end,
2022-11-28 18:04:32 +08:00
run = function(self)
local args = {
"fetch",
"--recurse-submodules",
"--tags", -- also fetch remote tags
"--force", -- overwrite existing tags if needed
"--progress",
}
if self.plugin.submodules == false then
table.remove(args, 2)
end
self:spawn("git", {
args = args,
cwd = self.plugin.dir,
})
end,
}
-- checkout to the target commit
-- branches will exists at this point, so so will the commit
M.checkout = {
skip = function(plugin)
return not plugin._.installed or plugin._.is_local
end,
2022-11-29 07:15:13 +08:00
---@param opts {lockfile?:boolean}
run = function(self, opts)
local info = assert(Git.info(self.plugin.dir))
local target = assert(Git.get_target(self.plugin))
-- if the plugin is pinned and we did not just clone it,
-- then don't update
if self.plugin.pin and not self.plugin._.cloned then
target = info
end
2022-11-29 07:15:13 +08:00
local lock
if opts.lockfile then
-- restore to the lock if it exists
2022-11-29 07:15:13 +08:00
lock = Lock.get(self.plugin)
if lock then
---@diagnostic disable-next-line: cast-local-type
target = lock
end
end
-- dont run checkout if target is already reached.
-- unless we just cloned, since then we won't have any data yet
if Git.eq(info, target) and info.branch == target.branch then
self.plugin._.updated = {
from = info.commit,
to = info.commit,
}
return
2022-11-28 18:04:32 +08:00
end
local args = {
"checkout",
"--progress",
"--recurse-submodules",
}
if self.plugin.submodules == false then
table.remove(args, 3)
end
2022-11-29 07:15:13 +08:00
if lock then
table.insert(args, lock.commit)
elseif target.tag then
table.insert(args, "tags/" .. target.tag)
elseif self.plugin.commit then
table.insert(args, self.plugin.commit)
else
table.insert(args, target.commit)
end
self:spawn("git", {
args = args,
cwd = self.plugin.dir,
on_exit = function(ok)
if ok then
local new_info = assert(Git.info(self.plugin.dir))
if not self.plugin._.cloned then
self.plugin._.updated = {
from = info.commit,
to = new_info.commit,
}
if self.plugin._.updated.from ~= self.plugin._.updated.to then
self.plugin._.dirty = true
end
end
end
end,
})
2022-11-28 18:04:32 +08:00
end,
}
return M