util: Rewrite makePath (#10111)

The previous iteration, besides failing to handle leaf-only input,
was relying on splitFilePathName, which just doesn't do what's required
to incrementally build the directory tree the right way around ;).

This should more closely match mkdir -p, i.e., it will *fail* if any
part (or all of it) of the path exists but is *not* a directory.

Re #10074
This commit is contained in:
NiLuJe
2023-02-12 23:48:33 +01:00
committed by GitHub
parent dbad14e20b
commit 318a22d913

View File

@@ -763,15 +763,33 @@ end
-- @string path the directory to create
-- @treturn bool true on success; nil, err_message on error
function util.makePath(path)
path = path:gsub("/+$", "")
if util.pathExists(path) then return true end
local success, err = util.makePath((util.splitFilePathName(path)))
if not success then
return nil, err.." (creating "..path..")"
if lfs.attributes(path, "mode") == "directory" then
return true
end
return lfs.mkdir(path)
local components
if path:sub(1, 1) == "/" then
-- Leading slash, remember that it's an absolute path
components = "/"
else
-- Relative path
components = ""
end
local success, err
-- NOTE: mkdir -p handles umask shenanigans for intermediate components, we don't
for component in path:gmatch("([^/]+)") do
-- The trailing slash ensures we properly fail via mkdir if the composite path already exists as a file/link
components = components .. component .. "/"
if not util.pathExists(components) then
success, err = lfs.mkdir(components)
if not success then
return nil, err .. " (creating `" .. components .. "` for `" .. path .. "`)"
end
end
end
return success, err
end
--- As `rm`