From e0e6f355d4794dc26541cf5b9a6afe162b4ae7d6 Mon Sep 17 00:00:00 2001
From: jan-vcapgemini <59438728+jan-vcapgemini@users.noreply.github.com>
Date: Mon, 22 Apr 2024 16:11:32 +0200
Subject: [PATCH] Fix/line endings (#304)
* adjusted .gitattributes
* fixed line endings
---
.gitattributes | 7 +-
.../java/com/devonfw/tools/ide/step/Step.java | 488 +++++++--------
.../com/devonfw/tools/ide/step/StepImpl.java | 590 +++++++++---------
.../tools/ide/tool/PackageManagerCommand.java | 52 +-
.../tools/ide/variable/IdeVariables.java | 150 ++---
.../devonfw/tools/ide/log/IdeSlf4jLogger.java | 154 ++---
.../com/devonfw/tools/ide/step/StepTest.java | 266 ++++----
documentation/symlink.adoc | 44 +-
8 files changed, 878 insertions(+), 873 deletions(-)
diff --git a/.gitattributes b/.gitattributes
index 1ffaa5d71..931eb4a75 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,8 @@
* eol=lf
*.bat eol=crlf
-*.png -text
+*.png binary
+*.zip binary
+*.tgz binary
+*.tar binary
+*.bz2 binary
+*.gz binary
\ No newline at end of file
diff --git a/cli/src/main/java/com/devonfw/tools/ide/step/Step.java b/cli/src/main/java/com/devonfw/tools/ide/step/Step.java
index 94e8e85d0..2536733c2 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/step/Step.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/step/Step.java
@@ -1,245 +1,245 @@
-package com.devonfw.tools.ide.step;
-
-import java.util.concurrent.Callable;
-
-/**
- * Interface for a {@link Step} of the process. Allows to split larger processes into smaller steps that are traced and
- * measured. At the end you can get a report with the hierarchy of all steps and their success/failure status, duration
- * in absolute and relative numbers to gain transparency.
The typical use should follow this pattern:
- *
- *
- * Step step = context.{@link com.devonfw.tools.ide.context.IdeContext#newStep(String) newStep}("My step description");
- * try {
- * // ... do something ...
- * step.{@link #success(String) success}("Did something successfully.");
- * } catch (Exception e) {
- * step.{@link #error(Throwable, String)}(e, "Failed to do something.");
- * } finally {
- * step.{@link #end() end()};
- * }
- *
- */
-public interface Step {
-
- /** Empty object array for no parameters. */
- Object[] NO_PARAMS = new Object[0];
-
- /**
- * @return the name of this {@link Step} as given to constructor.
- */
- String getName();
-
- /**
- * @return the duration of this {@link Step} from construction to {@link #success()} or {@link #end()}. Will be
- * {@code 0} if not {@link #end() ended}.
- */
- long getDuration();
-
- /**
- * @return {@code Boolean#TRUE} if this {@link Step} has {@link #success() succeeded}, {@code Boolean#FALSE} if the
- * {@link Step} has {@link #end() ended} without {@link #success() success} and {@code null} if the {@link Step} is
- * still running.
- */
- Boolean getSuccess();
-
- /**
- * @return {@code true} if this step completed {@link #success() successfully}, {@code false} otherwise.
- */
- default boolean isSuccess() {
-
- return Boolean.TRUE.equals(getSuccess());
- }
-
- /**
- * @return {@code true} if this step {@link #end() ended} without {@link #success() success} e.g. with an
- * {@link #error(String) error}, {@code false} otherwise.
- */
- default boolean isFailure() {
-
- return Boolean.FALSE.equals(getSuccess());
- }
-
- /**
- * @return {@code true} if this step is silent and not logged by default, {@code false} otherwise (default).
- */
- boolean isSilent();
-
- /**
- * Should be called to end this {@link Step} {@link #getSuccess() successfully}. May be called only once.
- */
- default void success() {
-
- success(null);
- }
-
- /**
- * Should be called to end this {@link Step} {@link #getSuccess() successfully}. May be called only once.
- *
- * @param message the explicit message to log as success.
- */
- default void success(String message) {
-
- success(message, (Object[]) null);
- }
-
- /**
- * Should be called to end this {@link Step} {@link #getSuccess() successfully}. May be called only once.
- *
- * @param message the explicit message to log as success.
- * @param args the optional arguments to fill as placeholder into the {@code message}.
- */
- void success(String message, Object... args);
-
- /**
- * Ensures this {@link Step} is properly ended. Has to be called from a finally block.
- */
- void end();
-
- /**
- * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message. May be
- * called only once.
- *
- * @param message the explicit message to log as error.
- */
- default void error(String message) {
-
- error(null, message);
- }
-
- /**
- * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
- * {@link Throwable exception}. May be called only once.
- *
- * @param message the explicit message to log as error.
- * @param args the optional arguments to fill as placeholder into the {@code message}.
- */
- default void error(String message, Object... args) {
-
- error(null, message, args);
- }
-
- /**
- * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
- * {@link Throwable exception}. May be called only once.
- *
- * @param error the catched {@link Throwable}.
- */
- default void error(Throwable error) {
-
- error(error, false);
- }
-
- /**
- * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
- * {@link Throwable exception}. May be called only once.
- *
- * @param error the catched {@link Throwable}.
- * @param suppress to suppress the error logging (if error will be rethrown and duplicated error messages shall be
- * avoided).
- */
- default void error(Throwable error, boolean suppress) {
-
- assert (error != null);
- error(error, suppress, null, (Object[]) null);
- }
-
- /**
- * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
- * {@link Throwable exception}. May be called only once.
- *
- * @param error the catched {@link Throwable}. May be {@code null} if only a {@code message} is provided.
- * @param message the explicit message to log as error.
- */
- default void error(Throwable error, String message) {
-
- error(error, message, (Object[]) null);
- }
-
- /**
- * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
- * {@link Throwable exception}. May be called only once.
- *
- * @param error the catched {@link Throwable}. May be {@code null} if only a {@code message} is provided.
- * @param message the explicit message to log as error.
- * @param args the optional arguments to fill as placeholder into the {@code message}.
- */
- default void error(Throwable error, String message, Object... args) {
-
- error(error, false, message, args);
- }
-
- /**
- * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
- * {@link Throwable exception}. May be called only once.
- *
- * @param error the catched {@link Throwable}. May be {@code null} if only a {@code message} is provided.
- * @param suppress to suppress the error logging (if error will be rethrown and duplicated error messages shall be
- * avoided).
- * @param message the explicit message to log as error.
- * @param args the optional arguments to fill as placeholder into the {@code message}.
- */
- void error(Throwable error, boolean suppress, String message, Object... args);
-
- /**
- * @return the parent {@link Step} or {@code null} if there is no parent.
- */
- Step getParent();
-
- /**
- * @param i the index of the requested parameter. Should be in the range from {@code 0} to
- * {@link #getParameterCount()}-1
.
- * @return the parameter at the given index {@code i} or {@code null} if no such parameter exists.
- */
- Object getParameter(int i);
-
- /**
- * @return the number of {@link #getParameter(int) parameters}.
- */
- int getParameterCount();
-
- /**
- * @param stepCode the {@link Runnable} to {@link Runnable#run() execute} for this {@link Step}.
- */
- default void run(Runnable stepCode) {
-
- try {
- stepCode.run();
- if (getSuccess() == null) {
- success();
- }
- } catch (RuntimeException | Error e) {
- error(e);
- throw e;
- } finally {
- end();
- }
- }
-
- /**
- * @param stepCode the {@link Callable} to {@link Callable#call() execute} for this {@link Step}.
- * @param type of the return value.
- * @return the value returned from {@link Callable#call()}.
- */
- default R call(Callable stepCode) {
-
- try {
- R result = stepCode.call();
- if (getSuccess() == null) {
- success();
- }
- return result;
- } catch (Throwable e) {
- error(e);
- if (e instanceof RuntimeException re) {
- throw re;
- } else if (e instanceof Error error) {
- throw error;
- } else {
- throw new IllegalStateException(e);
- }
- } finally {
- end();
- }
- }
-
+package com.devonfw.tools.ide.step;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Interface for a {@link Step} of the process. Allows to split larger processes into smaller steps that are traced and
+ * measured. At the end you can get a report with the hierarchy of all steps and their success/failure status, duration
+ * in absolute and relative numbers to gain transparency.
The typical use should follow this pattern:
+ *
+ *
+ * Step step = context.{@link com.devonfw.tools.ide.context.IdeContext#newStep(String) newStep}("My step description");
+ * try {
+ * // ... do something ...
+ * step.{@link #success(String) success}("Did something successfully.");
+ * } catch (Exception e) {
+ * step.{@link #error(Throwable, String)}(e, "Failed to do something.");
+ * } finally {
+ * step.{@link #end() end()};
+ * }
+ *
+ */
+public interface Step {
+
+ /** Empty object array for no parameters. */
+ Object[] NO_PARAMS = new Object[0];
+
+ /**
+ * @return the name of this {@link Step} as given to constructor.
+ */
+ String getName();
+
+ /**
+ * @return the duration of this {@link Step} from construction to {@link #success()} or {@link #end()}. Will be
+ * {@code 0} if not {@link #end() ended}.
+ */
+ long getDuration();
+
+ /**
+ * @return {@code Boolean#TRUE} if this {@link Step} has {@link #success() succeeded}, {@code Boolean#FALSE} if the
+ * {@link Step} has {@link #end() ended} without {@link #success() success} and {@code null} if the {@link Step} is
+ * still running.
+ */
+ Boolean getSuccess();
+
+ /**
+ * @return {@code true} if this step completed {@link #success() successfully}, {@code false} otherwise.
+ */
+ default boolean isSuccess() {
+
+ return Boolean.TRUE.equals(getSuccess());
+ }
+
+ /**
+ * @return {@code true} if this step {@link #end() ended} without {@link #success() success} e.g. with an
+ * {@link #error(String) error}, {@code false} otherwise.
+ */
+ default boolean isFailure() {
+
+ return Boolean.FALSE.equals(getSuccess());
+ }
+
+ /**
+ * @return {@code true} if this step is silent and not logged by default, {@code false} otherwise (default).
+ */
+ boolean isSilent();
+
+ /**
+ * Should be called to end this {@link Step} {@link #getSuccess() successfully}. May be called only once.
+ */
+ default void success() {
+
+ success(null);
+ }
+
+ /**
+ * Should be called to end this {@link Step} {@link #getSuccess() successfully}. May be called only once.
+ *
+ * @param message the explicit message to log as success.
+ */
+ default void success(String message) {
+
+ success(message, (Object[]) null);
+ }
+
+ /**
+ * Should be called to end this {@link Step} {@link #getSuccess() successfully}. May be called only once.
+ *
+ * @param message the explicit message to log as success.
+ * @param args the optional arguments to fill as placeholder into the {@code message}.
+ */
+ void success(String message, Object... args);
+
+ /**
+ * Ensures this {@link Step} is properly ended. Has to be called from a finally block.
+ */
+ void end();
+
+ /**
+ * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message. May be
+ * called only once.
+ *
+ * @param message the explicit message to log as error.
+ */
+ default void error(String message) {
+
+ error(null, message);
+ }
+
+ /**
+ * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
+ * {@link Throwable exception}. May be called only once.
+ *
+ * @param message the explicit message to log as error.
+ * @param args the optional arguments to fill as placeholder into the {@code message}.
+ */
+ default void error(String message, Object... args) {
+
+ error(null, message, args);
+ }
+
+ /**
+ * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
+ * {@link Throwable exception}. May be called only once.
+ *
+ * @param error the catched {@link Throwable}.
+ */
+ default void error(Throwable error) {
+
+ error(error, false);
+ }
+
+ /**
+ * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
+ * {@link Throwable exception}. May be called only once.
+ *
+ * @param error the catched {@link Throwable}.
+ * @param suppress to suppress the error logging (if error will be rethrown and duplicated error messages shall be
+ * avoided).
+ */
+ default void error(Throwable error, boolean suppress) {
+
+ assert (error != null);
+ error(error, suppress, null, (Object[]) null);
+ }
+
+ /**
+ * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
+ * {@link Throwable exception}. May be called only once.
+ *
+ * @param error the catched {@link Throwable}. May be {@code null} if only a {@code message} is provided.
+ * @param message the explicit message to log as error.
+ */
+ default void error(Throwable error, String message) {
+
+ error(error, message, (Object[]) null);
+ }
+
+ /**
+ * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
+ * {@link Throwable exception}. May be called only once.
+ *
+ * @param error the catched {@link Throwable}. May be {@code null} if only a {@code message} is provided.
+ * @param message the explicit message to log as error.
+ * @param args the optional arguments to fill as placeholder into the {@code message}.
+ */
+ default void error(Throwable error, String message, Object... args) {
+
+ error(error, false, message, args);
+ }
+
+ /**
+ * Should be called to end this {@link Step} as {@link #isFailure() failure} with an explicit error message and/or
+ * {@link Throwable exception}. May be called only once.
+ *
+ * @param error the catched {@link Throwable}. May be {@code null} if only a {@code message} is provided.
+ * @param suppress to suppress the error logging (if error will be rethrown and duplicated error messages shall be
+ * avoided).
+ * @param message the explicit message to log as error.
+ * @param args the optional arguments to fill as placeholder into the {@code message}.
+ */
+ void error(Throwable error, boolean suppress, String message, Object... args);
+
+ /**
+ * @return the parent {@link Step} or {@code null} if there is no parent.
+ */
+ Step getParent();
+
+ /**
+ * @param i the index of the requested parameter. Should be in the range from {@code 0} to
+ * {@link #getParameterCount()}-1
.
+ * @return the parameter at the given index {@code i} or {@code null} if no such parameter exists.
+ */
+ Object getParameter(int i);
+
+ /**
+ * @return the number of {@link #getParameter(int) parameters}.
+ */
+ int getParameterCount();
+
+ /**
+ * @param stepCode the {@link Runnable} to {@link Runnable#run() execute} for this {@link Step}.
+ */
+ default void run(Runnable stepCode) {
+
+ try {
+ stepCode.run();
+ if (getSuccess() == null) {
+ success();
+ }
+ } catch (RuntimeException | Error e) {
+ error(e);
+ throw e;
+ } finally {
+ end();
+ }
+ }
+
+ /**
+ * @param stepCode the {@link Callable} to {@link Callable#call() execute} for this {@link Step}.
+ * @param type of the return value.
+ * @return the value returned from {@link Callable#call()}.
+ */
+ default R call(Callable stepCode) {
+
+ try {
+ R result = stepCode.call();
+ if (getSuccess() == null) {
+ success();
+ }
+ return result;
+ } catch (Throwable e) {
+ error(e);
+ if (e instanceof RuntimeException re) {
+ throw re;
+ } else if (e instanceof Error error) {
+ throw error;
+ } else {
+ throw new IllegalStateException(e);
+ }
+ } finally {
+ end();
+ }
+ }
+
}
\ No newline at end of file
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 a8b8ad523..a0745faf8 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
@@ -1,295 +1,295 @@
-package com.devonfw.tools.ide.step;
-
-import com.devonfw.tools.ide.context.AbstractIdeContext;
-import com.devonfw.tools.ide.context.IdeContext;
-import com.devonfw.tools.ide.log.IdeSubLogger;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Regular implementation of {@link Step}.
- */
-public final class StepImpl implements Step {
-
- private final AbstractIdeContext context;
-
- private final StepImpl parent;
-
- private final String name;
-
- private final Object[] params;
-
- private final List children;
-
- private final long start;
-
- private final boolean silent;
-
- private Boolean success;
-
- private String errorMessage;
-
- private long duration;
-
- /**
- * Creates and starts a new {@link StepImpl}.
- *
- * @param context the {@link IdeContext}.
- * @param parent the {@link #getParent() parent step}.
- * @param name the {@link #getName() step name}.
- * @param silent the {@link #isSilent() silent flag}.
- * @param params the parameters. Should have reasonable {@link Object#toString() string representations}.
- */
- public StepImpl(AbstractIdeContext context, StepImpl parent, String name, boolean silent, Object... params) {
-
- super();
- this.context = context;
- this.parent = parent;
- this.name = name;
- this.params = params;
- this.silent = silent;
- this.children = new ArrayList<>();
- this.start = System.currentTimeMillis();
- if (parent != null) {
- parent.children.add(this);
- }
- if (params.length == 0) {
- this.context.trace("Starting step {}...", name);
- } else {
- this.context.trace("Starting step {} with params {}...", name, Arrays.toString(params));
- }
- if (!this.silent) {
- this.context.step("Start: {}", name);
- }
- }
-
- @Override
- public StepImpl getParent() {
-
- return this.parent;
- }
-
- @Override
- public String getName() {
-
- return this.name;
- }
-
- @Override
- public Object getParameter(int i) {
-
- if ((i < 0) || (i >= this.params.length)) {
- return null;
- }
- return this.params[i];
- }
-
- @Override
- public int getParameterCount() {
-
- return this.params.length;
- }
-
- @Override
- public boolean isSilent() {
-
- return this.silent;
- }
-
- @Override
- public long getDuration() {
-
- return this.duration;
- }
-
- @Override
- public Boolean getSuccess() {
-
- return this.success;
- }
-
- @Override
- public void success(String message, Object... args) {
-
- end(Boolean.TRUE, null, false, message, args);
- }
-
- @Override
- public void error(Throwable error, boolean suppress, String message, Object... args) {
-
- end(Boolean.FALSE, error, suppress, message, args);
- }
-
- @Override
- public void end() {
-
- end(null, null, false, null, null);
- }
-
- private void end(Boolean newSuccess, Throwable error, boolean suppress, String message, Object[] args) {
-
- boolean firstCallOfEnd = (this.success == null);
- if (!firstCallOfEnd) {
- assert (this.duration > 0);
- if (newSuccess != null) {
- this.context.warning("Step '{}' already ended with {} and now ended again with {}.", this.name, this.success,
- newSuccess);
- } else {
- return;
- }
- }
- long delay = System.currentTimeMillis() - this.start;
- if (delay == 0) {
- delay = 1;
- }
- if (newSuccess == null) {
- newSuccess = Boolean.FALSE;
- }
- if (this.success != Boolean.FALSE) { // never allow a failed step to change to success
- this.duration = delay;
- this.success = newSuccess;
- }
- if (newSuccess.booleanValue()) {
- assert (error == null);
- if (message != null) {
- this.context.success(message, args);
- } else if (!this.silent) {
- this.context.success(this.name);
- }
- this.context.debug("Step '{}' ended successfully.", this.name);
- } else {
- IdeSubLogger logger;
- if ((message != null) || (error != null)) {
- if (suppress) {
- if (error != null) {
- this.errorMessage = error.toString();
- } else {
- this.errorMessage = message;
- }
- } else {
- this.errorMessage = this.context.error().log(error, message, args);
- }
- logger = this.context.debug();
- } else {
- logger = this.context.info();
- }
- logger.log("Step '{}' ended with failure.", this.name);
- }
- if (firstCallOfEnd) {
- this.context.endStep(this);
- }
- }
-
- /**
- * Logs the summary of this {@link Step}. Should typically only be called on the top-level {@link Step}.
- *
- * @param suppressSuccess - {@code true} to suppress the success message, {@code false} otherwise.
- */
- public void logSummary(boolean suppressSuccess) {
-
- if (this.context.trace().isEnabled()) {
- this.context.trace(toString());
- }
- if (this.context.isQuietMode()) {
- return;
- }
- StepSummary summary = new StepSummary();
- logErrorSummary(0, summary);
- if (summary.getError() == 0) {
- if (!suppressSuccess) {
- this.context.success("Successfully completed {}", getNameWithParams());
- }
- } else {
- this.context.error(summary.toString());
- }
- }
-
- 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);
- }
- depth++;
- for (StepImpl child : this.children) {
- child.logErrorSummary(depth, summary);
- }
- }
-
- private String getNameWithParams() {
-
- if ((this.params == null) || (this.params.length == 0)) {
- return this.name;
- }
- StringBuilder sb = new StringBuilder(this.name.length() + 3 + this.params.length * 6);
- getNameWithParams(sb);
- return sb.toString();
- }
-
- private void getNameWithParams(StringBuilder sb) {
-
- sb.append(this.name);
- sb.append(" (");
- String seperator = "";
- if (this.params != null) {
- for (Object param : this.params) {
- sb.append(seperator);
- sb.append(param);
- seperator = ",";
- }
- }
- sb.append(')');
- }
-
- private void append(int depth, long totalDuration, long parentDuration, StringBuilder sb) {
-
- // indent
- sb.append(getIndent(depth));
- getNameWithParams(sb);
- sb.append(' ');
- if (this.success == null) {
- sb.append("is still running or was not properly ended due to programming error not using finally block ");
- } else {
- if (this.success.booleanValue()) {
- sb.append("succeeded after ");
- } else {
- sb.append("failed after ");
- }
- sb.append(Duration.ofMillis(this.duration));
- }
- if (this.duration < totalDuration) {
- sb.append(" ");
- double percentageBase = this.duration * 100;
- double totalPercentage = percentageBase / totalDuration;
- sb.append(totalPercentage);
- sb.append("% of total ");
- if (parentDuration < totalDuration) {
- double parentPercentage = percentageBase / parentDuration;
- sb.append(parentPercentage);
- sb.append("% of parent");
- }
- }
- sb.append('\n');
- int childDepth = depth + 1;
- for (StepImpl child : this.children) {
- child.append(childDepth, totalDuration, this.duration, sb);
- }
- }
-
- private String getIndent(int depth) {
-
- return " ".repeat(depth);
- }
-
- @Override
- public String toString() {
-
- StringBuilder sb = new StringBuilder(4096);
- append(0, this.duration, this.duration, sb);
- return sb.toString();
- }
-}
+package com.devonfw.tools.ide.step;
+
+import com.devonfw.tools.ide.context.AbstractIdeContext;
+import com.devonfw.tools.ide.context.IdeContext;
+import com.devonfw.tools.ide.log.IdeSubLogger;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Regular implementation of {@link Step}.
+ */
+public final class StepImpl implements Step {
+
+ private final AbstractIdeContext context;
+
+ private final StepImpl parent;
+
+ private final String name;
+
+ private final Object[] params;
+
+ private final List children;
+
+ private final long start;
+
+ private final boolean silent;
+
+ private Boolean success;
+
+ private String errorMessage;
+
+ private long duration;
+
+ /**
+ * Creates and starts a new {@link StepImpl}.
+ *
+ * @param context the {@link IdeContext}.
+ * @param parent the {@link #getParent() parent step}.
+ * @param name the {@link #getName() step name}.
+ * @param silent the {@link #isSilent() silent flag}.
+ * @param params the parameters. Should have reasonable {@link Object#toString() string representations}.
+ */
+ public StepImpl(AbstractIdeContext context, StepImpl parent, String name, boolean silent, Object... params) {
+
+ super();
+ this.context = context;
+ this.parent = parent;
+ this.name = name;
+ this.params = params;
+ this.silent = silent;
+ this.children = new ArrayList<>();
+ this.start = System.currentTimeMillis();
+ if (parent != null) {
+ parent.children.add(this);
+ }
+ if (params.length == 0) {
+ this.context.trace("Starting step {}...", name);
+ } else {
+ this.context.trace("Starting step {} with params {}...", name, Arrays.toString(params));
+ }
+ if (!this.silent) {
+ this.context.step("Start: {}", name);
+ }
+ }
+
+ @Override
+ public StepImpl getParent() {
+
+ return this.parent;
+ }
+
+ @Override
+ public String getName() {
+
+ return this.name;
+ }
+
+ @Override
+ public Object getParameter(int i) {
+
+ if ((i < 0) || (i >= this.params.length)) {
+ return null;
+ }
+ return this.params[i];
+ }
+
+ @Override
+ public int getParameterCount() {
+
+ return this.params.length;
+ }
+
+ @Override
+ public boolean isSilent() {
+
+ return this.silent;
+ }
+
+ @Override
+ public long getDuration() {
+
+ return this.duration;
+ }
+
+ @Override
+ public Boolean getSuccess() {
+
+ return this.success;
+ }
+
+ @Override
+ public void success(String message, Object... args) {
+
+ end(Boolean.TRUE, null, false, message, args);
+ }
+
+ @Override
+ public void error(Throwable error, boolean suppress, String message, Object... args) {
+
+ end(Boolean.FALSE, error, suppress, message, args);
+ }
+
+ @Override
+ public void end() {
+
+ end(null, null, false, null, null);
+ }
+
+ private void end(Boolean newSuccess, Throwable error, boolean suppress, String message, Object[] args) {
+
+ boolean firstCallOfEnd = (this.success == null);
+ if (!firstCallOfEnd) {
+ assert (this.duration > 0);
+ if (newSuccess != null) {
+ this.context.warning("Step '{}' already ended with {} and now ended again with {}.", this.name, this.success,
+ newSuccess);
+ } else {
+ return;
+ }
+ }
+ long delay = System.currentTimeMillis() - this.start;
+ if (delay == 0) {
+ delay = 1;
+ }
+ if (newSuccess == null) {
+ newSuccess = Boolean.FALSE;
+ }
+ if (this.success != Boolean.FALSE) { // never allow a failed step to change to success
+ this.duration = delay;
+ this.success = newSuccess;
+ }
+ if (newSuccess.booleanValue()) {
+ assert (error == null);
+ if (message != null) {
+ this.context.success(message, args);
+ } else if (!this.silent) {
+ this.context.success(this.name);
+ }
+ this.context.debug("Step '{}' ended successfully.", this.name);
+ } else {
+ IdeSubLogger logger;
+ if ((message != null) || (error != null)) {
+ if (suppress) {
+ if (error != null) {
+ this.errorMessage = error.toString();
+ } else {
+ this.errorMessage = message;
+ }
+ } else {
+ this.errorMessage = this.context.error().log(error, message, args);
+ }
+ logger = this.context.debug();
+ } else {
+ logger = this.context.info();
+ }
+ logger.log("Step '{}' ended with failure.", this.name);
+ }
+ if (firstCallOfEnd) {
+ this.context.endStep(this);
+ }
+ }
+
+ /**
+ * Logs the summary of this {@link Step}. Should typically only be called on the top-level {@link Step}.
+ *
+ * @param suppressSuccess - {@code true} to suppress the success message, {@code false} otherwise.
+ */
+ public void logSummary(boolean suppressSuccess) {
+
+ if (this.context.trace().isEnabled()) {
+ this.context.trace(toString());
+ }
+ if (this.context.isQuietMode()) {
+ return;
+ }
+ StepSummary summary = new StepSummary();
+ logErrorSummary(0, summary);
+ if (summary.getError() == 0) {
+ if (!suppressSuccess) {
+ this.context.success("Successfully completed {}", getNameWithParams());
+ }
+ } else {
+ this.context.error(summary.toString());
+ }
+ }
+
+ 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);
+ }
+ depth++;
+ for (StepImpl child : this.children) {
+ child.logErrorSummary(depth, summary);
+ }
+ }
+
+ private String getNameWithParams() {
+
+ if ((this.params == null) || (this.params.length == 0)) {
+ return this.name;
+ }
+ StringBuilder sb = new StringBuilder(this.name.length() + 3 + this.params.length * 6);
+ getNameWithParams(sb);
+ return sb.toString();
+ }
+
+ private void getNameWithParams(StringBuilder sb) {
+
+ sb.append(this.name);
+ sb.append(" (");
+ String seperator = "";
+ if (this.params != null) {
+ for (Object param : this.params) {
+ sb.append(seperator);
+ sb.append(param);
+ seperator = ",";
+ }
+ }
+ sb.append(')');
+ }
+
+ private void append(int depth, long totalDuration, long parentDuration, StringBuilder sb) {
+
+ // indent
+ sb.append(getIndent(depth));
+ getNameWithParams(sb);
+ sb.append(' ');
+ if (this.success == null) {
+ sb.append("is still running or was not properly ended due to programming error not using finally block ");
+ } else {
+ if (this.success.booleanValue()) {
+ sb.append("succeeded after ");
+ } else {
+ sb.append("failed after ");
+ }
+ sb.append(Duration.ofMillis(this.duration));
+ }
+ if (this.duration < totalDuration) {
+ sb.append(" ");
+ double percentageBase = this.duration * 100;
+ double totalPercentage = percentageBase / totalDuration;
+ sb.append(totalPercentage);
+ sb.append("% of total ");
+ if (parentDuration < totalDuration) {
+ double parentPercentage = percentageBase / parentDuration;
+ sb.append(parentPercentage);
+ sb.append("% of parent");
+ }
+ }
+ sb.append('\n');
+ int childDepth = depth + 1;
+ for (StepImpl child : this.children) {
+ child.append(childDepth, totalDuration, this.duration, sb);
+ }
+ }
+
+ private String getIndent(int depth) {
+
+ return " ".repeat(depth);
+ }
+
+ @Override
+ public String toString() {
+
+ StringBuilder sb = new StringBuilder(4096);
+ append(0, this.duration, this.duration, sb);
+ return sb.toString();
+ }
+}
diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/PackageManagerCommand.java b/cli/src/main/java/com/devonfw/tools/ide/tool/PackageManagerCommand.java
index d39516ac9..6c687e969 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/tool/PackageManagerCommand.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/tool/PackageManagerCommand.java
@@ -1,26 +1,26 @@
-package com.devonfw.tools.ide.tool;
-
-import java.util.List;
-
-/**
- * Represents a command to be executed by a package manager. Each command consists of a {@link PackageManager} and a
- * list of commands to be executed by that package manager.
- *
- * @param packageManager The package manager associated with this command.
- * @param commands The list of commands to be executed by the package manager.
- */
-public record PackageManagerCommand(PackageManager packageManager, List commands) {
-
- /**
- * Constructs a {@code PackageManagerCommand} based on the provided command string. The package manager is retrieved
- * from the command string using {@link PackageManager#extractPackageManager(String)}.
- *
- * @param command The command string.
- * @return A {@code PackageManagerCommand} based on the provided command string.
- */
- public static PackageManagerCommand of(String command) {
-
- PackageManager pm = PackageManager.extractPackageManager(command);
- return new PackageManagerCommand(pm, List.of(command));
- }
-}
+package com.devonfw.tools.ide.tool;
+
+import java.util.List;
+
+/**
+ * Represents a command to be executed by a package manager. Each command consists of a {@link PackageManager} and a
+ * list of commands to be executed by that package manager.
+ *
+ * @param packageManager The package manager associated with this command.
+ * @param commands The list of commands to be executed by the package manager.
+ */
+public record PackageManagerCommand(PackageManager packageManager, List commands) {
+
+ /**
+ * Constructs a {@code PackageManagerCommand} based on the provided command string. The package manager is retrieved
+ * from the command string using {@link PackageManager#extractPackageManager(String)}.
+ *
+ * @param command The command string.
+ * @return A {@code PackageManagerCommand} based on the provided command string.
+ */
+ public static PackageManagerCommand of(String command) {
+
+ PackageManager pm = PackageManager.extractPackageManager(command);
+ return new PackageManagerCommand(pm, List.of(command));
+ }
+}
diff --git a/cli/src/main/java/com/devonfw/tools/ide/variable/IdeVariables.java b/cli/src/main/java/com/devonfw/tools/ide/variable/IdeVariables.java
index 9e6259a82..6c01c1ad1 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/variable/IdeVariables.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/variable/IdeVariables.java
@@ -1,75 +1,75 @@
-package com.devonfw.tools.ide.variable;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Interface (mis)used to define all the available variables.
- */
-public interface IdeVariables {
-
- /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getIdeHome() IDE_HOME}. */
- VariableDefinitionPath IDE_HOME = new VariableDefinitionPath("IDE_HOME", "DEVON_IDE_HOME", c -> c.getIdeHome(), true);
-
- /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getIdeRoot() IDE_ROOT}. */
- VariableDefinitionPath IDE_ROOT = new VariableDefinitionPath("IDE_ROOT", null, c -> c.getIdeRoot());
-
- /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getUserHome() HOME}. */
- VariableDefinitionPath HOME = new VariableDefinitionPath("HOME", null, c -> c.getUserHome(), true);
-
- /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspaceName() WORKSPACE}. */
- VariableDefinitionString WORKSPACE = new VariableDefinitionString("WORKSPACE", null, c -> c.getWorkspaceName(), true);
-
- /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getPath() PATH}. */
- VariableDefinitionSystemPath PATH = new VariableDefinitionSystemPath("PATH", null, c -> c.getPath(), true, true);
-
- /**
- * {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspacePath() WORKSPACE_PATH}.
- */
- VariableDefinitionPath WORKSPACE_PATH = new VariableDefinitionPath("WORKSPACE_PATH", null, c -> c.getWorkspacePath(), true);
-
- /** {@link VariableDefinition} for list of tools to install by default. */
- VariableDefinitionStringList IDE_TOOLS = new VariableDefinitionStringList("IDE_TOOLS", "DEVON_IDE_TOOLS", c -> List.of("mvn", "npm"));
-
- /** {@link VariableDefinition} for list of IDE tools to create start scripts for. */
- VariableDefinitionStringList CREATE_START_SCRIPTS = new VariableDefinitionStringList("CREATE_START_SCRIPTS", "DEVON_CREATE_START_SCRIPTS");
-
- /** {@link VariableDefinition} for minimum IDE product version. */
- // TODO define initial IDEasy version as default value
- VariableDefinitionVersion IDE_MIN_VERSION = new VariableDefinitionVersion("IDE_MIN_VERSION", "DEVON_IDE_MIN_VERSION");
-
- /** {@link VariableDefinition} for version of maven (mvn). */
- VariableDefinitionVersion MVN_VERSION = new VariableDefinitionVersion("MVN_VERSION", "MAVEN_VERSION");
-
- /** {@link VariableDefinition} arguments for maven to set the m2 repo location. */
- VariableDefinitionString MAVEN_ARGS = new VariableDefinitionString("MAVEN_ARGS", null, c -> c.getMavenArgs(), false, true);
-
- /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspaceName() WORKSPACE}. */
- VariableDefinitionString DOCKER_EDITION = new VariableDefinitionString("DOCKER_EDITION", null, c -> "rancher");
-
- /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspaceName() WORKSPACE}. */
- VariableDefinitionString GRAALVM_EDITION = new VariableDefinitionString("GRAALVM_EDITION", null, c -> "community");
-
- /** {@link VariableDefinition} for options of jasypt */
- VariableDefinitionString JASYPT_OPTS = new VariableDefinitionString("JASYPT_OPTS", null,
- c -> "algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator");
-
- /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getProjectName() PROJECT_NAME}. */
- VariableDefinitionString PROJECT_NAME = new VariableDefinitionString("PROJECT_NAME", null, c -> c.getProjectName());
-
- /** A {@link Collection} with all pre-defined {@link VariableDefinition}s. */
- Collection> VARIABLES = List.of(PATH, HOME, WORKSPACE_PATH, IDE_HOME, IDE_ROOT, WORKSPACE, IDE_TOOLS, CREATE_START_SCRIPTS,
- IDE_MIN_VERSION, MVN_VERSION, DOCKER_EDITION, GRAALVM_EDITION, JASYPT_OPTS, MAVEN_ARGS, PROJECT_NAME);
-
- /**
- * @param name the name of the requested {@link VariableDefinition}.
- * @return the {@link VariableDefinition} for the given {@code name} or {@code null} if not defined.
- * @see VariableDefinition#getName()
- * @see VariableDefinition#getLegacyName()
- */
- static VariableDefinition> get(String name) {
-
- return IdeVariablesList.get(name);
- }
-
-}
+package com.devonfw.tools.ide.variable;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Interface (mis)used to define all the available variables.
+ */
+public interface IdeVariables {
+
+ /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getIdeHome() IDE_HOME}. */
+ VariableDefinitionPath IDE_HOME = new VariableDefinitionPath("IDE_HOME", "DEVON_IDE_HOME", c -> c.getIdeHome(), true);
+
+ /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getIdeRoot() IDE_ROOT}. */
+ VariableDefinitionPath IDE_ROOT = new VariableDefinitionPath("IDE_ROOT", null, c -> c.getIdeRoot());
+
+ /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getUserHome() HOME}. */
+ VariableDefinitionPath HOME = new VariableDefinitionPath("HOME", null, c -> c.getUserHome(), true);
+
+ /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspaceName() WORKSPACE}. */
+ VariableDefinitionString WORKSPACE = new VariableDefinitionString("WORKSPACE", null, c -> c.getWorkspaceName(), true);
+
+ /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getPath() PATH}. */
+ VariableDefinitionSystemPath PATH = new VariableDefinitionSystemPath("PATH", null, c -> c.getPath(), true, true);
+
+ /**
+ * {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspacePath() WORKSPACE_PATH}.
+ */
+ VariableDefinitionPath WORKSPACE_PATH = new VariableDefinitionPath("WORKSPACE_PATH", null, c -> c.getWorkspacePath(), true);
+
+ /** {@link VariableDefinition} for list of tools to install by default. */
+ VariableDefinitionStringList IDE_TOOLS = new VariableDefinitionStringList("IDE_TOOLS", "DEVON_IDE_TOOLS", c -> List.of("mvn", "npm"));
+
+ /** {@link VariableDefinition} for list of IDE tools to create start scripts for. */
+ VariableDefinitionStringList CREATE_START_SCRIPTS = new VariableDefinitionStringList("CREATE_START_SCRIPTS", "DEVON_CREATE_START_SCRIPTS");
+
+ /** {@link VariableDefinition} for minimum IDE product version. */
+ // TODO define initial IDEasy version as default value
+ VariableDefinitionVersion IDE_MIN_VERSION = new VariableDefinitionVersion("IDE_MIN_VERSION", "DEVON_IDE_MIN_VERSION");
+
+ /** {@link VariableDefinition} for version of maven (mvn). */
+ VariableDefinitionVersion MVN_VERSION = new VariableDefinitionVersion("MVN_VERSION", "MAVEN_VERSION");
+
+ /** {@link VariableDefinition} arguments for maven to set the m2 repo location. */
+ VariableDefinitionString MAVEN_ARGS = new VariableDefinitionString("MAVEN_ARGS", null, c -> c.getMavenArgs(), false, true);
+
+ /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspaceName() WORKSPACE}. */
+ VariableDefinitionString DOCKER_EDITION = new VariableDefinitionString("DOCKER_EDITION", null, c -> "rancher");
+
+ /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspaceName() WORKSPACE}. */
+ VariableDefinitionString GRAALVM_EDITION = new VariableDefinitionString("GRAALVM_EDITION", null, c -> "community");
+
+ /** {@link VariableDefinition} for options of jasypt */
+ VariableDefinitionString JASYPT_OPTS = new VariableDefinitionString("JASYPT_OPTS", null,
+ c -> "algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator");
+
+ /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getProjectName() PROJECT_NAME}. */
+ VariableDefinitionString PROJECT_NAME = new VariableDefinitionString("PROJECT_NAME", null, c -> c.getProjectName());
+
+ /** A {@link Collection} with all pre-defined {@link VariableDefinition}s. */
+ Collection> VARIABLES = List.of(PATH, HOME, WORKSPACE_PATH, IDE_HOME, IDE_ROOT, WORKSPACE, IDE_TOOLS, CREATE_START_SCRIPTS,
+ IDE_MIN_VERSION, MVN_VERSION, DOCKER_EDITION, GRAALVM_EDITION, JASYPT_OPTS, MAVEN_ARGS, PROJECT_NAME);
+
+ /**
+ * @param name the name of the requested {@link VariableDefinition}.
+ * @return the {@link VariableDefinition} for the given {@code name} or {@code null} if not defined.
+ * @see VariableDefinition#getName()
+ * @see VariableDefinition#getLegacyName()
+ */
+ static VariableDefinition> get(String name) {
+
+ return IdeVariablesList.get(name);
+ }
+
+}
diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeSlf4jLogger.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeSlf4jLogger.java
index 102d40a8e..efd06b047 100644
--- a/cli/src/test/java/com/devonfw/tools/ide/log/IdeSlf4jLogger.java
+++ b/cli/src/test/java/com/devonfw/tools/ide/log/IdeSlf4jLogger.java
@@ -1,77 +1,77 @@
-package com.devonfw.tools.ide.log;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.event.Level;
-import org.slf4j.spi.LoggingEventBuilder;
-
-/**
- * Implementation of {@link IdeSubLogger} for testing that delegates to slf4j.
- */
-public class IdeSlf4jLogger extends AbstractIdeSubLogger {
-
- private static final Logger LOG = LoggerFactory.getLogger(IdeSlf4jLogger.class);
-
- private final Level logLevel;
-
- /**
- * The constructor.
- *
- * @param level the {@link #getLevel() log-level}.
- */
- public IdeSlf4jLogger(IdeLogLevel level) {
-
- super(level);
- this.logLevel = switch (level) {
- case TRACE -> Level.TRACE;
- case DEBUG -> Level.DEBUG;
- case INFO, STEP, INTERACTION, SUCCESS -> Level.INFO;
- case WARNING -> Level.WARN;
- case ERROR -> Level.ERROR;
- default -> throw new IllegalArgumentException("" + level);
- };
- }
-
- @Override
- public String log(Throwable error, String message, Object... args) {
-
- if ((message == null) && (error != null)) {
- message = error.getMessage();
- if (message == null) {
- message = error.toString();
- }
- }
- String msg = message;
- if ((this.level == IdeLogLevel.STEP) || (this.level == IdeLogLevel.INTERACTION)
- || (this.level == IdeLogLevel.SUCCESS)) {
- msg = this.level.name() + ":" + message;
- }
- LoggingEventBuilder builder = LOG.atLevel(this.logLevel);
- if (error != null) {
- builder.setCause(error);
- }
- if (args == null) {
- builder.log(msg);
- } else {
- builder.log(msg, args);
- }
- if (message == null) {
- if (error == null) {
- return null;
- } else {
- return error.toString();
- }
- } else if (args == null) {
- return message;
- } else {
- return compose(message, args);
- }
- }
-
- @Override
- public boolean isEnabled() {
-
- return LOG.isEnabledForLevel(this.logLevel);
- }
-
-}
+package com.devonfw.tools.ide.log;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.event.Level;
+import org.slf4j.spi.LoggingEventBuilder;
+
+/**
+ * Implementation of {@link IdeSubLogger} for testing that delegates to slf4j.
+ */
+public class IdeSlf4jLogger extends AbstractIdeSubLogger {
+
+ private static final Logger LOG = LoggerFactory.getLogger(IdeSlf4jLogger.class);
+
+ private final Level logLevel;
+
+ /**
+ * The constructor.
+ *
+ * @param level the {@link #getLevel() log-level}.
+ */
+ public IdeSlf4jLogger(IdeLogLevel level) {
+
+ super(level);
+ this.logLevel = switch (level) {
+ case TRACE -> Level.TRACE;
+ case DEBUG -> Level.DEBUG;
+ case INFO, STEP, INTERACTION, SUCCESS -> Level.INFO;
+ case WARNING -> Level.WARN;
+ case ERROR -> Level.ERROR;
+ default -> throw new IllegalArgumentException("" + level);
+ };
+ }
+
+ @Override
+ public String log(Throwable error, String message, Object... args) {
+
+ if ((message == null) && (error != null)) {
+ message = error.getMessage();
+ if (message == null) {
+ message = error.toString();
+ }
+ }
+ String msg = message;
+ if ((this.level == IdeLogLevel.STEP) || (this.level == IdeLogLevel.INTERACTION)
+ || (this.level == IdeLogLevel.SUCCESS)) {
+ msg = this.level.name() + ":" + message;
+ }
+ LoggingEventBuilder builder = LOG.atLevel(this.logLevel);
+ if (error != null) {
+ builder.setCause(error);
+ }
+ if (args == null) {
+ builder.log(msg);
+ } else {
+ builder.log(msg, args);
+ }
+ if (message == null) {
+ if (error == null) {
+ return null;
+ } else {
+ return error.toString();
+ }
+ } else if (args == null) {
+ return message;
+ } else {
+ return compose(message, args);
+ }
+ }
+
+ @Override
+ public boolean isEnabled() {
+
+ return LOG.isEnabledForLevel(this.logLevel);
+ }
+
+}
diff --git a/cli/src/test/java/com/devonfw/tools/ide/step/StepTest.java b/cli/src/test/java/com/devonfw/tools/ide/step/StepTest.java
index 132cc869f..8477a9683 100644
--- a/cli/src/test/java/com/devonfw/tools/ide/step/StepTest.java
+++ b/cli/src/test/java/com/devonfw/tools/ide/step/StepTest.java
@@ -1,133 +1,133 @@
-package com.devonfw.tools.ide.step;
-
-import com.devonfw.tools.ide.context.AbstractIdeContextTest;
-import com.devonfw.tools.ide.context.IdeTestContext;
-import com.devonfw.tools.ide.log.IdeLogLevel;
-import org.junit.jupiter.api.Test;
-
-/**
- * Test of {@link Step}.
- */
-public class StepTest extends AbstractIdeContextTest {
-
- @Test
- public void testValidUsageSuccess() {
-
- // arrage
- IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
- // act
- Step step = context.newStep("Test-Step");
- try {
- step.success("The Test-Step succeeded as expected");
- } finally {
- step.end();
- }
- // assert
- assertThat(step.getSuccess()).isTrue();
- assertThat(step.getDuration()).isPositive();
- assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step...");
- assertLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
- assertLogMessage(context, IdeLogLevel.SUCCESS, "The Test-Step succeeded as expected");
- assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended successfully.");
- }
-
- @Test
- public void testValidUsageSuccessSilent() {
-
- // arrage
- IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
- // act
- Step step = context.newStep(true, "Test-Step", "arg1", "arg2");
- try {
- step.success();
- } finally {
- step.end();
- }
- // assert
- assertThat(step.getSuccess()).isTrue();
- assertThat(step.getDuration()).isPositive();
- assertThat(step.getParameterCount()).isEqualTo(2);
- assertThat(step.getParameter(0)).isEqualTo("arg1");
- assertThat(step.getParameter(1)).isEqualTo("arg2");
- assertThat(step.getParameter(2)).isNull();
- assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step with params [arg1, arg2]...");
- assertNoLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
- assertNoLogMessage(context, IdeLogLevel.SUCCESS, "Test-Step", true);
- assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended successfully.");
- }
-
- @Test
- public void testValidUsageError() {
-
- // arrage
- IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
- // act
- Step step = context.newStep("Test-Step");
- try {
- step.error("The Test-Step failed as expected");
- } finally {
- step.end();
- }
- assertThat(step.getSuccess()).isFalse();
- assertThat(step.getDuration()).isPositive();
- // assert
- assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step...");
- assertLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
- assertLogMessage(context, IdeLogLevel.ERROR, "The Test-Step failed as expected");
- assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended with failure.");
- }
-
- @Test
- public void testInvalidUsageSuccessError() {
-
- // arrage
- IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
- // act
- Step step = context.newStep("Test-Step");
- try {
- step.success("The Test-Step succeeded as expected");
- throw new IllegalStateException("unexpected situation!");
- } catch (IllegalStateException e) {
- step.error(e);
- } finally {
- step.end();
- }
- assertThat(step.getSuccess()).isFalse();
- assertThat(step.getDuration()).isPositive();
- // assert
- assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step...");
- assertLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
- assertLogMessage(context, IdeLogLevel.WARNING,
- "Step 'Test-Step' already ended with true and now ended again with false.");
- assertLogMessage(context, IdeLogLevel.ERROR, "unexpected situation!");
- assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended with failure.");
- }
-
- @Test
- public void testInvalidUsageErrorSuccess() {
-
- // arrage
- IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
- // act
- Step step = context.newStep("Test-Step");
- try {
- step.error("The Test-Step failed as expected");
- // WOW this is really inconsistent and hopefully never happens elsewhere
- step.success("The Test-Step succeeded as expected");
- } finally {
- step.end();
- }
- assertThat(step.getSuccess()).isFalse();
- assertThat(step.getDuration()).isPositive();
- // assert
- assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step...");
- assertLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
- assertLogMessage(context, IdeLogLevel.ERROR, "The Test-Step failed as expected");
- assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended with failure.");
- assertLogMessage(context, IdeLogLevel.WARNING,
- "Step 'Test-Step' already ended with false and now ended again with true.");
- assertLogMessage(context, IdeLogLevel.SUCCESS, "The Test-Step succeeded as expected");
- assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended successfully.");
- }
-
-}
+package com.devonfw.tools.ide.step;
+
+import com.devonfw.tools.ide.context.AbstractIdeContextTest;
+import com.devonfw.tools.ide.context.IdeTestContext;
+import com.devonfw.tools.ide.log.IdeLogLevel;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test of {@link Step}.
+ */
+public class StepTest extends AbstractIdeContextTest {
+
+ @Test
+ public void testValidUsageSuccess() {
+
+ // arrage
+ IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
+ // act
+ Step step = context.newStep("Test-Step");
+ try {
+ step.success("The Test-Step succeeded as expected");
+ } finally {
+ step.end();
+ }
+ // assert
+ assertThat(step.getSuccess()).isTrue();
+ assertThat(step.getDuration()).isPositive();
+ assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step...");
+ assertLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
+ assertLogMessage(context, IdeLogLevel.SUCCESS, "The Test-Step succeeded as expected");
+ assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended successfully.");
+ }
+
+ @Test
+ public void testValidUsageSuccessSilent() {
+
+ // arrage
+ IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
+ // act
+ Step step = context.newStep(true, "Test-Step", "arg1", "arg2");
+ try {
+ step.success();
+ } finally {
+ step.end();
+ }
+ // assert
+ assertThat(step.getSuccess()).isTrue();
+ assertThat(step.getDuration()).isPositive();
+ assertThat(step.getParameterCount()).isEqualTo(2);
+ assertThat(step.getParameter(0)).isEqualTo("arg1");
+ assertThat(step.getParameter(1)).isEqualTo("arg2");
+ assertThat(step.getParameter(2)).isNull();
+ assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step with params [arg1, arg2]...");
+ assertNoLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
+ assertNoLogMessage(context, IdeLogLevel.SUCCESS, "Test-Step", true);
+ assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended successfully.");
+ }
+
+ @Test
+ public void testValidUsageError() {
+
+ // arrage
+ IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
+ // act
+ Step step = context.newStep("Test-Step");
+ try {
+ step.error("The Test-Step failed as expected");
+ } finally {
+ step.end();
+ }
+ assertThat(step.getSuccess()).isFalse();
+ assertThat(step.getDuration()).isPositive();
+ // assert
+ assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step...");
+ assertLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
+ assertLogMessage(context, IdeLogLevel.ERROR, "The Test-Step failed as expected");
+ assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended with failure.");
+ }
+
+ @Test
+ public void testInvalidUsageSuccessError() {
+
+ // arrage
+ IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
+ // act
+ Step step = context.newStep("Test-Step");
+ try {
+ step.success("The Test-Step succeeded as expected");
+ throw new IllegalStateException("unexpected situation!");
+ } catch (IllegalStateException e) {
+ step.error(e);
+ } finally {
+ step.end();
+ }
+ assertThat(step.getSuccess()).isFalse();
+ assertThat(step.getDuration()).isPositive();
+ // assert
+ assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step...");
+ assertLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
+ assertLogMessage(context, IdeLogLevel.WARNING,
+ "Step 'Test-Step' already ended with true and now ended again with false.");
+ assertLogMessage(context, IdeLogLevel.ERROR, "unexpected situation!");
+ assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended with failure.");
+ }
+
+ @Test
+ public void testInvalidUsageErrorSuccess() {
+
+ // arrage
+ IdeTestContext context = newContext(PROJECT_BASIC, "project", false);
+ // act
+ Step step = context.newStep("Test-Step");
+ try {
+ step.error("The Test-Step failed as expected");
+ // WOW this is really inconsistent and hopefully never happens elsewhere
+ step.success("The Test-Step succeeded as expected");
+ } finally {
+ step.end();
+ }
+ assertThat(step.getSuccess()).isFalse();
+ assertThat(step.getDuration()).isPositive();
+ // assert
+ assertLogMessage(context, IdeLogLevel.TRACE, "Starting step Test-Step...");
+ assertLogMessage(context, IdeLogLevel.STEP, "Start: Test-Step");
+ assertLogMessage(context, IdeLogLevel.ERROR, "The Test-Step failed as expected");
+ assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended with failure.");
+ assertLogMessage(context, IdeLogLevel.WARNING,
+ "Step 'Test-Step' already ended with false and now ended again with true.");
+ assertLogMessage(context, IdeLogLevel.SUCCESS, "The Test-Step succeeded as expected");
+ assertLogMessage(context, IdeLogLevel.DEBUG, "Step 'Test-Step' ended successfully.");
+ }
+
+}
diff --git a/documentation/symlink.adoc b/documentation/symlink.adoc
index 738c14c9f..3c1d11886 100644
--- a/documentation/symlink.adoc
+++ b/documentation/symlink.adoc
@@ -1,22 +1,22 @@
-:toc:
-toc::[]
-
-= Symlink
-
-The creation of real symbolic links on Windows, requires the user to have according permissions.
-In order to grant these permissions to yourself, run `secpol.msc` (`Local Security Policy`) and select `Local Policies/User Rights Assignment`
-
-1. Right click `Create Symbolic Link`, to open `Properties` and `Add User or Group`
-+
-image::images/LocalSecurityPolicy.png[LocalSecurityPolicy]
-+
-2. Add your own user account.
-To do so you might need to be connected to a VPN depending on the company settings.
-
-[cols="3,1a,1a,3", frame=none, grid=none]
-|===
-|
-| image::images/LSPPoperty.png[]
-| image::images/LSPAddUser.png[]
-|
-|===
+:toc:
+toc::[]
+
+= Symlink
+
+The creation of real symbolic links on Windows, requires the user to have according permissions.
+In order to grant these permissions to yourself, run `secpol.msc` (`Local Security Policy`) and select `Local Policies/User Rights Assignment`
+
+1. Right click `Create Symbolic Link`, to open `Properties` and `Add User or Group`
++
+image::images/LocalSecurityPolicy.png[LocalSecurityPolicy]
++
+2. Add your own user account.
+To do so you might need to be connected to a VPN depending on the company settings.
+
+[cols="3,1a,1a,3", frame=none, grid=none]
+|===
+|
+| image::images/LSPPoperty.png[]
+| image::images/LSPAddUser.png[]
+|
+|===