diff options
Diffstat (limited to 'lua/lvim/utils/git.lua')
-rw-r--r-- | lua/lvim/utils/git.lua | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/lua/lvim/utils/git.lua b/lua/lvim/utils/git.lua new file mode 100644 index 00000000..73ba7c96 --- /dev/null +++ b/lua/lvim/utils/git.lua @@ -0,0 +1,158 @@ +local M = {} + +local Log = require "lvim.core.log" + +local function git_cmd(opts) + local plenary_loaded, Job = pcall(require, "plenary.job") + if not plenary_loaded then + vim.cmd "packadd plenary.nvim" + end + + opts = opts or {} + opts.cwd = opts.cwd or get_lvim_base_dir() + + local stderr = {} + local stdout, ret = Job + :new({ + command = "git", + args = opts.args, + cwd = opts.cwd, + on_stderr = function(_, data) + table.insert(stderr, data) + end, + }) + :sync() + + if not vim.tbl_isempty(stderr) then + Log:debug(stderr) + end + + if not vim.tbl_isempty(stdout) then + Log:debug(stdout) + end + + return ret, stdout +end + +local function safe_deep_fetch() + local ret, result = git_cmd { args = { "rev-parse", "--is-shallow-repository" } } + if ret ~= 0 then + Log:error "Git fetch failed! Check the log for further information" + return + end + -- git fetch --unshallow will cause an error on a a complete clone + local fetch_mode = result[1] == "true" and "--unshallow" or "--all" + ret = git_cmd { args = { "fetch", fetch_mode } } + if ret ~= 0 then + Log:error "Git fetch failed! Check the log for further information" + return + end + return true +end + +---pulls the latest changes from github +function M.update_base_lvim() + Log:info "Checking for updates" + + local ret = git_cmd { args = { "fetch" } } + if ret ~= 0 then + Log:error "Update failed! Check the log for further information" + return + end + + ret = git_cmd { args = { "diff", "--quiet", "@{upstream}" } } + if ret == 0 then + Log:info "LunarVim is already up-to-date" + return + end + + ret = git_cmd { args = { "merge", "--ff-only", "--progress" } } + if ret ~= 0 then + Log:error "Update failed! Please pull the changes manually instead." + return + end +end + +---Switch Lunarvim to the specified development branch +---@param branch string +function M.switch_lvim_branch(branch) + if not safe_deep_fetch() then + return + end + local ret = git_cmd { args = { "switch", branch } } + if ret ~= 0 then + Log:error "Unable to switch branches! Check the log for further information" + return + end +end + +---Get the current Lunarvim development branch +---@return string|nil +function M.get_lvim_branch() + local ret, branch = git_cmd { args = { "branch", "--show-current" } } + if ret ~= 0 or (not branch or branch[1] == "") then + Log:error "Unable to retrieve the name of the current branch. Check the log for further information" + return + end + return branch[1] +end + +---Get currently checked-out tag of Lunarvim +---@param type string can be "short" +---@return string|nil +function M.get_lvim_tag(type) + type = type or "" + local ret, results = git_cmd { args = { "describe", "--tags" } } + local lvim_full_ver = results[1] or "" + + if ret ~= 0 or string.match(lvim_full_ver, "%d") == nil then + Log:error "Unable to retrieve current tag. Check the log for further information" + return nil + end + if type == "short" then + return vim.fn.split(lvim_full_ver, "-")[1] + else + return string.sub(lvim_full_ver, 1, #lvim_full_ver - 1) + end +end + +---Get the commit hash of currently checked-out commit of Lunarvim +---@param type string can be "short" +---@return string|nil +function M.get_lvim_version(type) + type = type or "" + local branch = M.get_lvim_branch() + if branch == "master" then + return M.get_lvim_tag(type) + end + local ret, log_results = git_cmd { args = { "log", "--pretty=format:%h", "-1" } } + local abbrev_version = log_results[1] or "" + if ret ~= 0 or string.match(abbrev_version, "%d") == nil then + Log:error "Unable to retrieve current version. Check the log for further information" + return nil + end + if type == "short" then + return abbrev_version + end + return branch .. "-" .. abbrev_version +end + +function M.generate_plugins_sha(output) + local list = {} + output = output or "commits.lua" + + local core_plugins = require "lvim.plugins" + for _, plugin in pairs(core_plugins) do + local name = plugin[1]:match "/(%S*)" + local url = "https://github.com/" .. plugin[1] + print("checking: " .. name .. ", at: " .. url) + local retval, latest_sha = git_cmd { args = { "ls-remote", url, "origin", "HEAD" } } + if retval == 0 then + -- replace dashes, remove postfixes and use lowercase + local normalize_name = (name:gsub("-", "_"):gsub("%.%S+", "")):lower() + list[normalize_name] = latest_sha[1]:gsub("\tHEAD", "") + end + end + require("lvim.utils").write_file(output, "local commit = " .. vim.inspect(list), "w") +end +return M |