forked from erf/vis-outdated
-
Notifications
You must be signed in to change notification settings - Fork 0
/
init.lua
135 lines (120 loc) · 3.09 KB
/
init.lua
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
126
127
128
129
130
131
132
133
134
135
local M = {}
local get_default_cache_path = function()
local HOME = os.getenv('HOME')
local XDG_CACHE_HOME = os.getenv('XDG_CACHE_HOME')
local BASE = XDG_CACHE_HOME or HOME
return BASE .. '/.vis-outdated.csv'
end
M.path = get_default_cache_path()
-- configure in visrc
M.repos = {}
local concat = function(iterable, func)
local arr = {}
for key, val in pairs(iterable) do
table.insert(arr, func(key, val))
end
return table.concat(arr, '\n')
end
local read_hashes = function()
local f = io.open(M.path)
if f == nil then
return nil
end
local result= {}
for line in f:lines() do
for k, v in string.gmatch(line, '(.+)[,%s](%w+)') do
result[k] = v
end
end
f:close()
return result
end
local write_hashes = function(hashes)
local f = io.open(M.path, 'w+')
if f == nil then
return
end
local str = concat(hashes, function(url, hash)
return url .. ',' .. hash
end)
f:write(str)
f:close()
end
local execute = function(command)
local handle = io.popen(command)
local result = handle:read("*a")
handle:close()
return result
end
local fetch_hash = function(repo)
local command = 'git ls-remote ' .. repo .. ' HEAD | cut -c1-7'
local result = execute(command)
return string.gsub(result, '[%s\n\r]', '')
end
local fetch_hashes = function(repos)
local latest = {}
for i, repo in ipairs(repos) do
latest[repo] = fetch_hash(repo)
end
return latest
end
local per_repo_outdated = function()
local local_hashes = read_hashes()
local write_to_file = local_hashes == nil
local latest_hashes = {}
for i, repo in pairs(M.repos) do
local latest_hash = fetch_hash(repo)
local local_hash = local_hashes and local_hashes[repo]
if local_hash == nil then
write_to_file = true
local_hash = latest_hash
end
local short_repo = repo:match('^.*//(.*)')
local str = '' .. short_repo .. ' ' .. local_hash .. ' -> ' .. latest_hash
if local_hash == latest_hash then
str = str .. ' LATEST'
else
str = str .. ' OUT-OF-DATE'
end
vis:message(str)
vis:redraw()
latest_hashes[repo] = latest_hash
end
-- write local hashes to file if not in sync with latest
if write_to_file then
write_hashes(latest_hashes)
end
end
local getFileName = function(url)
return url:match("^.+/(.+)$")
end
vis:command_register('outdated', function()
vis:message('fetching latest..')
vis:redraw()
per_repo_outdated()
return true
end)
vis:command_register('outdated-up', function()
vis:message('updating..')
vis:redraw()
write_hashes(fetch_hashes(M.repos))
vis:message('UP-TO-DATE')
return true
end)
-- TODO move to vis-fetch?
-- git clone (shallow) repos to the vis-plugins folder
vis:command_register('outdated-install', function()
local visrc, err = package.searchpath('visrc', package.path)
assert(not err)
local vis_path = visrc:match('(.*/)')
assert(vis_path)
local path = vis_path ..'plugins'
vis:message('installing to ' .. path)
for i, url in ipairs(M.repos) do
local name = getFileName(url)
execute('git -C ' .. path .. ' clone --depth 1 --branch=master ' .. url .. ' --quiet 2> /dev/null')
vis:message('git cloned (shallow) ' .. url .. ' to ' .. name)
end
return true
end)
return M