123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- #!/usr/bin/env -S nvim -l
- -- Usage:
- -- ./scripts/bump_deps.lua -h
- assert(vim.fn.executable('gh') == 1)
- assert(vim.fn.executable('sed') == 1)
- local required_branch_prefix = 'bump-'
- local commit_prefix = 'build(deps): '
- local repos = {
- 'luajit/luajit',
- 'libuv/libuv',
- 'luvit/luv',
- 'neovim/unibilium',
- 'juliastrings/utf8proc',
- 'tree-sitter/tree-sitter',
- 'tree-sitter/tree-sitter-c',
- 'tree-sitter-grammars/tree-sitter-lua',
- 'tree-sitter-grammars/tree-sitter-vim',
- 'neovim/tree-sitter-vimdoc',
- 'tree-sitter-grammars/tree-sitter-query',
- 'tree-sitter-grammars/tree-sitter-markdown',
- 'bytecodealliance/wasmtime',
- 'uncrustify/uncrustify',
- }
- local dependency_table = {} --- @type table<string, string>
- for _, repo in pairs(repos) do
- dependency_table[vim.fs.basename(repo)] = repo
- end
- local function die(msg)
- print(msg)
- vim.cmd('cquit 1')
- end
- -- Executes and returns the output of `cmd`, or nil on failure.
- -- if die_on_fail is true, process dies with die_msg on failure
- local function _run(cmd, die_on_fail, die_msg)
- local rv = vim.system(cmd):wait()
- if rv.code ~= 0 then
- if die_on_fail then
- die(die_msg)
- end
- return nil
- end
- return vim.trim(rv.stdout)
- end
- -- Run a command, return nil on failure
- local function run(cmd)
- return _run(cmd, false, '')
- end
- -- Run a command, die on failure with err_msg
- local function run_die(cmd, err_msg)
- return _run(cmd, true, err_msg)
- end
- local nvim_src_dir = run({ 'git', 'rev-parse', '--show-toplevel' })
- local deps_file = nvim_src_dir .. '/' .. 'cmake.deps/deps.txt'
- --- @param repo string
- --- @param ref string
- local function get_archive_info(repo, ref)
- local temp_dir = os.getenv('TMPDIR') or os.getenv('TEMP')
- local archive_name = ref .. '.tar.gz'
- local archive_path = temp_dir .. '/' .. archive_name
- local archive_url = 'https://github.com/' .. repo .. '/archive/' .. archive_name
- run_die(
- { 'curl', '-sfL', archive_url, '-o', archive_path },
- 'Failed to download archive from GitHub'
- )
- local shacmd = (
- vim.fn.executable('sha256sum') == 1 and { 'sha256sum', archive_path }
- or { 'shasum', '-a', '256', archive_path }
- )
- local archive_sha = run(shacmd):gmatch('%w+')()
- return { url = archive_url, sha = archive_sha }
- end
- local function get_gh_commit_sha(repo, ref)
- local full_repo = string.format('https://github.com/%s.git', repo)
- local tag_exists = run_die({ 'git', 'ls-remote', full_repo, 'refs/tags/' .. ref }) ~= ''
- -- We'd rather use the git tag over commit sha if possible
- if tag_exists then
- return ref
- end
- local sha = assert(
- run_die(
- { 'gh', 'api', 'repos/' .. repo .. '/commits/' .. ref, '--jq', '.sha' },
- 'Failed to get commit hash from GitHub. Not a valid ref?'
- )
- )
- return sha
- end
- local function update_deps_file(symbol, kind, value)
- run_die({
- 'sed',
- '-i',
- '-e',
- 's/' .. symbol .. '_' .. kind .. '.*$' .. '/' .. symbol .. '_' .. kind .. ' ' .. value .. '/',
- deps_file,
- }, 'Failed to write ' .. deps_file)
- end
- local function ref(name, _ref)
- local repo = dependency_table[name]
- local symbol = string.gsub(name, 'tree%-sitter', 'treesitter'):gsub('%-', '_'):upper()
- run_die(
- { 'git', 'diff', '--quiet', 'HEAD', '--', deps_file },
- deps_file .. ' has uncommitted changes'
- )
- _ref = get_gh_commit_sha(repo, _ref)
- local archive = get_archive_info(repo, _ref)
- local comment = string.sub(_ref, 1, 9)
- local checked_out_branch = assert(run({ 'git', 'rev-parse', '--abbrev-ref', 'HEAD' }))
- if not checked_out_branch:match('^' .. required_branch_prefix) then
- print(
- "Current branch '"
- .. checked_out_branch
- .. "' doesn't seem to start with "
- .. required_branch_prefix
- )
- print('Checking out to bump-' .. name)
- run_die({ 'git', 'checkout', '-b', 'bump-' .. name }, 'git failed to create branch')
- end
- print('Updating ' .. name .. ' to ' .. archive.url .. '\n')
- update_deps_file(symbol, 'URL', archive.url:gsub('/', '\\/'))
- update_deps_file(symbol, 'SHA256', archive.sha)
- run_die({
- 'git',
- 'commit',
- deps_file,
- '-m',
- commit_prefix .. 'bump ' .. name .. ' to ' .. comment,
- }, 'git failed to commit')
- end
- local function usage()
- local this_script = tostring(vim.fs.basename(_G.arg[0]))
- local script_exe = './' .. this_script
- local help = ([=[
- Bump Nvim dependencies
- Usage: %s [options]
- Bump to HEAD, tagged version or commit:
- %s luv --head
- %s luv --ref 1.43.0-0
- %s luv --ref abc123
- Options:
- -h, --help show this message and exit.
- --list list all dependencies
- Dependency Options:
- --ref <ref> bump to a specific commit or tag.
- --head bump to a current head.
- ]=]):format(script_exe, script_exe, script_exe, script_exe)
- print(help)
- end
- local function list_deps()
- local l = 'Dependencies:\n'
- for k in vim.spairs(dependency_table) do
- l = string.format('%s\n%s%s', l, string.rep(' ', 2), k)
- end
- print(l)
- end
- do
- local args = {}
- local i = 1
- while i <= #_G.arg do
- if _G.arg[i] == '-h' or _G.arg[i] == '--help' then
- args.h = true
- elseif _G.arg[i] == '--list' then
- args.list = true
- elseif _G.arg[i] == '--ref' then
- args.ref = _G.arg[i + 1]
- i = i + 1
- elseif _G.arg[i] == '--head' then
- args.ref = 'HEAD'
- elseif vim.startswith(_G.arg[i], '--') then
- die(string.format('Invalid argument %s\n', _G.arg[i]))
- else
- args.dep = _G.arg[i]
- end
- i = i + 1
- end
- if args.h then
- usage()
- elseif args.list then
- list_deps()
- elseif args.ref then
- ref(args.dep, args.ref)
- else
- die('missing required arg\n')
- end
- end
|