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.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.sun.jna.Platform;
|
||||||
|
|
||||||
import net.filebot.util.FileUtilities;
|
import net.filebot.util.FileUtilities;
|
||||||
|
|
||||||
public enum StandardRenameAction implements RenameAction {
|
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 {
|
DUPLICATE {
|
||||||
|
|
||||||
@Override
|
@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 {
|
TEST {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -136,10 +147,10 @@ public enum StandardRenameAction implements RenameAction {
|
||||||
return "Symlink";
|
return "Symlink";
|
||||||
case HARDLINK:
|
case HARDLINK:
|
||||||
return "Hardlink";
|
return "Hardlink";
|
||||||
|
case CLONE:
|
||||||
|
return "Clone";
|
||||||
case DUPLICATE:
|
case DUPLICATE:
|
||||||
return "Hardlink or Copy";
|
return "Hardlink or Copy";
|
||||||
case REFLINK:
|
|
||||||
return "Lightweight Copy";
|
|
||||||
default:
|
default:
|
||||||
return "Test";
|
return "Test";
|
||||||
}
|
}
|
||||||
|
@ -157,10 +168,10 @@ public enum StandardRenameAction implements RenameAction {
|
||||||
return "Symlinking";
|
return "Symlinking";
|
||||||
case HARDLINK:
|
case HARDLINK:
|
||||||
return "Hardlinking";
|
return "Hardlinking";
|
||||||
|
case CLONE:
|
||||||
|
return "Cloning";
|
||||||
case DUPLICATE:
|
case DUPLICATE:
|
||||||
return "Duplicating";
|
return "Duplicating";
|
||||||
case REFLINK:
|
|
||||||
return "Reflinking";
|
|
||||||
default:
|
default:
|
||||||
return "Testing";
|
return "Testing";
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class ArgumentBean {
|
||||||
@Option(name = "--order", usage = "Episode order", metaVar = "[Airdate, Absolute, DVD]")
|
@Option(name = "--order", usage = "Episode order", metaVar = "[Airdate, Absolute, DVD]")
|
||||||
public String order = "Airdate";
|
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";
|
public String action = "move";
|
||||||
|
|
||||||
@Option(name = "--conflict", usage = "Conflict resolution", metaVar = "[skip, override, auto, index, fail]")
|
@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 java.util.Collections.*;
|
||||||
import static net.filebot.Logging.*;
|
import static net.filebot.Logging.*;
|
||||||
|
import static net.filebot.Settings.*;
|
||||||
import static net.filebot.WebServices.*;
|
import static net.filebot.WebServices.*;
|
||||||
import static net.filebot.util.FileUtilities.*;
|
import static net.filebot.util.FileUtilities.*;
|
||||||
|
|
||||||
|
@ -147,7 +148,14 @@ public class Preset {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StandardRenameAction[] getSupportedActions() {
|
public static StandardRenameAction[] getSupportedActions() {
|
||||||
return new StandardRenameAction[] { StandardRenameAction.MOVE, StandardRenameAction.COPY, StandardRenameAction.KEEPLINK, StandardRenameAction.SYMLINK, StandardRenameAction.HARDLINK };
|
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() {
|
public static Language[] getSupportedLanguages() {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.awt.datatransfer.Transferable;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -547,7 +546,7 @@ public class RenamePanel extends JComponent {
|
||||||
actionPopup.addSeparator();
|
actionPopup.addSeparator();
|
||||||
|
|
||||||
actionPopup.addDescription(new JLabel("Action:"));
|
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));
|
actionPopup.add(new SetRenameAction(action));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue