Skip to content

Commit b2182ee

Browse files
committed
fix: handle race conditions when removing temporary directories
1 parent 36618cd commit b2182ee

File tree

1 file changed

+10
-33
lines changed

1 file changed

+10
-33
lines changed

lua/conform/runner.lua

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -370,35 +370,6 @@ local function run_formatter(bufnr, formatter, config, ctx, input_lines, opts, c
370370

371371
if not config.stdin then
372372
log.debug("Creating temp file %s", ctx.filename)
373-
-- ctx.filename can contain directories relative to ctx.dirname
374-
-- Thus, we check which directories relative to ctx.dirname exist and remove
375-
-- the first one that does not exist.
376-
local res = vim
377-
.iter(
378-
vim.split(
379-
assert(
380-
vim.fs.relpath(ctx.dirname, ctx.filename),
381-
"filename " .. ctx.filename .. " is not a child of dirname " .. ctx.dirname
382-
),
383-
"/",
384-
{ plain = true }
385-
)
386-
)
387-
:rskip(1)
388-
:fold(
389-
{ path = ctx.dirname, found_not_exists = false },
390-
---@param path_part string
391-
function(acc, path_part)
392-
local new_path = vim.fs.joinpath(acc.path, path_part)
393-
if not acc.found_not_exists then
394-
acc.path = new_path
395-
end
396-
acc.found_not_exists = vim.fn.isdirectory(new_path) == 0
397-
return acc
398-
end
399-
)
400-
local dir_to_remove = res.path
401-
local can_remove = res.found_not_exists
402373

403374
vim.fn.mkdir(vim.fs.dirname(ctx.filename), "p")
404375
local fd = assert(uv.fs_open(ctx.filename, "w", 448)) -- 0700
@@ -407,10 +378,15 @@ local function run_formatter(bufnr, formatter, config, ctx, input_lines, opts, c
407378
callback = util.wrap_callback(callback, function()
408379
log.debug("Cleaning up temp file %s", ctx.filename)
409380
uv.fs_unlink(ctx.filename)
410-
-- If all directories relative to ctx.dirname exist, there are no directories to remove.
411-
if can_remove then
412-
log.debug("Cleaning up temp dir %s", dir_to_remove)
413-
vim.fs.rm(dir_to_remove, { recursive = true })
381+
local current = vim.fs.dirname(ctx.filename)
382+
-- Remove empty directories from filename to dirname
383+
while current and vim.startswith(current, ctx.dirname) and current ~= ctx.dirname do
384+
log.debug("Cleaning up temp dir %s", current)
385+
local success, err_name, err_msg = uv.fs_rmdir(current)
386+
if not success then
387+
log.trace("Failed to remove directory %s: %s: %s", current, err_name, err_msg)
388+
end
389+
current = vim.fs.dirname(current)
414390
end
415391
end)
416392
end
@@ -763,3 +739,4 @@ M.format_lines_sync = function(bufnr, formatters, timeout_ms, range, input_lines
763739
end
764740

765741
return M
742+

0 commit comments

Comments
 (0)