瀏覽代碼

refactor(bootstrap): more robust git module (#2127)

kylo252 3 年之前
父節點
當前提交
eefc148313
共有 9 個文件被更改,包括 187 次插入134 次删除
  1. 1 2
      .luacheckrc
  2. 1 1
      Makefile
  3. 21 100
      lua/lvim/bootstrap.lua
  4. 2 4
      lua/lvim/config/init.lua
  5. 1 1
      lua/lvim/core/dashboard.lua
  6. 0 13
      lua/lvim/lsp/init.lua
  7. 2 10
      lua/lvim/lsp/peek.lua
  8. 158 0
      lua/lvim/utils/git.lua
  9. 1 3
      tests/minimal_lsp.lua

+ 1 - 2
.luacheckrc

@@ -23,8 +23,7 @@ stds.nvim = {
     "get_config_dir",
     "get_config_dir",
     "get_cache_dir",
     "get_cache_dir",
     "get_lvim_base_dir",
     "get_lvim_base_dir",
-    "get_version",
-    -- vim = { fields = { "cmd", "api", "fn", "o" } },
+    "require_clean",
   },
   },
 }
 }
 std = "lua51+nvim"
 std = "lua51+nvim"

+ 1 - 1
Makefile

@@ -14,7 +14,7 @@ uninstall:
 
 
 generate_plugins_sha:
 generate_plugins_sha:
 	@echo generating core-plugins latest SHA list
 	@echo generating core-plugins latest SHA list
-	lvim --headless -c 'lua require("lvim.utils").generate_plugins_sha("latest-sha.lua")' -c 'qall'
+	lvim --headless -c 'lua require("lvim.utils.git").generate_plugins_sha("latest-sha.lua")' -c 'qall'
 
 
 lint: lint-lua lint-sh
 lint: lint-lua lint-sh
 
 

+ 21 - 100
lua/lvim/bootstrap.lua

@@ -1,5 +1,13 @@
 local M = {}
 local M = {}
 
 
+if vim.fn.has "nvim-0.6" ~= 1 then
+  vim.notify("Please upgrade your Neovim base installation. Lunarvim requires v0.6+", vim.log.levels.WARN)
+  vim.wait(5000, function()
+    return false
+  end)
+  vim.cmd "cquit"
+end
+
 local uv = vim.loop
 local uv = vim.loop
 local path_sep = uv.os_uname().version:match "Windows" and "\\" or "/"
 local path_sep = uv.os_uname().version:match "Windows" and "\\" or "/"
 local in_headless = #vim.api.nvim_list_uis() == 0
 local in_headless = #vim.api.nvim_list_uis() == 0
@@ -11,6 +19,16 @@ function _G.join_paths(...)
   return result
   return result
 end
 end
 
 
+---Require a module in protected mode without relying on its cached value
+---@param module string
+---@return any
+function _G.require_clean(module)
+  package.loaded[module] = nil
+  _G[module] = nil
+  local _, requested = pcall(require, module)
+  return requested
+end
+
 ---Get the full path to `$LUNARVIM_RUNTIME_DIR`
 ---Get the full path to `$LUNARVIM_RUNTIME_DIR`
 ---@return string
 ---@return string
 function _G.get_runtime_dir()
 function _G.get_runtime_dir()
@@ -96,106 +114,9 @@ end
 ---Update LunarVim
 ---Update LunarVim
 ---pulls the latest changes from github and, resets the startup cache
 ---pulls the latest changes from github and, resets the startup cache
 function M:update()
 function M:update()
-  package.loaded["lvim.utils.hooks"] = nil
-  local _, hooks = pcall(require, "lvim.utils.hooks")
-  hooks.run_pre_update()
-  M:update_repo()
-  hooks.run_post_update()
-end
-
-local function git_cmd(subcmd, opts)
-  local Job = require "plenary.job"
-  local Log = require "lvim.core.log"
-  local args = { "-C", opts.cwd }
-  vim.list_extend(args, subcmd)
-
-  local stderr = {}
-  local stdout, ret = Job
-    :new({
-      command = "git",
-      args = 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
-
----pulls the latest changes from github
-function M:update_repo()
-  local Log = require "lvim.core.log"
-  local sub_commands = {
-    fetch = { "fetch" },
-    diff = { "diff", "--quiet", "@{upstream}" },
-    merge = { "merge", "--ff-only", "--progress" },
-  }
-  local opts = {
-    cwd = get_lvim_base_dir(),
-  }
-  Log:info "Checking for updates"
-
-  local ret = git_cmd(sub_commands.fetch, opts)
-  if ret ~= 0 then
-    Log:error "Update failed! Check the log for further information"
-    return
-  end
-
-  ret = git_cmd(sub_commands.diff, opts)
-
-  if ret == 0 then
-    Log:info "LunarVim is already up-to-date"
-    return
-  end
-
-  ret = git_cmd(sub_commands.merge, opts)
-
-  if ret ~= 0 then
-    Log:error "Update failed! Please pull the changes manually instead."
-    return
-  end
-end
-
----Get currently installed version of LunarVim
----@param type string can be "short"
----@return string
-function M:get_version(type)
-  type = type or ""
-  local opts = { cwd = get_lvim_base_dir() }
-
-  local _, branch = git_cmd({ "branch", "--show-current" }, opts)
-
-  local is_on_master = branch == "master"
-  if not is_on_master then
-    local log_status_ok, log_results = git_cmd({ "log", "--pretty=format:%h", "-1" }, opts)
-    local abbrev_version = log_results[1] or ""
-    if not log_status_ok or string.match(abbrev_version, "%d") == nil then
-      return nil
-    end
-    return "dev-" .. abbrev_version
-  end
-
-  local tag_status_ok, results = git_cmd({ "describe", "--tags" }, opts)
-  local lvim_full_ver = results[1] or ""
-
-  if not tag_status_ok or string.match(lvim_full_ver, "%d") == nil then
-    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
+  require_clean("lvim.utils.hooks").run_pre_update()
+  require_clean("lvim.utils.git").update_base_lvim()
+  require_clean("lvim.utils.hooks").run_post_update()
 end
 end
 
 
 return M
 return M

+ 2 - 4
lua/lvim/config/init.lua

@@ -102,9 +102,7 @@ end
 --- Override the configuration with a user provided one
 --- Override the configuration with a user provided one
 -- @param config_path The path to the configuration overrides
 -- @param config_path The path to the configuration overrides
 function M:reload()
 function M:reload()
-  package.loaded["lvim.utils.hooks"] = nil
-  local _, hooks = pcall(require, "lvim.utils.hooks")
-  hooks.run_pre_reload()
+  require_clean("lvim.utils.hooks").run_pre_reload()
 
 
   M:init()
   M:init()
   M:load()
   M:load()
@@ -115,7 +113,7 @@ function M:reload()
   local plugin_loader = require "lvim.plugin-loader"
   local plugin_loader = require "lvim.plugin-loader"
 
 
   plugin_loader.load { plugins, lvim.plugins }
   plugin_loader.load { plugins, lvim.plugins }
-  hooks.run_post_reload()
+  require_clean("lvim.utils.hooks").run_post_reload()
 end
 end
 
 
 return M
 return M

+ 1 - 1
lua/lvim/core/dashboard.lua

@@ -73,7 +73,7 @@ M.setup = function()
   vim.g.dashboard_session_directory = lvim.builtin.dashboard.session_directory
   vim.g.dashboard_session_directory = lvim.builtin.dashboard.session_directory
 
 
   local lvim_site = "lunarvim.org"
   local lvim_site = "lunarvim.org"
-  local lvim_version = require("lvim.bootstrap"):get_version "short"
+  local lvim_version = require("lvim.utils.git"):get_lvim_version "short"
   local num_plugins_loaded = #vim.fn.globpath(get_runtime_dir() .. "/site/pack/packer/start", "*", 0, 1)
   local num_plugins_loaded = #vim.fn.globpath(get_runtime_dir() .. "/site/pack/packer/start", "*", 0, 1)
 
 
   local footer = {
   local footer = {

+ 0 - 13
lua/lvim/lsp/init.lua

@@ -126,13 +126,6 @@ function M.get_common_opts()
   }
   }
 end
 end
 
 
-local LSP_DEPRECATED_SIGN_MAP = {
-  ["DiagnosticSignError"] = "LspDiagnosticsSignError",
-  ["DiagnosticSignWarn"] = "LspDiagnosticsSignWarning",
-  ["DiagnosticSignHint"] = "LspDiagnosticsSignHint",
-  ["DiagnosticSignInfo"] = "LspDiagnosticsSignInformation",
-}
-
 function M.setup()
 function M.setup()
   Log:debug "Setting up LSP support"
   Log:debug "Setting up LSP support"
 
 
@@ -141,13 +134,7 @@ function M.setup()
     return
     return
   end
   end
 
 
-  local is_neovim_5 = vim.fn.has "nvim-0.6" ~= 1
-
   for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do
   for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do
-    local lsp_sign_name = LSP_DEPRECATED_SIGN_MAP[sign.name]
-    if is_neovim_5 and lsp_sign_name then
-      vim.fn.sign_define(lsp_sign_name, { texthl = lsp_sign_name, text = sign.text, numhl = lsp_sign_name })
-    end
     vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name })
     vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name })
   end
   end
 
 

+ 2 - 10
lua/lvim/lsp/peek.lua

@@ -47,9 +47,8 @@ local function create_floating_file(location, opts)
 
 
   -- Set some autocmds to close the window
   -- Set some autocmds to close the window
   vim.api.nvim_command(
   vim.api.nvim_command(
-    "autocmd QuitPre <buffer> ++nested ++once lua pcall(vim.api.nvim_win_close, " .. winnr .. ", true)"
+    string.format("autocmd %s <buffer> ++once lua pcall(vim.api.nvim_win_close, %d, true)", unpack(close_events), winnr)
   )
   )
-  vim.lsp.util.close_preview_autocmd(close_events, winnr)
 
 
   return bufnr, winnr
   return bufnr, winnr
 end
 end
@@ -73,10 +72,6 @@ local function preview_location_callback(result)
   end
   end
 end
 end
 
 
-local function preview_location_callback_old_signature(_, _, result)
-  return preview_location_callback(result)
-end
-
 local function preview_location_callback_new_signature(_, result)
 local function preview_location_callback_new_signature(_, result)
   return preview_location_callback(result)
   return preview_location_callback(result)
 end
 end
@@ -136,10 +131,7 @@ function M.Peek(what)
   else
   else
     -- Make a new request and then create the new window in the callback
     -- Make a new request and then create the new window in the callback
     local params = vim.lsp.util.make_position_params()
     local params = vim.lsp.util.make_position_params()
-    local preview_callback = preview_location_callback_old_signature
-    if vim.fn.has "nvim-0.5.1" > 0 then
-      preview_callback = preview_location_callback_new_signature
-    end
+    local preview_callback = preview_location_callback_new_signature
     local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback)
     local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback)
     if not success then
     if not success then
       print(
       print(

+ 158 - 0
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

+ 1 - 3
tests/minimal_lsp.lua

@@ -41,9 +41,7 @@ end
 
 
 _G.load_config = function()
 _G.load_config = function()
   vim.lsp.set_log_level "trace"
   vim.lsp.set_log_level "trace"
-  if vim.fn.has "nvim-0.5.1" == 1 then
-    require("vim.lsp.log").set_format_func(vim.inspect)
-  end
+  require("vim.lsp.log").set_format_func(vim.inspect)
   local nvim_lsp = require "lspconfig"
   local nvim_lsp = require "lspconfig"
   local on_attach = function(_, bufnr)
   local on_attach = function(_, bufnr)
     local function buf_set_keymap(...)
     local function buf_set_keymap(...)