Save the lockfile through a temp file and a rename
An interrupted save could leave a truncated lock.json.
This commit is contained in:
@@ -33,15 +33,23 @@ function M:load()
|
||||
return self
|
||||
end
|
||||
|
||||
-- Write then rename, so an interrupted save cannot truncate the live lockfile.
|
||||
function M:save()
|
||||
vim.fn.mkdir(dirname(self.path), 'p')
|
||||
local payload = { version = 1, plugins = self.entries }
|
||||
local fd, err = io.open(self.path, 'w')
|
||||
local tmp = string.format('%s.%d.tmp', self.path, vim.uv and vim.uv.os_getpid() or vim.loop.os_getpid())
|
||||
local fd, err = io.open(tmp, 'w')
|
||||
if not fd then
|
||||
return false, err
|
||||
end
|
||||
fd:write(vim.json.encode(payload))
|
||||
fd:close()
|
||||
|
||||
local ok, rename_err = os.rename(tmp, self.path)
|
||||
if not ok then
|
||||
os.remove(tmp)
|
||||
return false, rename_err
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
@@ -42,6 +42,19 @@ t.describe('lock', function()
|
||||
t.eq({}, Lock.new(path):load():names())
|
||||
end)
|
||||
|
||||
t.it('leaves no temporary file beside the state file', function()
|
||||
local dir = tmpdir()
|
||||
local lock = Lock.new(dir .. '/lock.json')
|
||||
lock:set('plenary.nvim', { tag = 'v0.1.4' })
|
||||
t.truthy(lock:save())
|
||||
|
||||
local names = {}
|
||||
for _, entry in ipairs(vim.fn.readdir(dir)) do
|
||||
table.insert(names, entry)
|
||||
end
|
||||
t.eq({ 'lock.json' }, names)
|
||||
end)
|
||||
|
||||
t.it('lists names in sorted order', function()
|
||||
local lock = Lock.new(tmpdir() .. '/lock.json')
|
||||
lock:set('zebra', { tag = 'v1' })
|
||||
|
||||
Reference in New Issue
Block a user