diff --git a/runtime/doc/pack.txt b/runtime/doc/pack.txt index 6cf225aec6..557f1bc762 100644 --- a/runtime/doc/pack.txt +++ b/runtime/doc/pack.txt @@ -224,8 +224,9 @@ tags following semver convention `v..`. 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. Should not be -edited by hand or deleted. +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 ~ @@ -260,7 +261,8 @@ Basic install and management: plugin1 = require('plugin1') < • 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: • Execute |vim.pack.update()|. This will download updates from source and show confirmation buffer in a separate tabpage. diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua index 268f43e063..6790350bc3 100644 --- a/runtime/lua/vim/pack.lua +++ b/runtime/lua/vim/pack.lua @@ -18,7 +18,8 @@ ---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. ----Should not be edited by hand or deleted. +---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 ~ --- @@ -56,7 +57,8 @@ ---``` --- ---- 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: --- - Execute |vim.pack.update()|. This will download updates from source and @@ -625,6 +627,9 @@ local function install_list(plug_list, confirm) 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 -- have new repo in expected detached HEAD state and generated help files. checkout(p, timestamp, false) diff --git a/test/functional/plugin/pack_spec.lua b/test/functional/plugin/pack_spec.lua index 7440d2b9ca..4ea9a0eca7 100644 --- a/test/functional/plugin/pack_spec.lua +++ b/test/functional/plugin/pack_spec.lua @@ -341,6 +341,8 @@ describe('vim.pack', function() after_each(function() 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) teardown(function() @@ -502,6 +504,43 @@ describe('vim.pack', function() 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() local out = exec_lua(function() vim.pack.add({