git.lua 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. local M = {}
  2. local Log = require "lvim.core.log"
  3. local fmt = string.format
  4. local if_nil = vim.F.if_nil
  5. local function git_cmd(opts)
  6. local plenary_loaded, Job = pcall(require, "plenary.job")
  7. if not plenary_loaded then
  8. return 1, { "" }
  9. end
  10. opts = opts or {}
  11. opts.cwd = opts.cwd or get_lvim_base_dir()
  12. local stderr = {}
  13. local stdout, ret = Job:new({
  14. command = "git",
  15. args = opts.args,
  16. cwd = opts.cwd,
  17. on_stderr = function(_, data)
  18. table.insert(stderr, data)
  19. end,
  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, stderr
  28. end
  29. local function safe_deep_fetch()
  30. local ret, result, error = git_cmd { args = { "rev-parse", "--is-shallow-repository" } }
  31. if ret ~= 0 then
  32. Log:error(vim.inspect(error))
  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(fmt "Git fetch %s failed! Please pull the changes manually in %s", fetch_mode, get_lvim_base_dir())
  40. return
  41. end
  42. if fetch_mode == "--unshallow" then
  43. ret = git_cmd { args = { "remote", "set-branches", "origin", "*" } }
  44. if ret ~= 0 then
  45. Log:error(fmt "Git fetch %s failed! Please pull the changes manually in %s", fetch_mode, get_lvim_base_dir())
  46. return
  47. end
  48. end
  49. return true
  50. end
  51. ---pulls the latest changes from github
  52. function M.update_base_lvim()
  53. Log:info "Checking for updates"
  54. if not vim.loop.fs_access(get_lvim_base_dir(), "w") then
  55. Log:warn(fmt("Lunarvim update aborted! cannot write to %s", get_lvim_base_dir()))
  56. return
  57. end
  58. if not safe_deep_fetch() then
  59. return
  60. end
  61. local ret
  62. ret = git_cmd { args = { "diff", "--quiet", "@{upstream}" } }
  63. if ret == 0 then
  64. Log:info "LunarVim is already up-to-date"
  65. return
  66. end
  67. ret = git_cmd { args = { "merge", "--ff-only", "--progress" } }
  68. if ret ~= 0 then
  69. Log:error("Update failed! Please pull the changes manually in " .. get_lvim_base_dir())
  70. return
  71. end
  72. return true
  73. end
  74. ---Switch Lunarvim to the specified development branch
  75. ---@param branch string
  76. function M.switch_lvim_branch(branch)
  77. if not safe_deep_fetch() then
  78. return
  79. end
  80. local args = { "switch", branch }
  81. if branch:match "^[0-9]" then
  82. -- avoids producing an error for tags
  83. vim.list_extend(args, { "--detach" })
  84. end
  85. local ret = git_cmd { args = args }
  86. if ret ~= 0 then
  87. Log:error "Unable to switch branches! Check the log for further information"
  88. return
  89. end
  90. return true
  91. end
  92. ---Get the current Lunarvim development branch
  93. ---@return string|nil
  94. function M.get_lvim_branch()
  95. local _, results = git_cmd { args = { "rev-parse", "--abbrev-ref", "HEAD" } }
  96. local branch = if_nil(results[1], "")
  97. return branch
  98. end
  99. ---Get currently checked-out tag of Lunarvim
  100. ---@return string
  101. function M.get_lvim_tag()
  102. local args = { "describe", "--tags", "--abbrev=0" }
  103. local _, results = git_cmd { args = args }
  104. local tag = if_nil(results[1], "")
  105. return tag
  106. end
  107. ---Get currently running version of Lunarvim
  108. ---@return string
  109. function M.get_lvim_version()
  110. local current_branch = M.get_lvim_branch()
  111. local lvim_version
  112. if current_branch ~= "HEAD" or "" then
  113. lvim_version = current_branch .. "-" .. M.get_lvim_current_sha()
  114. else
  115. lvim_version = "v" .. M.get_lvim_tag()
  116. end
  117. return lvim_version
  118. end
  119. ---Get the commit hash of currently checked-out commit of Lunarvim
  120. ---@return string|nil
  121. function M.get_lvim_current_sha()
  122. local _, log_results = git_cmd { args = { "log", "--pretty=format:%h", "-1" } }
  123. local abbrev_version = if_nil(log_results[1], "")
  124. return abbrev_version
  125. end
  126. return M