adding initial base config from astrovim
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
--- ### AstroNvim Updater
|
||||
--
|
||||
-- This module is automatically loaded by AstroNvim on during it's initialization into global variable `astronvim.updater`
|
||||
--
|
||||
-- This module can also be manually loaded with `local updater = require("core.utils").updater`
|
||||
--
|
||||
-- @module core.utils.updater
|
||||
-- @see core.utils
|
||||
-- @copyright 2022
|
||||
-- @license GNU General Public License v3.0
|
||||
|
||||
local fn = vim.fn
|
||||
local git = require "core.utils.git"
|
||||
--- Updater settings overridden with any user provided configuration
|
||||
local options = astronvim.user_plugin_opts("updater", {
|
||||
remote = "origin",
|
||||
channel = "stable",
|
||||
show_changelog = true,
|
||||
auto_reload = true,
|
||||
auto_quit = true,
|
||||
})
|
||||
|
||||
-- set the install channel
|
||||
if options.branch and options.branch ~= "main" then options.channel = "nightly" end
|
||||
if astronvim.install.is_stable ~= nil then options.channel = astronvim.install.is_stable and "stable" or "nightly" end
|
||||
|
||||
astronvim.updater = { options = options }
|
||||
-- if the channel is stable or the user has chosen to pin the system plugins
|
||||
if options.pin_plugins == nil and options.channel == "stable" or options.pin_plugins then
|
||||
-- load the current packer snapshot from the installation home location
|
||||
local loaded, snapshot = pcall(fn.readfile, astronvim.install.home .. "/packer_snapshot")
|
||||
if loaded then
|
||||
-- decode the snapshot JSON and save it to a variable
|
||||
loaded, snapshot = pcall(fn.json_decode, snapshot)
|
||||
astronvim.updater.snapshot = type(snapshot) == "table" and snapshot or nil
|
||||
end
|
||||
-- if there is an error loading the snapshot, print an error
|
||||
if not loaded then vim.api.nvim_err_writeln "Error loading packer snapshot" end
|
||||
end
|
||||
|
||||
--- Get the current AstroNvim version
|
||||
-- @param quiet boolean to quietly execute or send a notification
|
||||
-- @return the current AstroNvim version string
|
||||
function astronvim.updater.version(quiet)
|
||||
local version = astronvim.install.version or git.current_version(false)
|
||||
if version and not quiet then astronvim.notify("Version: " .. version) end
|
||||
return version
|
||||
end
|
||||
|
||||
--- Get the full AstroNvim changelog
|
||||
-- @param quiet boolean to quietly execute or display the changelog
|
||||
-- @return the current AstroNvim changelog table of commit messages
|
||||
function astronvim.updater.changelog(quiet)
|
||||
local summary = {}
|
||||
vim.list_extend(summary, git.pretty_changelog(git.get_commit_range()))
|
||||
if not quiet then astronvim.echo(summary) end
|
||||
return summary
|
||||
end
|
||||
|
||||
--- Attempt an update of AstroNvim
|
||||
-- @param target the target if checking out a specific tag or commit or nil if just pulling
|
||||
local function attempt_update(target)
|
||||
-- if updating to a new stable version or a specific commit checkout the provided target
|
||||
if options.channel == "stable" or options.commit then
|
||||
return git.checkout(target, false)
|
||||
-- if no target, pull the latest
|
||||
else
|
||||
return git.pull(false)
|
||||
end
|
||||
end
|
||||
|
||||
--- Cancelled update message
|
||||
local cancelled_message = { { "Update cancelled", "WarningMsg" } }
|
||||
|
||||
--- Reload the AstroNvim configuration live (Experimental)
|
||||
-- @param quiet boolean to quietly execute or send a notification
|
||||
function astronvim.updater.reload(quiet)
|
||||
-- stop LSP if it is running
|
||||
if vim.fn.exists ":LspStop" ~= 0 then vim.cmd.LspStop() end
|
||||
local reload_module = require("plenary.reload").reload_module
|
||||
-- unload AstroNvim configuration files
|
||||
reload_module "user"
|
||||
reload_module "configs"
|
||||
reload_module "default_theme"
|
||||
reload_module "core"
|
||||
-- manual unload some plugins that need it if they exist
|
||||
reload_module "cmp"
|
||||
reload_module "which-key"
|
||||
-- source the AstroNvim configuration
|
||||
local reloaded, _ = pcall(dofile, vim.fn.expand "$MYVIMRC")
|
||||
-- if successful reload and not quiet, display a notification
|
||||
if reloaded and not quiet then astronvim.notify "Reloaded AstroNvim" end
|
||||
end
|
||||
|
||||
--- Sync Packer and then update Mason
|
||||
function astronvim.updater.update_packages()
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
once = true,
|
||||
desc = "Update Mason with Packer",
|
||||
group = vim.api.nvim_create_augroup("astro_sync", { clear = true }),
|
||||
pattern = "PackerComplete",
|
||||
callback = function()
|
||||
if astronvim.is_available "mason.nvim" then
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "AstroMasonUpdateComplete",
|
||||
once = true,
|
||||
callback = function() astronvim.event "UpdatePackagesComplete" end,
|
||||
})
|
||||
astronvim.mason.update_all()
|
||||
else
|
||||
astronvim.event "UpdatePackagesComplete"
|
||||
end
|
||||
end,
|
||||
})
|
||||
vim.cmd.PackerSync()
|
||||
end
|
||||
|
||||
--- AstroNvim's updater function
|
||||
function astronvim.updater.update()
|
||||
-- if the git command is not available, then throw an error
|
||||
if not git.available() then
|
||||
astronvim.notify(
|
||||
"git command is not available, please verify it is accessible in a command line. This may be an issue with your PATH",
|
||||
"error"
|
||||
)
|
||||
return
|
||||
end
|
||||
|
||||
-- if installed with an external package manager, disable the internal updater
|
||||
if not git.is_repo() then
|
||||
astronvim.notify("Updater not available for non-git installations", "error")
|
||||
return
|
||||
end
|
||||
-- set up any remotes defined by the user if they do not exist
|
||||
for remote, entry in pairs(options.remotes and options.remotes or {}) do
|
||||
local url = git.parse_remote_url(entry)
|
||||
local current_url = git.remote_url(remote, false)
|
||||
local check_needed = false
|
||||
if not current_url then
|
||||
git.remote_add(remote, url)
|
||||
check_needed = true
|
||||
elseif
|
||||
current_url ~= url
|
||||
and astronvim.confirm_prompt {
|
||||
{ "Remote " },
|
||||
{ remote, "Title" },
|
||||
{ " is currently set to " },
|
||||
{ current_url, "WarningMsg" },
|
||||
{ "\nWould you like us to set it to " },
|
||||
{ url, "String" },
|
||||
{ "?" },
|
||||
}
|
||||
then
|
||||
git.remote_update(remote, url)
|
||||
check_needed = true
|
||||
end
|
||||
if check_needed and git.remote_url(remote, false) ~= url then
|
||||
vim.api.nvim_err_writeln("Error setting up remote " .. remote .. " to " .. url)
|
||||
return
|
||||
end
|
||||
end
|
||||
local is_stable = options.channel == "stable"
|
||||
if is_stable then
|
||||
options.branch = "main"
|
||||
elseif not options.branch then
|
||||
options.branch = "nightly"
|
||||
end
|
||||
-- fetch the latest remote
|
||||
if not git.fetch(options.remote) then
|
||||
vim.api.nvim_err_writeln("Error fetching remote: " .. options.remote)
|
||||
return
|
||||
end
|
||||
-- switch to the necessary branch only if not on the stable channel
|
||||
if not is_stable then
|
||||
local local_branch = (options.remote == "origin" and "" or (options.remote .. "_")) .. options.branch
|
||||
if git.current_branch() ~= local_branch then
|
||||
astronvim.echo {
|
||||
{ "Switching to branch: " },
|
||||
{ options.remote .. "/" .. options.branch .. "\n\n", "String" },
|
||||
}
|
||||
if not git.checkout(local_branch, false) then
|
||||
git.checkout("-b " .. local_branch .. " " .. options.remote .. "/" .. options.branch, false)
|
||||
end
|
||||
end
|
||||
-- check if the branch was switched to successfully
|
||||
if git.current_branch() ~= local_branch then
|
||||
vim.api.nvim_err_writeln("Error checking out branch: " .. options.remote .. "/" .. options.branch)
|
||||
return
|
||||
end
|
||||
end
|
||||
local source = git.local_head() -- calculate current commit
|
||||
local target -- calculate target commit
|
||||
if is_stable then -- if stable get tag commit
|
||||
local version_search = options.version or "latest"
|
||||
options.version = git.latest_version(git.get_versions(version_search))
|
||||
if not options.version then -- continue only if stable version is found
|
||||
vim.api.nvim_err_writeln("Error finding version: " .. version_search)
|
||||
return
|
||||
end
|
||||
target = git.tag_commit(options.version)
|
||||
elseif options.commit then -- if commit specified use it
|
||||
target = git.branch_contains(options.remote, options.branch, options.commit) and options.commit or nil
|
||||
else -- get most recent commit
|
||||
target = git.remote_head(options.remote, options.branch)
|
||||
end
|
||||
if not source or not target then -- continue if current and target commits were found
|
||||
vim.api.nvim_err_writeln "Error checking for updates"
|
||||
return
|
||||
elseif source == target then
|
||||
astronvim.echo { { "No updates available", "String" } }
|
||||
return
|
||||
elseif -- prompt user if they want to accept update
|
||||
not options.skip_prompts
|
||||
and not astronvim.confirm_prompt {
|
||||
{ "Update available to ", "Title" },
|
||||
{ is_stable and options.version or target, "String" },
|
||||
{ "\nUpdating requires a restart, continue?" },
|
||||
}
|
||||
then
|
||||
astronvim.echo(cancelled_message)
|
||||
return
|
||||
else -- perform update
|
||||
-- calculate and print the changelog
|
||||
local changelog = git.get_commit_range(source, target)
|
||||
local breaking = git.breaking_changes(changelog)
|
||||
local breaking_prompt = { { "Update contains the following breaking changes:\n", "WarningMsg" } }
|
||||
vim.list_extend(breaking_prompt, git.pretty_changelog(breaking))
|
||||
vim.list_extend(breaking_prompt, { { "\nWould you like to continue?" } })
|
||||
if #breaking > 0 and not options.skip_prompts and not astronvim.confirm_prompt(breaking_prompt) then
|
||||
astronvim.echo(cancelled_message)
|
||||
return
|
||||
end
|
||||
-- attempt an update
|
||||
local updated = attempt_update(target)
|
||||
-- check for local file conflicts and prompt user to continue or abort
|
||||
if
|
||||
not updated
|
||||
and not options.skip_prompts
|
||||
and not astronvim.confirm_prompt {
|
||||
{ "Unable to pull due to local modifications to base files.\n", "ErrorMsg" },
|
||||
{ "Reset local files and continue?" },
|
||||
}
|
||||
then
|
||||
astronvim.echo(cancelled_message)
|
||||
return
|
||||
-- if continued and there were errors reset the base config and attempt another update
|
||||
elseif not updated then
|
||||
git.hard_reset(source)
|
||||
updated = attempt_update(target)
|
||||
end
|
||||
-- if update was unsuccessful throw an error
|
||||
if not updated then
|
||||
vim.api.nvim_err_writeln "Error ocurred performing update"
|
||||
return
|
||||
end
|
||||
-- print a summary of the update with the changelog
|
||||
local summary = {
|
||||
{ "AstroNvim updated successfully to ", "Title" },
|
||||
{ git.current_version(), "String" },
|
||||
{ "!\n", "Title" },
|
||||
{
|
||||
options.auto_reload and "AstroNvim will now sync packer and quit.\n\n"
|
||||
or "Please restart and run :PackerSync.\n\n",
|
||||
"WarningMsg",
|
||||
},
|
||||
}
|
||||
if options.show_changelog and #changelog > 0 then
|
||||
vim.list_extend(summary, { { "Changelog:\n", "Title" } })
|
||||
vim.list_extend(summary, git.pretty_changelog(changelog))
|
||||
end
|
||||
astronvim.echo(summary)
|
||||
|
||||
-- if the user wants to auto quit, create an autocommand to quit AstroNvim on the update completing
|
||||
if options.auto_quit then
|
||||
vim.api.nvim_create_autocmd("User", { pattern = "AstroUpdateComplete", command = "quitall" })
|
||||
end
|
||||
|
||||
-- if the user wants to reload and sync packer
|
||||
if options.auto_reload then
|
||||
-- perform a reload
|
||||
vim.opt.modifiable = true
|
||||
astronvim.updater.reload(true) -- run quiet to not show notification on reload
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
once = true,
|
||||
pattern = "AstroUpdatePackagesComplete",
|
||||
callback = function() astronvim.event "UpdateComplete" end,
|
||||
})
|
||||
require "core.plugins"
|
||||
astronvim.updater.update_packages()
|
||||
-- if packer isn't available send successful update event
|
||||
else
|
||||
-- send user event of successful update
|
||||
astronvim.event "UpdateComplete"
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user