Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f24a728
#1058: fixed missing JAVA_HOME env var
jan-vcapgemini Feb 28, 2025
d22844c
#1058: removed unnecessary withEnvVar call
jan-vcapgemini Mar 3, 2025
e164048
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini Mar 3, 2025
074a7b8
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini Mar 4, 2025
0488bfd
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini Mar 4, 2025
b3b7d53
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini Apr 7, 2025
0733a7f
#1058: fixed mvn encrypt password
jan-vcapgemini Apr 9, 2025
3d1809a
#1058: added changelog entry
jan-vcapgemini Apr 9, 2025
862d774
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini Apr 9, 2025
328297f
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini Apr 11, 2025
0514aa3
#1058: fixed missing mvn arguments
jan-vcapgemini Apr 11, 2025
8264262
#1058: optimized MvnTest
jan-vcapgemini Apr 16, 2025
760ed9d
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini Apr 16, 2025
c883d70
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini Apr 22, 2025
c554bf7
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini Apr 28, 2025
f97e3bd
Merge branch 'dependabot/maven/org.jline-jline-3.29.0' of https://git…
jan-vcapgemini May 5, 2025
b67ca8e
#1058: implemented requested changes
jan-vcapgemini May 5, 2025
b348472
#1058: refactored getMavenArgs method
jan-vcapgemini May 5, 2025
8dde2ee
#1058: implemented requested changes
jan-vcapgemini May 6, 2025
bfe3860
#1058: implemented requested changes
jan-vcapgemini May 6, 2025
7f2af3f
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini May 7, 2025
573f528
#1058: implemented requested changes
jan-vcapgemini May 7, 2025
2748742
#1058: implemented requested changes
jan-vcapgemini May 7, 2025
0bacb71
#1058: implemented requested changes
jan-vcapgemini May 9, 2025
7cfeba3
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini May 12, 2025
b82e534
#1058: implemented requested change
jan-vcapgemini May 12, 2025
6146152
#1058: implemented requested changes
jan-vcapgemini May 12, 2025
3808252
Merge branch 'main' into fix/1058-faulty-java-home
jan-vcapgemini May 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Release with new features and bugfixes:

* https://github.com/devonfw/IDEasy/issues/1272[#1272]: Add name of file with missing namespace to warning message
* https://github.com/devonfw/IDEasy/issues/1190[#1190]: Add pycharm support to IDEasy
* https://github.com/devonfw/IDEasy/issues/1058[#1058]: ide create still cannot handle faulty JAVA_HOME

The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/27?closed=1[milestone 2025.05.001].

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.devonfw.tools.ide.process;

import com.devonfw.tools.ide.log.IdeSubLogger;

import java.nio.file.Path;
import java.util.List;
import java.util.Objects;

import com.devonfw.tools.ide.log.IdeSubLogger;

/**
* Wrapper for {@link ProcessBuilder} to simplify its usage and avoid common mistakes and pitfalls.
*/
Expand All @@ -26,8 +26,9 @@ public interface ProcessContext extends EnvironmentContext {
/**
* Sets the executable command to be {@link #run()}.
*
* @param executable the {@link Path} to the command to be executed by {@link #run()}. Depending on your operating system and the extension of the executable
* or OS specific conventions. So e.g. a *.cmd or *.bat file will be called via CMD shell on windows while a *.sh file will be called via Bash, etc.
* @param executable the {@link Path} to the command to be executed by {@link #run()}. Depending on your operating system and the extension of the
* executable or OS specific conventions. So e.g. a *.cmd or *.bat file will be called via CMD shell on windows while a *.sh file will be called via Bash,
* etc.
* @return this {@link ProcessContext} for fluent API calls.
*/
ProcessContext executable(Path executable);
Expand Down Expand Up @@ -165,41 +166,12 @@ default String runAndGetSingleOutput(String executable, String... arguments) {
*/
default String runAndGetSingleOutput(IdeSubLogger logger, String executable, String... arguments) {

String errorMessage;
executable(executable).addArgs(arguments);
if (logger == null) {
errorHandling(ProcessErrorHandling.THROW_ERR);
}
ProcessResult result = run(ProcessMode.DEFAULT_CAPTURE);
if (result.isSuccessful()) {
List<String> out = result.getOut();
int size = out.size();
if (size == 1) {
return out.get(0);
} else if (size == 0) {
errorMessage = "No output received from " + result.getCommand();
} else {
StringBuilder sb = new StringBuilder();
sb.append("Expected single line of output but received ");
sb.append(size);
sb.append(" lines from ");
sb.append(result.getCommand());
sb.append(":");
for (String line : out) {
sb.append("\n");
sb.append(line);
}
errorMessage = sb.toString();
}
} else {
errorMessage = "Command " + result.getCommand() + " failed with exit code " + result.getExitCode();
}
if (logger == null) {
throw new IllegalStateException(errorMessage);
} else {
logger.log(errorMessage);
return null;
}
return result.getSingleOutput(logger);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.devonfw.tools.ide.cli.CliProcessException;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.log.IdeLogLevel;
import com.devonfw.tools.ide.log.IdeSubLogger;

/**
* Result of a {@link Process} execution.
Expand Down Expand Up @@ -66,6 +67,13 @@ default boolean isSuccessful() {
return getExitCode() == SUCCESS;
}

/**
* @param logger the {@link IdeSubLogger logger} to use.
* @return the first captured standard out. Will be {@code null} if not captured but redirected.
* @throws IllegalStateException if more than one output was captured and the {@link IdeSubLogger logger} was null.
*/
String getSingleOutput(IdeSubLogger logger) throws IllegalStateException;

/**
* @return the {@link List} with the lines captured on standard out. Will be {@code null} if not captured but redirected.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.devonfw.tools.ide.cli.CliProcessException;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.log.IdeLogLevel;
import com.devonfw.tools.ide.log.IdeSubLogger;

/**
* Implementation of {@link ProcessResult}.
Expand Down Expand Up @@ -56,6 +57,40 @@ public int getExitCode() {
return this.exitCode;
}

@Override
public String getSingleOutput(IdeSubLogger logger) throws IllegalStateException {
String errorMessage;
if (this.isSuccessful()) {
List<String> out = this.getOut();
int size = out.size();
if (size == 1) {
return out.getFirst();
} else if (size == 0) {
errorMessage = "No output received from " + this.getCommand();
} else {
StringBuilder sb = new StringBuilder();
sb.append("Expected single line of output but received ");
sb.append(size);
sb.append(" lines from ");
sb.append(this.getCommand());
sb.append(":");
for (String line : out) {
sb.append("\n");
sb.append(line);
}
errorMessage = sb.toString();
}
} else {
errorMessage = "Command " + this.getCommand() + " failed with exit code " + this.getExitCode();
}
if (logger == null) {
throw new IllegalStateException(errorMessage);
} else {
logger.log(errorMessage);
return null;
}
}

@Override
public List<String> getOut() {

Expand Down
31 changes: 17 additions & 14 deletions cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
import com.devonfw.tools.ide.common.Tag;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.git.GitContext;
import com.devonfw.tools.ide.log.IdeLogLevel;
import com.devonfw.tools.ide.log.IdeSubLogger;
import com.devonfw.tools.ide.process.ProcessContext;
import com.devonfw.tools.ide.process.ProcessErrorHandling;
import com.devonfw.tools.ide.process.ProcessMode;
import com.devonfw.tools.ide.process.ProcessResult;
import com.devonfw.tools.ide.step.Step;
Expand Down Expand Up @@ -96,12 +99,7 @@ private void createSettingsSecurityFile(Path settingsSecurityFile) {
secureRandom.nextBytes(randomBytes);
String base64String = Base64.getEncoder().encodeToString(randomBytes);

ProcessContext pc = this.context.newProcess().executable("mvn");
pc.addArgs("--encrypt-master-password", base64String);

ProcessResult result = pc.run(ProcessMode.DEFAULT_CAPTURE);

String encryptedMasterPassword = result.getOut().get(0);
String encryptedMasterPassword = retrievePassword("--encrypt-master-password", base64String);

String settingsSecurityXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<settingsSecurity>\n" + " <master>" + encryptedMasterPassword + "</master>\n"
Expand Down Expand Up @@ -154,17 +152,21 @@ private String getEncryptedPassword(String variable) {

String input = this.context.askForInput("Please enter secret value for variable " + variable + ":");

ProcessContext pc = this.context.newProcess().executable("mvn");
pc.addArgs("--encrypt-password", input);
pc.addArg(getSettingsSecurityProperty());
ProcessResult result = pc.run(ProcessMode.DEFAULT_CAPTURE);

String encryptedPassword = result.getOut().get(0);
String encryptedPassword = retrievePassword("--encrypt-password", input);
this.context.info("Encrypted as " + encryptedPassword);

return encryptedPassword;
}

private String retrievePassword(String args, String input) {

ProcessResult result = runTool(ProcessMode.DEFAULT_CAPTURE, ProcessErrorHandling.LOG_WARNING, this.context.newProcess(), args, input,
getSettingsSecurityProperty());

IdeSubLogger logger = this.context.level(IdeLogLevel.WARNING);
return result.getSingleOutput(logger);
}

private Set<String> findVariables(String content) {

Set<String> variables = new LinkedHashSet<>();
Expand Down Expand Up @@ -248,9 +250,10 @@ public Path getMavenConfFolder(boolean legacy) {
* @return the maven arguments (MVN_ARGS).
*/
public String getMavenArgs() {
Path mavenConfFolder = getMavenConfFolder(false);
Path mavenConfFolder = this.context.getMavenConfigurationFolder();
Path mvnSettingsFile = mavenConfFolder.resolve(Mvn.SETTINGS_FILE);
if (!Files.exists(mvnSettingsFile)) {
Path settingsSecurityFile = mavenConfFolder.resolve(SETTINGS_SECURITY_FILE);
if (!Files.exists(mvnSettingsFile) && !Files.exists(settingsSecurityFile)) {
return null;
}
String settingsPath = mvnSettingsFile.toString();
Expand Down
17 changes: 6 additions & 11 deletions cli/src/test/java/com/devonfw/tools/ide/tool/mvn/MvnTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import org.junit.jupiter.api.Test;

import com.devonfw.tools.ide.commandlet.InstallCommandlet;
import com.devonfw.tools.ide.context.AbstractIdeContextTest;
import com.devonfw.tools.ide.context.IdeTestContext;
import com.devonfw.tools.ide.variable.IdeVariables;
Expand All @@ -22,7 +21,6 @@ public class MvnTest extends AbstractIdeContextTest {

private static final String PROJECT_MVN = "mvn";

//private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\$\\[(.*?)\\]");
private static final Pattern VARIABLE_PATTERN = Pattern.compile("<([^>]+)>(.*?)</\\1>");

/**
Expand All @@ -36,11 +34,10 @@ public void testMvnInstall() throws IOException {
// arrange
IdeTestContext context = newContext(PROJECT_MVN);
context.setAnswers("testLogin", "testPassword");
InstallCommandlet install = context.getCommandletManager().getCommandlet(InstallCommandlet.class);
install.tool.setValueAsString("mvn", context);
Mvn mvn = context.getCommandletManager().getCommandlet(Mvn.class);

// act
install.run();
mvn.run();

// assert
checkInstallation(context);
Expand All @@ -56,14 +53,12 @@ public void testMvnRun() throws IOException {
// arrange
IdeTestContext context = newContext(PROJECT_MVN);
context.setAnswers("testLogin", "testPassword");
InstallCommandlet install = context.getCommandletManager().getCommandlet(InstallCommandlet.class);
install.tool.setValueAsString("mvn", context);
Mvn commandlet = (Mvn) install.tool.getValue();
commandlet.arguments.addValue("foo");
commandlet.arguments.addValue("bar");
Mvn mvn = context.getCommandletManager().getCommandlet(Mvn.class);
mvn.arguments.addValue("foo");
mvn.arguments.addValue("bar");

// act
commandlet.run();
mvn.run();

// assert
assertThat(context).logAtInfo().hasMessage("mvn " + "foo bar");
Expand Down