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 385778781..e8fbefaae 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
@@ -9,6 +9,7 @@
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.property.KeywordProperty;
import com.devonfw.tools.ide.property.Property;
+import com.devonfw.tools.ide.tool.aws.Aws;
import com.devonfw.tools.ide.tool.az.Azure;
import com.devonfw.tools.ide.tool.eclipse.Eclipse;
import com.devonfw.tools.ide.tool.gcviewer.GcViewer;
@@ -75,6 +76,7 @@ public CommandletManagerImpl(IdeContext context) {
add(new KotlincNative(context));
add(new Vscode(context));
add(new Azure(context));
+ add(new Aws(context));
add(new Cobigen(context));
}
diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/ToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/ToolCommandlet.java
index 971ae1f2a..4f8f0a0d8 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/tool/ToolCommandlet.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/tool/ToolCommandlet.java
@@ -89,7 +89,7 @@ public void run() {
* Ensures the tool is installed and then runs this tool with the given arguments.
*
* @param toolVersion the explicit version (pattern) to run. Typically {@code null} to ensure the configured version
- * is installed and use that one. Otherwise the specified version will be installed in the software repository
+ * is installed and use that one. Otherwise, the specified version will be installed in the software repository
* without touching and IDE installation and used to run.
* @param args the commandline arguments to run the tool.
*/
@@ -267,7 +267,7 @@ protected void extract(Path file, Path targetDir) {
} else {
throw new IllegalStateException("Unknown archive format " + extension + ". Can not extract " + file);
}
- fileAccess.move(getProperInstallationSubDirOf(tmpDir), targetDir);
+ moveAndProcessExtraction(getProperInstallationSubDirOf(tmpDir), targetDir);
fileAccess.delete(tmpDir);
} else {
this.context.trace("Extraction is disabled for '{}' hence just moving the downloaded file {}.", getName(), file);
@@ -285,6 +285,11 @@ protected void extract(Path file, Path targetDir) {
}
}
+ protected void moveAndProcessExtraction(Path from, Path to) {
+
+ this.context.getFileAccess().move(from, to);
+ }
+
/**
* @return {@code true} to extract (unpack) the downloaded binary file, {@code false} otherwise.
*/
diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/aws/Aws.java b/cli/src/main/java/com/devonfw/tools/ide/tool/aws/Aws.java
new file mode 100644
index 000000000..d2257228f
--- /dev/null
+++ b/cli/src/main/java/com/devonfw/tools/ide/tool/aws/Aws.java
@@ -0,0 +1,100 @@
+package com.devonfw.tools.ide.tool.aws;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.Set;
+
+import com.devonfw.tools.ide.common.Tag;
+import com.devonfw.tools.ide.context.IdeContext;
+import com.devonfw.tools.ide.environment.EnvironmentVariables;
+import com.devonfw.tools.ide.environment.EnvironmentVariablesType;
+import com.devonfw.tools.ide.process.ProcessContext;
+import com.devonfw.tools.ide.tool.LocalToolCommandlet;
+
+/**
+ * {@link LocalToolCommandlet} for AWS CLI (aws).
+ *
+ * @see AWS CLI homepage
+ */
+
+public class Aws extends LocalToolCommandlet {
+
+ /**
+ * The constructor.
+ *
+ * @param context the {@link IdeContext}.
+ */
+ public Aws(IdeContext context) {
+
+ super(context, "aws", Set.of(Tag.CLOUD));
+ }
+
+ private void makeExecutable(Path file) {
+
+ // TODO this can be removed if issue #132 is fixed. See https://github.com/devonfw/IDEasy/issues/132
+ Set permissions = null;
+ try {
+ permissions = Files.getPosixFilePermissions(file);
+ permissions.add(PosixFilePermission.GROUP_EXECUTE);
+ permissions.add(PosixFilePermission.OWNER_EXECUTE);
+ permissions.add(PosixFilePermission.OTHERS_EXECUTE);
+ Files.setPosixFilePermissions(file, permissions);
+ } catch (IOException e) {
+ throw new RuntimeException("Adding execution permission for Group, Owner and Others did not work for " + file, e);
+ }
+ }
+
+ @Override
+ protected void moveAndProcessExtraction(Path from, Path to) {
+
+ if (this.context.getSystemInfo().isLinux()) {
+ // make binary executable using java nio because unpacking didn't preserve the file permissions
+ // TODO this can be removed if issue #132 is fixed
+ Path awsInDistPath = from.resolve("dist").resolve("aws");
+ Path awsCompleterInDistPath = from.resolve("dist").resolve("aws_completer");
+ makeExecutable(awsInDistPath);
+ makeExecutable(awsCompleterInDistPath);
+
+ // running the install-script that aws shipped
+ ProcessContext pc = this.context.newProcess();
+ Path linuxInstallScript = from.resolve("install");
+ pc.executable(linuxInstallScript);
+ pc.addArgs("-i", from.toString(), "-b", from.toString());
+ pc.run();
+
+ // The install-script that aws ships creates symbolic links to binaries but using absolute paths.
+ // Since the current process happens in a temporary dir, these links wouldn't be valid after moving the
+ // installation files to the target dir. So the absolute paths are replaced by relative ones.
+ for (String file : new String[] { "aws", "aws_completer", Path.of("v2").resolve("current").toString() }) {
+ Path link = from.resolve(file);
+ try {
+ this.context.getFileAccess().symlink(link.toRealPath(), link, true);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Failed to replace absolute link (" + link + ") provided by AWS install script with relative link.", e);
+ }
+ }
+ this.context.getFileAccess().delete(linuxInstallScript);
+ this.context.getFileAccess().delete(from.resolve("dist"));
+ }
+ super.moveAndProcessExtraction(from, to);
+ }
+
+ @Override
+ public void postInstall() {
+
+ super.postInstall();
+
+ EnvironmentVariables variables = this.context.getVariables();
+ EnvironmentVariables typeVariables = variables.getByType(EnvironmentVariablesType.CONF);
+ Path awsConfigDir = this.context.getConfPath().resolve("aws");
+ this.context.getFileAccess().mkdirs(awsConfigDir);
+ Path awsConfigFile = awsConfigDir.resolve("config");
+ Path awsCredentialsFile = awsConfigDir.resolve("credentials");
+ typeVariables.set("AWS_CONFIG_FILE", awsConfigFile.toString(), true);
+ typeVariables.set("AWS_SHARED_CREDENTIALS_FILE", awsCredentialsFile.toString(), true);
+ typeVariables.save();
+ }
+}
diff --git a/cli/src/main/resources/nls/Ide.properties b/cli/src/main/resources/nls/Ide.properties
index bbe13b90e..a07f3d352 100644
--- a/cli/src/main/resources/nls/Ide.properties
+++ b/cli/src/main/resources/nls/Ide.properties
@@ -2,20 +2,21 @@ usage=Usage:
values=Values:
commandlets=Available commandlets:
options=Options:
+cmd-aws=Tool commandlet for AWS CLI.
+cmd-az=Tool commandlet for Azure CLI.
cmd---version=Print the version of IDEasy.
-cmd-az=Tool commandlet for Azure CLI
cmd-complete=Internal commandlet for bash auto-completion
cmd-eclipse=Tool commandlet for Eclipse (IDE)
cmd-env=Print the environment variables to set and export.
cmd-get-version=Get the version of the selected tool.
-cmd-gh=Tool commandlet for Github CLI
+cmd-gh=Tool commandlet for Github CLI.
cmd-gradle=Tool commandlet for Gradle (Build-Tool)
cmd-helm=Tool commandlet for Helm (Kubernetes Package Manager)
cmd-help=Prints this help.
cmd-install=Install the selected tool.
cmd-java=Tool commandlet for Java (OpenJDK)
-cmd-kotlinc=Tool commandlet for Kotlin
-cmd-kotlincnative=Tool commandlet for Kotlin-Native
+cmd-kotlinc=Tool commandlet for Kotlin.
+cmd-kotlincnative=Tool commandlet for Kotlin-Native.
cmd-list-version=List the available versions of the selected tool.
cmd-mvn=Tool commandlet for Maven (Build-Tool)
cmd-node=Tool commandlet for Node.js (JavaScript runtime)
diff --git a/cli/src/main/resources/nls/Ide_de.properties b/cli/src/main/resources/nls/Ide_de.properties
index 56071158e..82b1711b8 100644
--- a/cli/src/main/resources/nls/Ide_de.properties
+++ b/cli/src/main/resources/nls/Ide_de.properties
@@ -2,18 +2,19 @@ usage=Verwendung:
values=Werte:
commandlets=Verfügbare Kommandos:
options=Optionen:
+cmd-aws=Werkzeug Kommando fuer AWS Kommandoschnittstelle.
+cmd-az=Werkzeug Kommando fuer Azure Kommandoschnittstelle.
cmd---version=Gibt die Version von IDEasy aus.
-cmd-az=Werkzeug Kommando für die Azure Kommandoschnittstelle.
cmd-eclipse=Werkzeug Kommando für Eclipse (IDE)
cmd-env=Gibt die zu setztenden und exportierenden Umgebungsvariablen aus.
cmd-get-version=Zeigt die Version des selektierten Werkzeugs an.
-cmd-gh=Werkzeug Kommando für die Github Kommandoschnittstelle
+cmd-gh=Werkzeug Kommando für die Github Kommandoschnittstelle.
cmd-helm=Werkzeug Kommando für Helm (Kubernetes Package Manager)
cmd-help=Zeigt diese Hilfe an.
cmd-install=Installiert das selektierte Werkzeug.
cmd-java=Werkzeug Kommando für Java (OpenJDK)
-cmd-kotlinc=Werkzeug Kommando für Kotlin
-cmd-kotlincnative=Werkzeug Kommando für Kotlin-Native
+cmd-kotlinc=Werkzeug Kommando für Kotlin.
+cmd-kotlincnative=Werkzeug Kommando für Kotlin-Native.
cmd-list-version=Listet die verfügbaren Versionen des selektierten Werkzeugs auf.
cmd-mvn=Werkzeug Kommando für Maven (Build-Werkzeug)
cmd-node=Werkzeug Kommando für Node.js (JavaScript Laufzeitumgebung)
diff --git a/cli/src/test/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFileTest.java b/cli/src/test/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFileTest.java
index c7e0bbddb..7a8198b10 100644
--- a/cli/src/test/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFileTest.java
+++ b/cli/src/test/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFileTest.java
@@ -10,6 +10,7 @@
import org.junit.jupiter.api.Test;
import com.devonfw.tools.ide.context.IdeTestContextMock;
+import org.junit.jupiter.api.io.TempDir;
/**
* Test of {@link EnvironmentVariablesPropertiesFile}.
@@ -40,7 +41,7 @@ public void testLoad() {
}
@Test
- void testSave() throws Exception {
+ void testSave(@TempDir Path tempDir) throws Exception {
// arrange
List linesToWrite = new ArrayList<>();
@@ -60,7 +61,7 @@ void testSave() throws Exception {
linesToWrite.add("# 5th comment");
linesToWrite.add("var9=9");
- Path propertiesFilePath = Path.of("target/tmp-EnvironmentVariablesPropertiesFileTest-ide.properties");
+ Path propertiesFilePath = tempDir.resolve("test.properties");
Files.write(propertiesFilePath, linesToWrite, StandardOpenOption.CREATE_NEW);
// check if this writing was correct
List lines = Files.readAllLines(propertiesFilePath);
@@ -76,7 +77,7 @@ void testSave() throws Exception {
variables.set("var5", "5", true);
variables.set("var1", "1.0", false);
variables.set("var10", "10", false);
- variables.set("var11", "11", true); // var11 must be set after var 10, the other lines can be shuffled
+ variables.set("var11", "11", true);
variables.set("var3", "3", false);
variables.set("var7", "7", true);
variables.set("var6", "6.0", true);
@@ -107,7 +108,5 @@ void testSave() throws Exception {
lines = Files.readAllLines(propertiesFilePath);
assertThat(lines).containsExactlyElementsOf(linesAfterSave);
- // clean up
- Files.delete(propertiesFilePath);
}
}
\ No newline at end of file