]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Move instead of copy during content install if possible
authorsfan5 <sfan5@live.de>
Sun, 19 Sep 2021 16:16:53 +0000 (18:16 +0200)
committersfan5 <sfan5@live.de>
Wed, 6 Oct 2021 22:20:01 +0000 (00:20 +0200)
builtin/mainmenu/pkgmgr.lua
src/filesys.cpp
src/filesys.h
src/script/lua_api/l_mainmenu.cpp

index d07dc019c8377ba8572ec7c10b8abd8c7155068f..e83a93c91ca72bf53b33670ac21d8a4c7a19d3d1 100644 (file)
@@ -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
@@ -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
@@ -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
@@ -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
index 0972acbf95eded92c8c693ae4b0062e1976511b9..44f1c88b34fd05b933f01073f0d1ee365e2c35ce 100644 (file)
@@ -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();
index 233e56bba4cb2823f63bcc11d829652ec3197ee9..3fa2524c36a9d4850fd718631be0f444596633cf 100644 (file)
@@ -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
index 2a6a9c32d7f5ce15e9f66e46ad10266ae509f405..3d80bdafa17c7e86e10a1b83534af7b29ff4af38 100644 (file)
@@ -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;
 }