local sp = os.getenv "SNAPSHOT_PATH" local function call_proc(process, opts, cb) local output, error_output = "", "" local handle_stdout = function(err, chunk) assert(not err, err) if chunk then output = output .. chunk end end local handle_stderr = function(err, chunk) assert(not err, err) if chunk then error_output = error_output .. chunk end end local uv = vim.loop local handle local stdout = uv.new_pipe(false) local stderr = uv.new_pipe(false) local stdio = { nil, stdout, stderr } handle = uv.spawn( process, { args = opts.args, cwd = opts.cwd or uv.cwd(), stdio = stdio }, vim.schedule_wrap(function(code) if code ~= 0 then stdout:read_stop() stderr:read_stop() end local check = uv.new_check() check:start(function() for _, pipe in ipairs(stdio) do if pipe and not pipe:is_closing() then return end end check:stop() handle:close() cb(code, output, error_output) end) end) ) uv.read_start(stdout, handle_stdout) uv.read_start(stderr, handle_stderr) return handle end local plugins_list = {} local completed = 0 local function write_lockfile(verbose) local default_plugins = {} local active_jobs = {} local core_plugins = require "lvim.plugins" for _, plugin in pairs(core_plugins) do local name = plugin[1]:match "/(%S*)" local url = "https://github.com/" .. plugin[1] local commit = "" table.insert(default_plugins, { name = name, url = url, commit = commit, branch = plugin.branch or "HEAD", tag = plugin.tag, }) end table.sort(default_plugins, function(a, b) return a.name < b.name end) for _, entry in pairs(default_plugins) do local on_done = function(success, result, errors) completed = completed + 1 if not success then print("error: " .. errors) return end local latest_sha = result:gsub("\tHEAD\n", ""):sub(1, 7) if entry.tag then local dereferenced_commit = result:match("\n(.*)\trefs/tags/" .. entry.tag .. "%^{}\n") if dereferenced_commit then latest_sha = dereferenced_commit:sub(1, 7) end end plugins_list[entry.name] = { commit = latest_sha, } end local handle = call_proc("git", { args = { "ls-remote", entry.url, entry.tag and entry.tag .. "*" or entry.branch }, }, on_done) assert(handle) table.insert(active_jobs, handle) end print("active: " .. #active_jobs) print("plugins: " .. #default_plugins) vim.wait(#active_jobs * 60 * 1000, function() return completed == #active_jobs end) if verbose then print(vim.inspect(plugins_list)) end local fd = assert(io.open(sp, "w")) fd:write(vim.json.encode(plugins_list), "\n") fd:flush() end write_lockfile() vim.cmd "q"