summaryrefslogtreecommitdiff
path: root/utils/ci/generate_new_lockfile.lua
blob: 2677b20201b2c7c5ddfef1bad39390f92f1c47dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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"