Skip to content

Commit

Permalink
fix(compiler): broken .git dir path resolution
Browse files Browse the repository at this point in the history
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 #262
  • Loading branch information
tmillr committed May 30, 2023
1 parent f09a14e commit ec07bf9
Showing 1 changed file with 64 additions and 4 deletions.
68 changes: 64 additions & 4 deletions lua/github-theme/init.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local uv = vim.loop
local config = require('github-theme.config')

local function read_file(filepath)
Expand All @@ -17,6 +18,16 @@ local function write_file(filepath, content)
end
end

local function stat_file(path)
for _ = 1, 3 do
local stat = uv.fs_stat(path)
if stat then
return stat
end
uv.sleep(1)
end
end

local M = {}

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

local git_path = util.join_paths(debug.getinfo(1).source:sub(2, -23), '.git')
local git = vim.fn.getftime(git_path)
local hash = require('github-theme.lib.hash')(opts) .. (git == -1 and git_path or git)
local git_mtime
local git_path = debug.getinfo(1).source

if (git_path or ''):find('^@.') then
git_path = git_path:sub(2) .. '/../../../.git'
local st = stat_file(git_path)

if not st then
goto skip
end

-- Handle a .git "file" (e.g. worktree or submodule)
if st.type == 'file' then
local f = io.open(git_path, 'r')

if not f then
goto skip
end

local gitdir_path = (f:read('*l') or ''):match('^gitdir: (.+)')
f:close()

if not gitdir_path then
goto skip
end

git_path = gitdir_path
st = stat_file(git_path)

if not st then
goto skip
end
end

local sec, nsec = st.mtime.sec, st.mtime.nsec or 0

if nsec == 1e9 then
sec = sec + 1
nsec = 0
end

git_mtime = ('%d.%09d'):format(sec, nsec)
end

::skip::

local hash = ('%s %s'):format(
require('github-theme.lib.hash')(opts),
git_mtime or git_path
)

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

0 comments on commit ec07bf9

Please sign in to comment.