From 5e5f9f2af951bce7032c06d5bdc583ca107b6e3c Mon Sep 17 00:00:00 2001 From: majeste Silatsa Date: Fri, 14 Aug 2026 14:33:39 +0200 Subject: [PATCH 01/10] feat-2219: Add UnpackCommandlet for extracting already supported archive formats --- .../ide/commandlet/CommandletManagerImpl.java | 1 + .../ide/commandlet/UnpackCommandlet.java | 94 +++++++++++++ .../ide/commandlet/UnpackCommandletTest.java | 129 ++++++++++++++++++ 3 files changed, 224 insertions(+) create mode 100644 cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java create mode 100644 cli/src/test/java/com/devonfw/tools/ide/commandlet/UnpackCommandletTest.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java index 0f3aa2b6ab..9678b8447a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java @@ -130,6 +130,7 @@ public CommandletManagerImpl(IdeContext context) { add(new UninstallPluginCommandlet(context)); add(new UpgradeCommandlet(context)); add(new TruststoreCommandlet(context)); + add(new UnpackCommandlet(context)); add(new Gh(context)); add(new Helm(context)); add(new Java(context)); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java new file mode 100644 index 0000000000..5acbe6b695 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java @@ -0,0 +1,94 @@ +package com.devonfw.tools.ide.commandlet; + +import java.nio.file.Path; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.devonfw.tools.ide.cli.CliException; +import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.property.PathProperty; +import com.devonfw.tools.ide.util.FilenameUtil; + +/** + * {@link Commandlet} to extract an archive file to a target directory. + *

+ * Supports ZIP, TAR, TAR.GZ, TAR.BZ2, 7Z, JAR archives (cross-platform), as well as MSI (Windows) and DMG/PKG (Mac). + *

+ */ +public final class UnpackCommandlet extends Commandlet { + + private static final Logger LOG = LoggerFactory.getLogger(UnpackCommandlet.class); + + /** The archive file to extract. */ + public final PathProperty archive; + + /** The target directory to extract into. If not specified, defaults to {@code /}. */ + public final PathProperty target; + + /** + * The constructor. + * + * @param context the {@link IdeContext}. + */ + public UnpackCommandlet(IdeContext context) { + + super(context); + addKeyword(getName()); + + this.archive = add(new PathProperty("", true, "archive", true)); + this.target = add(new PathProperty("target", false, "target", false)); + } + + @Override + public String getName() { + + return "unpack"; + } + + @Override + public boolean isIdeRootRequired() { + + return false; + } + + @Override + public boolean isIdeHomeRequired() { + + return false; + } + + @Override + public boolean isWriteLogFile() { + + return false; + } + + @Override + protected void doRun() { + + Path cwd = this.context.getCwd(); + if (cwd == null) { + throw new CliException("Missing current working directory!"); + } + + Path archivePath = this.archive.getValue(); + if (!archivePath.isAbsolute()) { + archivePath = cwd.resolve(archivePath).normalize(); + } + + Path targetDir = this.target.getValue(); + if (targetDir == null) { + // Derive default target from archive filename without extension + String targetName = FilenameUtil.getFilenameWithoutExtension(archivePath); + targetDir = cwd.resolve(targetName); + } + if (!targetDir.isAbsolute()) { + targetDir = cwd.resolve(targetDir).normalize(); + } + + LOG.info("Extracting {} to {}", archivePath, targetDir); + this.context.getFileAccess().extract(archivePath, targetDir); + LOG.info("Extraction completed successfully."); + } +} diff --git a/cli/src/test/java/com/devonfw/tools/ide/commandlet/UnpackCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UnpackCommandletTest.java new file mode 100644 index 0000000000..3a17e3e35f --- /dev/null +++ b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UnpackCommandletTest.java @@ -0,0 +1,129 @@ +package com.devonfw.tools.ide.commandlet; + +import java.io.IOException; +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; + +import com.devonfw.tools.ide.context.AbstractIdeContextTest; +import com.devonfw.tools.ide.context.IdeTestContext; + +/** + * Test of {@link UnpackCommandlet}. + */ +class UnpackCommandletTest extends AbstractIdeContextTest { + + /** Base filename of the test archive without extension. */ + private static final String TEST_ARCHIVE_BASENAME = "executable_and_non_executable"; + + /** Path to the test archive directory. */ + private static final Path TEST_ARCHIVE_DIR = Path.of("src/test/resources/com/devonfw/tools/ide/io"); + + /** Test ZIP archive. */ + private static final Path TEST_ARCHIVE_ZIP = TEST_ARCHIVE_DIR.resolve(TEST_ARCHIVE_BASENAME + ".zip"); + + /** Test TAR.GZ archive. */ + private static final Path TEST_ARCHIVE_TAR_GZ = TEST_ARCHIVE_DIR.resolve(TEST_ARCHIVE_BASENAME + ".tar.gz"); + + /** Test 7Z archive. */ + private static final Path TEST_ARCHIVE_7Z = TEST_ARCHIVE_DIR.resolve(TEST_ARCHIVE_BASENAME + ".7z"); + + /** + * Tests extraction of a ZIP archive to the default target directory derived from the archive filename. + */ + @Test + void testUnpackZipWithDefaultTarget() throws IOException { + + IdeTestContext context = newContext(PROJECT_BASIC); + + Path archive = TEST_ARCHIVE_ZIP.toAbsolutePath(); + UnpackCommandlet cmd = new UnpackCommandlet(context); + cmd.archive.setValue(archive); + + cmd.run(); + + Path expectedTarget = context.getCwd().resolve(TEST_ARCHIVE_BASENAME); + assertThat(expectedTarget).isDirectory(); + assertThat(expectedTarget.resolve("executableFile.txt")).isRegularFile(); + assertThat(expectedTarget.resolve("nonExecutableFile.txt")).isRegularFile(); + } + + /** + * Tests extraction of a ZIP archive to an explicit target directory via --target. + */ + @Test + void testUnpackZipWithExplicitTarget() throws IOException { + + IdeTestContext context = newContext(PROJECT_BASIC); + + Path testDir = context.getWorkspacePath().resolve("unpack-test"); + context.getFileAccess().mkdirs(testDir); + context.setCwd(testDir, context.getWorkspaceName(), context.getIdeHome()); + + Path archive = TEST_ARCHIVE_ZIP.toAbsolutePath(); + Path target = testDir.resolve("my-extraction"); + + UnpackCommandlet cmd = new UnpackCommandlet(context); + cmd.archive.setValue(archive); + cmd.target.setValue(target); + + cmd.run(); + + assertThat(target).isDirectory(); + assertThat(target.resolve("executableFile.txt")).isRegularFile(); + assertThat(target.resolve("nonExecutableFile.txt")).isRegularFile(); + } + + /** + * Tests that extracting a non-existing archive fails with an appropriate error. + */ + @Test + void testUnpackNonExistingArchiveFails() { + + IdeTestContext context = newContext(PROJECT_BASIC); + + UnpackCommandlet cmd = new UnpackCommandlet(context); + cmd.archive.setValue(Path.of("does_not_exist.zip")); + + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(cmd::run) + .withMessageContaining("does_not_exist.zip") + .withMessageContaining("Failed to extract"); + } + + /** + * Tests extraction of a tar.gz archive with default target directory. + */ + @Test + void testUnpackTarGzWithDefaultTarget() throws IOException { + + IdeTestContext context = newContext(PROJECT_BASIC); + + Path archive = TEST_ARCHIVE_TAR_GZ.toAbsolutePath(); + UnpackCommandlet cmd = new UnpackCommandlet(context); + cmd.archive.setValue(archive); + + cmd.run(); + + Path expectedTarget = context.getCwd().resolve(TEST_ARCHIVE_BASENAME); + assertThat(expectedTarget).isDirectory(); + } + + /** + * Tests extraction of a 7z archive with default target directory. + */ + @Test + void testUnpack7zWithDefaultTarget() throws IOException { + + IdeTestContext context = newContext(PROJECT_BASIC); + + Path archive = TEST_ARCHIVE_7Z.toAbsolutePath(); + UnpackCommandlet cmd = new UnpackCommandlet(context); + cmd.archive.setValue(archive); + + cmd.run(); + + Path expectedTarget = context.getCwd().resolve(TEST_ARCHIVE_BASENAME); + assertThat(expectedTarget).isDirectory(); + } +} From e0c74646911808f9f30e3e4596252c8561ee0f5c Mon Sep 17 00:00:00 2001 From: majeste Silatsa Date: Fri, 14 Aug 2026 16:11:36 +0200 Subject: [PATCH 02/10] feat-2298: Update CHANGELOG and Help files for UnpackCommandlet --- CHANGELOG.adoc | 3 ++- cli/src/main/resources/nls/Help.properties | 1 + cli/src/main/resources/nls/Help_de.properties | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 8866a010de..6a6c474473 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -6,9 +6,10 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE Release with new features and bugfixes: - The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/49?closed=1[milestone 2026.08.002]. +* https://github.com/devonfw/IDEasy/issues/2298[#2298]: Add unpack commandlet + == 2026.08.001 Release with new features and bugfixes: diff --git a/cli/src/main/resources/nls/Help.properties b/cli/src/main/resources/nls/Help.properties index 6b1395ea84..f1a6b16ea6 100644 --- a/cli/src/main/resources/nls/Help.properties +++ b/cli/src/main/resources/nls/Help.properties @@ -162,6 +162,7 @@ cmd.uninstall=Uninstall selected tool(s). cmd.uninstall-plugin=Uninstall the selected plugin for the selected tool. cmd.uninstall-plugin.detail=Plugins can be only installed or uninstalled for tools that support such. Using the command "ide install-plugin", an uninstalled plugin can be restored. cmd.uninstall.detail=Can be used to uninstall selected tool(s). E.g. to uninstall java simply call 'ide uninstall java'. To uninstall IDEasy itself, run 'ide uninstall' without further arguments. To fully delete the selected tool from your machine, use force mode. E.g. 'ide --force uninstall java'. +cmd.unpack=Unpack the selected tool. cmd.update=Pull your settings and apply updates (software, configuration and repositories). cmd.update.detail=To update your IDE (if instructed by your ide-admin), you only need to run the following command: 'ide update'. cmd.upgrade=Upgrade the version of IDEasy to the latest version available. diff --git a/cli/src/main/resources/nls/Help_de.properties b/cli/src/main/resources/nls/Help_de.properties index 2c1fb07b21..5a50de783c 100644 --- a/cli/src/main/resources/nls/Help_de.properties +++ b/cli/src/main/resources/nls/Help_de.properties @@ -162,6 +162,7 @@ cmd.uninstall=Deinstalliert ausgewählte Werkzeug(e). cmd.uninstall-plugin=Deinstalliert die selektierte Erweiterung für das selektierte Werkzeug. cmd.uninstall-plugin.detail=Erweiterung können nur für Werkzeuge installiert und deinstalliert werden die diese unterstützen. Mit dem Befehl "ide install-plugin" kann die Erweiterung wieder hergestellt werden. cmd.uninstall.detail=Wird dazu verwendet um ausgewählte Werkzeuge zu deinstallieren. Um z.B. Java zu deinstallieren, dient der Befehl 'ide uninstall java'. Um IDEasy selbst zu installieren, dient der Befehl 'ide uninstall' ohne weitere Parameter. Um ein aktuelles Werzeug vollständig von der Maschine zu löschen, wird der Force-Modus verwendet. Z.B. 'ide --force uninstall java'. +cmd.unpack=Entpackt das ausgewählte Werkzeug. cmd.update=Updatet die Settings, Software und Repositories. cmd.update.detail=Um die IDE auf den neuesten Stand zu bringen (falls von Ihrem Admin angewiesen) geben Sie einfach 'ide update' in die Konsole ein. cmd.upgrade=Aktualisiere IDEasy auf die neueste Version. From 417b2cb9850f725502d97cc43da15fac3a00222b Mon Sep 17 00:00:00 2001 From: majeste Silatsa Date: Mon, 17 Aug 2026 09:48:45 +0200 Subject: [PATCH 03/10] feat-2298: Add detailed help entries for unpack commandlet in Help.properties and Help_de.properties --- cli/src/main/resources/nls/Help.properties | 3 +++ cli/src/main/resources/nls/Help_de.properties | 3 +++ 2 files changed, 6 insertions(+) diff --git a/cli/src/main/resources/nls/Help.properties b/cli/src/main/resources/nls/Help.properties index f1a6b16ea6..bc2b15bb38 100644 --- a/cli/src/main/resources/nls/Help.properties +++ b/cli/src/main/resources/nls/Help.properties @@ -163,6 +163,7 @@ cmd.uninstall-plugin=Uninstall the selected plugin for the selected tool. cmd.uninstall-plugin.detail=Plugins can be only installed or uninstalled for tools that support such. Using the command "ide install-plugin", an uninstalled plugin can be restored. cmd.uninstall.detail=Can be used to uninstall selected tool(s). E.g. to uninstall java simply call 'ide uninstall java'. To uninstall IDEasy itself, run 'ide uninstall' without further arguments. To fully delete the selected tool from your machine, use force mode. E.g. 'ide --force uninstall java'. cmd.unpack=Unpack the selected tool. +cmd.unpack.detail=Can be used to unpack selected tool(s). E.g. to unpack java simply call 'ide unpack java'. To unpack IDEasy itself, run 'ide unpack' without further arguments. To fully delete the selected tool from your machine, use force mode. E.g. 'ide --force unpack java'. cmd.update=Pull your settings and apply updates (software, configuration and repositories). cmd.update.detail=To update your IDE (if instructed by your ide-admin), you only need to run the following command: 'ide update'. cmd.upgrade=Upgrade the version of IDEasy to the latest version available. @@ -204,6 +205,7 @@ options.global=Global options: options.local=Local options: toolcommandlets=Available tool commandlets: usage=Usage: +val.archive=The archive file to unpack. val.args=The commandline arguments to pass to the tool. val.cfg=Selection of the configuration file (settings | home | conf | workspace). val.commandlet=The selected commandlet (use 'ide help' to list all commandlets). @@ -212,6 +214,7 @@ val.link=The path where the link is created. val.plugin=The plugin to select val.settingsRepository=The settings git repository with the IDEasy configuration for the project. val.source=The source path the link points to (existing file or directory). +val.target=The target path the link is created at (existing file or directory). val.tool=The tool commandlet to select. val.version=The tool version. values=Values: diff --git a/cli/src/main/resources/nls/Help_de.properties b/cli/src/main/resources/nls/Help_de.properties index 5a50de783c..5f9745ea1d 100644 --- a/cli/src/main/resources/nls/Help_de.properties +++ b/cli/src/main/resources/nls/Help_de.properties @@ -163,6 +163,7 @@ cmd.uninstall-plugin=Deinstalliert die selektierte Erweiterung für das selektie cmd.uninstall-plugin.detail=Erweiterung können nur für Werkzeuge installiert und deinstalliert werden die diese unterstützen. Mit dem Befehl "ide install-plugin" kann die Erweiterung wieder hergestellt werden. cmd.uninstall.detail=Wird dazu verwendet um ausgewählte Werkzeuge zu deinstallieren. Um z.B. Java zu deinstallieren, dient der Befehl 'ide uninstall java'. Um IDEasy selbst zu installieren, dient der Befehl 'ide uninstall' ohne weitere Parameter. Um ein aktuelles Werzeug vollständig von der Maschine zu löschen, wird der Force-Modus verwendet. Z.B. 'ide --force uninstall java'. cmd.unpack=Entpackt das ausgewählte Werkzeug. +cmd.unpack.detail=Dies wird das ausgewählte Werkzeug entpacken. Um z.B. Java zu entpacken, dient der Befehl 'ide unpack java'. Um IDEasy selbst zu entpacken, dient der Befehl 'ide unpack' ohne weitere Parameter. cmd.update=Updatet die Settings, Software und Repositories. cmd.update.detail=Um die IDE auf den neuesten Stand zu bringen (falls von Ihrem Admin angewiesen) geben Sie einfach 'ide update' in die Konsole ein. cmd.upgrade=Aktualisiere IDEasy auf die neueste Version. @@ -204,6 +205,7 @@ options.global=Globale Optionen: options.local=Lokale Optionen: toolcommandlets=Verfügbare Werkzeug Kommandos: usage=Verwendung: +val.archive=Die zu entpackende Archivdatei. val.args=Die Kommandozeilen-Argumente zur Übergabe an das Werkzeug. val.cfg=Auswahl der Konfigurationsdatei (settings | home | conf | workspace). val.commandlet=Das ausgewählte Commandlet ("ide help" verwenden, um alle Commandlets aufzulisten). @@ -212,6 +214,7 @@ val.link=Pfad des zu erstellenden Links. val.plugin=Die zu selektierende Erweiterung. val.settingsRepository=Das settings git Repository mit den IDEasy Einstellungen für das Projekt. val.source=Ziel des Links (existierender Pfad). +val.target=Ziel des Links (neuer Pfad). val.tool=Das zu selektierende Werkzeug Kommando. val.version=Die Werkzeug Version. values=Werte: From 6f0661e5d43b2012b15c3e95775184f5ee714093 Mon Sep 17 00:00:00 2001 From: majeste Silatsa Date: Tue, 18 Aug 2026 09:30:08 +0200 Subject: [PATCH 04/10] fix: Correct issue in CHANGELOG and update unpack commandlet help entries --- CHANGELOG.adoc | 2 +- .../com/devonfw/tools/ide/commandlet/UnpackCommandlet.java | 2 +- cli/src/main/resources/nls/Help.properties | 6 +++--- cli/src/main/resources/nls/Help_de.properties | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 6a6c474473..8f08b263ca 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -8,7 +8,7 @@ Release with new features and bugfixes: The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/49?closed=1[milestone 2026.08.002]. -* https://github.com/devonfw/IDEasy/issues/2298[#2298]: Add unpack commandlet +* https://github.com/devonfw/IDEasy/issues/2219[#2219]: Add unpack commandlet == 2026.08.001 diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java index 5acbe6b695..43a834cf73 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java @@ -37,7 +37,7 @@ public UnpackCommandlet(IdeContext context) { addKeyword(getName()); this.archive = add(new PathProperty("", true, "archive", true)); - this.target = add(new PathProperty("target", false, "target", false)); + this.target = add(new PathProperty("", false, "target", false)); } @Override diff --git a/cli/src/main/resources/nls/Help.properties b/cli/src/main/resources/nls/Help.properties index bc2b15bb38..89e98f45c9 100644 --- a/cli/src/main/resources/nls/Help.properties +++ b/cli/src/main/resources/nls/Help.properties @@ -162,8 +162,8 @@ cmd.uninstall=Uninstall selected tool(s). cmd.uninstall-plugin=Uninstall the selected plugin for the selected tool. cmd.uninstall-plugin.detail=Plugins can be only installed or uninstalled for tools that support such. Using the command "ide install-plugin", an uninstalled plugin can be restored. cmd.uninstall.detail=Can be used to uninstall selected tool(s). E.g. to uninstall java simply call 'ide uninstall java'. To uninstall IDEasy itself, run 'ide uninstall' without further arguments. To fully delete the selected tool from your machine, use force mode. E.g. 'ide --force uninstall java'. -cmd.unpack=Unpack the selected tool. -cmd.unpack.detail=Can be used to unpack selected tool(s). E.g. to unpack java simply call 'ide unpack java'. To unpack IDEasy itself, run 'ide unpack' without further arguments. To fully delete the selected tool from your machine, use force mode. E.g. 'ide --force unpack java'. +cmd.unpack=Unpack the selected archive. +cmd.unpack.detail=Can be used to unpack an archive file. E.g. to unpack an archive call 'ide unpack archive.zip'. cmd.update=Pull your settings and apply updates (software, configuration and repositories). cmd.update.detail=To update your IDE (if instructed by your ide-admin), you only need to run the following command: 'ide update'. cmd.upgrade=Upgrade the version of IDEasy to the latest version available. @@ -214,7 +214,7 @@ val.link=The path where the link is created. val.plugin=The plugin to select val.settingsRepository=The settings git repository with the IDEasy configuration for the project. val.source=The source path the link points to (existing file or directory). -val.target=The target path the link is created at (existing file or directory). +val.target=The target path where the archive is extracted. val.tool=The tool commandlet to select. val.version=The tool version. values=Values: diff --git a/cli/src/main/resources/nls/Help_de.properties b/cli/src/main/resources/nls/Help_de.properties index 5f9745ea1d..301f44b5ac 100644 --- a/cli/src/main/resources/nls/Help_de.properties +++ b/cli/src/main/resources/nls/Help_de.properties @@ -162,8 +162,8 @@ cmd.uninstall=Deinstalliert ausgewählte Werkzeug(e). cmd.uninstall-plugin=Deinstalliert die selektierte Erweiterung für das selektierte Werkzeug. cmd.uninstall-plugin.detail=Erweiterung können nur für Werkzeuge installiert und deinstalliert werden die diese unterstützen. Mit dem Befehl "ide install-plugin" kann die Erweiterung wieder hergestellt werden. cmd.uninstall.detail=Wird dazu verwendet um ausgewählte Werkzeuge zu deinstallieren. Um z.B. Java zu deinstallieren, dient der Befehl 'ide uninstall java'. Um IDEasy selbst zu installieren, dient der Befehl 'ide uninstall' ohne weitere Parameter. Um ein aktuelles Werzeug vollständig von der Maschine zu löschen, wird der Force-Modus verwendet. Z.B. 'ide --force uninstall java'. -cmd.unpack=Entpackt das ausgewählte Werkzeug. -cmd.unpack.detail=Dies wird das ausgewählte Werkzeug entpacken. Um z.B. Java zu entpacken, dient der Befehl 'ide unpack java'. Um IDEasy selbst zu entpacken, dient der Befehl 'ide unpack' ohne weitere Parameter. +cmd.unpack=Entpackt das ausgewählte Archiv. +cmd.unpack.detail=Dies wird das ausgewählte Archiv entpacken. Um ein Archiv zu entpacken, dient der Befehl 'ide unpack datei.zip'. Um IDEasy selbst zu entpacken, dient der Befehl 'ide unpack' ohne weitere Parameter. cmd.update=Updatet die Settings, Software und Repositories. cmd.update.detail=Um die IDE auf den neuesten Stand zu bringen (falls von Ihrem Admin angewiesen) geben Sie einfach 'ide update' in die Konsole ein. cmd.upgrade=Aktualisiere IDEasy auf die neueste Version. @@ -214,7 +214,7 @@ val.link=Pfad des zu erstellenden Links. val.plugin=Die zu selektierende Erweiterung. val.settingsRepository=Das settings git Repository mit den IDEasy Einstellungen für das Projekt. val.source=Ziel des Links (existierender Pfad). -val.target=Ziel des Links (neuer Pfad). +val.target=Ziel des zu extrahierenden Archives (neuer Pfad). val.tool=Das zu selektierende Werkzeug Kommando. val.version=Die Werkzeug Version. values=Werte: From 17bcdfcbf9581b1f33ad438a262853e45ac44fbf Mon Sep 17 00:00:00 2001 From: majeste Silatsa Date: Tue, 18 Aug 2026 09:30:08 +0200 Subject: [PATCH 05/10] #2219: Correct issue in CHANGELOG and update unpack commandlet help entries --- CHANGELOG.adoc | 2 +- .../com/devonfw/tools/ide/commandlet/UnpackCommandlet.java | 2 +- cli/src/main/resources/nls/Help.properties | 6 +++--- cli/src/main/resources/nls/Help_de.properties | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 6a6c474473..8f08b263ca 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -8,7 +8,7 @@ Release with new features and bugfixes: The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/49?closed=1[milestone 2026.08.002]. -* https://github.com/devonfw/IDEasy/issues/2298[#2298]: Add unpack commandlet +* https://github.com/devonfw/IDEasy/issues/2219[#2219]: Add unpack commandlet == 2026.08.001 diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java index 5acbe6b695..43a834cf73 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java @@ -37,7 +37,7 @@ public UnpackCommandlet(IdeContext context) { addKeyword(getName()); this.archive = add(new PathProperty("", true, "archive", true)); - this.target = add(new PathProperty("target", false, "target", false)); + this.target = add(new PathProperty("", false, "target", false)); } @Override diff --git a/cli/src/main/resources/nls/Help.properties b/cli/src/main/resources/nls/Help.properties index bc2b15bb38..89e98f45c9 100644 --- a/cli/src/main/resources/nls/Help.properties +++ b/cli/src/main/resources/nls/Help.properties @@ -162,8 +162,8 @@ cmd.uninstall=Uninstall selected tool(s). cmd.uninstall-plugin=Uninstall the selected plugin for the selected tool. cmd.uninstall-plugin.detail=Plugins can be only installed or uninstalled for tools that support such. Using the command "ide install-plugin", an uninstalled plugin can be restored. cmd.uninstall.detail=Can be used to uninstall selected tool(s). E.g. to uninstall java simply call 'ide uninstall java'. To uninstall IDEasy itself, run 'ide uninstall' without further arguments. To fully delete the selected tool from your machine, use force mode. E.g. 'ide --force uninstall java'. -cmd.unpack=Unpack the selected tool. -cmd.unpack.detail=Can be used to unpack selected tool(s). E.g. to unpack java simply call 'ide unpack java'. To unpack IDEasy itself, run 'ide unpack' without further arguments. To fully delete the selected tool from your machine, use force mode. E.g. 'ide --force unpack java'. +cmd.unpack=Unpack the selected archive. +cmd.unpack.detail=Can be used to unpack an archive file. E.g. to unpack an archive call 'ide unpack archive.zip'. cmd.update=Pull your settings and apply updates (software, configuration and repositories). cmd.update.detail=To update your IDE (if instructed by your ide-admin), you only need to run the following command: 'ide update'. cmd.upgrade=Upgrade the version of IDEasy to the latest version available. @@ -214,7 +214,7 @@ val.link=The path where the link is created. val.plugin=The plugin to select val.settingsRepository=The settings git repository with the IDEasy configuration for the project. val.source=The source path the link points to (existing file or directory). -val.target=The target path the link is created at (existing file or directory). +val.target=The target path where the archive is extracted. val.tool=The tool commandlet to select. val.version=The tool version. values=Values: diff --git a/cli/src/main/resources/nls/Help_de.properties b/cli/src/main/resources/nls/Help_de.properties index 5f9745ea1d..301f44b5ac 100644 --- a/cli/src/main/resources/nls/Help_de.properties +++ b/cli/src/main/resources/nls/Help_de.properties @@ -162,8 +162,8 @@ cmd.uninstall=Deinstalliert ausgewählte Werkzeug(e). cmd.uninstall-plugin=Deinstalliert die selektierte Erweiterung für das selektierte Werkzeug. cmd.uninstall-plugin.detail=Erweiterung können nur für Werkzeuge installiert und deinstalliert werden die diese unterstützen. Mit dem Befehl "ide install-plugin" kann die Erweiterung wieder hergestellt werden. cmd.uninstall.detail=Wird dazu verwendet um ausgewählte Werkzeuge zu deinstallieren. Um z.B. Java zu deinstallieren, dient der Befehl 'ide uninstall java'. Um IDEasy selbst zu installieren, dient der Befehl 'ide uninstall' ohne weitere Parameter. Um ein aktuelles Werzeug vollständig von der Maschine zu löschen, wird der Force-Modus verwendet. Z.B. 'ide --force uninstall java'. -cmd.unpack=Entpackt das ausgewählte Werkzeug. -cmd.unpack.detail=Dies wird das ausgewählte Werkzeug entpacken. Um z.B. Java zu entpacken, dient der Befehl 'ide unpack java'. Um IDEasy selbst zu entpacken, dient der Befehl 'ide unpack' ohne weitere Parameter. +cmd.unpack=Entpackt das ausgewählte Archiv. +cmd.unpack.detail=Dies wird das ausgewählte Archiv entpacken. Um ein Archiv zu entpacken, dient der Befehl 'ide unpack datei.zip'. Um IDEasy selbst zu entpacken, dient der Befehl 'ide unpack' ohne weitere Parameter. cmd.update=Updatet die Settings, Software und Repositories. cmd.update.detail=Um die IDE auf den neuesten Stand zu bringen (falls von Ihrem Admin angewiesen) geben Sie einfach 'ide update' in die Konsole ein. cmd.upgrade=Aktualisiere IDEasy auf die neueste Version. @@ -214,7 +214,7 @@ val.link=Pfad des zu erstellenden Links. val.plugin=Die zu selektierende Erweiterung. val.settingsRepository=Das settings git Repository mit den IDEasy Einstellungen für das Projekt. val.source=Ziel des Links (existierender Pfad). -val.target=Ziel des Links (neuer Pfad). +val.target=Ziel des zu extrahierenden Archives (neuer Pfad). val.tool=Das zu selektierende Werkzeug Kommando. val.version=Die Werkzeug Version. values=Werte: From 2ceeb428d799510f17a972cab565699273cf212b Mon Sep 17 00:00:00 2001 From: majeste Silatsa Date: Tue, 18 Aug 2026 14:18:23 +0200 Subject: [PATCH 06/10] #2219 test: Add end-to-end test for unpack commandlet with positional target argument --- .../ide/commandlet/UnpackCommandletTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/cli/src/test/java/com/devonfw/tools/ide/commandlet/UnpackCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UnpackCommandletTest.java index 3a17e3e35f..9c6c9f2f39 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/commandlet/UnpackCommandletTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UnpackCommandletTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test; +import com.devonfw.tools.ide.cli.CliArguments; import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeTestContext; @@ -126,4 +127,33 @@ void testUnpack7zWithDefaultTarget() throws IOException { Path expectedTarget = context.getCwd().resolve(TEST_ARCHIVE_BASENAME); assertThat(expectedTarget).isDirectory(); } + + /** + * End-to-end test that a positional {@code target} argument on the command line ({@code ide unpack }) + * is bound to the target property and the archive is extracted into the given directory. + *

+ * The {@code target} property has no long option (it is a positional value argument); this guards that the positional + * binding works end-to-end, which the property-level tests above (which set the property directly) cannot verify. + *

+ */ + @Test + void testUnpackWithPositionalTarget() throws IOException { + + IdeTestContext context = newContext(PROJECT_BASIC); + + Path archive = TEST_ARCHIVE_ZIP.toAbsolutePath(); + Path target = context.getCwd().resolve("e2e-unpack-target"); + CliArguments args = new CliArguments("unpack", archive.toString(), target.toString()); + args.next(); + + int exitCode = context.run(args); + + assertThat(exitCode).isEqualTo(0); + assertThat(context).logAtError().hasNoMessageContaining("Unknown command"); + assertThat(context).logAtError().hasNoMessageContaining("Invalid option"); + assertThat(context).logAtError().hasNoMessageContaining("No matching property"); + assertThat(target).isDirectory(); + assertThat(target.resolve("executableFile.txt")).isRegularFile(); + assertThat(target.resolve("nonExecutableFile.txt")).isRegularFile(); + } } From a0fa1df681ab43f12688d34c498ce47c0f548a68 Mon Sep 17 00:00:00 2001 From: Majeste Silatsa Date: Wed, 19 Aug 2026 10:45:42 +0200 Subject: [PATCH 07/10] #2219 review: Update unpack commandlet help entries and remove issue reference from CHANGELOG --- CHANGELOG.adoc | 2 -- cli/src/main/resources/nls/Help.properties | 2 +- cli/src/main/resources/nls/Help_de.properties | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 8f08b263ca..aef3947773 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -8,8 +8,6 @@ Release with new features and bugfixes: The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/49?closed=1[milestone 2026.08.002]. -* https://github.com/devonfw/IDEasy/issues/2219[#2219]: Add unpack commandlet - == 2026.08.001 Release with new features and bugfixes: diff --git a/cli/src/main/resources/nls/Help.properties b/cli/src/main/resources/nls/Help.properties index 89e98f45c9..72ff83557e 100644 --- a/cli/src/main/resources/nls/Help.properties +++ b/cli/src/main/resources/nls/Help.properties @@ -214,7 +214,7 @@ val.link=The path where the link is created. val.plugin=The plugin to select val.settingsRepository=The settings git repository with the IDEasy configuration for the project. val.source=The source path the link points to (existing file or directory). -val.target=The target path where the archive is extracted. +val.target=The target directory to extract the archive into. val.tool=The tool commandlet to select. val.version=The tool version. values=Values: diff --git a/cli/src/main/resources/nls/Help_de.properties b/cli/src/main/resources/nls/Help_de.properties index 301f44b5ac..409cef88cc 100644 --- a/cli/src/main/resources/nls/Help_de.properties +++ b/cli/src/main/resources/nls/Help_de.properties @@ -163,7 +163,7 @@ cmd.uninstall-plugin=Deinstalliert die selektierte Erweiterung für das selektie cmd.uninstall-plugin.detail=Erweiterung können nur für Werkzeuge installiert und deinstalliert werden die diese unterstützen. Mit dem Befehl "ide install-plugin" kann die Erweiterung wieder hergestellt werden. cmd.uninstall.detail=Wird dazu verwendet um ausgewählte Werkzeuge zu deinstallieren. Um z.B. Java zu deinstallieren, dient der Befehl 'ide uninstall java'. Um IDEasy selbst zu installieren, dient der Befehl 'ide uninstall' ohne weitere Parameter. Um ein aktuelles Werzeug vollständig von der Maschine zu löschen, wird der Force-Modus verwendet. Z.B. 'ide --force uninstall java'. cmd.unpack=Entpackt das ausgewählte Archiv. -cmd.unpack.detail=Dies wird das ausgewählte Archiv entpacken. Um ein Archiv zu entpacken, dient der Befehl 'ide unpack datei.zip'. Um IDEasy selbst zu entpacken, dient der Befehl 'ide unpack' ohne weitere Parameter. +cmd.unpack.detail=Dies wird das ausgewählte Archiv entpacken. Um ein Archiv zu entpacken, dient der Befehl 'ide unpack datei.zip'. cmd.update=Updatet die Settings, Software und Repositories. cmd.update.detail=Um die IDE auf den neuesten Stand zu bringen (falls von Ihrem Admin angewiesen) geben Sie einfach 'ide update' in die Konsole ein. cmd.upgrade=Aktualisiere IDEasy auf die neueste Version. From 4ea9af6b4797dde11497ad1450b61270e9194f71 Mon Sep 17 00:00:00 2001 From: Majeste Silatsa Date: Wed, 19 Aug 2026 10:52:46 +0200 Subject: [PATCH 08/10] #2219 fix:redo CHANGELOG.adoc modification for release --- CHANGELOG.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 2a82f6b630..687333a101 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -11,6 +11,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/1165[#1165]: Fix automatic project import for Eclipse * https://github.com/devonfw/IDEasy/issues/2040[#2040]: Fixed buggy workspace selection in the GUI * https://github.com/devonfw/IDEasy/issues/2253[#2253]: Fix structure and log documentation +* https://github.com/devonfw/IDEasy/issues/2219[#2219]: Add unpack commandlet The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/49?closed=1[milestone 2026.08.002]. From 9f427399bdadde5743aa12eadc21cdb7df131581 Mon Sep 17 00:00:00 2001 From: Majeste Silatsa Date: Wed, 26 Aug 2026 10:15:20 +0200 Subject: [PATCH 09/10] #2219 fix: replace PathProperty with FileProperty for archive in UnpackCommandlet and remove IsIdeRiitRequired() method --- .../devonfw/tools/ide/commandlet/UnpackCommandlet.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java index 43a834cf73..01545bba33 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java @@ -7,6 +7,7 @@ import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.property.FileProperty; import com.devonfw.tools.ide.property.PathProperty; import com.devonfw.tools.ide.util.FilenameUtil; @@ -36,7 +37,7 @@ public UnpackCommandlet(IdeContext context) { super(context); addKeyword(getName()); - this.archive = add(new PathProperty("", true, "archive", true)); + this.archive = add(new FileProperty("", true, "archive", true)); this.target = add(new PathProperty("", false, "target", false)); } @@ -46,12 +47,6 @@ public String getName() { return "unpack"; } - @Override - public boolean isIdeRootRequired() { - - return false; - } - @Override public boolean isIdeHomeRequired() { From e9c86e810b670b465bda47e1cbe0e800ee4f5a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Thu, 27 Aug 2026 09:48:16 +0200 Subject: [PATCH 10/10] constructive review --- .../java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java index 01545bba33..cf3251fe90 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UnpackCommandlet.java @@ -22,7 +22,7 @@ public final class UnpackCommandlet extends Commandlet { private static final Logger LOG = LoggerFactory.getLogger(UnpackCommandlet.class); /** The archive file to extract. */ - public final PathProperty archive; + public final FileProperty archive; /** The target directory to extract into. If not specified, defaults to {@code /}. */ public final PathProperty target;