Support CoW clones on both macOS (with APFS) and Linux (with BTRFS) and enable those actions in the GUI
This commit is contained in:
parent
8ac28f25e4
commit
d3c7028710
|
@ -11,6 +11,8 @@ import java.nio.file.LinkOption;
|
|||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Platform;
|
||||
|
||||
import net.filebot.util.FileUtilities;
|
||||
|
||||
public enum StandardRenameAction implements RenameAction {
|
||||
|
@ -79,6 +81,35 @@ public enum StandardRenameAction implements RenameAction {
|
|||
}
|
||||
},
|
||||
|
||||
CLONE {
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws Exception {
|
||||
File dest = FileUtilities.resolveDestination(from, to);
|
||||
|
||||
// clonefile or reflink requires filesystem that supports copy-on-write (e.g. apfs or btrfs)
|
||||
ProcessBuilder process = new ProcessBuilder();
|
||||
|
||||
if (Platform.isMac()) {
|
||||
// -c copy files using clonefile
|
||||
process.command("cp", "-c", "-f", from.getPath(), dest.getPath());
|
||||
} else {
|
||||
// --reflink copy files using reflink
|
||||
process.command("cp", "--reflink", "--force", from.isDirectory() ? "--recursive" : "--no-target-directory", from.getPath(), dest.getPath());
|
||||
}
|
||||
|
||||
process.directory(from.getParentFile());
|
||||
process.inheritIO();
|
||||
|
||||
int exitCode = process.start().waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IOException(String.format("%s failed with exit code %d", process.command(), exitCode));
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
},
|
||||
|
||||
DUPLICATE {
|
||||
|
||||
@Override
|
||||
|
@ -91,26 +122,6 @@ public enum StandardRenameAction implements RenameAction {
|
|||
}
|
||||
},
|
||||
|
||||
REFLINK {
|
||||
|
||||
@Override
|
||||
public File rename(File from, File to) throws Exception {
|
||||
File dest = FileUtilities.resolveDestination(from, to);
|
||||
|
||||
// reflink requires Linux and a filesystem that supports copy-on-write (e.g. btrfs)
|
||||
ProcessBuilder process = new ProcessBuilder("cp", "--reflink", "--force", from.isDirectory() ? "--recursive" : "--no-target-directory", from.getPath(), dest.getPath());
|
||||
process.directory(from.getParentFile());
|
||||
process.inheritIO();
|
||||
|
||||
int exitCode = process.start().waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IOException(String.format("reflink: %s failed with exit code %d", process.command(), exitCode));
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
},
|
||||
|
||||
TEST {
|
||||
|
||||
@Override
|
||||
|
@ -136,10 +147,10 @@ public enum StandardRenameAction implements RenameAction {
|
|||
return "Symlink";
|
||||
case HARDLINK:
|
||||
return "Hardlink";
|
||||
case CLONE:
|
||||
return "Clone";
|
||||
case DUPLICATE:
|
||||
return "Hardlink or Copy";
|
||||
case REFLINK:
|
||||
return "Lightweight Copy";
|
||||
default:
|
||||
return "Test";
|
||||
}
|
||||
|
@ -157,10 +168,10 @@ public enum StandardRenameAction implements RenameAction {
|
|||
return "Symlinking";
|
||||
case HARDLINK:
|
||||
return "Hardlinking";
|
||||
case CLONE:
|
||||
return "Cloning";
|
||||
case DUPLICATE:
|
||||
return "Duplicating";
|
||||
case REFLINK:
|
||||
return "Reflinking";
|
||||
default:
|
||||
return "Testing";
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public class ArgumentBean {
|
|||
@Option(name = "--order", usage = "Episode order", metaVar = "[Airdate, Absolute, DVD]")
|
||||
public String order = "Airdate";
|
||||
|
||||
@Option(name = "--action", usage = "Rename action", metaVar = "[move, copy, keeplink, symlink, hardlink, reflink, test]")
|
||||
@Option(name = "--action", usage = "Rename action", metaVar = "[move, copy, keeplink, symlink, hardlink, clone, test]")
|
||||
public String action = "move";
|
||||
|
||||
@Option(name = "--conflict", usage = "Conflict resolution", metaVar = "[skip, override, auto, index, fail]")
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
|
@ -2,6 +2,7 @@ package net.filebot.ui.rename;
|
|||
|
||||
import static java.util.Collections.*;
|
||||
import static net.filebot.Logging.*;
|
||||
import static net.filebot.Settings.*;
|
||||
import static net.filebot.WebServices.*;
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
|
||||
|
@ -147,7 +148,14 @@ public class Preset {
|
|||
}
|
||||
|
||||
public static StandardRenameAction[] getSupportedActions() {
|
||||
if (isWindowsApp()) {
|
||||
// CoW clones not supported on Windows
|
||||
return new StandardRenameAction[] { StandardRenameAction.MOVE, StandardRenameAction.COPY, StandardRenameAction.KEEPLINK, StandardRenameAction.SYMLINK, StandardRenameAction.HARDLINK };
|
||||
} else {
|
||||
// CoW clones / reflinks supported on macOS and Linux
|
||||
return new StandardRenameAction[] { StandardRenameAction.MOVE, StandardRenameAction.COPY, StandardRenameAction.KEEPLINK, StandardRenameAction.SYMLINK, StandardRenameAction.HARDLINK, StandardRenameAction.CLONE };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Language[] getSupportedLanguages() {
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.awt.datatransfer.Transferable;
|
|||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -547,7 +546,7 @@ public class RenamePanel extends JComponent {
|
|||
actionPopup.addSeparator();
|
||||
|
||||
actionPopup.addDescription(new JLabel("Action:"));
|
||||
for (StandardRenameAction action : EnumSet.of(StandardRenameAction.MOVE, StandardRenameAction.COPY, StandardRenameAction.KEEPLINK, StandardRenameAction.SYMLINK, StandardRenameAction.HARDLINK)) {
|
||||
for (StandardRenameAction action : Preset.getSupportedActions()) {
|
||||
actionPopup.add(new SetRenameAction(action));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue