Skip to content

Commit ec07bf9

Browse files
committed
fix(compiler): broken .git dir path resolution
Currently, in the file `lua/github-theme/init.lua`, the code `util.join_paths(debug.getinfo(1).source:sub(2, -23), '.git')` returns an absolute path ending in `**/lua/.git` which is not, and will never be, a valid path to the `.git` directory. This means that recompilation does not currently occur when the plugin updates or changes (unless user config changes too) and that users may miss crucial updates (e.g. bug fixes). 1. Fix bug by changing `util.join_paths(debug.getinfo(1).source:sub(2, -23), '.git')` to `debug.getinfo(1).source .. '/../../../.git'`, and then use luv's/libuv's `fs_stat()` to get the last modified time of this path. This change does not rely on any particular filenames existing in the path, but it still relies on a hard-coded depth. If the path does not exist or the stat is unsuccessful, force recompilation (as otherwise plugin updates could be missed by many users). 2. Use libuv/luv `fs_stat()` to get `.git` dir's mtime with nanosecond precision (NOTE: this function is only available by default in Neovim, not Vim, however, it appears that this plugin isn't compatible with Vim currently anyway, so this shouldn't be an issue). 3. Correctly handle `.git` files, as `.git` is not always a directory. See projekt0n#262
1 parent f09a14e commit ec07bf9

File tree

1 file changed

+64
-4
lines changed

1 file changed

+64
-4
lines changed

lua/github-theme/init.lua

+64-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
local uv = vim.loop
12
local config = require('github-theme.config')
23

34
local function read_file(filepath)
@@ -17,6 +18,16 @@ local function write_file(filepath, content)
1718
end
1819
end
1920

21+
local function stat_file(path)
22+
for _ = 1, 3 do
23+
local stat = uv.fs_stat(path)
24+
if stat then
25+
return stat
26+
end
27+
uv.sleep(1)
28+
end
29+
end
30+
2031
local M = {}
2132

2233
function M.reset()
@@ -94,11 +105,60 @@ M.setup = function(opts)
94105
local cached_path = util.join_paths(config.options.compile_path, 'cache')
95106
local cached = read_file(cached_path)
96107

97-
local git_path = util.join_paths(debug.getinfo(1).source:sub(2, -23), '.git')
98-
local git = vim.fn.getftime(git_path)
99-
local hash = require('github-theme.lib.hash')(opts) .. (git == -1 and git_path or git)
108+
local git_mtime
109+
local git_path = debug.getinfo(1).source
110+
111+
if (git_path or ''):find('^@.') then
112+
git_path = git_path:sub(2) .. '/../../../.git'
113+
local st = stat_file(git_path)
114+
115+
if not st then
116+
goto skip
117+
end
118+
119+
-- Handle a .git "file" (e.g. worktree or submodule)
120+
if st.type == 'file' then
121+
local f = io.open(git_path, 'r')
122+
123+
if not f then
124+
goto skip
125+
end
126+
127+
local gitdir_path = (f:read('*l') or ''):match('^gitdir: (.+)')
128+
f:close()
129+
130+
if not gitdir_path then
131+
goto skip
132+
end
133+
134+
git_path = gitdir_path
135+
st = stat_file(git_path)
136+
137+
if not st then
138+
goto skip
139+
end
140+
end
141+
142+
local sec, nsec = st.mtime.sec, st.mtime.nsec or 0
143+
144+
if nsec == 1e9 then
145+
sec = sec + 1
146+
nsec = 0
147+
end
148+
149+
git_mtime = ('%d.%09d'):format(sec, nsec)
150+
end
151+
152+
::skip::
153+
154+
local hash = ('%s %s'):format(
155+
require('github-theme.lib.hash')(opts),
156+
git_mtime or git_path
157+
)
100158

101-
if cached ~= hash then
159+
-- Force re-compile if .git dir could not be detected (plugin may have been
160+
-- updated and we don't want to use a stale cache).
161+
if cached ~= hash or not git_mtime then
102162
M.compile()
103163
write_file(cached_path, hash)
104164
end

0 commit comments

Comments
 (0)