git.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. local M = {}
  2. local Log = require "lvim.core.log"
  3. local function git_cmd(opts)
  4. local plenary_loaded, Job = pcall(require, "plenary.job")
  5. if not plenary_loaded then
  6. vim.cmd "packadd plenary.nvim"
  7. end
  8. opts = opts or {}
  9. opts.cwd = opts.cwd or get_lvim_base_dir()
  10. local stderr = {}
  11. local stdout, ret = Job
  12. :new({
  13. command = "git",
  14. args = opts.args,
  15. cwd = opts.cwd,
  16. on_stderr = function(_, data)
  17. table.insert(stderr, data)
  18. end,
  19. })
  20. :sync()
  21. if not vim.tbl_isempty(stderr) then
  22. Log:debug(stderr)
  23. end
  24. if not vim.tbl_isempty(stdout) then
  25. Log:debug(stdout)
  26. end
  27. return ret, stdout
  28. end
  29. local function safe_deep_fetch()
  30. local ret, result = git_cmd { args = { "rev-parse", "--is-shallow-repository" } }
  31. if ret ~= 0 then
  32. Log:error "Git fetch failed! Check the log for further information"
  33. return
  34. end
  35. -- git fetch --unshallow will cause an error on a a complete clone
  36. local fetch_mode = result[1] == "true" and "--unshallow" or "--all"
  37. ret = git_cmd { args = { "fetch", fetch_mode } }
  38. if ret ~= 0 then
  39. Log:error "Git fetch failed! Check the log for further information"
  40. return
  41. end
  42. return true
  43. end
  44. ---pulls the latest changes from github
  45. function M.update_base_lvim()
  46. Log:info "Checking for updates"
  47. local ret = git_cmd { args = { "fetch" } }
  48. if ret ~= 0 then
  49. Log:error "Update failed! Check the log for further information"
  50. return
  51. end
  52. ret = git_cmd { args = { "diff", "--quiet", "@{upstream}" } }
  53. if ret == 0 then
  54. Log:info "LunarVim is already up-to-date"
  55. return
  56. end
  57. ret = git_cmd { args = { "merge", "--ff-only", "--progress" } }
  58. if ret ~= 0 then
  59. Log:error "Update failed! Please pull the changes manually instead."
  60. return
  61. end
  62. end
  63. ---Switch Lunarvim to the specified development branch
  64. ---@param branch string
  65. function M.switch_lvim_branch(branch)
  66. if not safe_deep_fetch() then
  67. return
  68. end
  69. local ret = git_cmd { args = { "switch", branch } }
  70. if ret ~= 0 then
  71. Log:error "Unable to switch branches! Check the log for further information"
  72. return
  73. end
  74. end
  75. ---Get the current Lunarvim development branch
  76. ---@return string|nil
  77. function M.get_lvim_branch()
  78. local ret, branch = git_cmd { args = { "branch", "--show-current" } }
  79. if ret ~= 0 or (not branch or branch[1] == "") then
  80. Log:error "Unable to retrieve the name of the current branch. Check the log for further information"
  81. return
  82. end
  83. return branch[1]
  84. end
  85. ---Get currently checked-out tag of Lunarvim
  86. ---@param type string can be "short"
  87. ---@return string|nil
  88. function M.get_lvim_tag(type)
  89. type = type or ""
  90. local ret, results = git_cmd { args = { "describe", "--tags" } }
  91. local lvim_full_ver = results[1] or ""
  92. if ret ~= 0 or string.match(lvim_full_ver, "%d") == nil then
  93. Log:error "Unable to retrieve current tag. Check the log for further information"
  94. return nil
  95. end
  96. if type == "short" then
  97. return vim.fn.split(lvim_full_ver, "-")[1]
  98. else
  99. return string.sub(lvim_full_ver, 1, #lvim_full_ver - 1)
  100. end
  101. end
  102. ---Get the commit hash of currently checked-out commit of Lunarvim
  103. ---@param type string can be "short"
  104. ---@return string|nil
  105. function M.get_lvim_version(type)
  106. type = type or ""
  107. local branch = M.get_lvim_branch()
  108. if branch == "master" then
  109. return M.get_lvim_tag(type)
  110. end
  111. local ret, log_results = git_cmd { args = { "log", "--pretty=format:%h", "-1" } }
  112. local abbrev_version = log_results[1] or ""
  113. if ret ~= 0 or string.match(abbrev_version, "%d") == nil then
  114. Log:error "Unable to retrieve current version. Check the log for further information"
  115. return nil
  116. end
  117. if type == "short" then
  118. return abbrev_version
  119. end
  120. return branch .. "-" .. abbrev_version
  121. end
  122. function M.generate_plugins_sha(output)
  123. local list = {}
  124. output = output or "commits.lua"
  125. local core_plugins = require "lvim.plugins"
  126. for _, plugin in pairs(core_plugins) do
  127. local name = plugin[1]:match "/(%S*)"
  128. local url = "https://github.com/" .. plugin[1]
  129. print("checking: " .. name .. ", at: " .. url)
  130. local retval, latest_sha = git_cmd { args = { "ls-remote", url, "origin", "HEAD" } }
  131. if retval == 0 then
  132. -- replace dashes, remove postfixes and use lowercase
  133. local normalize_name = (name:gsub("-", "_"):gsub("%.%S+", "")):lower()
  134. list[normalize_name] = latest_sha[1]:gsub("\tHEAD", "")
  135. end
  136. end
  137. require("lvim.utils").write_file(output, "local commit = " .. vim.inspect(list), "w")
  138. end
  139. return M