Rework compress actions

This commit is contained in:
crschnick
2025-06-16 16:36:10 +00:00
parent 553e6d2aef
commit e7992907fc
11 changed files with 352 additions and 294 deletions

View File

@@ -22,6 +22,9 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
@JsonIgnore
protected BrowserFileSystemTabModel model;
@JsonIgnore
private List<BrowserEntry> entries;
@Override
protected boolean beforeExecute() throws Exception {
AppLayoutModel.get().selectBrowser();
@@ -67,7 +70,11 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
}
protected List<BrowserEntry> getEntries() {
return files.stream()
if (entries != null) {
return entries;
}
entries = files.stream()
.map(filePath -> {
var be = model.getFileList().getAll().getValue().stream()
.filter(browserEntry ->
@@ -81,6 +88,7 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
})
.filter(browserEntry -> browserEntry != null)
.toList();
return entries;
}
public abstract static class BrowserActionBuilder<C extends BrowserAction, B extends BrowserActionBuilder<C, B>>
@@ -92,6 +100,7 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
files(entries.stream()
.map(browserEntry -> browserEntry.getRawFileEntry().getPath())
.toList());
entries(entries);
}
public void initFiles(BrowserFileSystemTabModel model, List<FilePath> entries) {

View File

@@ -451,41 +451,6 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
});
}
public void runCommandAsync(CommandBuilder command, boolean refresh) {
ThreadHelper.runFailableAsync(() -> {
BooleanScope.executeExclusive(busy, () -> {
if (getCurrentDirectory() == null) {
return;
}
fileSystem
.getShell()
.orElseThrow()
.command(command)
.withWorkingDirectory(getCurrentDirectory().getPath())
.execute();
if (refresh) {
refreshSync();
}
});
});
}
public void runAsync(FailableRunnable<Exception> r, boolean refresh) {
ThreadHelper.runFailableAsync(() -> {
BooleanScope.executeExclusive(busy, () -> {
if (getCurrentDirectory() == null) {
return;
}
r.run();
if (refresh) {
refreshSync();
}
});
});
}
public boolean isClosed() {
return false;
}

View File

@@ -1,5 +1,7 @@
package io.xpipe.app.browser.menu.impl.compress;
import io.xpipe.app.action.AbstractAction;
import io.xpipe.app.browser.action.BrowserActionProvider;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
import io.xpipe.app.browser.icon.BrowserIconFileType;
@@ -38,28 +40,12 @@ public class BaseUntarMenuProvider implements BrowserApplicationPathMenuProvider
}
@Override
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
model.runAsync(
() -> {
ShellControl sc = model.getFileSystem().getShell().orElseThrow();
for (BrowserEntry entry : entries) {
var target = getTarget(entry.getRawFileEntry().getPath());
var c = CommandBuilder.of().add("tar");
if (toDirectory) {
c.add("-C").addFile(target);
}
c.add("-x").addIf(gz, "-z").add("-f");
c.addFile(entry.getRawFileEntry().getPath());
if (toDirectory) {
model.getFileSystem().mkdirs(target);
}
sc.command(c)
.withWorkingDirectory(
model.getCurrentDirectory().getPath())
.execute();
}
},
true);
public AbstractAction createAction(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var builder = UntarActionProvider.Action.builder();
builder.initEntries(model, entries);
builder.gz(gz);
builder.toDirectory(toDirectory);
return builder.build();
}
@Override

View File

@@ -1,5 +1,6 @@
package io.xpipe.app.browser.menu.impl.compress;
import io.xpipe.app.action.AbstractAction;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
import io.xpipe.app.browser.icon.BrowserIconFileType;
@@ -36,23 +37,12 @@ public abstract class BaseUnzipUnixMenuProvider implements BrowserMenuLeafProvid
return "unzip";
}
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) throws Exception {
ShellControl sc = model.getFileSystem().getShell().orElseThrow();
for (BrowserEntry entry : entries) {
var command = CommandBuilder.of()
.add("unzip", "-o")
.addFile(entry.getRawFileEntry().getPath());
if (toDirectory) {
command.add("-d").addFile(getTarget(entry.getRawFileEntry().getPath()));
}
try (var cc = sc.command(command)
.withWorkingDirectory(model.getCurrentDirectory().getPath())
.start()) {
cc.discardOrThrow();
}
}
model.refreshSync();
@Override
public AbstractAction createAction(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var builder = UnzipActionProvider.Action.builder();
builder.initEntries(model, entries);
builder.toDirectory(toDirectory);
return builder.build();
}
@Override
@@ -65,14 +55,10 @@ public abstract class BaseUnzipUnixMenuProvider implements BrowserMenuLeafProvid
var sep = model.getFileSystem().getShell().orElseThrow().getOsType().getFileSystemSeparator();
var dir = entries.size() > 1
? "[...]"
: getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
: UnzipActionProvider.getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
return toDirectory ? AppI18n.observable("unzipDirectory", dir) : AppI18n.observable("unzipHere");
}
private FilePath getTarget(FilePath name) {
return FilePath.of(name.toString().replaceAll("\\.zip$", ""));
}
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
return entries.stream()

View File

@@ -1,5 +1,6 @@
package io.xpipe.app.browser.menu.impl.compress;
import io.xpipe.app.action.AbstractAction;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
import io.xpipe.app.browser.icon.BrowserIconFileType;
@@ -8,11 +9,7 @@ import io.xpipe.app.browser.menu.BrowserMenuCategory;
import io.xpipe.app.browser.menu.BrowserMenuLeafProvider;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.FilePath;
import javafx.beans.value.ObservableValue;
@@ -31,38 +28,6 @@ public abstract class BaseUnzipWindowsActionProvider implements BrowserMenuLeafP
return new LabelGraphic.CompGraphic(BrowserIcons.createContextMenuIcon(BrowserIconFileType.byId("zip")));
}
@Override
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
model.runAsync(
() -> {
var sc = model.getFileSystem().getShell().orElseThrow();
if (ShellDialects.isPowershell(sc)) {
for (BrowserEntry entry : entries) {
runCommand(sc, model, entry);
}
} else {
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
for (BrowserEntry entry : entries) {
runCommand(sub, model, entry);
}
}
}
},
true);
}
private void runCommand(ShellControl sc, BrowserFileSystemTabModel model, BrowserEntry entry) throws Exception {
var command = CommandBuilder.of().add("Expand-Archive", "-Force");
if (toDirectory) {
var target = getTarget(entry.getRawFileEntry().getPath());
command.add("-DestinationPath").addFile(target);
}
command.add("-Path").addFile(entry.getRawFileEntry().getPath());
sc.command(command)
.withWorkingDirectory(model.getCurrentDirectory().getPath())
.execute();
}
@Override
public BrowserMenuCategory getCategory() {
return BrowserMenuCategory.CUSTOM;
@@ -73,12 +38,16 @@ public abstract class BaseUnzipWindowsActionProvider implements BrowserMenuLeafP
var sep = model.getFileSystem().getShell().orElseThrow().getOsType().getFileSystemSeparator();
var dir = entries.size() > 1
? "[...]"
: getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
: UnzipActionProvider.getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
return toDirectory ? AppI18n.observable("unzipDirectory", dir) : AppI18n.observable("unzipHere");
}
private FilePath getTarget(FilePath name) {
return FilePath.of(name.toString().replaceAll("\\.zip$", ""));
@Override
public AbstractAction createAction(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var builder = UnzipActionProvider.Action.builder();
builder.initEntries(model, entries);
builder.toDirectory(toDirectory);
return builder.build();
}
@Override

View File

@@ -10,18 +10,13 @@ import io.xpipe.app.comp.base.ModalOverlay;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.CommandSupport;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.FileKind;
import io.xpipe.core.store.FilePath;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextField;
import org.kordamp.ikonli.javafx.FontIcon;
import java.util.List;
public abstract class CompressMenuProvider implements BrowserMenuBranchProvider {
@@ -39,20 +34,7 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
var foundTar = CommandSupport.findProgram(sc, "tar");
model.getCache().getInstalledApplications().put("tar", foundTar.isPresent());
if (sc.getOsType() == OsType.WINDOWS) {
var found = CommandSupport.findProgram(sc, "7z");
if (found.isPresent()) {
model.getCache().getMultiPurposeCache().put("7zExecutable", "7z");
return;
}
var pf = sc.command(sc.getShellDialect().getPrintEnvironmentVariableCommand("ProgramFiles"))
.readStdoutOrThrow();
var loc = FilePath.of(pf).join("7-Zip", "7z.exe").toWindows();
if (model.getFileSystem().fileExists(loc)) {
model.getCache().getMultiPurposeCache().put("7zExecutable", loc);
}
} else {
if (sc.getOsType() != OsType.WINDOWS) {
var found = CommandSupport.findProgram(sc, "zip");
model.getCache().getInstalledApplications().put("zip", found.isPresent());
}
@@ -75,7 +57,7 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var ext = List.of("zip", "tar", "tar.gz", "tgz", "7z", "rar", "xar");
var ext = List.of("zip", "tar", "tar.gz", "tgz", "rar", "xar");
if (entries.stream().anyMatch(browserEntry -> ext.stream().anyMatch(s -> browserEntry
.getRawFileEntry()
.getPath()
@@ -94,9 +76,7 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
public List<BrowserMenuLeafProvider> getBranchingActions(
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
return List.of(
new Windows7ZActionProvider(),
new WindowsZipActionProvider(),
new UnixZipActionProvider(),
new ZipActionProvider(),
new TarBasedActionProvider(false) {
@Override
protected String getExtension() {
@@ -150,141 +130,21 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
protected abstract String getExtension();
}
private class WindowsZipActionProvider extends LeafProvider {
private class ZipActionProvider extends LeafProvider {
@Override
protected void create(String fileName, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var base = model.getCurrentDirectory().getPath();
var target = base.join(fileName);
var command = CommandBuilder.of()
.add("Compress-Archive", "-Force", "-DestinationPath")
.addFile(target)
.add("-Path");
for (int i = 0; i < entries.size(); i++) {
var rel = entries.get(i).getRawFileEntry().getPath().relativize(base);
if (directory) {
command.addQuoted(rel.toDirectory().toWindows() + "*");
} else {
command.addFile(rel.toWindows());
}
if (i != entries.size() - 1) {
command.add(",");
}
}
model.runAsync(
() -> {
var sc = model.getFileSystem().getShell().orElseThrow();
if (ShellDialects.isPowershell(sc)) {
sc.command(command).withWorkingDirectory(base).execute();
} else {
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
sub.command(command).withWorkingDirectory(base).execute();
}
}
},
true);
var builder = io.xpipe.app.browser.menu.impl.compress.ZipActionProvider.Action.builder();
builder.initEntries(model, entries);
builder.target(model.getCurrentDirectory().getPath().join(fileName));
builder.directoryContentOnly(directory);
builder.build().executeAsync();
}
@Override
protected String getExtension() {
return "zip";
}
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
return model.getFileSystem().getShell().orElseThrow().getOsType() == OsType.WINDOWS;
}
}
private class UnixZipActionProvider extends LeafProvider {
@Override
protected void create(String fileName, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var base = model.getCurrentDirectory().getPath();
var target = base.join(fileName);
var command = CommandBuilder.of().add("zip", "-r", "-");
for (BrowserEntry entry : entries) {
var rel = entry.getRawFileEntry().getPath().relativize(base).toUnix();
if (directory) {
command.add(".");
} else {
command.addFile(rel);
}
}
command.add(">").addFile(target);
if (directory) {
model.runAsync(
() -> {
var sc = model.getFileSystem().getShell().orElseThrow();
sc.command(command)
.withWorkingDirectory(
entries.getFirst().getRawFileEntry().getPath())
.execute();
},
true);
} else {
model.runCommandAsync(command, true);
}
}
@Override
protected String getExtension() {
return "zip";
}
@Override
public boolean isActive(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
return model.getCache().getInstalledApplications().get("zip");
}
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
return model.getFileSystem().getShell().orElseThrow().getOsType() != OsType.WINDOWS;
}
}
private class Windows7ZActionProvider extends LeafProvider {
@Override
protected void create(String fileName, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var base = model.getCurrentDirectory().getPath();
var target = base.join(fileName);
var command = CommandBuilder.of()
.addFile(model.getCache()
.getMultiPurposeCache()
.get("7zExecutable")
.toString())
.add("a")
.add("-r")
.addFile(target);
for (BrowserEntry entry : entries) {
var rel = entry.getRawFileEntry().getPath().relativize(base);
if (directory) {
command.addQuoted(".\\" + rel.toDirectory().toWindows() + "*");
} else {
command.addFile(rel.toWindows());
}
}
model.runCommandAsync(command, true);
}
@Override
protected String getExtension() {
return "7z";
}
@Override
public boolean isActive(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
return model.getCache().getMultiPurposeCache().containsKey("7zExecutable");
}
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
return model.getFileSystem().getShell().orElseThrow().getOsType() == OsType.WINDOWS;
}
}
private abstract class TarBasedActionProvider extends LeafProvider {
@@ -297,32 +157,12 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
@Override
protected void create(String fileName, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
var tar = CommandBuilder.of()
.add("tar", "-c")
.addIf(gz, "-z")
.add("-f")
.addFile(fileName);
var base = model.getCurrentDirectory().getPath();
if (directory) {
var dir = entries.getFirst().getRawFileEntry().getPath();
// Fix for bsd find, remove /
var command = CommandBuilder.of()
.add("find")
.addFile(dir.removeTrailingSlash().toUnix())
.add("|", "sed")
.addLiteral("s,^" + dir.toDirectory().toUnix() + "*,,")
.add("|");
command.add(tar).add("-C").addFile(dir.toDirectory().toUnix()).add("-T", "-");
model.runCommandAsync(command, true);
} else {
var command = CommandBuilder.of().add(tar);
for (BrowserEntry entry : entries) {
var rel = entry.getRawFileEntry().getPath().relativize(base);
command.addFile(rel);
}
model.runCommandAsync(command, true);
}
var builder = TarActionProvider.Action.builder();
builder.initEntries(model, entries);
builder.target(model.getCurrentDirectory().getPath().join(fileName));
builder.directoryContentOnly(directory);
builder.gz(gz);
builder.build().executeAsync();
}
@Override

View File

@@ -0,0 +1,67 @@
package io.xpipe.app.browser.menu.impl.compress;
import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.browser.action.BrowserActionProvider;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.store.FilePath;
import lombok.NonNull;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
public class TarActionProvider implements BrowserActionProvider {
@Jacksonized
@SuperBuilder
public static class Action extends BrowserAction {
@NonNull
private final FilePath target;
private final boolean directoryContentOnly;
private final boolean gz;
@Override
public boolean isMutation() {
return true;
}
@Override
public void executeImpl() throws Exception {
var sc = model.getFileSystem().getShell().orElseThrow();
var tar = CommandBuilder.of()
.add("tar", "-c")
.addIf(gz, "-z")
.add("-f")
.addFile(target);
var base = model.getCurrentDirectory().getPath();
if (directoryContentOnly) {
var dir = getEntries().getFirst().getRawFileEntry().getPath();
// Fix for bsd find, remove /
var command = CommandBuilder.of()
.add("find")
.addFile(dir.removeTrailingSlash().toUnix())
.add("|", "sed")
.addLiteral("s,^" + dir.toDirectory().toUnix() + "*,,")
.add("|");
command.add(tar).add("-C").addFile(dir.toDirectory().toUnix()).add("-T", "-");
sc.command(command).execute();
} else {
var command = CommandBuilder.of().add(tar);
for (BrowserEntry entry : getEntries()) {
var rel = entry.getRawFileEntry().getPath().relativize(base);
command.addFile(rel);
}
sc.command(command).execute();
}
model.refreshSync();
}
}
@Override
public String getId() {
return "tar";
}
}

View File

@@ -0,0 +1,61 @@
package io.xpipe.app.browser.menu.impl.compress;
import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.browser.action.BrowserActionProvider;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.store.FileKind;
import io.xpipe.core.store.FilePath;
import lombok.NonNull;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
public class UntarActionProvider implements BrowserActionProvider {
@Jacksonized
@SuperBuilder
public static class Action extends BrowserAction {
private final boolean gz;
private final boolean toDirectory;
@Override
public boolean isMutation() {
return true;
}
@Override
public void executeImpl() throws Exception {
ShellControl sc = model.getFileSystem().getShell().orElseThrow();
for (BrowserEntry entry : getEntries()) {
var target = getTarget(entry.getRawFileEntry().getPath());
var c = CommandBuilder.of().add("tar");
if (toDirectory) {
c.add("-C").addFile(target);
}
c.add("-x").addIf(gz, "-z").add("-f");
c.addFile(entry.getRawFileEntry().getPath());
if (toDirectory) {
model.getFileSystem().mkdirs(target);
}
sc.command(c)
.withWorkingDirectory(
model.getCurrentDirectory().getPath())
.execute();
}
}
private FilePath getTarget(FilePath name) {
return FilePath.of(name.toString()
.replaceAll("\\.tar$", "")
.replaceAll("\\.tar.gz$", "")
.replaceAll("\\.tgz$", ""));
}
}
@Override
public String getId() {
return "untar";
}
}

View File

@@ -0,0 +1,82 @@
package io.xpipe.app.browser.menu.impl.compress;
import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.browser.action.BrowserActionProvider;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.FilePath;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
public class UnzipActionProvider implements BrowserActionProvider {
public static FilePath getTarget(FilePath name) {
return FilePath.of(name.toString().replaceAll("\\.zip$", ""));
}
@Jacksonized
@SuperBuilder
public static class Action extends BrowserAction {
private final boolean toDirectory;
@Override
public boolean isMutation() {
return true;
}
@Override
public void executeImpl() throws Exception {
var sc = model.getFileSystem().getShell().orElseThrow();
if (sc.getOsType() == OsType.WINDOWS) {
if (ShellDialects.isPowershell(sc)) {
for (BrowserEntry entry : getEntries()) {
runPowershellCommand(sc, model, entry);
}
} else {
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
for (BrowserEntry entry : getEntries()) {
runPowershellCommand(sub, model, entry);
}
}
}
} else {
for (BrowserEntry entry : getEntries()) {
var command = CommandBuilder.of()
.add("unzip", "-o")
.addFile(entry.getRawFileEntry().getPath());
if (toDirectory) {
command.add("-d").addFile(getTarget(entry.getRawFileEntry().getPath()));
}
try (var cc = sc.command(command)
.withWorkingDirectory(model.getCurrentDirectory().getPath())
.start()) {
cc.discardOrThrow();
}
}
}
model.refreshSync();
}
private void runPowershellCommand(ShellControl sc, BrowserFileSystemTabModel model, BrowserEntry entry) throws Exception {
var command = CommandBuilder.of().add("Expand-Archive", "-Force");
if (toDirectory) {
var target = getTarget(entry.getRawFileEntry().getPath());
command.add("-DestinationPath").addFile(target);
}
command.add("-Path").addFile(entry.getRawFileEntry().getPath());
sc.command(command)
.withWorkingDirectory(model.getCurrentDirectory().getPath())
.execute();
}
}
@Override
public String getId() {
return "unzip";
}
}

View File

@@ -0,0 +1,89 @@
package io.xpipe.app.browser.menu.impl.compress;
import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.browser.action.BrowserActionProvider;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.FileKind;
import io.xpipe.core.store.FilePath;
import lombok.NonNull;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
public class ZipActionProvider implements BrowserActionProvider {
@Jacksonized
@SuperBuilder
public static class Action extends BrowserAction {
@NonNull
private final FilePath target;
private final boolean directoryContentOnly;
@Override
public boolean isMutation() {
return true;
}
@Override
public void executeImpl() throws Exception {
var sc = model.getFileSystem().getShell().orElseThrow();
if (sc.getOsType() == OsType.WINDOWS) {
var base = model.getCurrentDirectory().getPath();
var command = CommandBuilder.of()
.add("Compress-Archive", "-Force", "-DestinationPath")
.addFile(target)
.add("-Path");
for (int i = 0; i < getEntries().size(); i++) {
var rel = getEntries().get(i).getRawFileEntry().getPath().relativize(base);
if (getEntries().get(i).getRawFileEntry().getKind() == FileKind.DIRECTORY && directoryContentOnly) {
command.addQuoted(rel.toDirectory().toWindows() + "*");
} else {
command.addFile(rel.toWindows());
}
if (i != getEntries().size() - 1) {
command.add(",");
}
}
if (ShellDialects.isPowershell(sc)) {
sc.command(command).withWorkingDirectory(base).execute();
} else {
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
sub.command(command).withWorkingDirectory(base).execute();
}
}
} else {
var command = CommandBuilder.of().add("zip", "-r", "-");
for (BrowserEntry entry : getEntries()) {
var base = target.getParent();
var rel = entry.getRawFileEntry().getPath().relativize(base).toUnix();
if (entry.getRawFileEntry().getKind() == FileKind.DIRECTORY && directoryContentOnly) {
command.add(".");
} else {
command.addFile(rel);
}
}
command.add(">").addFile(target);
if (directoryContentOnly) {
sc.command(command)
.withWorkingDirectory(
getEntries().getFirst().getRawFileEntry().getPath())
.execute();
} else {
sc.command(command).execute();
}
}
model.refreshSync();
}
}
@Override
public String getId() {
return "zip";
}
}

View File

@@ -157,6 +157,10 @@ open module io.xpipe.app {
DeleteMenuProvider,
ChownActionProvider,
ChmodActionProvider,
TarActionProvider,
UntarActionProvider,
ZipActionProvider,
UnzipActionProvider,
UnzipHereUnixMenuProvider,
UnzipDirectoryUnixMenuProvider,
UnzipHereWindowsActionProvider,