diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 1082ebb06..75bc1a018 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -10,6 +10,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/pull/693[#693]: Setup not working on Mac * https://github.com/devonfw/IDEasy/issues/704[#704]: settings-security.xml not found * https://github.com/devonfw/IDEasy/issues/302[#302]: Add plugin support for GraalVM +* https://github.com/devonfw/IDEasy/issues/710[#710]: Make IDE workspace configuration robust The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/14?closed=1[milestone 2024.10.001]. diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java index 34864d953..b4fb4d780 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java @@ -54,21 +54,23 @@ public DirectoryMerger(IdeContext context) { } @Override - public void merge(Path setup, Path update, EnvironmentVariables variables, Path workspace) { + public int merge(Path setup, Path update, EnvironmentVariables variables, Path workspace) { + int errors = 0; Set children = null; children = addChildren(setup, children); children = addChildren(update, children); if (children == null) { // file merge FileMerger merger = getMerger(workspace); - merger.merge(setup, update, variables, workspace); + errors += merger.merge(setup, update, variables, workspace); } else { // directory scan for (String filename : children) { - merge(setup.resolve(filename), update.resolve(filename), variables, workspace.resolve(filename)); + errors += merge(setup.resolve(filename), update.resolve(filename), variables, workspace.resolve(filename)); } } + return errors; } private FileMerger getMerger(Path file) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/FallbackMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/FallbackMerger.java index 2111c2fd1..54bd3bae2 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/FallbackMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/FallbackMerger.java @@ -24,7 +24,7 @@ public FallbackMerger(IdeContext context) { } @Override - public void merge(Path setup, Path update, EnvironmentVariables variables, Path workspace) { + protected void doMerge(Path setup, Path update, EnvironmentVariables variables, Path workspace) { if (Files.exists(update)) { copy(update, workspace); diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/FileMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/FileMerger.java index 2bc511322..c931f17df 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/FileMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/FileMerger.java @@ -5,6 +5,7 @@ import java.nio.file.StandardCopyOption; import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.environment.EnvironmentVariables; import com.devonfw.tools.ide.variable.IdeVariables; /** @@ -39,4 +40,24 @@ protected void copy(Path sourceFile, Path targetFile) { } } + @Override + public final int merge(Path setup, Path update, EnvironmentVariables variables, Path workspace) { + try { + doMerge(setup, update, variables, workspace); + } catch (Exception e) { + this.context.error(e, "Failed to merge workspace file {}", workspace); + return 1; + } + return 0; + } + + /** + * Same as {@link #merge(Path, Path, EnvironmentVariables, Path)} but without error handling. + * + * @param setup the setup {@link Path} for creation. + * @param update the update {@link Path} for creation and update. + * @param variables the {@link EnvironmentVariables} to {@link EnvironmentVariables#resolve(String, Object) resolve variables}. + * @param workspace the workspace {@link Path} to create or update. + */ + protected abstract void doMerge(Path setup, Path update, EnvironmentVariables variables, Path workspace); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/JsonMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/JsonMerger.java index f17fa5f5f..8ea8f5c21 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/JsonMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/JsonMerger.java @@ -40,7 +40,7 @@ public JsonMerger(IdeContext context) { } @Override - public void merge(Path setup, Path update, EnvironmentVariables variables, Path workspace) { + protected void doMerge(Path setup, Path update, EnvironmentVariables variables, Path workspace) { JsonStructure json = null; Path template = setup; diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/PropertiesMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/PropertiesMerger.java index 1bcf6bb9a..8fddfc6d4 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/PropertiesMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/PropertiesMerger.java @@ -30,7 +30,7 @@ public PropertiesMerger(IdeContext context) { } @Override - public void merge(Path setup, Path update, EnvironmentVariables resolver, Path workspace) { + protected void doMerge(Path setup, Path update, EnvironmentVariables resolver, Path workspace) { SortedProperties properties = new SortedProperties(); boolean updateFileExists = Files.exists(update); diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/TextMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/TextMerger.java index e9ad49d9e..e1f71ea73 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/TextMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/TextMerger.java @@ -24,7 +24,7 @@ public TextMerger(IdeContext context) { } @Override - public void merge(Path setup, Path update, EnvironmentVariables variables, Path workspace) { + protected void doMerge(Path setup, Path update, EnvironmentVariables variables, Path workspace) { Path template = update; if (!Files.exists(template)) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/WorkspaceMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/WorkspaceMerger.java index 36290ec3b..e09ee7795 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/WorkspaceMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/WorkspaceMerger.java @@ -14,8 +14,9 @@ public interface WorkspaceMerger { * @param update the update {@link Path} for creation and update. * @param variables the {@link EnvironmentVariables} to {@link EnvironmentVariables#resolve(String, Object) resolve variables}. * @param workspace the workspace {@link Path} to create or update. + * @return the number of errors that occurred. Should be {@code 0} for success. */ - void merge(Path setup, Path update, EnvironmentVariables variables, Path workspace); + int merge(Path setup, Path update, EnvironmentVariables variables, Path workspace); /** * @param workspace the workspace {@link Path} where to get the changes from. diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/XmlMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/XmlMerger.java index 20f9982cb..03d4931cb 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/XmlMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/XmlMerger.java @@ -54,7 +54,7 @@ public XmlMerger(IdeContext context) { } @Override - public void merge(Path setup, Path update, EnvironmentVariables resolver, Path workspace) { + protected void doMerge(Path setup, Path update, EnvironmentVariables resolver, Path workspace) { Document document = null; Path template = setup; @@ -82,6 +82,7 @@ public void merge(Path setup, Path update, EnvironmentVariables resolver, Path w resolve(document, resolver, false, template); save(document, workspace); } + return; } /** diff --git a/cli/src/main/java/com/devonfw/tools/ide/step/StepImpl.java b/cli/src/main/java/com/devonfw/tools/ide/step/StepImpl.java index 56c0dc3d8..7788e0068 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/step/StepImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/step/StepImpl.java @@ -211,7 +211,11 @@ private void logErrorSummary(int depth, StepSummary summary) { boolean failure = isFailure(); summary.add(failure); if (failure) { - this.context.error("{}Step '{}' failed: {}", getIndent(depth), getNameWithParams(), this.errorMessage); + String error = this.errorMessage; + if (error == null) { + error = "unexpected error"; + } + this.context.error("{}Step '{}' failed: {}", getIndent(depth), getNameWithParams(), error); } depth++; for (StepImpl child : this.children) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeToolCommandlet.java index 73649064d..699e96019 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeToolCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeToolCommandlet.java @@ -7,6 +7,7 @@ import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.FileAccess; import com.devonfw.tools.ide.process.ProcessMode; +import com.devonfw.tools.ide.step.Step; import com.devonfw.tools.ide.tool.ToolCommandlet; import com.devonfw.tools.ide.tool.eclipse.Eclipse; import com.devonfw.tools.ide.tool.intellij.Intellij; @@ -74,7 +75,17 @@ protected void configureWorkspace() { if (!fileAccess.isExpectedFolder(ideWorkspacePath)) { return; // should actually never happen... } - this.context.step("Configuring workspace {} for IDE {}", ideWorkspacePath.getFileName(), this.tool); - this.context.getWorkspaceMerger().merge(setupFolder, updateFolder, this.context.getVariables(), ideWorkspacePath); + try (Step step = this.context.newStep("Configuring workspace " + ideWorkspacePath.getFileName() + " for IDE " + this.tool)) { + int errors = this.context.getWorkspaceMerger().merge(setupFolder, updateFolder, this.context.getVariables(), ideWorkspacePath); + if (errors == 0) { + step.success(); + } else { + step.error("Your workspace configuration failed with {} error(s) - see log above.\n" + + "This is either a configuration error in your settings git repository or a bug in IDEasy.\n" + + "Please analyze the above errors with your team or IDE-admin and try to fix the problem.", errors); + this.context.askToContinue( + "In order to prevent you from being blocked, you can start your IDE anyhow but some configuration may not be in sync."); + } + } } }