lazy.nvim/lua/lazy/task.lua

228 lines
4.4 KiB
Lua
Raw Normal View History

2022-11-21 06:04:56 +08:00
local Process = require("lazy.process")
local Loader = require("lazy.core.loader")
local Util = require("lazy.core.util")
2022-11-21 06:04:56 +08:00
---@class LazyTask
---@field plugin LazyPlugin
---@field type TaskType
---@field running boolean
local Task = {}
2022-11-23 04:12:50 +08:00
---@alias TaskType "update"|"install"|"run"|"clean"|"log"
2022-11-21 06:04:56 +08:00
---@param plugin LazyPlugin
---@param type TaskType
function Task.new(plugin, type)
local self = setmetatable({}, {
__index = Task,
})
self.plugin = plugin
self.type = type
self.output = ""
self.status = ""
plugin.tasks = plugin.tasks or {}
table.insert(plugin.tasks, self)
return self
end
function Task:_done()
self.running = false
vim.cmd("do User LazyRender")
end
function Task:clean()
local function rm(path)
for _, entry in ipairs(Util.scandir(path)) do
if entry.type == "directory" then
rm(entry.path)
else
vim.loop.fs_unlink(entry.path)
end
end
vim.loop.fs_rmdir(path)
end
2022-11-21 07:27:28 +08:00
local dir = self.plugin.dir:gsub("/+$", "")
local stat = vim.loop.fs_lstat(dir)
2022-11-21 06:04:56 +08:00
if stat.type == "directory" then
2022-11-21 07:27:28 +08:00
rm(dir)
2022-11-21 06:04:56 +08:00
else
2022-11-21 07:27:28 +08:00
vim.loop.fs_unlink(dir)
2022-11-21 06:04:56 +08:00
end
self.plugin.installed = false
2022-11-23 04:12:50 +08:00
self:_done()
2022-11-21 06:04:56 +08:00
end
function Task:install()
if Util.file_exists(self.plugin.uri) then
vim.loop.fs_symlink(self.plugin.uri, self.plugin.dir, {
dir = true,
})
vim.opt.runtimepath:append(self.plugin.uri)
self:_done()
else
local args = {
"clone",
self.plugin.uri,
"--depth=1",
"--recurse-submodules",
"--shallow-submodules",
"--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.installed = true
self.plugin.dirty = true
end
end,
})
end
end
function Task:run()
Loader.load(self.plugin)
local run = self.plugin.run
if run then
if type(run) == "string" and run:sub(1, 1) == ":" then
vim.cmd(run:sub(2))
elseif type(run) == "function" then
run()
else
local args = vim.split(run, "%s+")
return self:spawn(table.remove(args, 1), {
args = args,
cwd = self.plugin.dir,
})
end
end
self:_done()
end
---@param cmd string
---@param opts ProcessOpts
function Task:spawn(cmd, opts)
opts = opts or {}
local on_line = opts.on_line
local on_exit = opts.on_exit
function opts.on_line(line)
self.status = line
if on_line then
pcall(on_line, line)
end
vim.cmd("do User LazyRender")
end
function opts.on_exit(ok, output)
self.output = output
if not ok then
self.error = output
end
if on_exit then
pcall(on_exit, ok, output)
end
self:_done()
end
Process.spawn(cmd, opts)
end
function Task:start()
self.running = true
local ok, err = pcall(function()
if self.type == "update" then
self:update()
elseif self.type == "install" then
self:install()
elseif self.type == "run" then
self:run()
elseif self.type == "clean" then
self:clean()
2022-11-23 04:12:50 +08:00
elseif self.type == "log" then
self:log()
2022-11-21 06:04:56 +08:00
end
end)
if not ok then
self.error = err or "failed"
2022-11-23 04:12:50 +08:00
self:_done()
end
end
2022-11-21 06:04:56 +08:00
2022-11-23 04:12:50 +08:00
function Task:log()
if not Util.file_exists(self.plugin.dir .. "/.git") then
2022-11-21 06:04:56 +08:00
self:_done()
2022-11-23 04:12:50 +08:00
return
2022-11-21 06:04:56 +08:00
end
2022-11-23 04:12:50 +08:00
local args = {
"log",
"--pretty=format:%h %s (%cr)",
"--abbrev-commit",
"--decorate",
"--date=short",
"--color=never",
"--since='7 days ago'",
}
self:spawn("git", {
args = args,
cwd = self.plugin.dir,
})
2022-11-21 06:04:56 +08:00
end
function Task:update()
if Util.file_exists(self.plugin.uri) then
if vim.loop.fs_realpath(self.plugin.uri) ~= vim.loop.fs_realpath(self.plugin.dir) then
vim.loop.fs_unlink(self.plugin.dir)
vim.loop.fs_symlink(self.plugin.uri, self.plugin.dir, {
dir = true,
})
vim.opt.runtimepath:append(self.plugin.uri)
end
self:_done()
else
local args = {
"pull",
"--recurse-submodules",
"--update-shallow",
"--progress",
}
local git = Util.git_info(self.plugin.dir)
self:spawn("git", {
args = args,
cwd = self.plugin.dir,
on_exit = function(ok)
if ok then
local git_new = Util.git_info(self.plugin.dir)
self.plugin.dirty = not vim.deep_equal(git, git_new)
end
end,
})
end
end
return Task