Skip to content

Commit

Permalink
Move instead of copy during content install if possible
Browse files Browse the repository at this point in the history
  • Loading branch information
sfan5 committed Oct 6, 2021
1 parent 2b5075f commit 6de8d77
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 22 deletions.
8 changes: 2 additions & 6 deletions builtin/mainmenu/pkgmgr.lua
Expand Up @@ -546,11 +546,10 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
local from = basefolder and basefolder.path or path
if targetpath then
core.delete_dir(targetpath)
core.create_dir(targetpath)
else
targetpath = core.get_texturepath() .. DIR_DELIM .. basename
end
if not core.copy_dir(from, targetpath) then
if not core.copy_dir(from, targetpath, false) then
return nil,
fgettext("Failed to install $1 to $2", basename, targetpath)
end
Expand All @@ -571,7 +570,6 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
-- Get destination name for modpack
if targetpath then
core.delete_dir(targetpath)
core.create_dir(targetpath)
else
local clean_path = nil
if basename ~= nil then
Expand All @@ -595,7 +593,6 @@ function pkgmgr.install_dir(type, path, basename, targetpath)

if targetpath then
core.delete_dir(targetpath)
core.create_dir(targetpath)
else
local targetfolder = basename
if targetfolder == nil then
Expand All @@ -621,14 +618,13 @@ function pkgmgr.install_dir(type, path, basename, targetpath)

if targetpath then
core.delete_dir(targetpath)
core.create_dir(targetpath)
else
targetpath = core.get_gamepath() .. DIR_DELIM .. basename
end
end

-- Copy it
if not core.copy_dir(basefolder.path, targetpath) then
if not core.copy_dir(basefolder.path, targetpath, false) then
return nil,
fgettext("Failed to install $1 to $2", basename, targetpath)
end
Expand Down
24 changes: 24 additions & 0 deletions src/filesys.cpp
Expand Up @@ -558,6 +558,30 @@ bool CopyDir(const std::string &source, const std::string &target)
return false;
}

bool MoveDir(const std::string &source, const std::string &target)
{
infostream << "Moving \"" << source << "\" to \"" << target << "\"" << std::endl;

// If target exists as empty folder delete, otherwise error
if (fs::PathExists(target)) {
if (rmdir(target.c_str()) != 0) {
errorstream << "MoveDir: target \"" << target
<< "\" exists as file or non-empty folder" << std::endl;
return false;
}
}

// Try renaming first which is instant
if (fs::Rename(source, target))
return true;

infostream << "MoveDir: rename not possible, will copy instead" << std::endl;
bool retval = fs::CopyDir(source, target);
if (retval)
retval &= fs::RecursiveDelete(source);
return retval;
}

bool PathStartsWith(const std::string &path, const std::string &prefix)
{
size_t pathsize = path.size();
Expand Down
4 changes: 4 additions & 0 deletions src/filesys.h
Expand Up @@ -106,6 +106,10 @@ bool CopyFileContents(const std::string &source, const std::string &target);
// Omits files and subdirectories that start with a period
bool CopyDir(const std::string &source, const std::string &target);

// Move directory and all subdirectories
// Behavior with files/subdirs that start with a period is undefined
bool MoveDir(const std::string &source, const std::string &target);

// Check if one path is prefix of another
// For example, "/tmp" is a prefix of "/tmp" and "/tmp/file" but not "/tmp2"
// Ignores case differences and '/' vs. '\\' on Windows
Expand Down
30 changes: 14 additions & 16 deletions src/script/lua_api/l_mainmenu.cpp
Expand Up @@ -606,26 +606,24 @@ int ModApiMainMenu::l_copy_dir(lua_State *L)
const char *destination = luaL_checkstring(L, 2);

bool keep_source = true;
if (!lua_isnoneornil(L, 3))
keep_source = readParam<bool>(L, 3);

if ((!lua_isnone(L,3)) &&
(!lua_isnil(L,3))) {
keep_source = readParam<bool>(L,3);
}

std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
std::string absolute_source = fs::RemoveRelativePathComponents(source);

if ((ModApiMainMenu::mayModifyPath(absolute_destination))) {
bool retval = fs::CopyDir(absolute_source,absolute_destination);

if (retval && (!keep_source)) {
std::string abs_destination = fs::RemoveRelativePathComponents(destination);
std::string abs_source = fs::RemoveRelativePathComponents(source);

retval &= fs::RecursiveDelete(absolute_source);
}
lua_pushboolean(L,retval);
if (!ModApiMainMenu::mayModifyPath(abs_destination) ||
(!keep_source && !ModApiMainMenu::mayModifyPath(abs_source))) {
lua_pushboolean(L, false);
return 1;
}
lua_pushboolean(L,false);

bool retval;
if (keep_source)
retval = fs::CopyDir(abs_source, abs_destination);
else
retval = fs::MoveDir(abs_source, abs_destination);
lua_pushboolean(L, retval);
return 1;
}

Expand Down

0 comments on commit 6de8d77

Please sign in to comment.