From 318a22d91368b98028fda3442ee5705d17178a2a Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Sun, 12 Feb 2023 23:48:33 +0100 Subject: [PATCH] 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 --- frontend/util.lua | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/frontend/util.lua b/frontend/util.lua index ffaad46a8..ff39c9f27 100644 --- a/frontend/util.lua +++ b/frontend/util.lua @@ -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 + if lfs.attributes(path, "mode") == "directory" then + return true + end + + 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 = util.makePath((util.splitFilePathName(path))) - if not success then - return nil, err.." (creating "..path..")" + 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 lfs.mkdir(path) + return success, err end --- As `rm`