Skip to content

Commit 6de8d77

Browse files
committed
Move instead of copy during content install if possible
1 parent 2b5075f commit 6de8d77

4 files changed

Lines changed: 44 additions & 22 deletions

File tree

builtin/mainmenu/pkgmgr.lua

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -546,11 +546,10 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
546546
local from = basefolder and basefolder.path or path
547547
if targetpath then
548548
core.delete_dir(targetpath)
549-
core.create_dir(targetpath)
550549
else
551550
targetpath = core.get_texturepath() .. DIR_DELIM .. basename
552551
end
553-
if not core.copy_dir(from, targetpath) then
552+
if not core.copy_dir(from, targetpath, false) then
554553
return nil,
555554
fgettext("Failed to install $1 to $2", basename, targetpath)
556555
end
@@ -571,7 +570,6 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
571570
-- Get destination name for modpack
572571
if targetpath then
573572
core.delete_dir(targetpath)
574-
core.create_dir(targetpath)
575573
else
576574
local clean_path = nil
577575
if basename ~= nil then
@@ -595,7 +593,6 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
595593

596594
if targetpath then
597595
core.delete_dir(targetpath)
598-
core.create_dir(targetpath)
599596
else
600597
local targetfolder = basename
601598
if targetfolder == nil then
@@ -621,14 +618,13 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
621618

622619
if targetpath then
623620
core.delete_dir(targetpath)
624-
core.create_dir(targetpath)
625621
else
626622
targetpath = core.get_gamepath() .. DIR_DELIM .. basename
627623
end
628624
end
629625

630626
-- Copy it
631-
if not core.copy_dir(basefolder.path, targetpath) then
627+
if not core.copy_dir(basefolder.path, targetpath, false) then
632628
return nil,
633629
fgettext("Failed to install $1 to $2", basename, targetpath)
634630
end

src/filesys.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,30 @@ bool CopyDir(const std::string &source, const std::string &target)
558558
return false;
559559
}
560560

561+
bool MoveDir(const std::string &source, const std::string &target)
562+
{
563+
infostream << "Moving \"" << source << "\" to \"" << target << "\"" << std::endl;
564+
565+
// If target exists as empty folder delete, otherwise error
566+
if (fs::PathExists(target)) {
567+
if (rmdir(target.c_str()) != 0) {
568+
errorstream << "MoveDir: target \"" << target
569+
<< "\" exists as file or non-empty folder" << std::endl;
570+
return false;
571+
}
572+
}
573+
574+
// Try renaming first which is instant
575+
if (fs::Rename(source, target))
576+
return true;
577+
578+
infostream << "MoveDir: rename not possible, will copy instead" << std::endl;
579+
bool retval = fs::CopyDir(source, target);
580+
if (retval)
581+
retval &= fs::RecursiveDelete(source);
582+
return retval;
583+
}
584+
561585
bool PathStartsWith(const std::string &path, const std::string &prefix)
562586
{
563587
size_t pathsize = path.size();

src/filesys.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ bool CopyFileContents(const std::string &source, const std::string &target);
106106
// Omits files and subdirectories that start with a period
107107
bool CopyDir(const std::string &source, const std::string &target);
108108

109+
// Move directory and all subdirectories
110+
// Behavior with files/subdirs that start with a period is undefined
111+
bool MoveDir(const std::string &source, const std::string &target);
112+
109113
// Check if one path is prefix of another
110114
// For example, "/tmp" is a prefix of "/tmp" and "/tmp/file" but not "/tmp2"
111115
// Ignores case differences and '/' vs. '\\' on Windows

src/script/lua_api/l_mainmenu.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -606,26 +606,24 @@ int ModApiMainMenu::l_copy_dir(lua_State *L)
606606
const char *destination = luaL_checkstring(L, 2);
607607

608608
bool keep_source = true;
609+
if (!lua_isnoneornil(L, 3))
610+
keep_source = readParam<bool>(L, 3);
609611

610-
if ((!lua_isnone(L,3)) &&
611-
(!lua_isnil(L,3))) {
612-
keep_source = readParam<bool>(L,3);
613-
}
614-
615-
std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
616-
std::string absolute_source = fs::RemoveRelativePathComponents(source);
617-
618-
if ((ModApiMainMenu::mayModifyPath(absolute_destination))) {
619-
bool retval = fs::CopyDir(absolute_source,absolute_destination);
620-
621-
if (retval && (!keep_source)) {
612+
std::string abs_destination = fs::RemoveRelativePathComponents(destination);
613+
std::string abs_source = fs::RemoveRelativePathComponents(source);
622614

623-
retval &= fs::RecursiveDelete(absolute_source);
624-
}
625-
lua_pushboolean(L,retval);
615+
if (!ModApiMainMenu::mayModifyPath(abs_destination) ||
616+
(!keep_source && !ModApiMainMenu::mayModifyPath(abs_source))) {
617+
lua_pushboolean(L, false);
626618
return 1;
627619
}
628-
lua_pushboolean(L,false);
620+
621+
bool retval;
622+
if (keep_source)
623+
retval = fs::CopyDir(abs_source, abs_destination);
624+
else
625+
retval = fs::MoveDir(abs_source, abs_destination);
626+
lua_pushboolean(L, retval);
629627
return 1;
630628
}
631629

0 commit comments

Comments
 (0)