summaryrefslogtreecommitdiff
path: root/lua/blink/cmp/fuzzy/download/init.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/blink/cmp/fuzzy/download/init.lua')
-rw-r--r--lua/blink/cmp/fuzzy/download/init.lua170
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