mirror of
https://github.com/neovim/neovim.git
synced 2025-10-06 09:56:31 +00:00
feat(vim.pack): lockfile support #35827
This commit is contained in:
@@ -221,6 +221,13 @@ Uses Git to manage plugins and requires present `git` executable of at least
|
|||||||
version 2.36. Target plugins should be Git repositories with versions as named
|
version 2.36. Target plugins should be Git repositories with versions as named
|
||||||
tags following semver convention `v<major>.<minor>.<patch>`.
|
tags following semver convention `v<major>.<minor>.<patch>`.
|
||||||
|
|
||||||
|
The latest state of all managed plugins is stored inside a *vim.pack-lockfile*
|
||||||
|
located at `$XDG_CONFIG_HOME/nvim/nvim-pack-lock.json`. It is a JSON file that
|
||||||
|
is used to persistently track data about plugins. For a more robust config
|
||||||
|
treat lockfile like its part: put under version control, etc. In this case
|
||||||
|
initial install prefers revision from the lockfile instead of inferring from
|
||||||
|
`version`. Should not be edited by hand or deleted.
|
||||||
|
|
||||||
Example workflows ~
|
Example workflows ~
|
||||||
|
|
||||||
Basic install and management:
|
Basic install and management:
|
||||||
@@ -254,17 +261,20 @@ Basic install and management:
|
|||||||
plugin1 = require('plugin1')
|
plugin1 = require('plugin1')
|
||||||
<
|
<
|
||||||
• Restart Nvim (for example, with |:restart|). Plugins that were not yet
|
• Restart Nvim (for example, with |:restart|). Plugins that were not yet
|
||||||
installed will be available on disk in target state after `add()` call.
|
installed will be available on disk after `add()` call. Their revision is
|
||||||
|
taken from |vim.pack-lockfile| (if present) or inferred from the `version`.
|
||||||
• To update all plugins with new changes:
|
• To update all plugins with new changes:
|
||||||
• Execute |vim.pack.update()|. This will download updates from source and
|
• Execute |vim.pack.update()|. This will download updates from source and
|
||||||
show confirmation buffer in a separate tabpage.
|
show confirmation buffer in a separate tabpage.
|
||||||
• Review changes. To confirm all updates execute |:write|. To discard
|
• Review changes. To confirm all updates execute |:write|. To discard
|
||||||
updates execute |:quit|.
|
updates execute |:quit|.
|
||||||
|
• (Optionally) |:restart| to start using code from updated plugins.
|
||||||
|
|
||||||
Switch plugin's version:
|
Switch plugin's version:
|
||||||
• Update 'init.lua' for plugin to have desired `version`. Let's say, plugin
|
• Update 'init.lua' for plugin to have desired `version`. Let's say, plugin
|
||||||
named 'plugin1' has changed to `vim.version.range('*')`.
|
named 'plugin1' has changed to `vim.version.range('*')`.
|
||||||
• |:restart|. The plugin's actual state on disk is not yet changed.
|
• |:restart|. The plugin's actual state on disk is not yet changed. Only
|
||||||
|
plugin's `version` in |vim.pack-lockfile| is updated.
|
||||||
• Execute `vim.pack.update({ 'plugin1' })`.
|
• Execute `vim.pack.update({ 'plugin1' })`.
|
||||||
• Review changes and either confirm or discard them. If discarded, revert any
|
• Review changes and either confirm or discard them. If discarded, revert any
|
||||||
changes in 'init.lua' as well or you will be prompted again next time you
|
changes in 'init.lua' as well or you will be prompted again next time you
|
||||||
@@ -272,7 +282,7 @@ Switch plugin's version:
|
|||||||
|
|
||||||
Freeze plugin from being updated:
|
Freeze plugin from being updated:
|
||||||
• Update 'init.lua' for plugin to have `version` set to current revision. Get
|
• Update 'init.lua' for plugin to have `version` set to current revision. Get
|
||||||
it with `:=vim.pack.get({ 'plug-name' })[1].rev` (looks like `abc12345`).
|
it from |vim.pack-lockfile| (plugin's field `rev`; looks like `abc12345`).
|
||||||
• |:restart|.
|
• |:restart|.
|
||||||
|
|
||||||
Unfreeze plugin to start receiving updates:
|
Unfreeze plugin to start receiving updates:
|
||||||
@@ -371,7 +381,7 @@ get({names}, {opts}) *vim.pack.get()*
|
|||||||
• {branches}? (`string[]`) Available Git branches (first is default).
|
• {branches}? (`string[]`) Available Git branches (first is default).
|
||||||
Missing if `info=false`.
|
Missing if `info=false`.
|
||||||
• {path} (`string`) Plugin's path on disk.
|
• {path} (`string`) Plugin's path on disk.
|
||||||
• {rev}? (`string`) Current Git revision. Missing if `info=false`.
|
• {rev} (`string`) Current Git revision.
|
||||||
• {spec} (`vim.pack.SpecResolved`) A |vim.pack.Spec| with resolved
|
• {spec} (`vim.pack.SpecResolved`) A |vim.pack.Spec| with resolved
|
||||||
`name`.
|
`name`.
|
||||||
• {tags}? (`string[]`) Available Git tags. Missing if `info=false`.
|
• {tags}? (`string[]`) Available Git tags. Missing if `info=false`.
|
||||||
@@ -402,8 +412,7 @@ update({names}, {opts}) *vim.pack.update()*
|
|||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {names} (`string[]?`) List of plugin names to update. Must be managed
|
• {names} (`string[]?`) List of plugin names to update. Must be managed
|
||||||
by |vim.pack|, not necessarily already added to current
|
by |vim.pack|, not necessarily already added to current
|
||||||
session. Default: names of all plugins added to current
|
session. Default: names of all plugins managed by |vim.pack|.
|
||||||
session via |vim.pack.add()|.
|
|
||||||
• {opts} (`table?`) A table with the following fields:
|
• {opts} (`table?`) A table with the following fields:
|
||||||
• {force}? (`boolean`) Whether to skip confirmation and make
|
• {force}? (`boolean`) Whether to skip confirmation and make
|
||||||
updates immediately. Default `false`.
|
updates immediately. Default `false`.
|
||||||
|
@@ -14,6 +14,13 @@
|
|||||||
---least version 2.36. Target plugins should be Git repositories with versions
|
---least version 2.36. Target plugins should be Git repositories with versions
|
||||||
---as named tags following semver convention `v<major>.<minor>.<patch>`.
|
---as named tags following semver convention `v<major>.<minor>.<patch>`.
|
||||||
---
|
---
|
||||||
|
---The latest state of all managed plugins is stored inside a [vim.pack-lockfile]()
|
||||||
|
---located at `$XDG_CONFIG_HOME/nvim/nvim-pack-lock.json`. It is a JSON file that
|
||||||
|
---is used to persistently track data about plugins.
|
||||||
|
---For a more robust config treat lockfile like its part: put under version control, etc.
|
||||||
|
---In this case initial install prefers revision from the lockfile instead of
|
||||||
|
---inferring from `version`. Should not be edited by hand or deleted.
|
||||||
|
---
|
||||||
---Example workflows ~
|
---Example workflows ~
|
||||||
---
|
---
|
||||||
---Basic install and management:
|
---Basic install and management:
|
||||||
@@ -50,18 +57,21 @@
|
|||||||
---```
|
---```
|
||||||
---
|
---
|
||||||
---- Restart Nvim (for example, with |:restart|). Plugins that were not yet
|
---- Restart Nvim (for example, with |:restart|). Plugins that were not yet
|
||||||
---installed will be available on disk in target state after `add()` call.
|
---installed will be available on disk after `add()` call. Their revision is
|
||||||
|
---taken from |vim.pack-lockfile| (if present) or inferred from the `version`.
|
||||||
---
|
---
|
||||||
---- To update all plugins with new changes:
|
---- To update all plugins with new changes:
|
||||||
--- - Execute |vim.pack.update()|. This will download updates from source and
|
--- - Execute |vim.pack.update()|. This will download updates from source and
|
||||||
--- show confirmation buffer in a separate tabpage.
|
--- show confirmation buffer in a separate tabpage.
|
||||||
--- - Review changes. To confirm all updates execute |:write|.
|
--- - Review changes. To confirm all updates execute |:write|.
|
||||||
--- To discard updates execute |:quit|.
|
--- To discard updates execute |:quit|.
|
||||||
|
--- - (Optionally) |:restart| to start using code from updated plugins.
|
||||||
---
|
---
|
||||||
---Switch plugin's version:
|
---Switch plugin's version:
|
||||||
---- Update 'init.lua' for plugin to have desired `version`. Let's say, plugin
|
---- Update 'init.lua' for plugin to have desired `version`. Let's say, plugin
|
||||||
---named 'plugin1' has changed to `vim.version.range('*')`.
|
---named 'plugin1' has changed to `vim.version.range('*')`.
|
||||||
---- |:restart|. The plugin's actual state on disk is not yet changed.
|
---- |:restart|. The plugin's actual state on disk is not yet changed.
|
||||||
|
--- Only plugin's `version` in |vim.pack-lockfile| is updated.
|
||||||
---- Execute `vim.pack.update({ 'plugin1' })`.
|
---- Execute `vim.pack.update({ 'plugin1' })`.
|
||||||
---- Review changes and either confirm or discard them. If discarded, revert
|
---- Review changes and either confirm or discard them. If discarded, revert
|
||||||
---any changes in 'init.lua' as well or you will be prompted again next time
|
---any changes in 'init.lua' as well or you will be prompted again next time
|
||||||
@@ -69,7 +79,7 @@
|
|||||||
---
|
---
|
||||||
---Freeze plugin from being updated:
|
---Freeze plugin from being updated:
|
||||||
---- Update 'init.lua' for plugin to have `version` set to current revision.
|
---- Update 'init.lua' for plugin to have `version` set to current revision.
|
||||||
---Get it with `:=vim.pack.get({ 'plug-name' })[1].rev` (looks like `abc12345`).
|
---Get it from |vim.pack-lockfile| (plugin's field `rev`; looks like `abc12345`).
|
||||||
---- |:restart|.
|
---- |:restart|.
|
||||||
---
|
---
|
||||||
---Unfreeze plugin to start receiving updates:
|
---Unfreeze plugin to start receiving updates:
|
||||||
@@ -190,13 +200,72 @@ local function git_get_tags(cwd)
|
|||||||
return tags == '' and {} or vim.split(tags, '\n')
|
return tags == '' and {} or vim.split(tags, '\n')
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Plugin operations ----------------------------------------------------------
|
-- Lockfile -------------------------------------------------------------------
|
||||||
|
|
||||||
--- @return string
|
--- @return string
|
||||||
local function get_plug_dir()
|
local function get_plug_dir()
|
||||||
return vim.fs.joinpath(vim.fn.stdpath('data'), 'site', 'pack', 'core', 'opt')
|
return vim.fs.joinpath(vim.fn.stdpath('data'), 'site', 'pack', 'core', 'opt')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @class (private) vim.pack.LockData
|
||||||
|
--- @field rev string Latest recorded revision.
|
||||||
|
--- @field src string Plugin source.
|
||||||
|
--- @field version? string|vim.VersionRange Plugin `version`, as supplied in `spec`.
|
||||||
|
|
||||||
|
--- @class (private) vim.pack.Lock
|
||||||
|
--- @field plugins table<string, vim.pack.LockData> Map from plugin name to its lock data.
|
||||||
|
|
||||||
|
--- @type vim.pack.Lock
|
||||||
|
local plugin_lock
|
||||||
|
|
||||||
|
local function lock_get_path()
|
||||||
|
return vim.fs.joinpath(vim.fn.stdpath('config'), 'nvim-pack-lock.json')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function lock_read()
|
||||||
|
if plugin_lock then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local fd = uv.fs_open(lock_get_path(), 'r', 438)
|
||||||
|
if not fd then
|
||||||
|
plugin_lock = { plugins = {} }
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local stat = assert(uv.fs_fstat(fd))
|
||||||
|
local data = assert(uv.fs_read(fd, stat.size, 0))
|
||||||
|
assert(uv.fs_close(fd))
|
||||||
|
plugin_lock = vim.json.decode(data) --- @type vim.pack.Lock
|
||||||
|
|
||||||
|
-- Deserialize `version`
|
||||||
|
for _, l_data in pairs(plugin_lock.plugins) do
|
||||||
|
local version = l_data.version
|
||||||
|
if type(version) == 'string' then
|
||||||
|
l_data.version = version:match("^'(.+)'$") or vim.version.range(version)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function lock_write()
|
||||||
|
-- Serialize `version`
|
||||||
|
local lock = vim.deepcopy(plugin_lock)
|
||||||
|
for _, l_data in pairs(lock.plugins) do
|
||||||
|
local version = l_data.version
|
||||||
|
if version then
|
||||||
|
l_data.version = type(version) == 'string' and ("'%s'"):format(version) or tostring(version)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local path = lock_get_path()
|
||||||
|
vim.fn.mkdir(vim.fs.dirname(path), 'p')
|
||||||
|
local fd = assert(uv.fs_open(path, 'w', 438))
|
||||||
|
|
||||||
|
local data = vim.json.encode(lock, { indent = ' ', sort_keys = true })
|
||||||
|
assert(uv.fs_write(fd, data))
|
||||||
|
assert(uv.fs_close(fd))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Plugin operations ----------------------------------------------------------
|
||||||
|
|
||||||
--- @param msg string|string[]
|
--- @param msg string|string[]
|
||||||
--- @param level ('DEBUG'|'TRACE'|'INFO'|'WARN'|'ERROR')?
|
--- @param level ('DEBUG'|'TRACE'|'INFO'|'WARN'|'ERROR')?
|
||||||
local function notify(msg, level)
|
local function notify(msg, level)
|
||||||
@@ -334,15 +403,8 @@ local function plug_list_from_names(names)
|
|||||||
local plug_dir = get_plug_dir()
|
local plug_dir = get_plug_dir()
|
||||||
local plugs = {} --- @type vim.pack.Plug[]
|
local plugs = {} --- @type vim.pack.Plug[]
|
||||||
for _, p_data in ipairs(p_data_list) do
|
for _, p_data in ipairs(p_data_list) do
|
||||||
-- NOTE: By default include only active plugins (and not all on disk). Using
|
plugs[#plugs + 1] = new_plug(p_data.spec, plug_dir)
|
||||||
-- not active plugins might lead to a confusion as default `version` and
|
|
||||||
-- user's desired one might mismatch.
|
|
||||||
-- TODO(echasnovski): Change this when there is lockfile.
|
|
||||||
if names ~= nil or p_data.active then
|
|
||||||
plugs[#plugs + 1] = new_plug(p_data.spec, plug_dir)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return plugs
|
return plugs
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -532,6 +594,8 @@ local function checkout(p, timestamp, skip_same_sha)
|
|||||||
|
|
||||||
git_cmd({ 'checkout', '--quiet', p.info.sha_target }, p.path)
|
git_cmd({ 'checkout', '--quiet', p.info.sha_target }, p.path)
|
||||||
|
|
||||||
|
plugin_lock.plugins[p.spec.name].rev = p.info.sha_target
|
||||||
|
|
||||||
trigger_event(p, 'PackChanged', 'update')
|
trigger_event(p, 'PackChanged', 'update')
|
||||||
|
|
||||||
-- (Re)Generate help tags according to the current help files.
|
-- (Re)Generate help tags according to the current help files.
|
||||||
@@ -561,6 +625,11 @@ local function install_list(plug_list, confirm)
|
|||||||
git_clone(p.spec.src, p.path)
|
git_clone(p.spec.src, p.path)
|
||||||
p.info.installed = true
|
p.info.installed = true
|
||||||
|
|
||||||
|
plugin_lock.plugins[p.spec.name].src = p.spec.src
|
||||||
|
|
||||||
|
-- Prefer revision from the lockfile instead of using `version`
|
||||||
|
p.info.sha_target = (plugin_lock.plugins[p.spec.name] or {}).rev
|
||||||
|
|
||||||
-- Do not skip checkout even if HEAD and target have same commit hash to
|
-- Do not skip checkout even if HEAD and target have same commit hash to
|
||||||
-- have new repo in expected detached HEAD state and generated help files.
|
-- have new repo in expected detached HEAD state and generated help files.
|
||||||
checkout(p, timestamp, false)
|
checkout(p, timestamp, false)
|
||||||
@@ -698,17 +767,34 @@ function M.add(specs, opts)
|
|||||||
end
|
end
|
||||||
plugs = normalize_plugs(plugs)
|
plugs = normalize_plugs(plugs)
|
||||||
|
|
||||||
-- Install
|
-- Pre-process
|
||||||
--- @param p vim.pack.Plug
|
lock_read()
|
||||||
local plugs_to_install = vim.tbl_filter(function(p)
|
local plugs_to_install = {} --- @type vim.pack.Plug[]
|
||||||
return not p.info.installed
|
local needs_lock_write = false
|
||||||
end, plugs)
|
for _, p in ipairs(plugs) do
|
||||||
|
-- TODO(echasnovski): check that lock's `src` is the same as in spec.
|
||||||
|
-- If not - cleanly reclone (delete directory and mark as not installed).
|
||||||
|
local p_lock = plugin_lock.plugins[p.spec.name] or {}
|
||||||
|
needs_lock_write = needs_lock_write or p_lock.version ~= p.spec.version
|
||||||
|
p_lock.version = p.spec.version
|
||||||
|
plugin_lock.plugins[p.spec.name] = p_lock
|
||||||
|
|
||||||
|
if not p.info.installed then
|
||||||
|
plugs_to_install[#plugs_to_install + 1] = p
|
||||||
|
needs_lock_write = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Install
|
||||||
if #plugs_to_install > 0 then
|
if #plugs_to_install > 0 then
|
||||||
git_ensure_exec()
|
git_ensure_exec()
|
||||||
install_list(plugs_to_install, opts.confirm)
|
install_list(plugs_to_install, opts.confirm)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if needs_lock_write then
|
||||||
|
lock_write()
|
||||||
|
end
|
||||||
|
|
||||||
-- Register and load those actually on disk while collecting errors
|
-- Register and load those actually on disk while collecting errors
|
||||||
-- Delay showing all errors to have "good" plugins added first
|
-- Delay showing all errors to have "good" plugins added first
|
||||||
local errors = {} --- @type string[]
|
local errors = {} --- @type string[]
|
||||||
@@ -887,7 +973,7 @@ end
|
|||||||
---
|
---
|
||||||
--- @param names? string[] List of plugin names to update. Must be managed
|
--- @param names? string[] List of plugin names to update. Must be managed
|
||||||
--- by |vim.pack|, not necessarily already added to current session.
|
--- by |vim.pack|, not necessarily already added to current session.
|
||||||
--- Default: names of all plugins added to current session via |vim.pack.add()|.
|
--- Default: names of all plugins managed by |vim.pack|.
|
||||||
--- @param opts? vim.pack.keyset.update
|
--- @param opts? vim.pack.keyset.update
|
||||||
function M.update(names, opts)
|
function M.update(names, opts)
|
||||||
vim.validate('names', names, vim.islist, true, 'list')
|
vim.validate('names', names, vim.islist, true, 'list')
|
||||||
@@ -899,6 +985,7 @@ function M.update(names, opts)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
git_ensure_exec()
|
git_ensure_exec()
|
||||||
|
lock_read()
|
||||||
|
|
||||||
-- Perform update
|
-- Perform update
|
||||||
local timestamp = get_timestamp()
|
local timestamp = get_timestamp()
|
||||||
@@ -925,6 +1012,7 @@ function M.update(names, opts)
|
|||||||
run_list(plug_list, do_update, progress_title)
|
run_list(plug_list, do_update, progress_title)
|
||||||
|
|
||||||
if opts.force then
|
if opts.force then
|
||||||
|
lock_write()
|
||||||
feedback_log(plug_list)
|
feedback_log(plug_list)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -950,6 +1038,7 @@ function M.update(names, opts)
|
|||||||
end
|
end
|
||||||
run_list(plugs_to_checkout, do_checkout, 'Applying updates')
|
run_list(plugs_to_checkout, do_checkout, 'Applying updates')
|
||||||
|
|
||||||
|
lock_write()
|
||||||
feedback_log(plugs_to_checkout)
|
feedback_log(plugs_to_checkout)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
@@ -967,6 +1056,8 @@ function M.del(names)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
lock_read()
|
||||||
|
|
||||||
for _, p in ipairs(plug_list) do
|
for _, p in ipairs(plug_list) do
|
||||||
trigger_event(p, 'PackChangedPre', 'delete')
|
trigger_event(p, 'PackChangedPre', 'delete')
|
||||||
|
|
||||||
@@ -974,8 +1065,12 @@ function M.del(names)
|
|||||||
active_plugins[p.path] = nil
|
active_plugins[p.path] = nil
|
||||||
notify(("Removed plugin '%s'"):format(p.spec.name), 'INFO')
|
notify(("Removed plugin '%s'"):format(p.spec.name), 'INFO')
|
||||||
|
|
||||||
|
plugin_lock.plugins[p.spec.name] = nil
|
||||||
|
|
||||||
trigger_event(p, 'PackChanged', 'delete')
|
trigger_event(p, 'PackChanged', 'delete')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
lock_write()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @inlinedoc
|
--- @inlinedoc
|
||||||
@@ -983,7 +1078,7 @@ end
|
|||||||
--- @field active boolean Whether plugin was added via |vim.pack.add()| to current session.
|
--- @field active boolean Whether plugin was added via |vim.pack.add()| to current session.
|
||||||
--- @field branches? string[] Available Git branches (first is default). Missing if `info=false`.
|
--- @field branches? string[] Available Git branches (first is default). Missing if `info=false`.
|
||||||
--- @field path string Plugin's path on disk.
|
--- @field path string Plugin's path on disk.
|
||||||
--- @field rev? string Current Git revision. Missing if `info=false`.
|
--- @field rev string Current Git revision.
|
||||||
--- @field spec vim.pack.SpecResolved A |vim.pack.Spec| with resolved `name`.
|
--- @field spec vim.pack.SpecResolved A |vim.pack.Spec| with resolved `name`.
|
||||||
--- @field tags? string[] Available Git tags. Missing if `info=false`.
|
--- @field tags? string[] Available Git tags. Missing if `info=false`.
|
||||||
|
|
||||||
@@ -999,7 +1094,6 @@ local function add_p_data_info(p_data_list)
|
|||||||
--- @async
|
--- @async
|
||||||
funs[i] = function()
|
funs[i] = function()
|
||||||
p_data.branches = git_get_branches(path)
|
p_data.branches = git_get_branches(path)
|
||||||
p_data.rev = git_get_hash('HEAD', path)
|
|
||||||
p_data.tags = git_get_tags(path)
|
p_data.tags = git_get_tags(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1025,30 +1119,29 @@ function M.get(names, opts)
|
|||||||
active[p_active.id] = p_active.plug
|
active[p_active.id] = p_active.plug
|
||||||
end
|
end
|
||||||
|
|
||||||
|
lock_read()
|
||||||
local res = {} --- @type vim.pack.PlugData[]
|
local res = {} --- @type vim.pack.PlugData[]
|
||||||
local used_names = {} --- @type table<string,boolean>
|
local used_names = {} --- @type table<string,boolean>
|
||||||
for i = 1, n_active_plugins do
|
for i = 1, n_active_plugins do
|
||||||
if active[i] and (not names or vim.tbl_contains(names, active[i].spec.name)) then
|
if active[i] and (not names or vim.tbl_contains(names, active[i].spec.name)) then
|
||||||
res[#res + 1] = { spec = vim.deepcopy(active[i].spec), path = active[i].path, active = true }
|
local name = active[i].spec.name
|
||||||
used_names[active[i].spec.name] = true
|
local spec = vim.deepcopy(active[i].spec)
|
||||||
|
local rev = (plugin_lock.plugins[name] or {}).rev
|
||||||
|
res[#res + 1] = { spec = spec, path = active[i].path, rev = rev, active = true }
|
||||||
|
used_names[name] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @async
|
local plug_dir = get_plug_dir()
|
||||||
local function do_get()
|
for name, l_data in vim.spairs(plugin_lock.plugins) do
|
||||||
-- Process not active plugins
|
local path = vim.fs.joinpath(plug_dir, name)
|
||||||
local plug_dir = get_plug_dir()
|
local is_in_names = not names or vim.tbl_contains(names, name)
|
||||||
for n, t in vim.fs.dir(plug_dir, { depth = 1 }) do
|
if not active_plugins[path] and is_in_names then
|
||||||
local path = vim.fs.joinpath(plug_dir, n)
|
local spec = { name = name, src = l_data.src, version = l_data.version }
|
||||||
local is_in_names = not names or vim.tbl_contains(names, n)
|
res[#res + 1] = { spec = spec, path = path, rev = l_data.rev, active = false }
|
||||||
if t == 'directory' and not active_plugins[path] and is_in_names then
|
used_names[name] = true
|
||||||
local spec = { name = n, src = git_cmd({ 'remote', 'get-url', 'origin' }, path) }
|
|
||||||
res[#res + 1] = { spec = spec, path = path, active = false }
|
|
||||||
used_names[n] = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
async.run(do_get):wait()
|
|
||||||
|
|
||||||
if names ~= nil then
|
if names ~= nil then
|
||||||
-- Align result with input
|
-- Align result with input
|
||||||
|
@@ -135,6 +135,12 @@ end
|
|||||||
function repos_setup.plugindirs()
|
function repos_setup.plugindirs()
|
||||||
init_test_repo('plugindirs')
|
init_test_repo('plugindirs')
|
||||||
|
|
||||||
|
-- Add semver tag
|
||||||
|
repo_write_file('plugindirs', 'lua/plugindirs.lua', 'return "plugindirs v0.0.1"')
|
||||||
|
git_add_commit('Add version v0.0.1', 'plugindirs')
|
||||||
|
git_cmd({ 'tag', 'v0.0.1' }, 'plugindirs')
|
||||||
|
|
||||||
|
-- Add various 'plugin/' files
|
||||||
repo_write_file('plugindirs', 'lua/plugindirs.lua', 'return "plugindirs main"')
|
repo_write_file('plugindirs', 'lua/plugindirs.lua', 'return "plugindirs main"')
|
||||||
repo_write_file('plugindirs', 'plugin/dirs.lua', 'vim.g._plugin = true')
|
repo_write_file('plugindirs', 'plugin/dirs.lua', 'vim.g._plugin = true')
|
||||||
repo_write_file('plugindirs', 'plugin/dirs_log.lua', '_G.DL = _G.DL or {}; DL[#DL+1] = "p"')
|
repo_write_file('plugindirs', 'plugin/dirs_log.lua', '_G.DL = _G.DL or {}; DL[#DL+1] = "p"')
|
||||||
@@ -310,6 +316,14 @@ local function is_jit()
|
|||||||
return exec_lua('return package.loaded.jit ~= nil')
|
return exec_lua('return package.loaded.jit ~= nil')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function get_lock_path()
|
||||||
|
return vim.fs.joinpath(fn.stdpath('config'), 'nvim-pack-lock.json')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_lock_tbl()
|
||||||
|
return vim.json.decode(fn.readblob(get_lock_path()))
|
||||||
|
end
|
||||||
|
|
||||||
-- Tests ======================================================================
|
-- Tests ======================================================================
|
||||||
|
|
||||||
describe('vim.pack', function()
|
describe('vim.pack', function()
|
||||||
@@ -326,6 +340,9 @@ describe('vim.pack', function()
|
|||||||
|
|
||||||
after_each(function()
|
after_each(function()
|
||||||
vim.fs.rm(pack_get_dir(), { force = true, recursive = true })
|
vim.fs.rm(pack_get_dir(), { force = true, recursive = true })
|
||||||
|
vim.fs.rm(get_lock_path(), { force = true })
|
||||||
|
local log_path = vim.fs.joinpath(fn.stdpath('log'), 'nvim-pack.log')
|
||||||
|
pcall(vim.fs.rm, log_path, { force = true })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
teardown(function()
|
teardown(function()
|
||||||
@@ -413,6 +430,117 @@ describe('vim.pack', function()
|
|||||||
eq('plugindirs main', exec_lua('return require("plugindirs")'))
|
eq('plugindirs main', exec_lua('return require("plugindirs")'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('creates lockfile', function()
|
||||||
|
local helptags_rev = git_get_hash('HEAD', 'helptags')
|
||||||
|
exec_lua(function()
|
||||||
|
vim.pack.add({
|
||||||
|
{ src = repos_src.basic, version = 'some-tag' },
|
||||||
|
{ src = repos_src.defbranch, version = 'main' },
|
||||||
|
{ src = repos_src.helptags, version = helptags_rev },
|
||||||
|
{ src = repos_src.plugindirs },
|
||||||
|
{ src = repos_src.semver, version = vim.version.range('*') },
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
local basic_rev = git_get_hash('some-tag', 'basic')
|
||||||
|
local defbranch_rev = git_get_hash('main', 'defbranch')
|
||||||
|
local plugindirs_rev = git_get_hash('HEAD', 'plugindirs')
|
||||||
|
local semver_rev = git_get_hash('v1.0.0', 'semver')
|
||||||
|
|
||||||
|
-- Should properly format as indented JSON
|
||||||
|
local ref_lockfile_lines = {
|
||||||
|
'{',
|
||||||
|
' "plugins": {',
|
||||||
|
' "basic": {',
|
||||||
|
' "rev": "' .. basic_rev .. '",',
|
||||||
|
' "src": "' .. repos_src.basic .. '",',
|
||||||
|
-- Branch, tag, and commit should be serialized like `'value'` to be
|
||||||
|
-- distinguishable from version ranges
|
||||||
|
' "version": "\'some-tag\'"',
|
||||||
|
' },',
|
||||||
|
' "defbranch": {',
|
||||||
|
' "rev": "' .. defbranch_rev .. '",',
|
||||||
|
' "src": "' .. repos_src.defbranch .. '",',
|
||||||
|
' "version": "\'main\'"',
|
||||||
|
' },',
|
||||||
|
' "helptags": {',
|
||||||
|
' "rev": "' .. helptags_rev .. '",',
|
||||||
|
' "src": "' .. repos_src.helptags .. '",',
|
||||||
|
' "version": "\'' .. helptags_rev .. '\'"',
|
||||||
|
' },',
|
||||||
|
' "plugindirs": {',
|
||||||
|
' "rev": "' .. plugindirs_rev .. '",',
|
||||||
|
' "src": "' .. repos_src.plugindirs .. '"',
|
||||||
|
-- Absent `version` should be missing and not autoresolved
|
||||||
|
' },',
|
||||||
|
' "semver": {',
|
||||||
|
' "rev": "' .. semver_rev .. '",',
|
||||||
|
' "src": "' .. repos_src.semver .. '",',
|
||||||
|
' "version": ">=0.0.0"',
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
'}',
|
||||||
|
}
|
||||||
|
eq(ref_lockfile_lines, fn.readfile(get_lock_path()))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('updates lockfile', function()
|
||||||
|
exec_lua(function()
|
||||||
|
vim.pack.add({ repos_src.basic })
|
||||||
|
end)
|
||||||
|
local ref_lockfile = {
|
||||||
|
plugins = {
|
||||||
|
basic = { rev = git_get_hash('main', 'basic'), src = repos_src.basic },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
eq(ref_lockfile, get_lock_tbl())
|
||||||
|
|
||||||
|
n.clear()
|
||||||
|
exec_lua(function()
|
||||||
|
vim.pack.add({ { src = repos_src.basic, version = 'main' } })
|
||||||
|
end)
|
||||||
|
|
||||||
|
ref_lockfile.plugins.basic.version = "'main'"
|
||||||
|
eq(ref_lockfile, get_lock_tbl())
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('uses lockfile revision during install', function()
|
||||||
|
exec_lua(function()
|
||||||
|
vim.pack.add({ { src = repos_src.basic, version = 'feat-branch' } })
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Mock clean initial install, but with lockfile present
|
||||||
|
n.clear()
|
||||||
|
local basic_plug_path = vim.fs.joinpath(pack_get_dir(), 'basic')
|
||||||
|
vim.fs.rm(basic_plug_path, { force = true, recursive = true })
|
||||||
|
|
||||||
|
local basic_rev = git_get_hash('feat-branch', 'basic')
|
||||||
|
local ref_lockfile = {
|
||||||
|
plugins = {
|
||||||
|
basic = { rev = basic_rev, src = repos_src.basic, version = "'feat-branch'" },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
eq(ref_lockfile, get_lock_tbl())
|
||||||
|
|
||||||
|
exec_lua(function()
|
||||||
|
-- Should use revision from lockfile (pointing at latest 'feat-branch'
|
||||||
|
-- commit) and not use latest `main` commit
|
||||||
|
vim.pack.add({ { src = repos_src.basic, version = 'main' } })
|
||||||
|
end)
|
||||||
|
local basic_lua_file = vim.fs.joinpath(pack_get_plug_path('basic'), 'lua', 'basic.lua')
|
||||||
|
eq({ 'return "basic feat-branch"' }, fn.readfile(basic_lua_file))
|
||||||
|
|
||||||
|
-- Running `update()` should still update to use `main`
|
||||||
|
exec_lua(function()
|
||||||
|
vim.pack.update(nil, { force = true })
|
||||||
|
end)
|
||||||
|
eq({ 'return "basic main"' }, fn.readfile(basic_lua_file))
|
||||||
|
|
||||||
|
ref_lockfile.plugins.basic.rev = git_get_hash('main', 'basic')
|
||||||
|
ref_lockfile.plugins.basic.version = "'main'"
|
||||||
|
eq(ref_lockfile, get_lock_tbl())
|
||||||
|
end)
|
||||||
|
|
||||||
it('installs at proper version', function()
|
it('installs at proper version', function()
|
||||||
local out = exec_lua(function()
|
local out = exec_lua(function()
|
||||||
vim.pack.add({
|
vim.pack.add({
|
||||||
@@ -597,9 +725,8 @@ describe('vim.pack', function()
|
|||||||
eq({}, n.exec_lua('return { vim.g._plugin, vim.g._after_plugin }'))
|
eq({}, n.exec_lua('return { vim.g._plugin, vim.g._after_plugin }'))
|
||||||
|
|
||||||
-- Plugins should still be marked as "active", since they were added
|
-- Plugins should still be marked as "active", since they were added
|
||||||
plugindirs_data.active = true
|
eq(true, exec_lua('return vim.pack.get({ "plugindirs" })[1].active'))
|
||||||
basic_data.active = true
|
eq(true, exec_lua('return vim.pack.get({ "basic" })[1].active'))
|
||||||
eq({ plugindirs_data, basic_data }, exec_lua('return vim.pack.get(nil, { info = false })'))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Works on initial install
|
-- Works on initial install
|
||||||
@@ -759,7 +886,7 @@ describe('vim.pack', function()
|
|||||||
-- Install initial versions of tested plugins
|
-- Install initial versions of tested plugins
|
||||||
exec_lua(function()
|
exec_lua(function()
|
||||||
vim.pack.add({
|
vim.pack.add({
|
||||||
repos_src.fetch,
|
{ src = repos_src.fetch, version = 'main' },
|
||||||
{ src = repos_src.semver, version = 'v0.3.0' },
|
{ src = repos_src.semver, version = 'v0.3.0' },
|
||||||
repos_src.defbranch,
|
repos_src.defbranch,
|
||||||
})
|
})
|
||||||
@@ -777,6 +904,11 @@ describe('vim.pack', function()
|
|||||||
|
|
||||||
repo_write_file('fetch', 'lua/fetch.lua', 'return "fetch new 2"')
|
repo_write_file('fetch', 'lua/fetch.lua', 'return "fetch new 2"')
|
||||||
git_add_commit('Commit to be added 2', 'fetch')
|
git_add_commit('Commit to be added 2', 'fetch')
|
||||||
|
|
||||||
|
-- Make `dev` default remote branch to check that `version` is respected
|
||||||
|
git_cmd({ 'checkout', '-b', 'dev' }, 'fetch')
|
||||||
|
repo_write_file('fetch', 'lua/fetch.lua', 'return "fetch dev"')
|
||||||
|
git_add_commit('Commit from default `dev` branch', 'fetch')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
after_each(function()
|
after_each(function()
|
||||||
@@ -854,8 +986,8 @@ describe('vim.pack', function()
|
|||||||
local screen
|
local screen
|
||||||
screen = Screen.new(85, 35)
|
screen = Screen.new(85, 35)
|
||||||
|
|
||||||
hashes.fetch_new = git_get_hash('HEAD', 'fetch')
|
hashes.fetch_new = git_get_hash('main', 'fetch')
|
||||||
hashes.fetch_new_prev = git_get_hash('HEAD~', 'fetch')
|
hashes.fetch_new_prev = git_get_hash('main~', 'fetch')
|
||||||
hashes.semver_head = git_get_hash('v0.3.0', 'semver')
|
hashes.semver_head = git_get_hash('v0.3.0', 'semver')
|
||||||
|
|
||||||
local tab_name = 'n' .. (t.is_os('win') and ':' or '') .. '//2/confirm-update'
|
local tab_name = 'n' .. (t.is_os('win') and ':' or '') .. '//2/confirm-update'
|
||||||
@@ -1087,12 +1219,27 @@ describe('vim.pack', function()
|
|||||||
local confirm_text = table.concat(api.nvim_buf_get_lines(0, 0, -1, false), '\n')
|
local confirm_text = table.concat(api.nvim_buf_get_lines(0, 0, -1, false), '\n')
|
||||||
matches('Available newer versions:\n• v1%.0%.0\n• v0%.4\n• 0%.3%.1$', confirm_text)
|
matches('Available newer versions:\n• v1%.0%.0\n• v0%.4\n• 0%.3%.1$', confirm_text)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('updates lockfile', function()
|
||||||
|
exec_lua(function()
|
||||||
|
vim.pack.add({ repos_src.fetch })
|
||||||
|
end)
|
||||||
|
local ref_fetch_lock = { rev = hashes.fetch_head, src = repos_src.fetch }
|
||||||
|
eq(ref_fetch_lock, get_lock_tbl().plugins.fetch)
|
||||||
|
|
||||||
|
exec_lua('vim.pack.update()')
|
||||||
|
n.exec('write')
|
||||||
|
|
||||||
|
ref_fetch_lock.rev = git_get_hash('main', 'fetch')
|
||||||
|
eq(ref_fetch_lock, get_lock_tbl().plugins.fetch)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('works with not active plugins', function()
|
it('works with not active plugins', function()
|
||||||
|
-- No plugins are added, but they are installed in `before_each()`
|
||||||
exec_lua(function()
|
exec_lua(function()
|
||||||
-- No plugins are added, but they are installed in `before_each()`
|
-- By default should also include not active plugins
|
||||||
vim.pack.update({ 'fetch' })
|
vim.pack.update()
|
||||||
end)
|
end)
|
||||||
eq({ 'return "fetch main"' }, fn.readfile(fetch_lua_file))
|
eq({ 'return "fetch main"' }, fn.readfile(fetch_lua_file))
|
||||||
n.exec('write')
|
n.exec('write')
|
||||||
@@ -1116,8 +1263,8 @@ describe('vim.pack', function()
|
|||||||
eq('', api.nvim_get_option_value('filetype', {}))
|
eq('', api.nvim_get_option_value('filetype', {}))
|
||||||
|
|
||||||
-- Write to log file
|
-- Write to log file
|
||||||
hashes.fetch_new = git_get_hash('HEAD', 'fetch')
|
hashes.fetch_new = git_get_hash('main', 'fetch')
|
||||||
hashes.fetch_new_prev = git_get_hash('HEAD~', 'fetch')
|
hashes.fetch_new_prev = git_get_hash('main~', 'fetch')
|
||||||
|
|
||||||
local log_path = vim.fs.joinpath(fn.stdpath('log'), 'nvim-pack.log')
|
local log_path = vim.fs.joinpath(fn.stdpath('log'), 'nvim-pack.log')
|
||||||
local log_lines = fn.readfile(log_path)
|
local log_lines = fn.readfile(log_path)
|
||||||
@@ -1138,17 +1285,21 @@ describe('vim.pack', function()
|
|||||||
'',
|
'',
|
||||||
}
|
}
|
||||||
eq(ref_log_lines, vim.list_slice(log_lines, 2))
|
eq(ref_log_lines, vim.list_slice(log_lines, 2))
|
||||||
|
|
||||||
|
-- Should update lockfile
|
||||||
|
eq(hashes.fetch_new, get_lock_tbl().plugins.fetch.rev)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('shows progress report', function()
|
it('shows progress report', function()
|
||||||
track_nvim_echo()
|
track_nvim_echo()
|
||||||
exec_lua(function()
|
exec_lua(function()
|
||||||
vim.pack.add({ repos_src.fetch, repos_src.defbranch })
|
vim.pack.add({ repos_src.fetch, repos_src.defbranch })
|
||||||
|
-- Should also include updates from not active plugins
|
||||||
vim.pack.update()
|
vim.pack.update()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- During initial download
|
-- During initial download
|
||||||
validate_progress_report('Downloading updates', { 'fetch', 'defbranch' })
|
validate_progress_report('Downloading updates', { 'fetch', 'defbranch', 'semver' })
|
||||||
exec_lua('_G.echo_log = {}')
|
exec_lua('_G.echo_log = {}')
|
||||||
|
|
||||||
-- During application (only for plugins that have updates)
|
-- During application (only for plugins that have updates)
|
||||||
@@ -1165,7 +1316,7 @@ describe('vim.pack', function()
|
|||||||
vim.pack.add({ repos_src.fetch, repos_src.defbranch })
|
vim.pack.add({ repos_src.fetch, repos_src.defbranch })
|
||||||
vim.pack.update(nil, { force = true })
|
vim.pack.update(nil, { force = true })
|
||||||
end)
|
end)
|
||||||
validate_progress_report('Updating', { 'fetch', 'defbranch' })
|
validate_progress_report('Updating', { 'fetch', 'defbranch', 'semver' })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('triggers relevant events', function()
|
it('triggers relevant events', function()
|
||||||
@@ -1246,10 +1397,10 @@ describe('vim.pack', function()
|
|||||||
local make_basic_data = function(active, info)
|
local make_basic_data = function(active, info)
|
||||||
local spec = { name = 'basic', src = repos_src.basic, version = 'feat-branch' }
|
local spec = { name = 'basic', src = repos_src.basic, version = 'feat-branch' }
|
||||||
local path = pack_get_plug_path('basic')
|
local path = pack_get_plug_path('basic')
|
||||||
local res = { active = active, path = path, spec = spec }
|
local rev = git_get_hash('feat-branch', 'basic')
|
||||||
|
local res = { active = active, path = path, spec = spec, rev = rev }
|
||||||
if info then
|
if info then
|
||||||
res.branches = { 'main', 'feat-branch' }
|
res.branches = { 'main', 'feat-branch' }
|
||||||
res.rev = git_get_hash('feat-branch', 'basic')
|
|
||||||
res.tags = { 'some-tag' }
|
res.tags = { 'some-tag' }
|
||||||
end
|
end
|
||||||
return res
|
return res
|
||||||
@@ -1258,50 +1409,74 @@ describe('vim.pack', function()
|
|||||||
local make_defbranch_data = function(active, info)
|
local make_defbranch_data = function(active, info)
|
||||||
local spec = { name = 'defbranch', src = repos_src.defbranch }
|
local spec = { name = 'defbranch', src = repos_src.defbranch }
|
||||||
local path = pack_get_plug_path('defbranch')
|
local path = pack_get_plug_path('defbranch')
|
||||||
local res = { active = active, path = path, spec = spec }
|
local rev = git_get_hash('dev', 'defbranch')
|
||||||
|
local res = { active = active, path = path, spec = spec, rev = rev }
|
||||||
if info then
|
if info then
|
||||||
res.branches = { 'dev', 'main' }
|
res.branches = { 'dev', 'main' }
|
||||||
res.rev = git_get_hash('dev', 'defbranch')
|
|
||||||
res.tags = {}
|
res.tags = {}
|
||||||
end
|
end
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local make_plugindirs_data = function(active, info)
|
||||||
|
local spec =
|
||||||
|
{ name = 'plugindirs', src = repos_src.plugindirs, version = vim.version.range('*') }
|
||||||
|
local path = pack_get_plug_path('plugindirs')
|
||||||
|
local rev = git_get_hash('v0.0.1', 'plugindirs')
|
||||||
|
local res = { active = active, path = path, spec = spec, rev = rev }
|
||||||
|
if info then
|
||||||
|
res.branches = { 'main' }
|
||||||
|
res.tags = { 'v0.0.1' }
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
it('returns list with necessary data', function()
|
it('returns list with necessary data', function()
|
||||||
local basic_data, defbranch_data
|
local basic_data, defbranch_data, plugindirs_data
|
||||||
|
|
||||||
-- Should work just after installation
|
-- Should work just after installation
|
||||||
exec_lua(function()
|
exec_lua(function()
|
||||||
vim.pack.add({ repos_src.defbranch, { src = repos_src.basic, version = 'feat-branch' } })
|
vim.pack.add({
|
||||||
|
repos_src.defbranch,
|
||||||
|
{ src = repos_src.basic, version = 'feat-branch' },
|
||||||
|
{ src = repos_src.plugindirs, version = vim.version.range('*') },
|
||||||
|
})
|
||||||
end)
|
end)
|
||||||
defbranch_data = make_defbranch_data(true, true)
|
defbranch_data = make_defbranch_data(true, true)
|
||||||
basic_data = make_basic_data(true, true)
|
basic_data = make_basic_data(true, true)
|
||||||
|
plugindirs_data = make_plugindirs_data(true, true)
|
||||||
-- Should preserve order in which plugins were `vim.pack.add()`ed
|
-- Should preserve order in which plugins were `vim.pack.add()`ed
|
||||||
eq({ defbranch_data, basic_data }, exec_lua('return vim.pack.get()'))
|
eq({ defbranch_data, basic_data, plugindirs_data }, exec_lua('return vim.pack.get()'))
|
||||||
|
|
||||||
-- Should also list non-active plugins
|
-- Should also list non-active plugins
|
||||||
n.clear()
|
n.clear()
|
||||||
|
|
||||||
exec_lua(function()
|
exec_lua(function()
|
||||||
vim.pack.add({ { src = repos_src.basic, version = 'feat-branch' } })
|
vim.pack.add({ repos_src.defbranch })
|
||||||
end)
|
end)
|
||||||
defbranch_data = make_defbranch_data(false, true)
|
defbranch_data = make_defbranch_data(true, true)
|
||||||
basic_data = make_basic_data(true, true)
|
basic_data = make_basic_data(false, true)
|
||||||
-- Should first list active, then non-active
|
plugindirs_data = make_plugindirs_data(false, true)
|
||||||
eq({ basic_data, defbranch_data }, exec_lua('return vim.pack.get()'))
|
-- Should first list active, then non-active (including their latest
|
||||||
|
-- set `version` which is inferred from lockfile)
|
||||||
|
eq({ defbranch_data, basic_data, plugindirs_data }, exec_lua('return vim.pack.get()'))
|
||||||
|
|
||||||
-- Should respect `names` for both active and not active plugins
|
-- Should respect `names` for both active and not active plugins
|
||||||
eq({ basic_data }, exec_lua('return vim.pack.get({ "basic" })'))
|
eq({ basic_data }, exec_lua('return vim.pack.get({ "basic" })'))
|
||||||
eq({ defbranch_data }, exec_lua('return vim.pack.get({ "defbranch" })'))
|
eq({ defbranch_data }, exec_lua('return vim.pack.get({ "defbranch" })'))
|
||||||
eq({ defbranch_data, basic_data }, exec_lua('return vim.pack.get({ "defbranch", "basic" })'))
|
eq({ basic_data, defbranch_data }, exec_lua('return vim.pack.get({ "basic", "defbranch" })'))
|
||||||
|
|
||||||
local bad_get_cmd = 'return vim.pack.get({ "ccc", "basic", "aaa" })'
|
local bad_get_cmd = 'return vim.pack.get({ "ccc", "basic", "aaa" })'
|
||||||
matches('Plugin `ccc` is not installed', pcall_err(exec_lua, bad_get_cmd))
|
matches('Plugin `ccc` is not installed', pcall_err(exec_lua, bad_get_cmd))
|
||||||
|
|
||||||
-- Should respect `opts.info`
|
-- Should respect `opts.info`
|
||||||
defbranch_data = make_defbranch_data(false, false)
|
defbranch_data = make_defbranch_data(true, false)
|
||||||
basic_data = make_basic_data(true, false)
|
basic_data = make_basic_data(false, false)
|
||||||
eq({ basic_data, defbranch_data }, exec_lua('return vim.pack.get(nil, { info = false })'))
|
plugindirs_data = make_plugindirs_data(false, false)
|
||||||
|
eq(
|
||||||
|
{ defbranch_data, basic_data, plugindirs_data },
|
||||||
|
exec_lua('return vim.pack.get(nil, { info = false })')
|
||||||
|
)
|
||||||
eq({ basic_data }, exec_lua('return vim.pack.get({ "basic" }, { info = false })'))
|
eq({ basic_data }, exec_lua('return vim.pack.get({ "basic" }, { info = false })'))
|
||||||
eq({ defbranch_data }, exec_lua('return vim.pack.get({ "defbranch" }, { info = false })'))
|
eq({ defbranch_data }, exec_lua('return vim.pack.get({ "defbranch" }, { info = false })'))
|
||||||
end)
|
end)
|
||||||
@@ -1350,6 +1525,10 @@ describe('vim.pack', function()
|
|||||||
eq(true, pack_exists('basic'))
|
eq(true, pack_exists('basic'))
|
||||||
eq(true, pack_exists('plugindirs'))
|
eq(true, pack_exists('plugindirs'))
|
||||||
|
|
||||||
|
local locked_plugins = vim.tbl_keys(get_lock_tbl().plugins)
|
||||||
|
table.sort(locked_plugins)
|
||||||
|
eq({ 'basic', 'plugindirs' }, locked_plugins)
|
||||||
|
|
||||||
watch_events({ 'PackChangedPre', 'PackChanged' })
|
watch_events({ 'PackChangedPre', 'PackChanged' })
|
||||||
|
|
||||||
n.exec('messages clear')
|
n.exec('messages clear')
|
||||||
@@ -1371,6 +1550,23 @@ describe('vim.pack', function()
|
|||||||
eq(3, find_in_log(log, 'PackChangedPre', 'delete', 'plugindirs', nil))
|
eq(3, find_in_log(log, 'PackChangedPre', 'delete', 'plugindirs', nil))
|
||||||
eq(4, find_in_log(log, 'PackChanged', 'delete', 'plugindirs', nil))
|
eq(4, find_in_log(log, 'PackChanged', 'delete', 'plugindirs', nil))
|
||||||
eq(4, #log)
|
eq(4, #log)
|
||||||
|
|
||||||
|
-- Should update lockfile
|
||||||
|
eq({ plugins = {} }, get_lock_tbl())
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('works without prior `add()`', function()
|
||||||
|
exec_lua(function()
|
||||||
|
vim.pack.add({ repos_src.basic })
|
||||||
|
end)
|
||||||
|
n.clear()
|
||||||
|
|
||||||
|
eq(true, pack_exists('basic'))
|
||||||
|
exec_lua(function()
|
||||||
|
vim.pack.del({ 'basic' })
|
||||||
|
end)
|
||||||
|
eq(false, pack_exists('basic'))
|
||||||
|
eq({ plugins = {} }, get_lock_tbl())
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('validates input', function()
|
it('validates input', function()
|
||||||
|
Reference in New Issue
Block a user