From 4b3ee931cd8ecc5937811cd8e9316d79c0c9c00e Mon Sep 17 00:00:00 2001 From: George Roman Date: Sat, 7 Jul 2018 18:49:41 +0300 Subject: Add general improvements to the fs module --- src/luarocks/fs/lua.lua | 17 +++++++++++------ src/luarocks/fs/tools.lua | 7 ++++++- src/luarocks/fs/win32/tools.lua | 11 ++++++++--- 3 files changed, 25 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index 373dcbdd..9da3875b 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua @@ -464,9 +464,13 @@ end --- Internal implementation function for fs.dir. -- Yields a filename on each iteration. -- @param at string: directory to list --- @return nil +-- @return nil or (nil and string): an error message on failure function fs_lua.dir_iterator(at) - for file in lfs.dir(at) do + local pok, iter, arg = pcall(lfs.dir, at) + if not pok then + return nil, iter + end + for file in iter, arg do if file ~= "." and file ~= ".." then coroutine.yield(file) end @@ -479,7 +483,11 @@ end -- @param prefix string: Auxiliary prefix string to form pathname. -- @param result table: Array of strings where results are collected. local function recursive_find(cwd, prefix, result) - for file in lfs.dir(cwd) do + local pok, iter, arg = pcall(lfs.dir, cwd) + if not pok then + return nil + end + for file in iter, arg do if file ~= "." and file ~= ".." then local item = prefix .. file table.insert(result, item) @@ -502,9 +510,6 @@ function fs_lua.find(at) at = fs.current_dir() end at = dir.normalize(at) - if not fs.is_dir(at) then - return {} - end local result = {} recursive_find(at, "", result) return result diff --git a/src/luarocks/fs/tools.lua b/src/luarocks/fs/tools.lua index 0cfdc9f7..d2dc08ae 100644 --- a/src/luarocks/fs/tools.lua +++ b/src/luarocks/fs/tools.lua @@ -82,7 +82,12 @@ end -- Allows leaving a directory (e.g. for deleting it) in -- a crossplatform way. function tools.change_dir_to_root() + local curr_dir = fs.current_dir() + if not curr_dir or not fs.is_dir(curr_dir) then + return false + end table.insert(dir_stack, "/") + return true end --- Change working directory to the previous in the directory stack. @@ -113,7 +118,7 @@ end -- @param at string: directory to list -- @return nil function tools.dir_iterator(at) - local pipe = io.popen(fs.command_at(at, fs.Q(vars.LS))) + local pipe = io.popen(fs.command_at(at, fs.Q(vars.LS), true)) for file in pipe:lines() do if file ~= "." and file ~= ".." then coroutine.yield(file) diff --git a/src/luarocks/fs/win32/tools.lua b/src/luarocks/fs/win32/tools.lua index c267b316..de3d9031 100644 --- a/src/luarocks/fs/win32/tools.lua +++ b/src/luarocks/fs/win32/tools.lua @@ -13,10 +13,15 @@ local vars = setmetatable({}, { __index = function(_,k) return cfg.variables[k] --- Adds prefix to command to make it run from a directory. -- @param directory string: Path to a directory. -- @param cmd string: A command-line string. +-- @param exit_on_error bool: Exits immediately if entering the directory failed. -- @return string: The command-line with prefix. -function tools.command_at(directory, cmd) +function tools.command_at(directory, cmd, exit_on_error) local drive = directory:match("^([A-Za-z]:)") - cmd = "cd " .. fs.Q(directory) .. " & " .. cmd + local op = " & " + if exit_on_error then + op = " && " + end + local cmd = "cd " .. fs.Q(directory) .. op .. cmd if drive then cmd = drive .. " & " .. cmd end @@ -113,7 +118,7 @@ function tools.find(at) return {} end local result = {} - local pipe = io.popen(fs.command_at(at, fs.quiet_stderr(fs.Q(vars.FIND)))) + local pipe = io.popen(fs.command_at(at, fs.quiet_stderr(fs.Q(vars.FIND)), true)) for file in pipe:lines() do -- Windows find is a bit different local first_two = file:sub(1,2) -- cgit v1.2.3-55-g6feb