diff options
Diffstat (limited to 'lua/blink/cmp/fuzzy/download/init.lua')
| -rw-r--r-- | lua/blink/cmp/fuzzy/download/init.lua | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/lua/blink/cmp/fuzzy/download/init.lua b/lua/blink/cmp/fuzzy/download/init.lua new file mode 100644 index 0000000..085becd --- /dev/null +++ b/lua/blink/cmp/fuzzy/download/init.lua @@ -0,0 +1,170 @@ +local download_config = require('blink.cmp.config').fuzzy.prebuilt_binaries +local async = require('blink.cmp.lib.async') +local git = require('blink.cmp.fuzzy.download.git') +local files = require('blink.cmp.fuzzy.download.files') +local system = require('blink.cmp.fuzzy.download.system') + +local download = {} + +--- @param callback fun(err: string | nil) +function download.ensure_downloaded(callback) + callback = vim.schedule_wrap(callback) + + if not download_config.download then return callback() end + + async.task + .await_all({ git.get_version(), files.get_version() }) + :map(function(results) + return { + git = results[1], + current = results[2], + } + end) + :map(function(version) + local target_git_tag = download_config.force_version or version.git.tag + + -- not built locally, not on a git tag, error + assert( + version.current.sha ~= nil or target_git_tag ~= nil, + "\nDetected an out of date or missing fuzzy matching library. Can't download from github due to not being on a git tag and no `fuzzy.prebuilt_binaries.force_version` is set." + .. '\nEither run `cargo build --release` via your package manager, switch to a git tag, or set `fuzzy.prebuilt_binaries.force_version` in config. ' + .. 'See the docs for more info.' + ) + + -- built locally, ignore + if + not download_config.force_version + and ( + version.current.sha == version.git.sha + or version.current.sha ~= nil and download_config.ignore_version_mismatch + ) + then + return + end + + -- built locally but outdated and not on a git tag, error + if + not download_config.force_version + and version.current.sha ~= nil + and version.current.sha ~= version.git.sha + then + assert( + target_git_tag or download_config.ignore_version_mismatch, + "\nFound an outdated version of the fuzzy matching library, but can't download from github due to not being on a git tag. " + .. '\n!! FOR DEVELOPERS !!, set `fuzzy.prebuilt_binaries.ignore_version_mismatch = true` in config. ' + .. '\n!! FOR USERS !!, either run `cargo build --release` via your package manager, switch to a git tag, or set `fuzzy.prebuilt_binaries.force_version` in config. ' + .. 'See the docs for more info.' + ) + if not download_config.ignore_version_mismatch then + vim.schedule( + function() + vim.notify( + '[blink.cmp]: Found an outdated version of the fuzzy matching library built locally', + vim.log.levels.INFO, + { title = 'blink.cmp' } + ) + end + ) + end + end + + -- already downloaded and the correct version, just verify the checksum, and re-download if checksum fails + if version.current.tag ~= nil and version.current.tag == target_git_tag then + return files.verify_checksum():catch(function(err) + vim.schedule(function() + vim.notify(err, vim.log.levels.WARN, { title = 'blink.cmp' }) + vim.notify( + '[blink.cmp]: Pre-built binary failed checksum verification, re-downloading', + vim.log.levels.WARN, + { title = 'blink.cmp' } + ) + end) + return download.download(target_git_tag) + end) + end + + -- unknown state + if not target_git_tag then error('Unknown error while getting pre-built binary. Consider re-installing') end + + -- download as per usual + vim.schedule( + function() vim.notify('[blink.cmp]: Downloading pre-built binary', vim.log.levels.INFO, { title = 'blink.cmp' }) end + ) + return download.download(target_git_tag) + end) + :map(function() callback() end) + :catch(function(err) callback(err) end) +end + +function download.download(version) + -- NOTE: we set the version to 'v0.0.0' to avoid a failure causing the pre-built binary being marked as locally built + return files + .set_version('v0.0.0') + :map(function() return download.from_github(version) end) + :map(function() return files.verify_checksum() end) + :map(function() return files.set_version(version) end) +end + +--- @param tag string +--- @return blink.cmp.Task +function download.from_github(tag) + return system.get_triple():map(function(system_triple) + if not system_triple then + return error( + 'Your system is not supported by pre-built binaries. You must run cargo build --release via your package manager with rust nightly. See the README for more info.' + ) + end + + local base_url = 'https://github.com/saghen/blink.cmp/releases/download/' .. tag .. '/' + local library_url = base_url .. system_triple .. files.get_lib_extension() + local checksum_url = base_url .. system_triple .. files.get_lib_extension() .. '.sha256' + + return async + .task + .await_all({ + download.download_file(library_url, files.lib_filename .. '.tmp'), + download.download_file(checksum_url, files.checksum_filename), + }) + -- Mac caches the library in the kernel, so updating in place causes a crash + -- We instead write to a temporary file and rename it, as mentioned in: + -- https://developer.apple.com/documentation/security/updating-mac-software + :map( + function() + return files.rename( + files.lib_folder .. '/' .. files.lib_filename .. '.tmp', + files.lib_folder .. '/' .. files.lib_filename + ) + end + ) + end) +end + +--- @param url string +--- @param filename string +--- @return blink.cmp.Task +function download.download_file(url, filename) + return async.task.new(function(resolve, reject) + local args = { 'curl' } + vim.list_extend(args, download_config.extra_curl_args) + vim.list_extend(args, { + '--fail', -- Fail on 4xx/5xx + '--location', -- Follow redirects + '--silent', -- Don't show progress + '--show-error', -- Show errors, even though we're using --silent + '--create-dirs', + '--output', + files.lib_folder .. '/' .. filename, + url, + }) + + vim.system(args, {}, function(out) + if out.code ~= 0 then + reject('Failed to download ' .. filename .. 'for pre-built binaries: ' .. out.stderr) + else + resolve() + end + end) + end) +end + +return download |
