From 3b2ac9e8400d8bc8493f92a745a1ed69f5d92a75 Mon Sep 17 00:00:00 2001 From: gustav-fff <286169375+gustav-fff@users.noreply.github.com> Date: Fri, 17 Jul 2026 14:21:23 -0700 Subject: [PATCH] feat(download): accept explicit version in download_or_build_binary (#687) `download_or_build_binary()` now takes an optional `{ version, proxy, extra_curl_args, timeout_ms }` table. Passing `version` pins the GitHub release tag downloaded from, so lazy.nvim users who set `version = "v0.10.0"` on the plugin spec can pass the same value to the build hook and guarantee the binary matches the pinned Lua code instead of falling through to a nightly/dev tag when the local tag lookup is ambiguous. Also exposes `timeout_ms` so slower boxes can raise the 2-minute cargo fallback ceiling. Refs #687 --- README.md | 8 ++++++-- lua/fff/download.lua | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d0879b3a5..73d6ed8c7 100644 --- a/README.md +++ b/README.md @@ -152,9 +152,13 @@ https://github.com/user-attachments/assets/5d0e1ce9-642c-4c44-aa88-01b05bb86abb ```lua { 'dmtrKovalenko/fff.nvim', + version = 'v0.10.0', build = function() - -- downloads a prebuilt binary or falls back to cargo build - require("fff.download").download_or_build_binary() + -- Downloads a prebuilt binary or falls back to `cargo build --release`. + -- Pass the same value you set as `version` above to guarantee the binary + -- matches the pinned Lua code. Omit to derive the tag from the checked-out + -- commit. + require("fff.download").download_or_build_binary({ version = 'v0.10.0' }) end, -- for nixos: -- build = "nix run .#release", diff --git a/lua/fff/download.lua b/lua/fff/download.lua index 175dc4c37..4c44326d4 100644 --- a/lua/fff/download.lua +++ b/lua/fff/download.lua @@ -232,11 +232,23 @@ function M.build_binary(callback) end) end -function M.download_or_build_binary() +--- opts.version pins the GitHub release tag (accepts "0.10.0" or "v0.10.0"). +--- When omitted the tag is derived from the checked-out git ref. +---@param opts? { version?: string, proxy?: string, extra_curl_args?: string[], timeout_ms?: integer } +function M.download_or_build_binary(opts) + opts = opts or {} + local ensure_opts = { force = true, proxy = opts.proxy, extra_curl_args = opts.extra_curl_args } + if type(opts.version) == 'string' and opts.version ~= '' then + local v = opts.version + -- Stable release tags are `v`; nightly/dev per-sha tags are unprefixed. + if v:match('^%d+%.%d+%.%d+$') then v = 'v' .. v end + ensure_opts.version = v + end + local done = false local fatal_error = nil - M.ensure_downloaded({ force = true }, function(download_success, download_error) + M.ensure_downloaded(ensure_opts, function(download_success, download_error) if download_success then done = true return @@ -267,7 +279,7 @@ function M.download_or_build_binary() -- and if Neovim exits before the final rename(tmp → libfff_nvim.{dylib,so,dll}) -- executes, the binary is never written to disk. vim.wait pumps the event -- loop so all vim.system / vim.schedule callbacks can fire. - local timeout_ms = 1000 * 60 * 2 -- 2 minutes + local timeout_ms = opts.timeout_ms or (1000 * 60 * 2) -- default: 2 minutes local ok, wait_err = vim.wait(timeout_ms, function() return done end, 100) if not ok and wait_err == -2 then error('fff.nvim: download_or_build_binary timed out') end