Fixed inability to clone due to unable to copy session.lock (#2392)

* Added ability to exclude files when copying folders

* Remove wildcard imports

* Added unit testing for ignoring files as well

Co-authored-by: wben1110 (desktop) <unconfigured@null.spigotmc.org>
This commit is contained in:
benwoo1110 2020-08-27 20:47:57 +08:00 committed by GitHub
parent 05cf052204
commit e1494808f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 12 deletions

View File

@ -16,7 +16,9 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
@ -72,14 +74,27 @@ public class FileUtils {
* @param target Target-File
* @param log A logger that logs the operation
*
* @return if it had success
* @return true if it had success
*/
public static boolean copyFolder(File source, File target, Logger log) {
return copyFolder(source, target, null, log);
}
/**
* Helper method to copy the world-folder.
* @param source Source-File
* @param target Target-File
* @param excludeFiles files to ignore and not copy over to Target-File
* @param log A logger that logs the operation
*
* @return true if it had success
*/
public static boolean copyFolder(File source, File target, List<String> excludeFiles, Logger log) {
Path sourceDir = source.toPath();
Path targetDir = target.toPath();
try {
Files.walkFileTree(sourceDir, new CopyDirFileVisitor(sourceDir, targetDir));
Files.walkFileTree(sourceDir, new CopyDirFileVisitor(sourceDir, targetDir, excludeFiles));
return true;
} catch (IOException e) {
log.log(Level.WARNING, "Unable to copy directory", e);
@ -91,10 +106,12 @@ public class FileUtils {
private final Path sourceDir;
private final Path targetDir;
private final List<String> excludeFiles;
private CopyDirFileVisitor(Path sourceDir, Path targetDir) {
private CopyDirFileVisitor(Path sourceDir, Path targetDir, List<String> excludeFiles) {
this.sourceDir = sourceDir;
this.targetDir = targetDir;
this.excludeFiles = excludeFiles;
}
@Override
@ -108,9 +125,13 @@ public class FileUtils {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
// Pass files that are set to ignore
if (excludeFiles != null && excludeFiles.contains(file.getFileName().toString()))
return FileVisitResult.CONTINUE;
// Copy the files
Path targetFile = targetDir.resolve(sourceDir.relativize(file));
Files.copy(file, targetFile, COPY_ATTRIBUTES);
return FileVisitResult.CONTINUE;
}
}
}
}

View File

@ -43,6 +43,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
@ -127,6 +128,7 @@ public class WorldManager implements MVWorldManager {
final File oldWorldFile = new File(this.plugin.getServer().getWorldContainer(), oldName);
final File newWorldFile = new File(this.plugin.getServer().getWorldContainer(), newName);
final List<String> ignoreFiles = new ArrayList<>(Arrays.asList("session.lock", "uid.dat"));
// Make sure the new world doesn't exist outside of multiverse.
if (newWorldFile.exists()) {
@ -177,20 +179,14 @@ public class WorldManager implements MVWorldManager {
oldWorld.getCBWorld().save();
}
Logging.config("Copying files for world '%s'", oldName);
if (!FileUtils.copyFolder(oldWorldFile, newWorldFile, Logging.getLogger())) {
if (!FileUtils.copyFolder(oldWorldFile, newWorldFile, ignoreFiles, Logging.getLogger())) {
Logging.warning("Failed to copy files for world '%s', see the log info", newName);
return false;
}
if (oldWorld != null && wasAutoSave) {
oldWorld.getCBWorld().setAutoSave(true);
}
File uidFile = new File(newWorldFile, "uid.dat");
if (uidFile.exists() && !uidFile.delete()) {
Logging.warning("Failed to delete unique ID file for world '%s'", newName);
return false;
}
if (newWorldFile.exists()) {
Logging.fine("Succeeded at copying files");
if (this.addWorld(newName, environment, seedString, worldType, generateStructures, generator, useSpawnAdjust)) {

View File

@ -6,6 +6,9 @@ import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.dumptruckman.minecraft.util.Logging;
import org.junit.After;
@ -86,6 +89,34 @@ public class FileUtilsTest {
assertTrue(Files.isRegularFile(targetChildDirFile));
}
@Test
public void copyFolder_excludingSomeFiles() throws Exception {
Path targetDir = tempDir.resolve("target");
Path targetFile = targetDir.resolve("parentDirFile.txt");
Path targetIgnoreFile = targetDir.resolve("parentIgnoreFile.txt");
Path targetChildDir = targetDir.resolve("childDir");
Path targetChildDirFile = targetChildDir.resolve("childDirFile.txt");
Path targetChildIgnoreFile = targetChildDir.resolve("childIgnoreFile.txt");
List<String> excludeFiles = new ArrayList<>(Arrays.asList("parentIgnoreFile.txt", "childIgnoreFile.txt"));
assertFalse(Files.isDirectory(targetDir));
assertFalse(Files.isRegularFile(targetFile));
assertFalse(Files.isRegularFile(targetIgnoreFile));
assertFalse(Files.isDirectory(targetChildDir));
assertFalse(Files.isRegularFile(targetChildDirFile));
assertFalse(Files.isRegularFile(targetChildIgnoreFile));
assertTrue(FileUtils.copyFolder(parentDir.toFile(), targetDir.toFile(), excludeFiles, Logging.getLogger()));
assertTrue(Files.isDirectory(targetDir));
assertTrue(Files.isRegularFile(targetFile));
assertFalse(Files.isRegularFile(targetIgnoreFile));
assertTrue(Files.isDirectory(targetChildDir));
assertTrue(Files.exists(targetChildDirFile));
assertFalse(Files.isRegularFile(targetChildIgnoreFile));
}
@Test
public void copyFolder_intoExistingFolder() throws Exception {
Path targetDir = Files.createDirectory(tempDir.resolve("target"));