summaryrefslogtreecommitdiffstatshomepage
path: root/runtime/lua
diff options
context:
space:
mode:
authorEvgeni Chasnovski <evgeni.chasnovski@gmail.com>2026-04-23 18:14:06 +0300
committerGitHub <noreply@github.com>2026-04-23 11:14:06 -0400
commitf8c94bb8cf470ff875ac6dc2e962cfb4b9cef0c2 (patch)
treeb816436d35af60589b27e69b86b4366c8674ae31 /runtime/lua
parent2124ffb27b6adbde23738d0a92fa95d20cdaaf50 (diff)
fix(pack): only use tags that strictly comply with semver spec #39342
Problem: Using `version=vim.version.range(...)` in plugin specification is meant to use semver-like tags. Whether a tag is semver-like was decided by a plain `vim.version.parse` which is not strict by default. This allowed treating tags like `nvim-0.6` (which is usually reserved for the latest revision compatible with Nvim<=0.6 version) like semver tags and resulted in confusing behavior (preferring `nvim-0.6` tag over `v0.2.2`, for example). Solution: Use `vim.version.range(x, { strict = true })` to decide if the tag name is semver-like or not. This allows tags like both `v1.2.3` and `1.2.3` while being consistent in what Nvim thinks is a semver string. This is technically not a breaking change since it was documented that only tags like `v<major>.<minor>.<patch>` will be recognized as semver.
Diffstat (limited to 'runtime/lua')
-rw-r--r--runtime/lua/vim/pack.lua19
1 files changed, 12 insertions, 7 deletions
diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua
index 9b5c28bc5f..ae965c68df 100644
--- a/runtime/lua/vim/pack.lua
+++ b/runtime/lua/vim/pack.lua
@@ -12,7 +12,8 @@
---
---Uses Git to manage plugins and requires present `git` executable.
---Target plugins should be Git repositories with versions as named tags
----following semver convention `v<major>.<minor>.<patch>`.
+---following semver convention `v<major>.<minor>.<patch>` (with or without `v` prefix).
+---Like `v1.2.0` or `1.2.0`, but not `1.2` or `v1`.
---
---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
@@ -255,6 +256,10 @@ local function git_cmd(cmd, cwd)
return (stdout:gsub('\n+$', ''))
end
+local function parse_semver(x)
+ return vim.version.parse(x, { strict = true })
+end
+
--- @type vim.Version
local git_version
@@ -274,7 +279,7 @@ local function git_clone(url, path)
if vim.startswith(url, 'file://') then
cmd[#cmd + 1] = '--no-hardlinks'
- elseif git_version >= vim.version.parse('2.27') then
+ elseif git_version >= parse_semver('2.27.0') then
cmd[#cmd + 1] = '--filter=blob:none'
end
@@ -343,7 +348,7 @@ end
--- @param x string
--- @return boolean
local function is_semver(x)
- return vim.version.parse(x) ~= nil
+ return parse_semver(x) ~= nil
end
local function is_nonempty_string(x)
@@ -585,7 +590,7 @@ end
local function get_last_semver_tag(tags, version_range)
local last_tag, last_ver_tag --- @type string, vim.Version
for _, tag in ipairs(tags) do
- local ver_tag = vim.version.parse(tag)
+ local ver_tag = parse_semver(tag)
if ver_tag then
if version_range:has(ver_tag) and (not last_ver_tag or ver_tag > last_ver_tag) then
last_tag, last_ver_tag = tag, ver_tag
@@ -667,7 +672,7 @@ local function checkout(p, timestamp, skip_stash)
if not skip_stash then
local stash_cmd = { 'stash' }
- if git_version > vim.version.parse('2.13') then
+ if git_version > parse_semver('2.13.0') then
-- Use 'push' to avoid a 'stash -m' bug in versions prior to git v2.26
stash_cmd[#stash_cmd + 1] = 'push'
stash_cmd[#stash_cmd + 1] = '--message'
@@ -680,7 +685,7 @@ local function checkout(p, timestamp, skip_stash)
git_cmd({ 'checkout', '--quiet', p.info.sha_target }, p.path)
local submodule_cmd = { 'submodule', 'update', '--init', '--recursive' }
- if git_version >= vim.version.parse('2.36') then
+ if git_version >= parse_semver('2.36.0') then
submodule_cmd[#submodule_cmd + 1] = '--filter=blob:none'
end
git_cmd(submodule_cmd, p.path)
@@ -760,7 +765,7 @@ local function infer_update_details(p)
end
local older_tags = ''
- if git_version >= vim.version.parse('2.13') then
+ if git_version >= parse_semver('2.13.0') then
older_tags = git_cmd({ 'tag', '--list', '--no-contains', sha_head }, p.path)
end
local cur_tags = git_cmd({ 'tag', '--list', '--points-at', sha_head }, p.path)