From 7af9fc54262d16b5d22b6bd557e8841a4f04720e Mon Sep 17 00:00:00 2001 From: Kian Date: Wed, 2 Oct 2024 14:49:32 +0200 Subject: [PATCH 01/51] #765: Fix typos in DoD asciidoc --- documentation/DoD.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/DoD.adoc b/documentation/DoD.adoc index 4a29de5159..69dce4b52a 100644 --- a/documentation/DoD.adoc +++ b/documentation/DoD.adoc @@ -21,11 +21,11 @@ Otherwise if a check failed (red cross) you need to click the `Details` link, re ** [ ] The build and all automated tests succeeded. If failed and you clicked on `Details` add read the logs to find the error. ** [ ] The contributors license agreement (CLA) is signed by all contributors of the PR. -** [ ] Git-Gardian did not report any security issue +** [ ] Git-Guardian did not report any security issue * [ ] The feature branch of the PR is up-to-date with the `main` branch. If you see `This branch is out-of-date with the base branch` in the PR click the `Update branch` button to fix (or manually merge with the `main` from upstream locally and push your changes). In case you see `This branch has conflicts that must be resolved` instead, you need to resolve conflicts. -Very simple conficts may be resolved in the browser on github. +Very simple conflicts may be resolved in the browser on github. But as a general recommendation you should resolve the conflicts locally with proper merge tool support and rerun tests before you push the merged changes. * [ ] You followed all link:coding-conventions.adoc[coding conventions] * [ ] You have already added the issue implemented by your PR in https://github.com/devonfw/ide/blob/master/CHANGELOG.adoc[CHANGELOG.adoc] to the next open release (see milestones or https://github.com/devonfw/IDEasy/blob/main/.mvn/maven.config[maven.config]). @@ -41,11 +41,11 @@ There are very few tools as exception to this rule like `Docker` that extend `Gl ** [ ] The tool can be configured locally inside `$IDE_HOME/conf` and not from a global location (e.g. in `$HOME`). Note: If a tool reads configuration files from the users home directory this is not given as two IDEasy projects using the same tool then would read the same config so one installation would influence the other. ** [ ] The help page displays information about the commandlet and its properties (CLI parameters) explaining how to use it properly. -There are no warnings logged in the help output (like `Cound not find key 'cmd-gcviewer' in ResourceBundle nls.Ide.properties`). +There are no warnings logged in the help output (like `Could not find key 'cmd-gcviewer' in ResourceBundle nls.Ide.properties`). Therefore add proper help texts for all supported languages https://github.com/devonfw/IDEasy/tree/main/cli/src/main/resources/nls[here]. -** [ ] The new tool is added to the table of tools in https://github.com/devonfw/ide/blob/master/documentation/LICENSE.asciidoc#license[LICENSE.asciidoc] with its according licesne. +** [ ] The new tool is added to the table of tools in https://github.com/devonfw/ide/blob/master/documentation/LICENSE.asciidoc#license[LICENSE.asciidoc] with its according license. If that license is not yet included, the full license text needs to be added. ** [ ] The new commandlet installs potential dependencies automatically (e.g. `getCommandlet(«DependentTool».class).install()` in overridden `install` method). ** [ ] The variables `«TOOL»_VERSION` and `«TOOL»_EDITION` are honored by your commandlet so if present that edition and version will be downloaded and installed (happens by default but important if you implement custom installation logic). -** [ ] The new commandlet is tested on all plattforms it is availible for. +** [ ] The new commandlet is tested on all platforms it is available for. Assuming you are using Windows, testing for Linux can be done with WSL or Virtual Box and for MacOS we have a virtual cloud instance. From 8921a0c880280156c27c88e5e3732c086d62e677 Mon Sep 17 00:00:00 2001 From: KianRolf Date: Mon, 11 Nov 2024 13:46:51 +0100 Subject: [PATCH 02/51] Testprovider --- .../java/com/devonfw/tools/ide/serviceprovider/TestLogger.java | 2 ++ .../devonfw/tools/ide/serviceprovider/TestLoggerFactory.java | 2 ++ .../com/devonfw/tools/ide/serviceprovider/TestProvider.java | 2 ++ .../META-INF/services/org.slf4j.spi.SLF4JServiceProvider | 0 4 files changed, 6 insertions(+) create mode 100644 cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java create mode 100644 cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java new file mode 100644 index 0000000000..37e438ddc3 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java @@ -0,0 +1,2 @@ +package com.devonfw.tools.ide.serviceprovider;public class TestLogger { +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java new file mode 100644 index 0000000000..bd4899bfd7 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java @@ -0,0 +1,2 @@ +package com.devonfw.tools.ide.serviceprovider;public class TestLoggerFactory { +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java new file mode 100644 index 0000000000..5b6dbec7b8 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java @@ -0,0 +1,2 @@ +package com.devonfw.tools.ide.serviceprovider;public class TestProvider { +} diff --git a/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider new file mode 100644 index 0000000000..e69de29bb2 From 6a139b3529d4b81a6512f6651b86867cd5debfbc Mon Sep 17 00:00:00 2001 From: KianRolf Date: Mon, 11 Nov 2024 13:47:11 +0100 Subject: [PATCH 03/51] extension --- .../tools/ide/serviceprovider/TestLogger.java | 329 +++++++++++++++++- .../serviceprovider/TestLoggerFactory.java | 13 +- .../ide/serviceprovider/TestProvider.java | 43 ++- .../org.slf4j.spi.SLF4JServiceProvider | 1 + 4 files changed, 383 insertions(+), 3 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java index 37e438ddc3..5c29fd0d0f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java @@ -1,2 +1,329 @@ -package com.devonfw.tools.ide.serviceprovider;public class TestLogger { +package com.devonfw.tools.ide.serviceprovider; + +import org.slf4j.Marker; + +public class TestLogger implements org.slf4j.Logger { + + private final String name; + + public TestLogger(String name) { + + this.name = name; + } + + @Override + public String getName() { + + return name; + } + + @Override + public boolean isTraceEnabled() { + + return false; + } + + @Override + public void trace(String s) { + + } + + @Override + public void trace(String s, Object o) { + + } + + @Override + public void trace(String s, Object o, Object o1) { + + } + + @Override + public void trace(String s, Object... objects) { + + } + + @Override + public void trace(String s, Throwable throwable) { + + } + + @Override + public boolean isTraceEnabled(Marker marker) { + + return false; + } + + @Override + public void trace(Marker marker, String s) { + + } + + @Override + public void trace(Marker marker, String s, Object o) { + + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1) { + + } + + @Override + public void trace(Marker marker, String s, Object... objects) { + + } + + @Override + public void trace(Marker marker, String s, Throwable throwable) { + + } + + @Override + public boolean isDebugEnabled() { + + return true; + } + + @Override + public void debug(String s) { + + } + + @Override + public void debug(String s, Object o) { + + } + + @Override + public void debug(String s, Object o, Object o1) { + + } + + @Override + public void debug(String s, Object... objects) { + + } + + @Override + public void debug(String s, Throwable throwable) { + + } + + @Override + public boolean isDebugEnabled(Marker marker) { + + return false; + } + + @Override + public void debug(Marker marker, String s) { + + } + + @Override + public void debug(Marker marker, String s, Object o) { + + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1) { + + } + + @Override + public void debug(Marker marker, String s, Object... objects) { + + } + + @Override + public void debug(Marker marker, String s, Throwable throwable) { + + } + + @Override + public boolean isInfoEnabled() { + + return false; + } + + @Override + public void info(String s) { + + } + + @Override + public void info(String s, Object o) { + + } + + @Override + public void info(String s, Object o, Object o1) { + + } + + @Override + public void info(String s, Object... objects) { + + } + + @Override + public void info(String s, Throwable throwable) { + + } + + @Override + public boolean isInfoEnabled(Marker marker) { + + return false; + } + + @Override + public void info(Marker marker, String s) { + + } + + @Override + public void info(Marker marker, String s, Object o) { + + } + + @Override + public void info(Marker marker, String s, Object o, Object o1) { + + } + + @Override + public void info(Marker marker, String s, Object... objects) { + + } + + @Override + public void info(Marker marker, String s, Throwable throwable) { + + } + + @Override + public boolean isWarnEnabled() { + + return false; + } + + @Override + public void warn(String s) { + + } + + @Override + public void warn(String s, Object o) { + + } + + @Override + public void warn(String s, Object... objects) { + + } + + @Override + public void warn(String s, Object o, Object o1) { + + } + + @Override + public void warn(String s, Throwable throwable) { + + } + + @Override + public boolean isWarnEnabled(Marker marker) { + + return false; + } + + @Override + public void warn(Marker marker, String s) { + + } + + @Override + public void warn(Marker marker, String s, Object o) { + + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1) { + + } + + @Override + public void warn(Marker marker, String s, Object... objects) { + + } + + @Override + public void warn(Marker marker, String s, Throwable throwable) { + + } + + @Override + public boolean isErrorEnabled() { + + return false; + } + + @Override + public void error(String s) { + + } + + @Override + public void error(String s, Object o) { + + } + + @Override + public void error(String s, Object o, Object o1) { + + } + + @Override + public void error(String s, Object... objects) { + + } + + @Override + public void error(String s, Throwable throwable) { + + } + + @Override + public boolean isErrorEnabled(Marker marker) { + + return false; + } + + @Override + public void error(Marker marker, String s) { + + } + + @Override + public void error(Marker marker, String s, Object o) { + + } + + @Override + public void error(Marker marker, String s, Object o, Object o1) { + + } + + @Override + public void error(Marker marker, String s, Object... objects) { + + } + + @Override + public void error(Marker marker, String s, Throwable throwable) { + + } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java index bd4899bfd7..796a69c1df 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java @@ -1,2 +1,13 @@ -package com.devonfw.tools.ide.serviceprovider;public class TestLoggerFactory { +package com.devonfw.tools.ide.serviceprovider; + +import org.slf4j.ILoggerFactory; +import org.slf4j.Logger; + +public class TestLoggerFactory implements ILoggerFactory { + + @Override + public Logger getLogger(String name) { + + return new TestLogger(name); + } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java index 5b6dbec7b8..98cea91868 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java @@ -1,2 +1,43 @@ -package com.devonfw.tools.ide.serviceprovider;public class TestProvider { +package com.devonfw.tools.ide.serviceprovider; + +import org.slf4j.ILoggerFactory; +import org.slf4j.IMarkerFactory; +import org.slf4j.helpers.NOPMDCAdapter; +import org.slf4j.spi.MDCAdapter; +import org.slf4j.spi.SLF4JServiceProvider; + +public class TestProvider implements SLF4JServiceProvider { + + private final String REQUESTED_API_VERSION = "2.0.12"; + private TestLoggerFactory testLoggerFactory; + + + @Override + public ILoggerFactory getLoggerFactory() { + + return testLoggerFactory; + } + + @Override + public IMarkerFactory getMarkerFactory() { + + return null; + } + + @Override + public MDCAdapter getMDCAdapter() { + + return new NOPMDCAdapter(); + } + + @Override + public String getRequestedApiVersion() { + + return REQUESTED_API_VERSION; + } + + @Override + public void initialize() { + testLoggerFactory = new TestLoggerFactory(); + } } diff --git a/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider index e69de29bb2..9ea9509eba 100644 --- a/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider +++ b/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider @@ -0,0 +1 @@ +com.devonfw.tools.ide.serviceprovider.TestProvider From fcf4a6463264a7318b19570005fb6618d32314b7 Mon Sep 17 00:00:00 2001 From: KianRolf Date: Wed, 13 Nov 2024 16:09:06 +0100 Subject: [PATCH 04/51] draft pr --- .../main/java/com/devonfw/tools/ide/cli/Ideasy.java | 5 +++++ cli/src/test/resources/xmlmerger/cpathtest/result.xml | 11 +++++++++++ cli/src/test/resources/xmlmerger/cpathtest/source.xml | 10 ++++++++++ cli/src/test/resources/xmlmerger/cpathtest/target.xml | 10 ++++++++++ 4 files changed, 36 insertions(+) create mode 100644 cli/src/test/resources/xmlmerger/cpathtest/result.xml create mode 100644 cli/src/test/resources/xmlmerger/cpathtest/source.xml create mode 100644 cli/src/test/resources/xmlmerger/cpathtest/target.xml diff --git a/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java b/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java index ae148c221a..484b0321d3 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java +++ b/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java @@ -3,6 +3,9 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.commandlet.ContextCommandlet; import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; @@ -24,6 +27,8 @@ public final class Ideasy { * * @param args the command-line arguments. */ + private static final Logger logger = LoggerFactory.getLogger(Ideasy.class); + public static void main(String... args) { int exitStatus = new Ideasy().run(args); diff --git a/cli/src/test/resources/xmlmerger/cpathtest/result.xml b/cli/src/test/resources/xmlmerger/cpathtest/result.xml new file mode 100644 index 0000000000..33c7c0f471 --- /dev/null +++ b/cli/src/test/resources/xmlmerger/cpathtest/result.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/cli/src/test/resources/xmlmerger/cpathtest/source.xml b/cli/src/test/resources/xmlmerger/cpathtest/source.xml new file mode 100644 index 0000000000..bed7e239e7 --- /dev/null +++ b/cli/src/test/resources/xmlmerger/cpathtest/source.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/cli/src/test/resources/xmlmerger/cpathtest/target.xml b/cli/src/test/resources/xmlmerger/cpathtest/target.xml new file mode 100644 index 0000000000..8626985a45 --- /dev/null +++ b/cli/src/test/resources/xmlmerger/cpathtest/target.xml @@ -0,0 +1,10 @@ + + + + + + From e2b1c2b42f64e153e90673ed028b6af80b12fefe Mon Sep 17 00:00:00 2001 From: KianRolf Date: Wed, 13 Nov 2024 16:12:29 +0100 Subject: [PATCH 05/51] fix --- cli/src/test/resources/xmlmerger/cpathtest/result.xml | 11 ----------- cli/src/test/resources/xmlmerger/cpathtest/source.xml | 10 ---------- cli/src/test/resources/xmlmerger/cpathtest/target.xml | 10 ---------- 3 files changed, 31 deletions(-) delete mode 100644 cli/src/test/resources/xmlmerger/cpathtest/result.xml delete mode 100644 cli/src/test/resources/xmlmerger/cpathtest/source.xml delete mode 100644 cli/src/test/resources/xmlmerger/cpathtest/target.xml diff --git a/cli/src/test/resources/xmlmerger/cpathtest/result.xml b/cli/src/test/resources/xmlmerger/cpathtest/result.xml deleted file mode 100644 index 33c7c0f471..0000000000 --- a/cli/src/test/resources/xmlmerger/cpathtest/result.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/cli/src/test/resources/xmlmerger/cpathtest/source.xml b/cli/src/test/resources/xmlmerger/cpathtest/source.xml deleted file mode 100644 index bed7e239e7..0000000000 --- a/cli/src/test/resources/xmlmerger/cpathtest/source.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/cli/src/test/resources/xmlmerger/cpathtest/target.xml b/cli/src/test/resources/xmlmerger/cpathtest/target.xml deleted file mode 100644 index 8626985a45..0000000000 --- a/cli/src/test/resources/xmlmerger/cpathtest/target.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - From 2fb8f0dc6a2bb78ff14d0f1d5589a6a512cda678 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Wed, 22 Jan 2025 14:20:40 +0100 Subject: [PATCH 06/51] #404: implemented requested changes renamed TestLogger to IdeLoggerAdapter added missing param to javadoc renamed TestProvider to TestProviderImpl renamed TestLoggerFactory to TestLoggerFactoryImpl --- .../com/devonfw/tools/ide/log/IdeSubLoggerOut.java | 1 + .../{TestLogger.java => IdeLoggerAdapter.java} | 13 +++++++++++-- ...oggerFactory.java => TestLoggerFactoryImpl.java} | 7 +++++-- .../{TestProvider.java => TestProviderImpl.java} | 9 ++++++--- .../services/org.slf4j.spi.SLF4JServiceProvider | 2 +- 5 files changed, 24 insertions(+), 8 deletions(-) rename cli/src/main/java/com/devonfw/tools/ide/serviceprovider/{TestLogger.java => IdeLoggerAdapter.java} (95%) rename cli/src/main/java/com/devonfw/tools/ide/serviceprovider/{TestLoggerFactory.java => TestLoggerFactoryImpl.java} (52%) rename cli/src/main/java/com/devonfw/tools/ide/serviceprovider/{TestProvider.java => TestProviderImpl.java} (75%) diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java index acd79c75ea..91cae563f1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java @@ -17,6 +17,7 @@ public class IdeSubLoggerOut extends AbstractIdeSubLogger { * @param out the {@link Appendable} to {@link Appendable#append(CharSequence) write} log messages to. * @param colored - {@code true} for colored output according to {@link IdeLogLevel}, {@code false} otherwise. * @param minLogLevel the minimum log level (threshold). + * @param listener the {@link IdeLogListener} to listen to. */ public IdeSubLoggerOut(IdeLogLevel level, Appendable out, boolean colored, IdeLogLevel minLogLevel, IdeLogListener listener) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java rename to cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java index 5c29fd0d0f..a541dd4367 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLogger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java @@ -1,12 +1,21 @@ package com.devonfw.tools.ide.serviceprovider; +import org.slf4j.Logger; import org.slf4j.Marker; -public class TestLogger implements org.slf4j.Logger { +/** + * Implementation of {@link Logger}. + */ +public class IdeLoggerAdapter implements Logger { private final String name; - public TestLogger(String name) { + /** + * The constructor. + * + * @param name of the logger. + */ + public IdeLoggerAdapter(String name) { this.name = name; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactoryImpl.java similarity index 52% rename from cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java rename to cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactoryImpl.java index 796a69c1df..69bf038107 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactory.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactoryImpl.java @@ -3,11 +3,14 @@ import org.slf4j.ILoggerFactory; import org.slf4j.Logger; -public class TestLoggerFactory implements ILoggerFactory { +/** + * Implementation of {@link ILoggerFactory}. + */ +public class TestLoggerFactoryImpl implements ILoggerFactory { @Override public Logger getLogger(String name) { - return new TestLogger(name); + return new IdeLoggerAdapter(name); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProviderImpl.java similarity index 75% rename from cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java rename to cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProviderImpl.java index 98cea91868..62fc569181 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProvider.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProviderImpl.java @@ -6,10 +6,13 @@ import org.slf4j.spi.MDCAdapter; import org.slf4j.spi.SLF4JServiceProvider; -public class TestProvider implements SLF4JServiceProvider { +/** + * Implementation of {@link SLF4JServiceProvider}. + */ +public class TestProviderImpl implements SLF4JServiceProvider { private final String REQUESTED_API_VERSION = "2.0.12"; - private TestLoggerFactory testLoggerFactory; + private TestLoggerFactoryImpl testLoggerFactory; @Override @@ -38,6 +41,6 @@ public String getRequestedApiVersion() { @Override public void initialize() { - testLoggerFactory = new TestLoggerFactory(); + testLoggerFactory = new TestLoggerFactoryImpl(); } } diff --git a/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider index 9ea9509eba..c70584fc82 100644 --- a/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider +++ b/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider @@ -1 +1 @@ -com.devonfw.tools.ide.serviceprovider.TestProvider +com.devonfw.tools.ide.serviceprovider.TestProviderImpl From aaa9fd33cd5feccef66bcc3c70ec66bf86e3d1c7 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 27 Jan 2025 16:37:51 +0100 Subject: [PATCH 07/51] #404: implemented IdeLoggerAdapter added first implementations for IdeLoggerAdapter methods replaced IdeSubLoggerSlf4j with IdeSubLoggerOut --- cli/pom.xml | 6 - .../tools/ide/context/AbstractIdeContext.java | 4 + .../ide/serviceprovider/IdeLoggerAdapter.java | 132 ++++++++---------- .../tools/ide/context/IdeSlf4jContext.java | 4 +- .../devonfw/tools/ide/log/IdeTestLogger.java | 2 +- 5 files changed, 69 insertions(+), 79 deletions(-) diff --git a/cli/pom.xml b/cli/pom.xml index afb0216403..759259eabc 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -62,12 +62,6 @@ 2.0.12 - - ch.qos.logback - logback-classic - 1.5.3 - - me.tongfei progressbar diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 3b4f56d8f7..9dd117dd57 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -142,6 +142,9 @@ public abstract class AbstractIdeContext implements IdeContext { private NetworkProxy networkProxy; + /** Context used for logging */ + public static IdeContext loggingContext; + /** * The constructor. * @@ -207,6 +210,7 @@ public AbstractIdeContext(IdeStartContextImpl startContext, Path workingDirector } this.defaultToolRepository = new DefaultToolRepository(this); + loggingContext = this; } private Path findIdeRoot(Path ideHomePath) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java index a541dd4367..ebc9e9851f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java @@ -1,5 +1,7 @@ package com.devonfw.tools.ide.serviceprovider; +import static com.devonfw.tools.ide.context.AbstractIdeContext.loggingContext; + import org.slf4j.Logger; import org.slf4j.Marker; @@ -28,311 +30,301 @@ public String getName() { @Override public boolean isTraceEnabled() { - - return false; + return loggingContext.trace().isEnabled(); } @Override public void trace(String s) { - + loggingContext.trace(s); } @Override public void trace(String s, Object o) { - + loggingContext.trace(s, o); } @Override public void trace(String s, Object o, Object o1) { - + loggingContext.trace(s, o, o1); } @Override public void trace(String s, Object... objects) { - + loggingContext.trace(s, objects); } @Override public void trace(String s, Throwable throwable) { - + loggingContext.trace(s, throwable); } @Override public boolean isTraceEnabled(Marker marker) { - - return false; + return loggingContext.trace().isEnabled(); } @Override public void trace(Marker marker, String s) { - + loggingContext.trace(s); } @Override public void trace(Marker marker, String s, Object o) { - + loggingContext.trace(s, o); } @Override public void trace(Marker marker, String s, Object o, Object o1) { - + loggingContext.trace(s, o, o1); } @Override public void trace(Marker marker, String s, Object... objects) { - + loggingContext.trace(s, objects); } @Override public void trace(Marker marker, String s, Throwable throwable) { - + loggingContext.trace(s, throwable); } @Override public boolean isDebugEnabled() { - - return true; + return loggingContext.debug().isEnabled(); } @Override public void debug(String s) { - + loggingContext.debug(s); } @Override public void debug(String s, Object o) { - + loggingContext.debug(s, o); } @Override public void debug(String s, Object o, Object o1) { - + loggingContext.debug(s, o, o1); } @Override public void debug(String s, Object... objects) { - + loggingContext.debug(s, objects); } @Override public void debug(String s, Throwable throwable) { - + loggingContext.debug(s, throwable); } @Override public boolean isDebugEnabled(Marker marker) { - - return false; + return loggingContext.debug().isEnabled(); } @Override public void debug(Marker marker, String s) { - + loggingContext.debug(s); } @Override public void debug(Marker marker, String s, Object o) { - + loggingContext.debug(s, o); } @Override public void debug(Marker marker, String s, Object o, Object o1) { - + loggingContext.debug(s, o, o1); } @Override public void debug(Marker marker, String s, Object... objects) { - + loggingContext.debug(s, objects); } @Override public void debug(Marker marker, String s, Throwable throwable) { - + loggingContext.debug(s, throwable); } @Override public boolean isInfoEnabled() { - - return false; + return loggingContext.info().isEnabled(); } @Override public void info(String s) { - + loggingContext.info(s); } @Override public void info(String s, Object o) { - + loggingContext.info(s, o); } @Override public void info(String s, Object o, Object o1) { - + loggingContext.info(s, o, o1); } @Override public void info(String s, Object... objects) { - + loggingContext.info(s, objects); } @Override public void info(String s, Throwable throwable) { - + loggingContext.info(s, throwable); } @Override public boolean isInfoEnabled(Marker marker) { - - return false; + return loggingContext.info().isEnabled(); } @Override public void info(Marker marker, String s) { - + loggingContext.info(s); } @Override public void info(Marker marker, String s, Object o) { - + loggingContext.info(s, o); } @Override public void info(Marker marker, String s, Object o, Object o1) { - + loggingContext.info(s, o, o1); } @Override public void info(Marker marker, String s, Object... objects) { - + loggingContext.info(s, objects); } @Override public void info(Marker marker, String s, Throwable throwable) { - + loggingContext.info(s, throwable); } @Override public boolean isWarnEnabled() { - - return false; + return loggingContext.warning().isEnabled(); } @Override public void warn(String s) { - + loggingContext.warning(s); } @Override public void warn(String s, Object o) { - + loggingContext.warning(s, o); } @Override public void warn(String s, Object... objects) { - + loggingContext.warning(s, objects); } @Override public void warn(String s, Object o, Object o1) { - + loggingContext.warning(s, o, o1); } @Override public void warn(String s, Throwable throwable) { - + loggingContext.warning(s, throwable); } @Override public boolean isWarnEnabled(Marker marker) { - - return false; + return loggingContext.warning().isEnabled(); } @Override public void warn(Marker marker, String s) { - + loggingContext.warning(s); } @Override public void warn(Marker marker, String s, Object o) { - + loggingContext.warning(s, o); } @Override public void warn(Marker marker, String s, Object o, Object o1) { - + loggingContext.warning(s, o, o1); } @Override public void warn(Marker marker, String s, Object... objects) { - + loggingContext.warning(s, objects); } @Override public void warn(Marker marker, String s, Throwable throwable) { - + loggingContext.warning(s, throwable); } @Override public boolean isErrorEnabled() { - - return false; + return loggingContext.error().isEnabled(); } @Override public void error(String s) { - + loggingContext.error(s); } @Override public void error(String s, Object o) { - + loggingContext.error(s, o); } @Override public void error(String s, Object o, Object o1) { - + loggingContext.error(s, o, o1); } @Override public void error(String s, Object... objects) { - + loggingContext.error(s, objects); } @Override public void error(String s, Throwable throwable) { - + loggingContext.error(s, throwable); } @Override public boolean isErrorEnabled(Marker marker) { - - return false; + return loggingContext.error().isEnabled(); } @Override public void error(Marker marker, String s) { - + loggingContext.error(s); } @Override public void error(Marker marker, String s, Object o) { - + loggingContext.error(s, o); } @Override public void error(Marker marker, String s, Object o, Object o1) { - + loggingContext.error(s, o, o1); } @Override public void error(Marker marker, String s, Object... objects) { - + loggingContext.error(s, objects); } @Override public void error(Marker marker, String s, Throwable throwable) { - + loggingContext.error(s, throwable); } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java index b7413879cc..88cc3b9c84 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java @@ -3,7 +3,7 @@ import java.nio.file.Path; import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeSubLoggerSlf4j; +import com.devonfw.tools.ide.log.IdeSubLoggerOut; /** * Implementation of {@link IdeContext} for testing. @@ -26,7 +26,7 @@ public IdeSlf4jContext() { */ public IdeSlf4jContext(Path workingDirectory) { - super(new IdeStartContextImpl(IdeLogLevel.TRACE, IdeSubLoggerSlf4j::new), workingDirectory); + super(new IdeStartContextImpl(IdeLogLevel.TRACE, level -> new IdeSubLoggerOut(level, null, true, IdeLogLevel.TRACE, null)), workingDirectory); } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java index ca889bbc22..ed2e3f18c4 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java +++ b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java @@ -24,7 +24,7 @@ public IdeTestLogger(IdeLogLevel minLogLevel) { private IdeTestLogger(List entries, IdeLogLevel minLogLevel, IdeLogListenerCollector collector) { - super(minLogLevel, level -> new IdeSubLoggerSlf4j(level, collector)); + super(minLogLevel, level -> new IdeSubLoggerOut(level, null, true, minLogLevel, collector)); this.collector = collector; } From ef08b4eeeea34c9bb7e275571e67fb32d2ada7da Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 27 Jan 2025 17:37:44 +0100 Subject: [PATCH 08/51] #404: fixed WireMock tests added null checks to IdeLoggerAdapter debug methods --- .../ide/serviceprovider/IdeLoggerAdapter.java | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java index ebc9e9851f..f2e298ce42 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java @@ -90,37 +90,56 @@ public void trace(Marker marker, String s, Throwable throwable) { @Override public boolean isDebugEnabled() { - return loggingContext.debug().isEnabled(); + if (loggingContext != null) { + return loggingContext.debug().isEnabled(); + } else { + return false; + } + } @Override public void debug(String s) { - loggingContext.debug(s); + if (loggingContext != null) { + loggingContext.debug(s); + } } @Override public void debug(String s, Object o) { - loggingContext.debug(s, o); + if (loggingContext != null) { + loggingContext.debug(s, o); + } } @Override public void debug(String s, Object o, Object o1) { - loggingContext.debug(s, o, o1); + if (loggingContext != null) { + loggingContext.debug(s, o, o1); + } } @Override public void debug(String s, Object... objects) { - loggingContext.debug(s, objects); + if (loggingContext != null) { + loggingContext.debug(s, objects); + } } @Override public void debug(String s, Throwable throwable) { - loggingContext.debug(s, throwable); + if (loggingContext != null) { + loggingContext.debug(s, throwable); + } } @Override public boolean isDebugEnabled(Marker marker) { - return loggingContext.debug().isEnabled(); + if (loggingContext != null) { + return loggingContext.debug().isEnabled(); + } else { + return false; + } } @Override @@ -170,7 +189,9 @@ public void info(String s, Object o, Object o1) { @Override public void info(String s, Object... objects) { - loggingContext.info(s, objects); + if (loggingContext != null) { + loggingContext.info(s, objects); + } } @Override From 5cd1ab373615a16fb252728c675535182b662494 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Tue, 28 Jan 2025 10:46:58 +0100 Subject: [PATCH 09/51] #404: fixed WireMock tests added rest of null checks --- .../ide/serviceprovider/IdeLoggerAdapter.java | 46 +++++++++++++++---- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java index f2e298ce42..4f44076a0c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java @@ -169,22 +169,32 @@ public void debug(Marker marker, String s, Throwable throwable) { @Override public boolean isInfoEnabled() { - return loggingContext.info().isEnabled(); + if (loggingContext != null) { + return loggingContext.info().isEnabled(); + } else { + return false; + } } @Override public void info(String s) { - loggingContext.info(s); + if (loggingContext != null) { + loggingContext.info(s); + } } @Override public void info(String s, Object o) { - loggingContext.info(s, o); + if (loggingContext != null) { + loggingContext.info(s, o); + } } @Override public void info(String s, Object o, Object o1) { - loggingContext.info(s, o, o1); + if (loggingContext != null) { + loggingContext.info(s, o, o1); + } } @Override @@ -291,17 +301,25 @@ public void warn(Marker marker, String s, Throwable throwable) { @Override public boolean isErrorEnabled() { - return loggingContext.error().isEnabled(); + if (loggingContext != null) { + return loggingContext.error().isEnabled(); + } else { + return false; + } } @Override public void error(String s) { - loggingContext.error(s); + if (loggingContext != null) { + loggingContext.error(s); + } } @Override public void error(String s, Object o) { - loggingContext.error(s, o); + if (loggingContext != null) { + loggingContext.error(s, o); + } } @Override @@ -311,17 +329,25 @@ public void error(String s, Object o, Object o1) { @Override public void error(String s, Object... objects) { - loggingContext.error(s, objects); + if (loggingContext != null) { + loggingContext.error(s, objects); + } } @Override public void error(String s, Throwable throwable) { - loggingContext.error(s, throwable); + if (loggingContext != null) { + loggingContext.error(s, throwable); + } } @Override public boolean isErrorEnabled(Marker marker) { - return loggingContext.error().isEnabled(); + if (loggingContext != null) { + return loggingContext.error().isEnabled(); + } else { + return false; + } } @Override From b4669bb355a199d441579f4150374e2cf1b1a899 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Tue, 28 Jan 2025 12:34:08 +0100 Subject: [PATCH 10/51] #404: fixed WireMock tests fixed compose array out of bounds exception --- .../java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java b/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java index 0a4a1e873d..ac1252a2d4 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java @@ -143,7 +143,7 @@ public String log(Throwable error, String message, Object... args) { // fail fast if assertions are enabled, so developers of IDEasy will find the bug immediately but in productive use better log the error and continue assert false : actualMessage; } - } else if (args != null) { + } else if (args != null && args.length > 0) { actualMessage = compose(actualMessage, args); } boolean accept = this.listener.onLog(this.level, actualMessage, message, args, error); From 98a0f2e4072f4faa2eeba88778072e78d5d4e1bd Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Tue, 4 Feb 2025 19:02:40 +0100 Subject: [PATCH 11/51] #404: refactored urls into url-updater updated WireMock dependency from 2.35.2 to 3.11.0 added jackson-core dependency to ide-cli added url namespace to tools added LogbackServiceProvider to service --- cli/pom.xml | 11 ++- .../ide/url/model/file/UrlStatusFileTest.java | 15 ++-- .../url/model/file/json/StatusJsonTest.java | 2 +- .../model/file/json/ToolDependenciesTest.java | 14 ++-- pom.xml | 1 + url-updater/pom.xml | 43 +++++++++++ .../tools/ide/url/UpdateInitiator.java | 0 .../AndroidStudioUrlUpdater.java | 5 +- .../ide/url}/tool/aws/AwsUrlUpdater.java | 2 +- .../ide/url}/tool/az/AzureUrlUpdater.java | 2 +- .../tool/docker/DockerDesktopUrlUpdater.java | 2 +- .../DockerRancherDesktopUrlUpdater.java | 2 +- .../url}/tool/dotnet/DotNetUrlUpdater.java | 2 +- .../tool/eclipse/EclipseCppUrlUpdater.java | 2 +- .../tool/eclipse/EclipseJavaUrlUpdater.java | 2 +- .../tool/eclipse/EclipseJeeUrlUpdater.java | 2 +- .../url}/tool/eclipse/EclipseUrlUpdater.java | 2 +- .../url}/tool/gcloud/GCloudUrlUpdater.java | 2 +- .../tool/gcviewer/GcViewerUrlUpdater.java | 2 +- .../tools/ide/url}/tool/gh/GhUrlUpdater.java | 2 +- .../tool/graalvm/GraalVmCommunityUpdater.java | 2 +- .../tool/graalvm/GraalVmOracleUrlUpdater.java | 2 +- .../url}/tool/graalvm/GraalVmUrlUpdater.java | 2 +- .../url}/tool/gradle/GradleUrlUpdater.java | 2 +- .../ide/url}/tool/helm/HelmUrlUpdater.java | 2 +- .../tool/intellij/IntellijUrlUpdater.java | 5 +- .../url}/tool/jasypt/JasyptUrlUpdater.java | 2 +- .../ide/url}/tool/java/JavaUrlUpdater.java | 4 +- .../url}/tool/jenkins/JenkinsUrlUpdater.java | 2 +- .../ide/url}/tool/jmc/JmcUrlUpdater.java | 2 +- .../tool/kotlinc/KotlincNativeUrlUpdater.java | 2 +- .../url}/tool/kotlinc/KotlincUrlUpdater.java | 2 +- .../tool/lazydocker/LazyDockerUrlUpdater.java | 2 +- .../ide/url}/tool/mvn/Mvn4UrlUpdater.java | 2 +- .../ide/url}/tool/mvn/MvnUrlUpdater.java | 2 +- .../ide/url}/tool/node/NodeUrlUpdater.java | 2 +- .../ide/url}/tool/npm/NpmUrlUpdater.java | 2 +- .../tools/ide/url}/tool/oc/OcUrlUpdater.java | 2 +- .../url}/tool/pgadmin/PgAdminUrlUpdater.java | 2 +- .../ide/url}/tool/pip/PipUrlUpdater.java | 2 +- .../url}/tool/python/PythonUrlUpdater.java | 5 +- .../url}/tool/quarkus/QuarkusUrlUpdater.java | 2 +- .../ide/url}/tool/sonar/SonarUrlUpdater.java | 2 +- .../tool/terraform/TerraformUrlUpdater.java | 2 +- .../url}/tool/tomcat/TomcatUrlUpdater.java | 2 +- .../url}/tool/vscode/VsCodeUrlUpdater.java | 2 +- .../updater/AbstractProcessorWithTimeout.java | 0 .../ide/url/updater/AbstractUrlUpdater.java | 4 +- .../ide/url/updater/GithubUrlUpdater.java | 0 .../tools/ide/url/updater/JsonUrlUpdater.java | 0 .../ide/url/updater/MavenBasedUrlUpdater.java | 0 .../ide/url/updater/NpmBasedUrlUpdater.java | 0 .../tools/ide/url/updater/UpdateManager.java | 74 +++++++++---------- .../tools/ide/url/updater/UrlUpdater.java | 0 .../ide/url/updater/WebsiteUrlUpdater.java | 0 .../org.slf4j.spi.SLF4JServiceProvider | 1 + .../ide/url/report/UrlUpdaterReportTest.java | 4 +- .../ide/url}/tool/AbstractUrlUpdaterTest.java | 2 +- .../tools/ide/url}/tool/UrlUpdaterMock.java | 2 +- .../ide/url}/tool/UrlUpdaterMockSingle.java | 2 +- .../tools/ide/url}/tool/UrlUpdaterTest.java | 9 ++- .../AndroidStudioJsonUrlUpdaterTest.java | 2 +- .../AndroidStudioUrlUpdaterMock.java | 2 +- .../intellij/IntellijJsonUrlUpdaterTest.java | 2 +- .../tool/intellij/IntellijUrlUpdaterMock.java | 2 +- .../url}/tool/java/JavaUrlUpdaterMock.java | 2 +- .../url}/tool/java/JavaUrlUpdaterTest.java | 4 +- .../url}/tool/npm/NpmJsonUrlUpdaterTest.java | 2 +- .../ide/url}/tool/npm/NpmUrlUpdaterMock.java | 2 +- .../ide/url}/tool/pip/PipUrlUpdaterMock.java | 2 +- .../ide/url}/tool/pip/PipUrlUpdaterTest.java | 13 ++-- .../tool/python/PythonUrlUpdaterMock.java | 3 +- .../tool/python/PythonUrlUpdaterTest.java | 2 +- .../android-version-without-checksum.json | 0 .../android-version.json | 0 .../intellij-version-without-checksum.json | 0 .../intellij-version.json | 0 .../JavaJsonUrlUpdater/java-version.json | 0 .../NpmJsonUrlUpdater/npm-version.json | 0 .../PythonJsonUrlUpdater/python-version.json | 0 .../mocked/mocked/1.0/status.json | 0 81 files changed, 191 insertions(+), 120 deletions(-) create mode 100644 url-updater/pom.xml rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java (100%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/androidstudio/AndroidStudioUrlUpdater.java (89%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/aws/AwsUrlUpdater.java (97%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/az/AzureUrlUpdater.java (96%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/docker/DockerDesktopUrlUpdater.java (97%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/docker/DockerRancherDesktopUrlUpdater.java (96%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/dotnet/DotNetUrlUpdater.java (96%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/eclipse/EclipseCppUrlUpdater.java (81%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/eclipse/EclipseJavaUrlUpdater.java (84%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/eclipse/EclipseJeeUrlUpdater.java (81%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/eclipse/EclipseUrlUpdater.java (98%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/gcloud/GCloudUrlUpdater.java (96%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/gcviewer/GcViewerUrlUpdater.java (94%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/gh/GhUrlUpdater.java (97%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/graalvm/GraalVmCommunityUpdater.java (95%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/graalvm/GraalVmOracleUrlUpdater.java (94%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/graalvm/GraalVmUrlUpdater.java (90%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/gradle/GradleUrlUpdater.java (98%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/helm/HelmUrlUpdater.java (96%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/intellij/IntellijUrlUpdater.java (94%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/jasypt/JasyptUrlUpdater.java (94%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/java/JavaUrlUpdater.java (94%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/jenkins/JenkinsUrlUpdater.java (93%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/jmc/JmcUrlUpdater.java (95%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/kotlinc/KotlincNativeUrlUpdater.java (95%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/kotlinc/KotlincUrlUpdater.java (94%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/lazydocker/LazyDockerUrlUpdater.java (96%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/mvn/Mvn4UrlUpdater.java (95%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/mvn/MvnUrlUpdater.java (94%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/node/NodeUrlUpdater.java (97%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/npm/NpmUrlUpdater.java (88%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/oc/OcUrlUpdater.java (95%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/pgadmin/PgAdminUrlUpdater.java (96%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/pip/PipUrlUpdater.java (95%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/python/PythonUrlUpdater.java (93%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/quarkus/QuarkusUrlUpdater.java (95%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/sonar/SonarUrlUpdater.java (93%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/terraform/TerraformUrlUpdater.java (95%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/tomcat/TomcatUrlUpdater.java (93%) rename {cli/src/main/java/com/devonfw/tools/ide => url-updater/src/main/java/com/devonfw/tools/ide/url}/tool/vscode/VsCodeUrlUpdater.java (95%) rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/updater/AbstractProcessorWithTimeout.java (100%) rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java (99%) rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/updater/GithubUrlUpdater.java (100%) rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/updater/JsonUrlUpdater.java (100%) rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/updater/MavenBasedUrlUpdater.java (100%) rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/updater/NpmBasedUrlUpdater.java (100%) rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java (61%) rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/updater/UrlUpdater.java (100%) rename {cli => url-updater}/src/main/java/com/devonfw/tools/ide/url/updater/WebsiteUrlUpdater.java (100%) create mode 100644 url-updater/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider rename {cli => url-updater}/src/test/java/com/devonfw/tools/ide/url/report/UrlUpdaterReportTest.java (98%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/AbstractUrlUpdaterTest.java (96%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/UrlUpdaterMock.java (97%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/UrlUpdaterMockSingle.java (96%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/UrlUpdaterTest.java (96%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/androidstudio/AndroidStudioJsonUrlUpdaterTest.java (99%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/androidstudio/AndroidStudioUrlUpdaterMock.java (92%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/intellij/IntellijJsonUrlUpdaterTest.java (99%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/intellij/IntellijUrlUpdaterMock.java (92%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/java/JavaUrlUpdaterMock.java (92%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/java/JavaUrlUpdaterTest.java (97%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/npm/NpmJsonUrlUpdaterTest.java (99%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/npm/NpmUrlUpdaterMock.java (91%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/pip/PipUrlUpdaterMock.java (95%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/pip/PipUrlUpdaterTest.java (80%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/python/PythonUrlUpdaterMock.java (85%) rename {cli/src/test/java/com/devonfw/tools/ide => url-updater/src/test/java/com/devonfw/tools/ide/url}/tool/python/PythonUrlUpdaterTest.java (98%) rename {cli => url-updater}/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version-without-checksum.json (100%) rename {cli => url-updater}/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version.json (100%) rename {cli => url-updater}/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version-without-checksum.json (100%) rename {cli => url-updater}/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version.json (100%) rename {cli => url-updater}/src/test/resources/integrationtest/JavaJsonUrlUpdater/java-version.json (100%) rename {cli => url-updater}/src/test/resources/integrationtest/NpmJsonUrlUpdater/npm-version.json (100%) rename {cli => url-updater}/src/test/resources/integrationtest/PythonJsonUrlUpdater/python-version.json (100%) rename {cli => url-updater}/src/test/resources/integrationtest/UrlUpdaterTest/mocked/mocked/1.0/status.json (100%) diff --git a/cli/pom.xml b/cli/pom.xml index 759259eabc..e8f68e93df 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -40,6 +40,11 @@ parsson 1.1.7 + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + com.fasterxml.jackson.core jackson-databind @@ -87,9 +92,9 @@ - com.github.tomakehurst - wiremock-jre8 - 2.35.2 + org.wiremock + wiremock + 3.11.0 test diff --git a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/UrlStatusFileTest.java b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/UrlStatusFileTest.java index fa785e79c8..02d9fdb5b6 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/UrlStatusFileTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/UrlStatusFileTest.java @@ -2,6 +2,7 @@ import java.time.Instant; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import com.devonfw.tools.ide.url.model.AbstractUrlModelTest; @@ -33,16 +34,16 @@ public void testReadJson() { UrlStatusFile status = version.getOrCreateStatus(); StatusJson statusJson = status.getStatusJson(); // then - assertThat(statusJson.getUrls()).hasSize(1); + Assertions.assertThat(statusJson.getUrls()).hasSize(1); UrlStatus urlStatus = statusJson.getUrls().values().iterator().next(); UrlStatusState success = urlStatus.getSuccess(); - assertThat(success.getTimestamp()).isEqualTo(Instant.parse("2023-02-21T15:03:09.387386Z")); - assertThat(success.getCode()).isNull(); - assertThat(success.getMessage()).isNull(); + Assertions.assertThat(success.getTimestamp()).isEqualTo(Instant.parse("2023-02-21T15:03:09.387386Z")); + Assertions.assertThat(success.getCode()).isNull(); + Assertions.assertThat(success.getMessage()).isNull(); UrlStatusState error = urlStatus.getError(); - assertThat(error.getTimestamp()).isEqualTo(Instant.parse("2023-01-01T23:59:59.999999Z")); - assertThat(error.getCode()).isEqualTo(500); - assertThat(error.getMessage()).isEqualTo("core dumped"); + Assertions.assertThat(error.getTimestamp()).isEqualTo(Instant.parse("2023-01-01T23:59:59.999999Z")); + Assertions.assertThat(error.getCode()).isEqualTo(500); + Assertions.assertThat(error.getMessage()).isEqualTo("core dumped"); } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/StatusJsonTest.java b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/StatusJsonTest.java index 6216b143d4..34e79e562d 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/StatusJsonTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/StatusJsonTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test; /** - * Test of {@link StatusJson}. + * Test of {@link com.devonfw.tools.ide.url.model.file.json.StatusJson}. */ public class StatusJsonTest extends Assertions { diff --git a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/ToolDependenciesTest.java b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/ToolDependenciesTest.java index fd7ba382fb..d28862c1d7 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/ToolDependenciesTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/ToolDependenciesTest.java @@ -23,10 +23,11 @@ public void testEditionSpecific() { IdeContext context = newContext(); // act - Collection dependencies = context.getDefaultToolRepository().findDependencies("tomcat", "tomcat", VersionIdentifier.of("11.0.0")); + Collection dependencies = context.getDefaultToolRepository() + .findDependencies("tomcat", "tomcat", VersionIdentifier.of("11.0.0")); // assert - assertThat(dependencies).containsExactly(new ToolDependency("java", VersionRange.of("[17,)"))); + assertThat(dependencies).containsExactly(new com.devonfw.tools.ide.url.model.file.json.ToolDependency("java", VersionRange.of("[17,)"))); } @Test @@ -36,10 +37,12 @@ public void testEditionFallback() { IdeContext context = newContext(); // act - Collection dependencies = context.getDefaultToolRepository().findDependencies("tomcat", "undefined", VersionIdentifier.of("11.0.0")); + Collection dependencies = context.getDefaultToolRepository() + .findDependencies("tomcat", "undefined", VersionIdentifier.of("11.0.0")); // assert - assertThat(dependencies).containsExactly(new ToolDependency("this-is-the-wrong-file-only-for-testing", VersionRange.of("[1.0,2.0]"))); + assertThat(dependencies).containsExactly( + new com.devonfw.tools.ide.url.model.file.json.ToolDependency("this-is-the-wrong-file-only-for-testing", VersionRange.of("[1.0,2.0]"))); } @Test @@ -49,7 +52,8 @@ public void testEditionUnspecific() { IdeContext context = newContext(); // act - Collection dependencies = context.getDefaultToolRepository().findDependencies("mvn", "undefined", VersionIdentifier.of("3.9.0")); + Collection dependencies = context.getDefaultToolRepository() + .findDependencies("mvn", "undefined", VersionIdentifier.of("3.9.0")); // assert assertThat(dependencies).containsExactly(new ToolDependency("java", VersionRange.of("[8,)"))); diff --git a/pom.xml b/pom.xml index 5df4e45d93..a3ca7fe706 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ documentation cli gui + url-updater diff --git a/url-updater/pom.xml b/url-updater/pom.xml new file mode 100644 index 0000000000..3cda6ca0ca --- /dev/null +++ b/url-updater/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + com.devonfw.tools.IDEasy.dev + ide + dev-SNAPSHOT + ../pom.xml + + com.devonfw.tools.IDEasy + url-updater + ${revision} + ${project.artifactId} + + + 21 + 21 + UTF-8 + 2.18.2 + + + + + ${project.groupId} + ide-cli + ${project.version} + + + ch.qos.logback + logback-classic + 1.5.16 + + + org.wiremock + wiremock + 3.11.0 + test + + + + diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java similarity index 100% rename from cli/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/androidstudio/AndroidStudioUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java similarity index 89% rename from cli/src/main/java/com/devonfw/tools/ide/tool/androidstudio/AndroidStudioUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java index 315e32110d..50fa57f41a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/androidstudio/AndroidStudioUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java @@ -1,10 +1,13 @@ -package com.devonfw.tools.ide.tool.androidstudio; +package com.devonfw.tools.ide.url.tool.androidstudio; import java.util.Collection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.devonfw.tools.ide.tool.androidstudio.AndroidJsonDownload; +import com.devonfw.tools.ide.tool.androidstudio.AndroidJsonItem; +import com.devonfw.tools.ide.tool.androidstudio.AndroidJsonObject; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/aws/AwsUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/aws/AwsUrlUpdater.java similarity index 97% rename from cli/src/main/java/com/devonfw/tools/ide/tool/aws/AwsUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/aws/AwsUrlUpdater.java index 7f9df6110c..4ebddd4b1a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/aws/AwsUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/aws/AwsUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.aws; +package com.devonfw.tools.ide.url.tool.aws; import com.devonfw.tools.ide.os.OperatingSystem; import com.devonfw.tools.ide.url.model.folder.UrlVersion; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/az/AzureUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/az/AzureUrlUpdater.java similarity index 96% rename from cli/src/main/java/com/devonfw/tools/ide/tool/az/AzureUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/az/AzureUrlUpdater.java index 9aca421537..b729df51a6 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/az/AzureUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/az/AzureUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.az; +package com.devonfw.tools.ide.url.tool.az; import com.devonfw.tools.ide.os.OperatingSystem; import com.devonfw.tools.ide.url.model.folder.UrlVersion; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerDesktopUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java similarity index 97% rename from cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerDesktopUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java index f4dd68754d..924a21debc 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerDesktopUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.docker; +package com.devonfw.tools.ide.url.tool.docker; import java.util.Set; import java.util.regex.Matcher; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerRancherDesktopUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerRancherDesktopUrlUpdater.java similarity index 96% rename from cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerRancherDesktopUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerRancherDesktopUrlUpdater.java index 4c5c820fa6..ced6ae9c6c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerRancherDesktopUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerRancherDesktopUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.docker; +package com.devonfw.tools.ide.url.tool.docker; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/dotnet/DotNetUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/dotnet/DotNetUrlUpdater.java similarity index 96% rename from cli/src/main/java/com/devonfw/tools/ide/tool/dotnet/DotNetUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/dotnet/DotNetUrlUpdater.java index 237298c394..98b8ca8c78 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/dotnet/DotNetUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/dotnet/DotNetUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.dotnet; +package com.devonfw.tools.ide.url.tool.dotnet; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseCppUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseCppUrlUpdater.java similarity index 81% rename from cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseCppUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseCppUrlUpdater.java index d1d127e247..02f3a6e2ef 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseCppUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseCppUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.eclipse; +package com.devonfw.tools.ide.url.tool.eclipse; /** * {@link EclipseUrlUpdater} for "cpp" (C++) edition of Eclipse. diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseJavaUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseJavaUrlUpdater.java similarity index 84% rename from cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseJavaUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseJavaUrlUpdater.java index 07ec659a71..28ad2cf509 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseJavaUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseJavaUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.eclipse; +package com.devonfw.tools.ide.url.tool.eclipse; /** * {@link EclipseUrlUpdater} for "java" edition of Eclipse. diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseJeeUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseJeeUrlUpdater.java similarity index 81% rename from cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseJeeUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseJeeUrlUpdater.java index d4a4205955..9d410be104 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseJeeUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseJeeUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.eclipse; +package com.devonfw.tools.ide.url.tool.eclipse; /** * {@link EclipseUrlUpdater} for "jee" (C++) edition of Eclipse. diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseUrlUpdater.java similarity index 98% rename from cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseUrlUpdater.java index ccefb8079f..b98bc3c7c1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/EclipseUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.eclipse; +package com.devonfw.tools.ide.url.tool.eclipse; import java.util.regex.Pattern; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/gcloud/GCloudUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcloud/GCloudUrlUpdater.java similarity index 96% rename from cli/src/main/java/com/devonfw/tools/ide/tool/gcloud/GCloudUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcloud/GCloudUrlUpdater.java index 45f62d2b6a..6acc212e9e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/gcloud/GCloudUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcloud/GCloudUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.gcloud; +package com.devonfw.tools.ide.url.tool.gcloud; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/gcviewer/GcViewerUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcviewer/GcViewerUrlUpdater.java similarity index 94% rename from cli/src/main/java/com/devonfw/tools/ide/tool/gcviewer/GcViewerUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcviewer/GcViewerUrlUpdater.java index 44f10a2429..d9d33c68a7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/gcviewer/GcViewerUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcviewer/GcViewerUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.gcviewer; +package com.devonfw.tools.ide.url.tool.gcviewer; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/gh/GhUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gh/GhUrlUpdater.java similarity index 97% rename from cli/src/main/java/com/devonfw/tools/ide/tool/gh/GhUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gh/GhUrlUpdater.java index bd8a30dbc4..903541560c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/gh/GhUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gh/GhUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.gh; +package com.devonfw.tools.ide.url.tool.gh; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/graalvm/GraalVmCommunityUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/graalvm/GraalVmCommunityUpdater.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/tool/graalvm/GraalVmCommunityUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/graalvm/GraalVmCommunityUpdater.java index a6a7f70e3d..e1b4234431 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/graalvm/GraalVmCommunityUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/graalvm/GraalVmCommunityUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.graalvm; +package com.devonfw.tools.ide.url.tool.graalvm; import com.devonfw.tools.ide.url.model.folder.UrlVersion; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/graalvm/GraalVmOracleUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/graalvm/GraalVmOracleUrlUpdater.java similarity index 94% rename from cli/src/main/java/com/devonfw/tools/ide/tool/graalvm/GraalVmOracleUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/graalvm/GraalVmOracleUrlUpdater.java index e169436c4f..2abc6f2033 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/graalvm/GraalVmOracleUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/graalvm/GraalVmOracleUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.graalvm; +package com.devonfw.tools.ide.url.tool.graalvm; import com.devonfw.tools.ide.url.model.folder.UrlVersion; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/graalvm/GraalVmUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/graalvm/GraalVmUrlUpdater.java similarity index 90% rename from cli/src/main/java/com/devonfw/tools/ide/tool/graalvm/GraalVmUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/graalvm/GraalVmUrlUpdater.java index 5925ffa030..e4d17b9ef5 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/graalvm/GraalVmUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/graalvm/GraalVmUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.graalvm; +package com.devonfw.tools.ide.url.tool.graalvm; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/gradle/GradleUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gradle/GradleUrlUpdater.java similarity index 98% rename from cli/src/main/java/com/devonfw/tools/ide/tool/gradle/GradleUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gradle/GradleUrlUpdater.java index 62d441b390..439be91c86 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/gradle/GradleUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gradle/GradleUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.gradle; +package com.devonfw.tools.ide.url.tool.gradle; import java.util.HashSet; import java.util.Set; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/helm/HelmUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/helm/HelmUrlUpdater.java similarity index 96% rename from cli/src/main/java/com/devonfw/tools/ide/tool/helm/HelmUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/helm/HelmUrlUpdater.java index 6515a3fe23..73f6cf0128 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/helm/HelmUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/helm/HelmUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.helm; +package com.devonfw.tools.ide.url.tool.helm; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/intellij/IntellijUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java similarity index 94% rename from cli/src/main/java/com/devonfw/tools/ide/tool/intellij/IntellijUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java index 1fc2ca03b6..9ee40b8d88 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/intellij/IntellijUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.intellij; +package com.devonfw.tools.ide.url.tool.intellij; import java.util.Collection; import java.util.List; @@ -7,6 +7,9 @@ import com.devonfw.tools.ide.json.JsonVersionItem; import com.devonfw.tools.ide.os.OperatingSystem; import com.devonfw.tools.ide.os.SystemArchitecture; +import com.devonfw.tools.ide.tool.intellij.IntellijJsonDownloadsItem; +import com.devonfw.tools.ide.tool.intellij.IntellijJsonObject; +import com.devonfw.tools.ide.tool.intellij.IntellijJsonRelease; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/jasypt/JasyptUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jasypt/JasyptUrlUpdater.java similarity index 94% rename from cli/src/main/java/com/devonfw/tools/ide/tool/jasypt/JasyptUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jasypt/JasyptUrlUpdater.java index a56caf0e2b..499f66bcdf 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/jasypt/JasyptUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jasypt/JasyptUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.jasypt; +package com.devonfw.tools.ide.url.tool.jasypt; import com.devonfw.tools.ide.url.updater.MavenBasedUrlUpdater; import com.devonfw.tools.ide.version.VersionIdentifier; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/java/JavaUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java similarity index 94% rename from cli/src/main/java/com/devonfw/tools/ide/tool/java/JavaUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java index c57f54e0dd..3456396c15 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/java/JavaUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java @@ -1,7 +1,9 @@ -package com.devonfw.tools.ide.tool.java; +package com.devonfw.tools.ide.url.tool.java; import java.util.Collection; +import com.devonfw.tools.ide.tool.java.JavaJsonObject; +import com.devonfw.tools.ide.tool.java.JavaJsonVersion; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/jenkins/JenkinsUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jenkins/JenkinsUrlUpdater.java similarity index 93% rename from cli/src/main/java/com/devonfw/tools/ide/tool/jenkins/JenkinsUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jenkins/JenkinsUrlUpdater.java index 8736480870..e31123ff36 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/jenkins/JenkinsUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jenkins/JenkinsUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.jenkins; +package com.devonfw.tools.ide.url.tool.jenkins; import java.util.regex.Pattern; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/JmcUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jmc/JmcUrlUpdater.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/tool/jmc/JmcUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jmc/JmcUrlUpdater.java index 699b5a9b7a..9f2fcdaae5 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/JmcUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jmc/JmcUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.jmc; +package com.devonfw.tools.ide.url.tool.jmc; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/kotlinc/KotlincNativeUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincNativeUrlUpdater.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/tool/kotlinc/KotlincNativeUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincNativeUrlUpdater.java index da7bb9d547..a963559908 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/kotlinc/KotlincNativeUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincNativeUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.kotlinc; +package com.devonfw.tools.ide.url.tool.kotlinc; import java.util.regex.Pattern; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/kotlinc/KotlincUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincUrlUpdater.java similarity index 94% rename from cli/src/main/java/com/devonfw/tools/ide/tool/kotlinc/KotlincUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincUrlUpdater.java index 79968ab7c1..6dba1e8710 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/kotlinc/KotlincUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.kotlinc; +package com.devonfw.tools.ide.url.tool.kotlinc; import java.util.regex.Pattern; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/lazydocker/LazyDockerUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/lazydocker/LazyDockerUrlUpdater.java similarity index 96% rename from cli/src/main/java/com/devonfw/tools/ide/tool/lazydocker/LazyDockerUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/lazydocker/LazyDockerUrlUpdater.java index 168e359533..24eadc1ff8 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/lazydocker/LazyDockerUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/lazydocker/LazyDockerUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.lazydocker; +package com.devonfw.tools.ide.url.tool.lazydocker; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn4UrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/Mvn4UrlUpdater.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn4UrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/Mvn4UrlUpdater.java index e6c855e93e..c71e4dfc53 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn4UrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/Mvn4UrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.mvn; +package com.devonfw.tools.ide.url.tool.mvn; import java.util.regex.Pattern; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/MvnUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/MvnUrlUpdater.java similarity index 94% rename from cli/src/main/java/com/devonfw/tools/ide/tool/mvn/MvnUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/MvnUrlUpdater.java index 5c7ab55ef0..423c60e5d4 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/MvnUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/MvnUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.mvn; +package com.devonfw.tools.ide.url.tool.mvn; import java.util.regex.Pattern; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/node/NodeUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/node/NodeUrlUpdater.java similarity index 97% rename from cli/src/main/java/com/devonfw/tools/ide/tool/node/NodeUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/node/NodeUrlUpdater.java index 8f0e40b78e..229b90b21b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/node/NodeUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/node/NodeUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.node; +package com.devonfw.tools.ide.url.tool.node; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/npm/NpmUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdater.java similarity index 88% rename from cli/src/main/java/com/devonfw/tools/ide/tool/npm/NpmUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdater.java index ae910b1ca7..8be230a233 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/npm/NpmUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.npm; +package com.devonfw.tools.ide.url.tool.npm; import com.devonfw.tools.ide.url.updater.NpmBasedUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/oc/OcUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/oc/OcUrlUpdater.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/tool/oc/OcUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/oc/OcUrlUpdater.java index b8f20c7aa4..e81a814412 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/oc/OcUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/oc/OcUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.oc; +package com.devonfw.tools.ide.url.tool.oc; import java.util.regex.Pattern; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/pgadmin/PgAdminUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pgadmin/PgAdminUrlUpdater.java similarity index 96% rename from cli/src/main/java/com/devonfw/tools/ide/tool/pgadmin/PgAdminUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pgadmin/PgAdminUrlUpdater.java index f43600137b..615813863c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/pgadmin/PgAdminUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pgadmin/PgAdminUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.pgadmin; +package com.devonfw.tools.ide.url.tool.pgadmin; import java.util.regex.Pattern; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdater.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdater.java index a1a601479a..693b72a6d1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.pip; +package com.devonfw.tools.ide.url.tool.pip; import java.util.regex.Pattern; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/python/PythonUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java similarity index 93% rename from cli/src/main/java/com/devonfw/tools/ide/tool/python/PythonUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java index de17bef4ed..f45f64bd1b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/python/PythonUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.python; +package com.devonfw.tools.ide.url.tool.python; import java.util.Collection; import java.util.List; @@ -7,6 +7,9 @@ import org.slf4j.LoggerFactory; import com.devonfw.tools.ide.json.JsonMapping; +import com.devonfw.tools.ide.tool.python.PythonFile; +import com.devonfw.tools.ide.tool.python.PythonJsonObject; +import com.devonfw.tools.ide.tool.python.PythonRelease; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/quarkus/QuarkusUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/quarkus/QuarkusUrlUpdater.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/tool/quarkus/QuarkusUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/quarkus/QuarkusUrlUpdater.java index f79129d332..addffe8d0d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/quarkus/QuarkusUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/quarkus/QuarkusUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.quarkus; +package com.devonfw.tools.ide.url.tool.quarkus; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/SonarUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/sonar/SonarUrlUpdater.java similarity index 93% rename from cli/src/main/java/com/devonfw/tools/ide/tool/sonar/SonarUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/sonar/SonarUrlUpdater.java index edb86b50c5..b902afa8a0 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/SonarUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/sonar/SonarUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.sonar; +package com.devonfw.tools.ide.url.tool.sonar; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/terraform/TerraformUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/terraform/TerraformUrlUpdater.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/tool/terraform/TerraformUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/terraform/TerraformUrlUpdater.java index 241b73965a..bf16fa0565 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/terraform/TerraformUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/terraform/TerraformUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.terraform; +package com.devonfw.tools.ide.url.tool.terraform; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/tomcat/TomcatUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/tomcat/TomcatUrlUpdater.java similarity index 93% rename from cli/src/main/java/com/devonfw/tools/ide/tool/tomcat/TomcatUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/tomcat/TomcatUrlUpdater.java index 7a33815109..09e800c437 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/tomcat/TomcatUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/tomcat/TomcatUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.tomcat; +package com.devonfw.tools.ide.url.tool.tomcat; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/vscode/VsCodeUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/vscode/VsCodeUrlUpdater.java similarity index 95% rename from cli/src/main/java/com/devonfw/tools/ide/tool/vscode/VsCodeUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/tool/vscode/VsCodeUrlUpdater.java index fc12b3e5bf..a187b2c41a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/vscode/VsCodeUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/vscode/VsCodeUrlUpdater.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.vscode; +package com.devonfw.tools.ide.url.tool.vscode; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.GithubUrlUpdater; diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/updater/AbstractProcessorWithTimeout.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractProcessorWithTimeout.java similarity index 100% rename from cli/src/main/java/com/devonfw/tools/ide/url/updater/AbstractProcessorWithTimeout.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractProcessorWithTimeout.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java similarity index 99% rename from cli/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java index eba14898f4..29e24e4427 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java @@ -38,6 +38,7 @@ import com.devonfw.tools.ide.url.model.folder.UrlTool; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.model.report.UrlUpdaterReport; +import com.devonfw.tools.ide.url.tool.pip.PipUrlUpdater; import com.devonfw.tools.ide.util.DateTimeUtil; import com.devonfw.tools.ide.util.HexUtil; @@ -363,8 +364,7 @@ private boolean isValidDownload(String url, String toolWithEdition, String versi } /** - * Checks if the content type was not of type text (this method is required because {@link com.devonfw.tools.ide.tool.pip.PipUrlUpdater} returns text and - * needs to be overridden) + * Checks if the content type was not of type text (this method is required because {@link PipUrlUpdater} returns text and needs to be overridden) *

* See: #1343 for reference. * diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/updater/GithubUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/GithubUrlUpdater.java similarity index 100% rename from cli/src/main/java/com/devonfw/tools/ide/url/updater/GithubUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/updater/GithubUrlUpdater.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/updater/JsonUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/JsonUrlUpdater.java similarity index 100% rename from cli/src/main/java/com/devonfw/tools/ide/url/updater/JsonUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/updater/JsonUrlUpdater.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/updater/MavenBasedUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/MavenBasedUrlUpdater.java similarity index 100% rename from cli/src/main/java/com/devonfw/tools/ide/url/updater/MavenBasedUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/updater/MavenBasedUrlUpdater.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/updater/NpmBasedUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/NpmBasedUrlUpdater.java similarity index 100% rename from cli/src/main/java/com/devonfw/tools/ide/url/updater/NpmBasedUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/updater/NpmBasedUrlUpdater.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java similarity index 61% rename from cli/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java index be8954257b..8fe278f9eb 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java @@ -8,45 +8,45 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.devonfw.tools.ide.tool.androidstudio.AndroidStudioUrlUpdater; -import com.devonfw.tools.ide.tool.aws.AwsUrlUpdater; -import com.devonfw.tools.ide.tool.az.AzureUrlUpdater; -import com.devonfw.tools.ide.tool.docker.DockerDesktopUrlUpdater; -import com.devonfw.tools.ide.tool.docker.DockerRancherDesktopUrlUpdater; -import com.devonfw.tools.ide.tool.dotnet.DotNetUrlUpdater; -import com.devonfw.tools.ide.tool.eclipse.EclipseCppUrlUpdater; -import com.devonfw.tools.ide.tool.eclipse.EclipseJavaUrlUpdater; -import com.devonfw.tools.ide.tool.eclipse.EclipseJeeUrlUpdater; -import com.devonfw.tools.ide.tool.gcloud.GCloudUrlUpdater; -import com.devonfw.tools.ide.tool.gcviewer.GcViewerUrlUpdater; -import com.devonfw.tools.ide.tool.gh.GhUrlUpdater; -import com.devonfw.tools.ide.tool.graalvm.GraalVmCommunityUpdater; -import com.devonfw.tools.ide.tool.graalvm.GraalVmOracleUrlUpdater; -import com.devonfw.tools.ide.tool.gradle.GradleUrlUpdater; -import com.devonfw.tools.ide.tool.helm.HelmUrlUpdater; -import com.devonfw.tools.ide.tool.intellij.IntellijUrlUpdater; -import com.devonfw.tools.ide.tool.jasypt.JasyptUrlUpdater; -import com.devonfw.tools.ide.tool.java.JavaUrlUpdater; -import com.devonfw.tools.ide.tool.jenkins.JenkinsUrlUpdater; -import com.devonfw.tools.ide.tool.jmc.JmcUrlUpdater; -import com.devonfw.tools.ide.tool.kotlinc.KotlincNativeUrlUpdater; -import com.devonfw.tools.ide.tool.kotlinc.KotlincUrlUpdater; -import com.devonfw.tools.ide.tool.lazydocker.LazyDockerUrlUpdater; -import com.devonfw.tools.ide.tool.mvn.Mvn4UrlUpdater; -import com.devonfw.tools.ide.tool.mvn.MvnUrlUpdater; -import com.devonfw.tools.ide.tool.node.NodeUrlUpdater; -import com.devonfw.tools.ide.tool.npm.NpmUrlUpdater; -import com.devonfw.tools.ide.tool.oc.OcUrlUpdater; -import com.devonfw.tools.ide.tool.pgadmin.PgAdminUrlUpdater; -import com.devonfw.tools.ide.tool.pip.PipUrlUpdater; -import com.devonfw.tools.ide.tool.python.PythonUrlUpdater; -import com.devonfw.tools.ide.tool.quarkus.QuarkusUrlUpdater; -import com.devonfw.tools.ide.tool.sonar.SonarUrlUpdater; -import com.devonfw.tools.ide.tool.terraform.TerraformUrlUpdater; -import com.devonfw.tools.ide.tool.tomcat.TomcatUrlUpdater; -import com.devonfw.tools.ide.tool.vscode.VsCodeUrlUpdater; import com.devonfw.tools.ide.url.model.folder.UrlRepository; import com.devonfw.tools.ide.url.model.report.UrlFinalReport; +import com.devonfw.tools.ide.url.tool.androidstudio.AndroidStudioUrlUpdater; +import com.devonfw.tools.ide.url.tool.aws.AwsUrlUpdater; +import com.devonfw.tools.ide.url.tool.az.AzureUrlUpdater; +import com.devonfw.tools.ide.url.tool.docker.DockerDesktopUrlUpdater; +import com.devonfw.tools.ide.url.tool.docker.DockerRancherDesktopUrlUpdater; +import com.devonfw.tools.ide.url.tool.dotnet.DotNetUrlUpdater; +import com.devonfw.tools.ide.url.tool.eclipse.EclipseCppUrlUpdater; +import com.devonfw.tools.ide.url.tool.eclipse.EclipseJavaUrlUpdater; +import com.devonfw.tools.ide.url.tool.eclipse.EclipseJeeUrlUpdater; +import com.devonfw.tools.ide.url.tool.gcloud.GCloudUrlUpdater; +import com.devonfw.tools.ide.url.tool.gcviewer.GcViewerUrlUpdater; +import com.devonfw.tools.ide.url.tool.gh.GhUrlUpdater; +import com.devonfw.tools.ide.url.tool.graalvm.GraalVmCommunityUpdater; +import com.devonfw.tools.ide.url.tool.graalvm.GraalVmOracleUrlUpdater; +import com.devonfw.tools.ide.url.tool.gradle.GradleUrlUpdater; +import com.devonfw.tools.ide.url.tool.helm.HelmUrlUpdater; +import com.devonfw.tools.ide.url.tool.intellij.IntellijUrlUpdater; +import com.devonfw.tools.ide.url.tool.jasypt.JasyptUrlUpdater; +import com.devonfw.tools.ide.url.tool.java.JavaUrlUpdater; +import com.devonfw.tools.ide.url.tool.jenkins.JenkinsUrlUpdater; +import com.devonfw.tools.ide.url.tool.jmc.JmcUrlUpdater; +import com.devonfw.tools.ide.url.tool.kotlinc.KotlincNativeUrlUpdater; +import com.devonfw.tools.ide.url.tool.kotlinc.KotlincUrlUpdater; +import com.devonfw.tools.ide.url.tool.lazydocker.LazyDockerUrlUpdater; +import com.devonfw.tools.ide.url.tool.mvn.Mvn4UrlUpdater; +import com.devonfw.tools.ide.url.tool.mvn.MvnUrlUpdater; +import com.devonfw.tools.ide.url.tool.node.NodeUrlUpdater; +import com.devonfw.tools.ide.url.tool.npm.NpmUrlUpdater; +import com.devonfw.tools.ide.url.tool.oc.OcUrlUpdater; +import com.devonfw.tools.ide.url.tool.pgadmin.PgAdminUrlUpdater; +import com.devonfw.tools.ide.url.tool.pip.PipUrlUpdater; +import com.devonfw.tools.ide.url.tool.python.PythonUrlUpdater; +import com.devonfw.tools.ide.url.tool.quarkus.QuarkusUrlUpdater; +import com.devonfw.tools.ide.url.tool.sonar.SonarUrlUpdater; +import com.devonfw.tools.ide.url.tool.terraform.TerraformUrlUpdater; +import com.devonfw.tools.ide.url.tool.tomcat.TomcatUrlUpdater; +import com.devonfw.tools.ide.url.tool.vscode.VsCodeUrlUpdater; /** * The {@code UpdateManager} class manages the update process for various tools by using a list of {@link AbstractUrlUpdater}s to update the diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/updater/UrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UrlUpdater.java similarity index 100% rename from cli/src/main/java/com/devonfw/tools/ide/url/updater/UrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UrlUpdater.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/updater/WebsiteUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/WebsiteUrlUpdater.java similarity index 100% rename from cli/src/main/java/com/devonfw/tools/ide/url/updater/WebsiteUrlUpdater.java rename to url-updater/src/main/java/com/devonfw/tools/ide/url/updater/WebsiteUrlUpdater.java diff --git a/url-updater/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/url-updater/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider new file mode 100644 index 0000000000..0bb90a9c2b --- /dev/null +++ b/url-updater/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider @@ -0,0 +1 @@ +ch.qos.logback.classic.spi.LogbackServiceProvider diff --git a/cli/src/test/java/com/devonfw/tools/ide/url/report/UrlUpdaterReportTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/report/UrlUpdaterReportTest.java similarity index 98% rename from cli/src/test/java/com/devonfw/tools/ide/url/report/UrlUpdaterReportTest.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/report/UrlUpdaterReportTest.java index 7ac5e32a8a..c918208a9f 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/url/report/UrlUpdaterReportTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/report/UrlUpdaterReportTest.java @@ -13,11 +13,11 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import com.devonfw.tools.ide.tool.AbstractUrlUpdaterTest; -import com.devonfw.tools.ide.tool.UrlUpdaterMock; import com.devonfw.tools.ide.url.model.folder.UrlRepository; import com.devonfw.tools.ide.url.model.report.UrlFinalReport; import com.devonfw.tools.ide.url.model.report.UrlUpdaterReport; +import com.devonfw.tools.ide.url.tool.AbstractUrlUpdaterTest; +import com.devonfw.tools.ide.url.tool.UrlUpdaterMock; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/AbstractUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/AbstractUrlUpdaterTest.java similarity index 96% rename from cli/src/test/java/com/devonfw/tools/ide/tool/AbstractUrlUpdaterTest.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/AbstractUrlUpdaterTest.java index 09f0fd5c15..0429716572 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/AbstractUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/AbstractUrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool; +package com.devonfw.tools.ide.url.tool; import org.assertj.core.api.Assertions; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMock.java similarity index 97% rename from cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMock.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMock.java index 9911aca7c2..cdb98c21b6 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMock.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMock.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool; +package com.devonfw.tools.ide.url.tool; import java.util.Arrays; import java.util.HashSet; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockSingle.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java similarity index 96% rename from cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockSingle.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java index b31272829c..3ca4b44072 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockSingle.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool; +package com.devonfw.tools.ide.url.tool; import java.util.HashSet; import java.util.List; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java similarity index 96% rename from cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java index b312a98a57..45bd77a3a6 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool; +package com.devonfw.tools.ide.url.tool; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.any; @@ -27,11 +27,12 @@ import com.devonfw.tools.ide.url.model.folder.UrlRepository; import com.devonfw.tools.ide.url.model.folder.UrlTool; import com.devonfw.tools.ide.url.model.folder.UrlVersion; +import com.devonfw.tools.ide.url.updater.UrlUpdater; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; /** - * Test of {@link com.devonfw.tools.ide.url.updater.UrlUpdater} using wiremock to simulate network downloads. + * Test of {@link UrlUpdater} using wiremock to simulate network downloads. */ @WireMockTest public class UrlUpdaterTest extends AbstractUrlUpdaterTest { @@ -42,7 +43,7 @@ public class UrlUpdaterTest extends AbstractUrlUpdaterTest { private final static String TEST_DATA_ROOT = "src/test/resources/integrationtest/UrlUpdaterTest"; /** - * Tests if the {@link com.devonfw.tools.ide.url.updater.UrlUpdater} can automatically add a missing OS (in this case the linux_x64) + * Tests if the {@link UrlUpdater} can automatically add a missing OS (in this case the linux_x64) * * @param tempDir Temporary directory * @param wmRuntimeInfo wireMock server on a random port @@ -254,7 +255,7 @@ public void testVersionRemovedIfErrorPersists(@TempDir Path tempDir, WireMockRun } /** - * Tests if the {@link com.devonfw.tools.ide.url.updater.UrlUpdater} will fail resolving a server with a Content-Type:text header response. + * Tests if the {@link UrlUpdater} will fail resolving a server with a Content-Type:text header response. *

* See: #1343 for reference. * diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/androidstudio/AndroidStudioJsonUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioJsonUrlUpdaterTest.java similarity index 99% rename from cli/src/test/java/com/devonfw/tools/ide/tool/androidstudio/AndroidStudioJsonUrlUpdaterTest.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioJsonUrlUpdaterTest.java index bb88cd62d6..2190f18180 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/androidstudio/AndroidStudioJsonUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioJsonUrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.androidstudio; +package com.devonfw.tools.ide.url.tool.androidstudio; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.any; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/androidstudio/AndroidStudioUrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdaterMock.java similarity index 92% rename from cli/src/test/java/com/devonfw/tools/ide/tool/androidstudio/AndroidStudioUrlUpdaterMock.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdaterMock.java index 67fd8919ef..7d7dcb13f2 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/androidstudio/AndroidStudioUrlUpdaterMock.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdaterMock.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.androidstudio; +package com.devonfw.tools.ide.url.tool.androidstudio; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijJsonUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/intellij/IntellijJsonUrlUpdaterTest.java similarity index 99% rename from cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijJsonUrlUpdaterTest.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/intellij/IntellijJsonUrlUpdaterTest.java index 523b1b6dd9..683994e841 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijJsonUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/intellij/IntellijJsonUrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.intellij; +package com.devonfw.tools.ide.url.tool.intellij; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.any; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijUrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdaterMock.java similarity index 92% rename from cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijUrlUpdaterMock.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdaterMock.java index 4c570ac310..65f8983287 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijUrlUpdaterMock.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdaterMock.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.intellij; +package com.devonfw.tools.ide.url.tool.intellij; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/java/JavaUrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdaterMock.java similarity index 92% rename from cli/src/test/java/com/devonfw/tools/ide/tool/java/JavaUrlUpdaterMock.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdaterMock.java index a697779277..8fc377c562 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/java/JavaUrlUpdaterMock.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdaterMock.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.java; +package com.devonfw.tools.ide.url.tool.java; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/java/JavaUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdaterTest.java similarity index 97% rename from cli/src/test/java/com/devonfw/tools/ide/tool/java/JavaUrlUpdaterTest.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdaterTest.java index bd89e5285f..648bbba3ba 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/java/JavaUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.java; +package com.devonfw.tools.ide.url.tool.java; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.any; @@ -14,8 +14,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import com.devonfw.tools.ide.tool.npm.NpmUrlUpdater; import com.devonfw.tools.ide.url.model.folder.UrlRepository; +import com.devonfw.tools.ide.url.tool.npm.NpmUrlUpdater; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/npm/NpmJsonUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/npm/NpmJsonUrlUpdaterTest.java similarity index 99% rename from cli/src/test/java/com/devonfw/tools/ide/tool/npm/NpmJsonUrlUpdaterTest.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/npm/NpmJsonUrlUpdaterTest.java index 0c740bc981..68575ad22c 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/npm/NpmJsonUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/npm/NpmJsonUrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.npm; +package com.devonfw.tools.ide.url.tool.npm; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.any; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/npm/NpmUrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdaterMock.java similarity index 91% rename from cli/src/test/java/com/devonfw/tools/ide/tool/npm/NpmUrlUpdaterMock.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdaterMock.java index c54b024af2..d27158d122 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/npm/NpmUrlUpdaterMock.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdaterMock.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.npm; +package com.devonfw.tools.ide.url.tool.npm; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/pip/PipUrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterMock.java similarity index 95% rename from cli/src/test/java/com/devonfw/tools/ide/tool/pip/PipUrlUpdaterMock.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterMock.java index c84ffc177d..9fa92a0c27 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/pip/PipUrlUpdaterMock.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterMock.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.pip; +package com.devonfw.tools.ide.url.tool.pip; import java.util.HashSet; import java.util.List; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/pip/PipUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java similarity index 80% rename from cli/src/test/java/com/devonfw/tools/ide/tool/pip/PipUrlUpdaterTest.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java index dcb0477046..ad1dac8f77 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/pip/PipUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.pip; +package com.devonfw.urls.tool.pip; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.any; @@ -8,13 +8,16 @@ import java.nio.file.Path; import java.time.Instant; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import com.devonfw.tools.ide.tool.AbstractUrlUpdaterTest; import com.devonfw.tools.ide.url.model.file.json.StatusJson; import com.devonfw.tools.ide.url.model.file.json.UrlStatus; import com.devonfw.tools.ide.url.model.folder.UrlRepository; +import com.devonfw.tools.ide.url.tool.AbstractUrlUpdaterTest; +import com.devonfw.tools.ide.url.tool.pip.PipUrlUpdater; +import com.devonfw.tools.ide.url.tool.pip.PipUrlUpdaterMock; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; @@ -25,7 +28,7 @@ public class PipUrlUpdaterTest extends AbstractUrlUpdaterTest { /** - * Tests if the {@link com.devonfw.tools.ide.tool.pip.PipUrlUpdater} will successfully resolve a server with a Content-Type:text header response. + * Tests if the {@link PipUrlUpdater} will successfully resolve a server with a Content-Type:text header response. *

* See: #1343 for reference. * @@ -53,13 +56,13 @@ public void testPipUrlUpdaterWithTextContentTypeWillSucceed(@TempDir Path tempDi Path versionsPath = tempDir.resolve(toolName).resolve(editionName).resolve(versionName); // then - assertThat(versionsPath.resolve("status.json")).exists(); + Assertions.assertThat(versionsPath.resolve("status.json")).exists(); StatusJson statusJson = retrieveStatusJson(urlRepository, toolName, editionName, versionName); UrlStatus urlStatus = statusJson.getOrCreateUrlStatus(statusUrl); Instant successTimestamp = urlStatus.getSuccess().getTimestamp(); - assertThat(successTimestamp).isNotNull(); + Assertions.assertThat(successTimestamp).isNotNull(); } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/python/PythonUrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterMock.java similarity index 85% rename from cli/src/test/java/com/devonfw/tools/ide/tool/python/PythonUrlUpdaterMock.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterMock.java index 9de6ee14e2..0b9121f525 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/python/PythonUrlUpdaterMock.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterMock.java @@ -1,5 +1,6 @@ -package com.devonfw.tools.ide.tool.python; +package com.devonfw.urls.tool.python; +import com.devonfw.tools.ide.url.tool.python.PythonUrlUpdater; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; /** diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/python/PythonUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterTest.java similarity index 98% rename from cli/src/test/java/com/devonfw/tools/ide/tool/python/PythonUrlUpdaterTest.java rename to url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterTest.java index df7dd3c727..8ef536a451 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/python/PythonUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.tool.python; +package com.devonfw.urls.tool.python; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.any; diff --git a/cli/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version-without-checksum.json b/url-updater/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version-without-checksum.json similarity index 100% rename from cli/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version-without-checksum.json rename to url-updater/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version-without-checksum.json diff --git a/cli/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version.json b/url-updater/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version.json similarity index 100% rename from cli/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version.json rename to url-updater/src/test/resources/integrationtest/AndroidStudioJsonUrlUpdater/android-version.json diff --git a/cli/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version-without-checksum.json b/url-updater/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version-without-checksum.json similarity index 100% rename from cli/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version-without-checksum.json rename to url-updater/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version-without-checksum.json diff --git a/cli/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version.json b/url-updater/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version.json similarity index 100% rename from cli/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version.json rename to url-updater/src/test/resources/integrationtest/IntellijJsonUrlUpdater/intellij-version.json diff --git a/cli/src/test/resources/integrationtest/JavaJsonUrlUpdater/java-version.json b/url-updater/src/test/resources/integrationtest/JavaJsonUrlUpdater/java-version.json similarity index 100% rename from cli/src/test/resources/integrationtest/JavaJsonUrlUpdater/java-version.json rename to url-updater/src/test/resources/integrationtest/JavaJsonUrlUpdater/java-version.json diff --git a/cli/src/test/resources/integrationtest/NpmJsonUrlUpdater/npm-version.json b/url-updater/src/test/resources/integrationtest/NpmJsonUrlUpdater/npm-version.json similarity index 100% rename from cli/src/test/resources/integrationtest/NpmJsonUrlUpdater/npm-version.json rename to url-updater/src/test/resources/integrationtest/NpmJsonUrlUpdater/npm-version.json diff --git a/cli/src/test/resources/integrationtest/PythonJsonUrlUpdater/python-version.json b/url-updater/src/test/resources/integrationtest/PythonJsonUrlUpdater/python-version.json similarity index 100% rename from cli/src/test/resources/integrationtest/PythonJsonUrlUpdater/python-version.json rename to url-updater/src/test/resources/integrationtest/PythonJsonUrlUpdater/python-version.json diff --git a/cli/src/test/resources/integrationtest/UrlUpdaterTest/mocked/mocked/1.0/status.json b/url-updater/src/test/resources/integrationtest/UrlUpdaterTest/mocked/mocked/1.0/status.json similarity index 100% rename from cli/src/test/resources/integrationtest/UrlUpdaterTest/mocked/mocked/1.0/status.json rename to url-updater/src/test/resources/integrationtest/UrlUpdaterTest/mocked/mocked/1.0/status.json From 793417a834470f01371112ae2297b32136a16228 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Wed, 5 Feb 2025 11:07:03 +0100 Subject: [PATCH 12/51] #404: fixed github actions workflow --- .github/workflows/update-urls.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-urls.yml b/.github/workflows/update-urls.yml index 491077e5aa..56f89e71d2 100644 --- a/.github/workflows/update-urls.yml +++ b/.github/workflows/update-urls.yml @@ -25,7 +25,7 @@ jobs: cache: 'maven' - name: Build and run url updater run: | - cd cli + cd url-updater mvn -B -ntp -Dstyle.color=always install mvn -B -ntp -Dstyle.color=always exec:java -Dexec.mainClass="com.devonfw.tools.ide.url.UpdateInitiator" -Dexec.args="../ide-urls PT5H30M" - name: Commit and push to ide-urls From 72f20001bc7f630c11a973b2e68b6a3f2d3c5044 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Wed, 5 Feb 2025 11:49:32 +0100 Subject: [PATCH 13/51] #404: fixed test package names --- .../com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java | 4 +--- .../tools/ide/url/tool/python/PythonUrlUpdaterMock.java | 3 +-- .../tools/ide/url/tool/python/PythonUrlUpdaterTest.java | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java index ad1dac8f77..f6feb87bf3 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.urls.tool.pip; +package com.devonfw.tools.ide.url.tool.pip; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.any; @@ -16,8 +16,6 @@ import com.devonfw.tools.ide.url.model.file.json.UrlStatus; import com.devonfw.tools.ide.url.model.folder.UrlRepository; import com.devonfw.tools.ide.url.tool.AbstractUrlUpdaterTest; -import com.devonfw.tools.ide.url.tool.pip.PipUrlUpdater; -import com.devonfw.tools.ide.url.tool.pip.PipUrlUpdaterMock; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterMock.java index 0b9121f525..393f1488d6 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterMock.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterMock.java @@ -1,6 +1,5 @@ -package com.devonfw.urls.tool.python; +package com.devonfw.tools.ide.url.tool.python; -import com.devonfw.tools.ide.url.tool.python.PythonUrlUpdater; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; /** diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterTest.java index 8ef536a451..a6f56ffd9c 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdaterTest.java @@ -1,4 +1,4 @@ -package com.devonfw.urls.tool.python; +package com.devonfw.tools.ide.url.tool.python; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.any; From e70b96e8e2443e2d03256649125544ae5ff6f734 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Wed, 5 Feb 2025 11:52:27 +0100 Subject: [PATCH 14/51] #404: fixed assertThat import --- .../ide/url/model/file/UrlStatusFileTest.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/UrlStatusFileTest.java b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/UrlStatusFileTest.java index 02d9fdb5b6..fa785e79c8 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/UrlStatusFileTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/UrlStatusFileTest.java @@ -2,7 +2,6 @@ import java.time.Instant; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import com.devonfw.tools.ide.url.model.AbstractUrlModelTest; @@ -34,16 +33,16 @@ public void testReadJson() { UrlStatusFile status = version.getOrCreateStatus(); StatusJson statusJson = status.getStatusJson(); // then - Assertions.assertThat(statusJson.getUrls()).hasSize(1); + assertThat(statusJson.getUrls()).hasSize(1); UrlStatus urlStatus = statusJson.getUrls().values().iterator().next(); UrlStatusState success = urlStatus.getSuccess(); - Assertions.assertThat(success.getTimestamp()).isEqualTo(Instant.parse("2023-02-21T15:03:09.387386Z")); - Assertions.assertThat(success.getCode()).isNull(); - Assertions.assertThat(success.getMessage()).isNull(); + assertThat(success.getTimestamp()).isEqualTo(Instant.parse("2023-02-21T15:03:09.387386Z")); + assertThat(success.getCode()).isNull(); + assertThat(success.getMessage()).isNull(); UrlStatusState error = urlStatus.getError(); - Assertions.assertThat(error.getTimestamp()).isEqualTo(Instant.parse("2023-01-01T23:59:59.999999Z")); - Assertions.assertThat(error.getCode()).isEqualTo(500); - Assertions.assertThat(error.getMessage()).isEqualTo("core dumped"); + assertThat(error.getTimestamp()).isEqualTo(Instant.parse("2023-01-01T23:59:59.999999Z")); + assertThat(error.getCode()).isEqualTo(500); + assertThat(error.getMessage()).isEqualTo("core dumped"); } } From eca4217e183a226281616e18310857adc8121aff Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Wed, 5 Feb 2025 11:57:00 +0100 Subject: [PATCH 15/51] #404: removed FQN --- .../ide/url/model/file/json/StatusJsonTest.java | 2 +- .../url/model/file/json/ToolDependenciesTest.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/StatusJsonTest.java b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/StatusJsonTest.java index 34e79e562d..6216b143d4 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/StatusJsonTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/StatusJsonTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test; /** - * Test of {@link com.devonfw.tools.ide.url.model.file.json.StatusJson}. + * Test of {@link StatusJson}. */ public class StatusJsonTest extends Assertions { diff --git a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/ToolDependenciesTest.java b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/ToolDependenciesTest.java index d28862c1d7..91a307e724 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/ToolDependenciesTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/url/model/file/json/ToolDependenciesTest.java @@ -11,7 +11,7 @@ import com.devonfw.tools.ide.version.VersionRange; /** - * Test of {@link com.devonfw.tools.ide.url.model.file.json.ToolDependencies} and {@link AbstractUrlToolOrEdition#getDependencyFile()}. + * Test of {@link ToolDependencies} and {@link AbstractUrlToolOrEdition#getDependencyFile()}. */ public class ToolDependenciesTest extends AbstractUrlModelTest { @@ -23,11 +23,11 @@ public void testEditionSpecific() { IdeContext context = newContext(); // act - Collection dependencies = context.getDefaultToolRepository() + Collection dependencies = context.getDefaultToolRepository() .findDependencies("tomcat", "tomcat", VersionIdentifier.of("11.0.0")); // assert - assertThat(dependencies).containsExactly(new com.devonfw.tools.ide.url.model.file.json.ToolDependency("java", VersionRange.of("[17,)"))); + assertThat(dependencies).containsExactly(new ToolDependency("java", VersionRange.of("[17,)"))); } @Test @@ -37,12 +37,12 @@ public void testEditionFallback() { IdeContext context = newContext(); // act - Collection dependencies = context.getDefaultToolRepository() + Collection dependencies = context.getDefaultToolRepository() .findDependencies("tomcat", "undefined", VersionIdentifier.of("11.0.0")); // assert assertThat(dependencies).containsExactly( - new com.devonfw.tools.ide.url.model.file.json.ToolDependency("this-is-the-wrong-file-only-for-testing", VersionRange.of("[1.0,2.0]"))); + new ToolDependency("this-is-the-wrong-file-only-for-testing", VersionRange.of("[1.0,2.0]"))); } @Test @@ -52,7 +52,7 @@ public void testEditionUnspecific() { IdeContext context = newContext(); // act - Collection dependencies = context.getDefaultToolRepository() + Collection dependencies = context.getDefaultToolRepository() .findDependencies("mvn", "undefined", VersionIdentifier.of("3.9.0")); // assert From cc145f3e99a50908248bc74865d5ae308f806be4 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Wed, 5 Feb 2025 12:02:55 +0100 Subject: [PATCH 16/51] #404: fixed assertThat import --- .../devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java index f6feb87bf3..007f47cc7e 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/pip/PipUrlUpdaterTest.java @@ -8,7 +8,6 @@ import java.nio.file.Path; import java.time.Instant; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -54,13 +53,13 @@ public void testPipUrlUpdaterWithTextContentTypeWillSucceed(@TempDir Path tempDi Path versionsPath = tempDir.resolve(toolName).resolve(editionName).resolve(versionName); // then - Assertions.assertThat(versionsPath.resolve("status.json")).exists(); + assertThat(versionsPath.resolve("status.json")).exists(); StatusJson statusJson = retrieveStatusJson(urlRepository, toolName, editionName, versionName); UrlStatus urlStatus = statusJson.getOrCreateUrlStatus(statusUrl); Instant successTimestamp = urlStatus.getSuccess().getTimestamp(); - Assertions.assertThat(successTimestamp).isNotNull(); + assertThat(successTimestamp).isNotNull(); } } From 1beb57d7c7b43edb5a49ee245b711e544dd27d5a Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Fri, 7 Feb 2025 11:27:00 +0100 Subject: [PATCH 17/51] #404: implemented requested changes applied reformat --- .../com/devonfw/tools/ide/log/AbstractIdeSubLogger.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java b/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java index bb8215482a..a1c2080673 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java @@ -141,7 +141,7 @@ public String log(Throwable error, String message, Object... args) { String actualMessage = message; if (error != null) { if (isOmitStacktrace(error)) { - if (message == null) { + if (message == null) { actualMessage = error.getMessage(); } error = null; @@ -150,9 +150,9 @@ public String log(Throwable error, String message, Object... args) { } } if (actualMessage == null) { - actualMessage = "Internal error: Both message and error is null - nothing to log!"; - // fail fast if assertions are enabled, so developers of IDEasy will find the bug immediately but in productive use better log the error and continue - assert false : actualMessage; + actualMessage = "Internal error: Both message and error is null - nothing to log!"; + // fail fast if assertions are enabled, so developers of IDEasy will find the bug immediately but in productive use better log the error and continue + assert false : actualMessage; } else if ((args != null) && (args.length > 0)) { actualMessage = compose(actualMessage, args); } From b87d21a9cff73e2422850f960d49845d5149d39f Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 31 Mar 2025 12:39:10 +0200 Subject: [PATCH 18/51] #404: removed outdated imports --- .../ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java | 3 --- .../tools/ide/url/tool/intellij/IntellijUrlUpdater.java | 3 --- .../com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java | 2 -- .../devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java | 3 --- .../com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java | 1 - 5 files changed, 12 deletions(-) diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java index 50fa57f41a..5c956c0df2 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java @@ -5,9 +5,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.devonfw.tools.ide.tool.androidstudio.AndroidJsonDownload; -import com.devonfw.tools.ide.tool.androidstudio.AndroidJsonItem; -import com.devonfw.tools.ide.tool.androidstudio.AndroidJsonObject; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java index 9ee40b8d88..e62c383dc2 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java @@ -7,9 +7,6 @@ import com.devonfw.tools.ide.json.JsonVersionItem; import com.devonfw.tools.ide.os.OperatingSystem; import com.devonfw.tools.ide.os.SystemArchitecture; -import com.devonfw.tools.ide.tool.intellij.IntellijJsonDownloadsItem; -import com.devonfw.tools.ide.tool.intellij.IntellijJsonObject; -import com.devonfw.tools.ide.tool.intellij.IntellijJsonRelease; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java index 3456396c15..a28e111a26 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java @@ -2,8 +2,6 @@ import java.util.Collection; -import com.devonfw.tools.ide.tool.java.JavaJsonObject; -import com.devonfw.tools.ide.tool.java.JavaJsonVersion; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java index f45f64bd1b..4afad2944a 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java @@ -7,9 +7,6 @@ import org.slf4j.LoggerFactory; import com.devonfw.tools.ide.json.JsonMapping; -import com.devonfw.tools.ide.tool.python.PythonFile; -import com.devonfw.tools.ide.tool.python.PythonJsonObject; -import com.devonfw.tools.ide.tool.python.PythonRelease; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.updater.JsonUrlUpdater; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java index f2e34a8bb5..67e5751dee 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java @@ -38,7 +38,6 @@ import com.devonfw.tools.ide.url.model.folder.UrlTool; import com.devonfw.tools.ide.url.model.folder.UrlVersion; import com.devonfw.tools.ide.url.model.report.UrlUpdaterReport; -import com.devonfw.tools.ide.url.tool.pip.PipUrlUpdater; import com.devonfw.tools.ide.util.DateTimeUtil; import com.devonfw.tools.ide.util.HexUtil; From e21c0a29016d3cec352f4a4cdebd1fb54ec618dc Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Tue, 1 Apr 2025 09:56:18 +0200 Subject: [PATCH 19/51] #404: removed jackson-core dependency --- cli/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cli/pom.xml b/cli/pom.xml index bfe5dc3c7f..894134a1c2 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -31,11 +31,6 @@ org.eclipse.parsson parsson - - com.fasterxml.jackson.core - jackson-core - ${jackson.version} - com.fasterxml.jackson.core jackson-databind From 1b924df4013cda3f2c38cc685c41734e52b0959f Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 28 Apr 2025 22:08:03 +0200 Subject: [PATCH 20/51] #404 implemented requested changes fixed code format --- .../tools/ide/context/AbstractIdeContext.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 6e83b6a0c5..f30d79fb69 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -183,7 +183,7 @@ public AbstractIdeContext(IdeStartContextImpl startContext, Path workingDirector if ((ideRootPath != null) && (ideRootPath.equals(currentDir))) { // prevent that during tests we traverse to the real IDE project of IDEasy developer currentDir = null; - } + } } // detection completed, initializing variables @@ -415,7 +415,7 @@ public Path getIdePath() { Path myIdeRoot = getIdeRoot(); if (myIdeRoot == null) { return null; - } + } return myIdeRoot.resolve(FOLDER_UNDERSCORE_IDE); } @@ -431,7 +431,7 @@ public Path getTempPath() { Path idePath = getIdePath(); if (idePath == null) { return null; - } + } return idePath.resolve("tmp"); } @@ -441,7 +441,7 @@ public Path getTempDownloadPath() { Path tmp = getTempPath(); if (tmp == null) { return null; - } + } return tmp.resolve(FOLDER_DOWNLOADS); } @@ -502,7 +502,7 @@ public Path getSoftwarePath() { if (this.ideHome == null) { return null; - } + } return this.ideHome.resolve(FOLDER_SOFTWARE); } @@ -512,7 +512,7 @@ public Path getSoftwareExtraPath() { Path softwarePath = getSoftwarePath(); if (softwarePath == null) { return null; - } + } return softwarePath.resolve(FOLDER_EXTRA); } @@ -522,7 +522,7 @@ public Path getSoftwareRepositoryPath() { Path idePath = getIdePath(); if (idePath == null) { return null; - } + } return idePath.resolve(FOLDER_SOFTWARE); } @@ -556,7 +556,7 @@ public Path getUrlsPath() { Path idePath = getIdePath(); if (idePath == null) { return null; - } + } return idePath.resolve(FOLDER_URLS); } @@ -566,7 +566,7 @@ public Path getToolRepositoryPath() { Path idePath = getIdePath(); if (idePath == null) { return null; - } + } return idePath.resolve(FOLDER_SOFTWARE); } From 31486250676c8b9af2464bd37c06c42e1629bc4d Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 28 Apr 2025 22:09:41 +0200 Subject: [PATCH 21/51] #404 implemented requested changes removed unused code --- cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java b/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java index ba608c01f3..49ed9b548b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java +++ b/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java @@ -3,9 +3,6 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.devonfw.tools.ide.commandlet.ContextCommandlet; import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; @@ -22,8 +19,6 @@ public final class Ideasy { private AbstractIdeContext context; - private static final Logger logger = LoggerFactory.getLogger(Ideasy.class); - /** * The default constructor. */ From 32e2ac835b191ce93f90b25ce877990d754381e0 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 7 Jul 2025 15:19:26 +0200 Subject: [PATCH 22/51] #404: implemented requested changes set loggingContext to private added getter for loggingContext added check to ignore WireMock specific log messages removed logback-classic from dependencies --- cli/pom.xml | 5 ----- .../tools/ide/context/AbstractIdeContext.java | 12 +++++++++++- .../ide/serviceprovider/IdeLoggerAdapter.java | 17 ++++++++++++++--- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/cli/pom.xml b/cli/pom.xml index 894134a1c2..1609facee8 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -49,11 +49,6 @@ slf4j-api - - ch.qos.logback - logback-classic - - org.graalvm.sdk nativeimage diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 6d8e718560..816dfd44d2 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -147,7 +147,7 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt private final Map privacyMap; /** Context used for logging */ - public static IdeContext loggingContext; + private static IdeContext loggingContext; /** * The constructor. @@ -1465,4 +1465,14 @@ public void writeVersionFile(VersionIdentifier version, Path installationPath) { getFileAccess().writeFileContent(version.toString(), versionFile); } + /** + * Gets the logging context. + * + * @return {@link IdeContext}. + */ + public static IdeContext getLoggingContext() { + + return loggingContext; + } + } diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java index 4f44076a0c..3dd361e418 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java @@ -1,10 +1,11 @@ package com.devonfw.tools.ide.serviceprovider; -import static com.devonfw.tools.ide.context.AbstractIdeContext.loggingContext; - import org.slf4j.Logger; import org.slf4j.Marker; +import com.devonfw.tools.ide.context.AbstractIdeContext; +import com.devonfw.tools.ide.context.IdeContext; + /** * Implementation of {@link Logger}. */ @@ -12,6 +13,8 @@ public class IdeLoggerAdapter implements Logger { private final String name; + private final IdeContext loggingContext; + /** * The constructor. * @@ -20,6 +23,12 @@ public class IdeLoggerAdapter implements Logger { public IdeLoggerAdapter(String name) { this.name = name; + // TODO: check for WireMock, com.github.jknack.handlebars.Handlebars, org.eclipse.jetty.util.Jetty + if (name.equals("WireMock") || name.contains("jknack") || name.contains("jetty")) { + loggingContext = null; + return; + } + loggingContext = AbstractIdeContext.getLoggingContext(); } @Override @@ -266,7 +275,9 @@ public void warn(String s, Object o, Object o1) { @Override public void warn(String s, Throwable throwable) { - loggingContext.warning(s, throwable); + if (loggingContext != null) { + loggingContext.warning(s, throwable); + } } @Override From 540717d63558bf1b6c2e56691b56a7e742780ce0 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 7 Jul 2025 15:28:18 +0200 Subject: [PATCH 23/51] #404: fixed gui --- gui/src/main/java/com/devonfw/ide/gui/MainController.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gui/src/main/java/com/devonfw/ide/gui/MainController.java b/gui/src/main/java/com/devonfw/ide/gui/MainController.java index 6e94acd8aa..a096c2a231 100644 --- a/gui/src/main/java/com/devonfw/ide/gui/MainController.java +++ b/gui/src/main/java/com/devonfw/ide/gui/MainController.java @@ -1,7 +1,5 @@ package com.devonfw.ide.gui; -import static ch.qos.logback.core.util.OptionHelper.getEnv; - import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -35,7 +33,7 @@ public class MainController { @FXML private Button vsCodeOpen; - private final String directoryPath = getEnv(IdeVariables.IDE_ROOT.getName()); + private final String directoryPath = IdeVariables.IDE_ROOT.getName(); private Path projectValue; private Path workspaceValue; From 8237ccbd88f04cb72b96f534e9c30d315349fe8c Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 11 Aug 2025 11:21:08 +0200 Subject: [PATCH 24/51] #404 fixed javadocs in UrlUpdaterTest --- .../com/devonfw/tools/ide/url/updater/UrlUpdaterTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/updater/UrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/updater/UrlUpdaterTest.java index 854395c1fd..0e7fb2d2aa 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/updater/UrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/updater/UrlUpdaterTest.java @@ -27,7 +27,6 @@ import com.devonfw.tools.ide.url.model.folder.UrlRepository; import com.devonfw.tools.ide.url.model.folder.UrlTool; import com.devonfw.tools.ide.url.model.folder.UrlVersion; -import com.devonfw.tools.ide.url.updater.UrlUpdater; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; @@ -210,7 +209,7 @@ public void testSuccessStateUpdatedAfterError(@TempDir Path tempDir, WireMockRun } /** - * Tests if the the tool version gets entirely removed if all versions are broken for a long time. + * Tests if the tool version gets entirely removed if all versions are broken for a long time. * * @param tempDir Temporary directory * @param wmRuntimeInfo wireMock server on a random port @@ -282,7 +281,7 @@ public void testUrlUpdaterWithTextContentTypeWillNotCreateStatusJson(@TempDir Pa } /** - * Tests if the {@link com.devonfw.tools.ide.url.updater.UrlUpdater} will handle the literally latest version of a tool correctly + * Tests if the {@link UrlUpdater} will handle the literally latest version of a tool correctly * * @param tempDir Temporary directory * @param wmRuntimeInfo wireMock server on a random port From 577c1cbd9f0f62c58b8413f84accb9ac60bcb6b2 Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 13 Oct 2025 23:26:18 +0200 Subject: [PATCH 25/51] #404: Removed old mavenRepository --- .../com/devonfw/tools/ide/context/AbstractIdeContext.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 0edd726633..8961d773fb 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -224,7 +224,6 @@ public AbstractIdeContext(IdeStartContextImpl startContext, Path workingDirector this.defaultToolRepository = new DefaultToolRepository(this); loggingContext = this; - this.mavenRepository = new MavenRepository(this); this.mvnRepository = new MvnRepository(this); this.npmRepository = new NpmRepository(this); } @@ -270,8 +269,8 @@ protected Path getIdeRootPathFromEnv(boolean withSanityCheck) { warning("IDE_ROOT is set to {} but was expanded to absolute path {} and does not match for segment {} and {} - fix your IDEasy installation!", rootPath, absoluteRootPath, rootName, absoluteRootName); break; - } - } + } + } } else { warning("IDE_ROOT is set to {} but was expanded to a shorter absolute path {}", rootPath, absoluteRootPath); @@ -322,7 +321,7 @@ private String getMessageIdeHomeFound() { String wks = this.workspaceName; if (isPrivacyMode() && !WORKSPACE_MAIN.equals(wks)) { wks = "*".repeat(wks.length()); - } + } return "IDE environment variables have been set for " + formatArgument(this.ideHome) + " in workspace " + wks; } From df7334c461788115f609e4ebc308f2249af2591e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Thu, 19 Feb 2026 23:35:10 +0100 Subject: [PATCH 26/51] #404: support SLF4J --- .../tools/ide/context/AbstractIdeContext.java | 21 +- .../tools/ide/environment/IdeSystemImpl.java | 23 +- .../tools/ide/log/AbstractIdeSubLogger.java | 21 +- .../com/devonfw/tools/ide/log/IdeLogger.java | 8 + .../devonfw/tools/ide/log/IdeLoggerImpl.java | 11 + .../ide/log/InvalidLogMessageHandler.java | 19 + .../com/devonfw/tools/ide/log/Markers.java | 46 ++ .../tools/ide/log/Slf4jLoggerAdapter.java | 441 ++++++++++++++++++ .../Slf4jLoggerFactoryIdeasy.java} | 6 +- .../Slf4jProviderIdeasy.java} | 22 +- .../ide/serviceprovider/IdeLoggerAdapter.java | 388 --------------- .../org.slf4j.spi.SLF4JServiceProvider | 2 +- .../ide/context/AbstractIdeTestContext.java | 2 +- .../tools/ide/context/IdeSlf4jContext.java | 2 +- .../ide/environment/IdeSystemTestImpl.java | 20 +- 15 files changed, 587 insertions(+), 445 deletions(-) create mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/InvalidLogMessageHandler.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/Markers.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java rename cli/src/main/java/com/devonfw/tools/ide/{serviceprovider/TestLoggerFactoryImpl.java => log/Slf4jLoggerFactoryIdeasy.java} (53%) rename cli/src/main/java/com/devonfw/tools/ide/{serviceprovider/TestProviderImpl.java => log/Slf4jProviderIdeasy.java} (60%) delete mode 100644 cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index a7015dd7aa..a2bd9ec819 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -80,10 +80,13 @@ */ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatter { + /** The default shell bash (Bourne Again SHell). */ + public static final String BASH = "bash"; + private static final GitUrl IDE_URLS_GIT = new GitUrl("https://github.com/devonfw/ide-urls.git", null); private static final String LICENSE_URL = "https://github.com/devonfw/IDEasy/blob/main/documentation/LICENSE.adoc"; - public static final String BASH = "bash"; + private static final String DEFAULT_WINDOWS_GIT_PATH = "C:\\Program Files\\Git\\bin\\bash.exe"; private static final String OPTION_DETAILS_START = "(["; @@ -152,9 +155,6 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt private final Map privacyMap; - /** Context used for logging */ - private static IdeContext loggingContext; - private Path bash; /** @@ -209,7 +209,6 @@ public AbstractIdeContext(IdeStartContextImpl startContext, Path workingDirector } } this.defaultToolRepository = new DefaultToolRepository(this); - loggingContext = this; } /** @@ -855,7 +854,7 @@ public ProcessContext newProcess() { public IdeSystem getSystem() { if (this.system == null) { - this.system = new IdeSystemImpl(this); + this.system = new IdeSystemImpl(); } return this.system; } @@ -1603,16 +1602,6 @@ public void writeVersionFile(VersionIdentifier version, Path installationPath) { getFileAccess().writeFileContent(version.toString(), versionFile); } - /** - * Gets the logging context. - * - * @return {@link IdeContext}. - */ - public static IdeContext getLoggingContext() { - - return loggingContext; - } - /* * @param home the IDE_HOME directory. * @param workspace the name of the active workspace folder. diff --git a/cli/src/main/java/com/devonfw/tools/ide/environment/IdeSystemImpl.java b/cli/src/main/java/com/devonfw/tools/ide/environment/IdeSystemImpl.java index 880e112229..10d4c04920 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/environment/IdeSystemImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/environment/IdeSystemImpl.java @@ -4,36 +4,37 @@ import java.util.Objects; import java.util.Properties; -import com.devonfw.tools.ide.log.IdeLogger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Implementation of {@link IdeSystem}. */ public class IdeSystemImpl implements IdeSystem { - private final IdeLogger logger; + private static final Logger LOG = LoggerFactory.getLogger(IdeSystemImpl.class); final Properties systemProperties; final Map environmentVariables; /** - * @param logger the {@link IdeLogger}. + * The constructor. */ - public IdeSystemImpl(IdeLogger logger) { + public IdeSystemImpl() { - this(logger, System.getProperties(), System.getenv()); + this(System.getProperties(), System.getenv()); } /** - * @param logger the {@link IdeLogger}. + * The constructor. + * * @param systemProperties the {@link System#getProperties() system properties}. * @param environmentVariables the {@link System#getenv() environment variables}. */ - protected IdeSystemImpl(IdeLogger logger, Properties systemProperties, Map environmentVariables) { + protected IdeSystemImpl(Properties systemProperties, Map environmentVariables) { super(); - this.logger = logger; this.systemProperties = systemProperties; this.environmentVariables = environmentVariables; } @@ -55,13 +56,13 @@ public void setProperty(String key, String value) { String old = getProperty(key); if (Objects.equals(old, value)) { - this.logger.trace("System property was already set to {}={}", key, value); + LOG.trace("System property was already set to {}={}", key, value); } else { this.systemProperties.put(key, value); if (old == null) { - this.logger.trace("System property was set to {}={}", key, value); + LOG.trace("System property was set to {}={}", key, value); } else { - this.logger.trace("System property was changed to {}={} from {}", key, value, old); + LOG.trace("System property was changed to {}={} from {}", key, value, old); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java b/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java index 5081fc5f7d..0a2f308d7b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java @@ -61,7 +61,7 @@ void setEnabled(boolean enabled) { } void setColored(boolean colored) { - + this.colored = colored; } @@ -73,11 +73,22 @@ void setColored(boolean colored) { * @return the resolved message with the parameters filled in. */ protected String compose(String message, Object... args) { + return compose(this.argFormatter, this::invalidMessage, message, args); + } + + /** + * Should only be used internally by logger implementation. + * + * @param message the message template. + * @param args the dynamic arguments to fill in. + * @return the resolved message with the parameters filled in. + */ + static String compose(IdeLogArgFormatter formatter, InvalidLogMessageHandler handler, String message, Object... args) { int pos = message.indexOf("{}"); if (pos < 0) { if (args.length > 0) { - invalidMessage(message, false, args); + handler.invalidMessage(message, false, args); } return message; } @@ -87,11 +98,11 @@ protected String compose(String message, Object... args) { StringBuilder sb = new StringBuilder(length + 48); while (pos >= 0) { sb.append(message, start, pos); - sb.append(this.argFormatter.formatArgument(args[argIndex++])); + sb.append(formatter.formatArgument(args[argIndex++])); start = pos + 2; pos = message.indexOf("{}", start); if ((argIndex >= args.length) && (pos > 0)) { - invalidMessage(message, true, args); + handler.invalidMessage(message, true, args); pos = -1; } } @@ -100,7 +111,7 @@ protected String compose(String message, Object... args) { sb.append(rest); } if (argIndex < args.length) { - invalidMessage(message, false, args); + handler.invalidMessage(message, false, args); } return sb.toString(); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogger.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogger.java index 927ade5004..883a43d1f7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogger.java @@ -239,4 +239,12 @@ default void error(Throwable error, String message, Object... args) { error().log(error, message, args); } + /** + * @return the current {@link IdeLogger} instance. + */ + static IdeLogger get() { + + return IdeLoggerImpl.getInstance(); + } + } diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLoggerImpl.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLoggerImpl.java index 6a0a0e3d8d..06593cdb11 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLoggerImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLoggerImpl.java @@ -12,6 +12,8 @@ public class IdeLoggerImpl implements IdeLogger { protected final IdeLogListener listener; + private static IdeLogger instance; + /** * @param minLogLevel the minimum enabled {@link IdeLogLevel}. * @param factory the factory to create active {@link IdeSubLogger} instances. @@ -30,6 +32,7 @@ public IdeLoggerImpl(IdeLogLevel minLogLevel, Function { + }; + + /** + * @param message the message template. + * @param more - {@code true} if more placeholders were present than {@code args} given, {@code false} otherwise (fewer placeholders present). + * @param args the dynamic arguments to fill into the message template. + */ + void invalidMessage(String message, boolean more, Object[] args); +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Markers.java b/cli/src/main/java/com/devonfw/tools/ide/log/Markers.java new file mode 100644 index 0000000000..681e320635 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Markers.java @@ -0,0 +1,46 @@ +package com.devonfw.tools.ide.log; + +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +/** + * Markers for SLF4J to emulate IDEasy custom log-levels. Always use log-level INFO on SLF4J in combination with the {@link Markers} defined here. + */ +public final class Markers { + + private Markers() { + + } + + /** {@link Marker} for {@link IdeLogLevel#INTERACTION}. */ + public static final Marker INTERACTION = MarkerFactory.getMarker("interaction"); + + /** {@link Marker} for {@link IdeLogLevel#STEP}. */ + public static final Marker STEP = MarkerFactory.getMarker("step"); + + /** {@link Marker} for {@link IdeLogLevel#SUCCESS}. */ + public static final Marker SUCCESS = MarkerFactory.getMarker("success"); + + /** {@link Marker} for {@link IdeLogLevel#PROCESSABLE}. */ + public static final Marker PROCESSABLE = MarkerFactory.getMarker("processable"); + + /** + * @param marker the {@link Marker}. + * @return the corresponding {@link IdeLogLevel}. + */ + public static IdeLogLevel getLevel(Marker marker) { + + if (marker == INTERACTION) { + return IdeLogLevel.INTERACTION; + } else if (marker == STEP) { + return IdeLogLevel.STEP; + } else if (marker == SUCCESS) { + return IdeLogLevel.SUCCESS; + } else if (marker == PROCESSABLE) { + return IdeLogLevel.PROCESSABLE; + } else { + return IdeLogLevel.INFO; // unknown marker + } + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java new file mode 100644 index 0000000000..4b38dc4b27 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java @@ -0,0 +1,441 @@ +package com.devonfw.tools.ide.log; + +import java.util.logging.Level; + +import org.slf4j.Logger; +import org.slf4j.Marker; + +/** + * Implementation of {@link Logger}. + */ +public class Slf4jLoggerAdapter implements Logger { + + private final String name; + + private final IdeLogger ideLogger; + + private final java.util.logging.Logger julLogger; + + /** + * The constructor. + * + * @param name of the logger. + */ + public Slf4jLoggerAdapter(String name) { + + this.name = name; + if (name.startsWith("com.devon.tools.ide.")) { + this.ideLogger = IdeLogger.get(); + this.julLogger = null; + } else { + this.ideLogger = null; + this.julLogger = java.util.logging.Logger.getLogger(name); + } + } + + @Override + public String getName() { + + return this.name; + } + + private String compose(String message, Object... args) { + return AbstractIdeSubLogger.compose(IdeLogArgFormatter.DEFAULT, InvalidLogMessageHandler.NONE, message, args); + } + + @Override + public boolean isTraceEnabled() { + if (this.julLogger != null) { + return this.julLogger.isLoggable(Level.FINER); + } else { + return this.ideLogger.trace().isEnabled(); + } + } + + @Override + public void trace(String message) { + if (this.julLogger != null) { + this.julLogger.fine(message); + } else { + this.ideLogger.trace(message); + } + } + + @Override + public void trace(String message, Object arg1) { + trace(message, new Object[] { arg1 }); + } + + @Override + public void trace(String message, Object arg1, Object arg2) { + trace(message, new Object[] { arg1, arg2 }); + } + + @Override + public void trace(String message, Object... args) { + if (this.julLogger != null) { + this.julLogger.finer(compose(message, args)); + } else { + this.ideLogger.trace(message, args); + } + } + + @Override + public void trace(String message, Throwable error) { + if (this.julLogger != null) { + this.julLogger.log(Level.FINER, message, error); + } else { + this.ideLogger.level(IdeLogLevel.TRACE).log(error, message); + } + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return isTraceEnabled(); + } + + @Override + public void trace(Marker marker, String message) { + trace(message); + } + + @Override + public void trace(Marker marker, String message, Object arg1) { + trace(message, arg1); + } + + @Override + public void trace(Marker marker, String message, Object arg1, Object arg2) { + trace(message, arg1, arg2); + } + + @Override + public void trace(Marker marker, String message, Object... args) { + trace(message, args); + } + + @Override + public void trace(Marker marker, String message, Throwable error) { + trace(message, error); + } + + @Override + public boolean isDebugEnabled() { + if (this.julLogger != null) { + return this.julLogger.isLoggable(Level.FINE); + } else { + return this.ideLogger.debug().isEnabled(); + } + } + + @Override + public void debug(String message) { + if (this.julLogger != null) { + this.julLogger.fine(message); + } else { + this.ideLogger.debug(message); + } + } + + @Override + public void debug(String message, Object arg1) { + debug(message, new Object[] { arg1 }); + } + + @Override + public void debug(String message, Object arg1, Object arg2) { + debug(message, new Object[] { arg1, arg2 }); + } + + @Override + public void debug(String message, Object... args) { + if (this.julLogger != null) { + this.julLogger.fine(compose(message, args)); + } else { + this.ideLogger.debug(message, args); + } + } + + @Override + public void debug(String message, Throwable error) { + if (this.julLogger != null) { + this.julLogger.log(Level.FINE, message, error); + } else { + this.ideLogger.level(IdeLogLevel.DEBUG).log(error, message); + } + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return isDebugEnabled(); + } + + @Override + public void debug(Marker marker, String message) { + debug(message); + } + + @Override + public void debug(Marker marker, String message, Object arg1) { + debug(message, arg1); + } + + @Override + public void debug(Marker marker, String message, Object arg1, Object arg2) { + debug(message, arg1, arg2); + } + + @Override + public void debug(Marker marker, String message, Object... args) { + debug(message, args); + } + + @Override + public void debug(Marker marker, String message, Throwable error) { + debug(message, error); + } + + @Override + public boolean isInfoEnabled() { + if (this.julLogger != null) { + return this.julLogger.isLoggable(Level.INFO); + } else { + return this.ideLogger.info().isEnabled(); + } + } + + @Override + public void info(String message) { + if (this.julLogger != null) { + this.julLogger.info(message); + } else { + this.ideLogger.info(message); + } + } + + @Override + public void info(String message, Object arg1) { + info(message, new Object[] { arg1 }); + } + + @Override + public void info(String message, Object arg1, Object arg2) { + info(message, new Object[] { arg1, arg2 }); + } + + @Override + public void info(String message, Object... args) { + if (this.julLogger != null) { + this.julLogger.info(compose(message, args)); + } else { + this.ideLogger.info(message, args); + } + } + + @Override + public void info(String message, Throwable error) { + if (this.julLogger != null) { + this.julLogger.log(Level.INFO, message, error); + } else { + this.ideLogger.level(IdeLogLevel.INFO).log(error, message); + } + } + + @Override + public boolean isInfoEnabled(Marker marker) { + if (this.julLogger != null) { + return isInfoEnabled(); + } else { + return this.ideLogger.level(Markers.getLevel(marker)).isEnabled(); + } + } + + @Override + public void info(Marker marker, String message) { + if (this.julLogger != null) { + this.julLogger.info(message); + } else { + this.ideLogger.level(Markers.getLevel(marker)).log(message); + } + } + + @Override + public void info(Marker marker, String message, Object arg1) { + info(marker, message, new Object[] { arg1 }); + } + + @Override + public void info(Marker marker, String message, Object arg1, Object arg2) { + info(marker, message, new Object[] { arg1, arg2 }); + } + + @Override + public void info(Marker marker, String message, Object... args) { + if (this.julLogger != null) { + this.julLogger.info(compose(message, args)); + } else { + this.ideLogger.level(Markers.getLevel(marker)).log(message, args); + } + } + + @Override + public void info(Marker marker, String message, Throwable error) { + if (this.julLogger != null) { + this.julLogger.log(Level.INFO, message, error); + } else { + this.ideLogger.level(Markers.getLevel(marker)).log(error, message); + } + } + + @Override + public boolean isWarnEnabled() { + if (this.julLogger != null) { + return this.julLogger.isLoggable(Level.WARNING); + } else { + return this.ideLogger.warning().isEnabled(); + } + } + + @Override + public void warn(String message) { + if (this.julLogger != null) { + this.julLogger.warning(message); + } else { + this.ideLogger.warning(message); + } + } + + @Override + public void warn(String message, Object arg1) { + warn(message, new Object[] { arg1 }); + } + + @Override + public void warn(String message, Object arg1, Object arg2) { + warn(message, new Object[] { arg1, arg2 }); + } + + @Override + public void warn(String message, Object... args) { + if (this.julLogger != null) { + this.julLogger.warning(compose(message, args)); + } else { + this.ideLogger.warning(message, args); + } + } + + @Override + public void warn(String message, Throwable error) { + if (this.julLogger != null) { + this.julLogger.log(Level.WARNING, message, error); + } else { + this.ideLogger.level(IdeLogLevel.WARNING).log(error, message); + } + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return isWarnEnabled(); + } + + @Override + public void warn(Marker marker, String message) { + warn(message); + } + + @Override + public void warn(Marker marker, String message, Object arg1) { + warn(message, arg1); + } + + @Override + public void warn(Marker marker, String message, Object arg1, Object arg2) { + warn(message, arg1, arg2); + } + + @Override + public void warn(Marker marker, String message, Object... args) { + warn(message, args); + } + + @Override + public void warn(Marker marker, String message, Throwable error) { + warn(message, error); + } + + @Override + public boolean isErrorEnabled() { + if (this.julLogger != null) { + return this.julLogger.isLoggable(Level.SEVERE); + } else { + return this.ideLogger.error().isEnabled(); + } + } + + @Override + public void error(String message) { + if (this.julLogger != null) { + this.julLogger.severe(message); + } else { + this.ideLogger.error(message); + } + } + + @Override + public void error(String message, Object arg1) { + error(message, new Object[] { arg1 }); + } + + @Override + public void error(String message, Object arg1, Object arg2) { + error(message, new Object[] { arg1, arg2 }); + } + + @Override + public void error(String message, Object... args) { + if (this.julLogger != null) { + this.julLogger.severe(compose(message, args)); + } else { + this.ideLogger.error(message, args); + } + } + + @Override + public void error(String message, Throwable error) { + if (this.julLogger != null) { + this.julLogger.log(Level.SEVERE, message, error); + } else { + this.ideLogger.error(error, message); + } + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return isErrorEnabled(); + } + + @Override + public void error(Marker marker, String message) { + error(message); + } + + @Override + public void error(Marker marker, String message, Object arg1) { + error(message, arg1); + } + + @Override + public void error(Marker marker, String message, Object arg1, Object arg2) { + error(message, arg1, arg2); + } + + @Override + public void error(Marker marker, String message, Object... args) { + error(message, args); + } + + @Override + public void error(Marker marker, String message, Throwable error) { + error(message, error); + } +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactoryImpl.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerFactoryIdeasy.java similarity index 53% rename from cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactoryImpl.java rename to cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerFactoryIdeasy.java index 69bf038107..b20dd39b92 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactoryImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerFactoryIdeasy.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.serviceprovider; +package com.devonfw.tools.ide.log; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; @@ -6,11 +6,11 @@ /** * Implementation of {@link ILoggerFactory}. */ -public class TestLoggerFactoryImpl implements ILoggerFactory { +public class Slf4jLoggerFactoryIdeasy implements ILoggerFactory { @Override public Logger getLogger(String name) { - return new IdeLoggerAdapter(name); + return new Slf4jLoggerAdapter(name); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProviderImpl.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jProviderIdeasy.java similarity index 60% rename from cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProviderImpl.java rename to cli/src/main/java/com/devonfw/tools/ide/log/Slf4jProviderIdeasy.java index 62fc569181..6754bf4af2 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProviderImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jProviderIdeasy.java @@ -1,4 +1,4 @@ -package com.devonfw.tools.ide.serviceprovider; +package com.devonfw.tools.ide.log; import org.slf4j.ILoggerFactory; import org.slf4j.IMarkerFactory; @@ -9,16 +9,22 @@ /** * Implementation of {@link SLF4JServiceProvider}. */ -public class TestProviderImpl implements SLF4JServiceProvider { +public class Slf4jProviderIdeasy implements SLF4JServiceProvider { - private final String REQUESTED_API_VERSION = "2.0.12"; - private TestLoggerFactoryImpl testLoggerFactory; - + private final Slf4jLoggerFactoryIdeasy loggerFactory; + + /** + * The constructor. + */ + public Slf4jProviderIdeasy() { + super(); + this.loggerFactory = new Slf4jLoggerFactoryIdeasy(); + } @Override public ILoggerFactory getLoggerFactory() { - return testLoggerFactory; + return this.loggerFactory; } @Override @@ -36,11 +42,11 @@ public MDCAdapter getMDCAdapter() { @Override public String getRequestedApiVersion() { - return REQUESTED_API_VERSION; + return "2.0.12"; } @Override public void initialize() { - testLoggerFactory = new TestLoggerFactoryImpl(); + // nothing to do... } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java deleted file mode 100644 index 3dd361e418..0000000000 --- a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java +++ /dev/null @@ -1,388 +0,0 @@ -package com.devonfw.tools.ide.serviceprovider; - -import org.slf4j.Logger; -import org.slf4j.Marker; - -import com.devonfw.tools.ide.context.AbstractIdeContext; -import com.devonfw.tools.ide.context.IdeContext; - -/** - * Implementation of {@link Logger}. - */ -public class IdeLoggerAdapter implements Logger { - - private final String name; - - private final IdeContext loggingContext; - - /** - * The constructor. - * - * @param name of the logger. - */ - public IdeLoggerAdapter(String name) { - - this.name = name; - // TODO: check for WireMock, com.github.jknack.handlebars.Handlebars, org.eclipse.jetty.util.Jetty - if (name.equals("WireMock") || name.contains("jknack") || name.contains("jetty")) { - loggingContext = null; - return; - } - loggingContext = AbstractIdeContext.getLoggingContext(); - } - - @Override - public String getName() { - - return name; - } - - @Override - public boolean isTraceEnabled() { - return loggingContext.trace().isEnabled(); - } - - @Override - public void trace(String s) { - loggingContext.trace(s); - } - - @Override - public void trace(String s, Object o) { - loggingContext.trace(s, o); - } - - @Override - public void trace(String s, Object o, Object o1) { - loggingContext.trace(s, o, o1); - } - - @Override - public void trace(String s, Object... objects) { - loggingContext.trace(s, objects); - } - - @Override - public void trace(String s, Throwable throwable) { - loggingContext.trace(s, throwable); - } - - @Override - public boolean isTraceEnabled(Marker marker) { - return loggingContext.trace().isEnabled(); - } - - @Override - public void trace(Marker marker, String s) { - loggingContext.trace(s); - } - - @Override - public void trace(Marker marker, String s, Object o) { - loggingContext.trace(s, o); - } - - @Override - public void trace(Marker marker, String s, Object o, Object o1) { - loggingContext.trace(s, o, o1); - } - - @Override - public void trace(Marker marker, String s, Object... objects) { - loggingContext.trace(s, objects); - } - - @Override - public void trace(Marker marker, String s, Throwable throwable) { - loggingContext.trace(s, throwable); - } - - @Override - public boolean isDebugEnabled() { - if (loggingContext != null) { - return loggingContext.debug().isEnabled(); - } else { - return false; - } - - } - - @Override - public void debug(String s) { - if (loggingContext != null) { - loggingContext.debug(s); - } - } - - @Override - public void debug(String s, Object o) { - if (loggingContext != null) { - loggingContext.debug(s, o); - } - } - - @Override - public void debug(String s, Object o, Object o1) { - if (loggingContext != null) { - loggingContext.debug(s, o, o1); - } - } - - @Override - public void debug(String s, Object... objects) { - if (loggingContext != null) { - loggingContext.debug(s, objects); - } - } - - @Override - public void debug(String s, Throwable throwable) { - if (loggingContext != null) { - loggingContext.debug(s, throwable); - } - } - - @Override - public boolean isDebugEnabled(Marker marker) { - if (loggingContext != null) { - return loggingContext.debug().isEnabled(); - } else { - return false; - } - } - - @Override - public void debug(Marker marker, String s) { - loggingContext.debug(s); - } - - @Override - public void debug(Marker marker, String s, Object o) { - loggingContext.debug(s, o); - } - - @Override - public void debug(Marker marker, String s, Object o, Object o1) { - loggingContext.debug(s, o, o1); - } - - @Override - public void debug(Marker marker, String s, Object... objects) { - loggingContext.debug(s, objects); - } - - @Override - public void debug(Marker marker, String s, Throwable throwable) { - loggingContext.debug(s, throwable); - } - - @Override - public boolean isInfoEnabled() { - if (loggingContext != null) { - return loggingContext.info().isEnabled(); - } else { - return false; - } - } - - @Override - public void info(String s) { - if (loggingContext != null) { - loggingContext.info(s); - } - } - - @Override - public void info(String s, Object o) { - if (loggingContext != null) { - loggingContext.info(s, o); - } - } - - @Override - public void info(String s, Object o, Object o1) { - if (loggingContext != null) { - loggingContext.info(s, o, o1); - } - } - - @Override - public void info(String s, Object... objects) { - if (loggingContext != null) { - loggingContext.info(s, objects); - } - } - - @Override - public void info(String s, Throwable throwable) { - loggingContext.info(s, throwable); - } - - @Override - public boolean isInfoEnabled(Marker marker) { - return loggingContext.info().isEnabled(); - } - - @Override - public void info(Marker marker, String s) { - loggingContext.info(s); - } - - @Override - public void info(Marker marker, String s, Object o) { - loggingContext.info(s, o); - } - - @Override - public void info(Marker marker, String s, Object o, Object o1) { - loggingContext.info(s, o, o1); - } - - @Override - public void info(Marker marker, String s, Object... objects) { - loggingContext.info(s, objects); - } - - @Override - public void info(Marker marker, String s, Throwable throwable) { - loggingContext.info(s, throwable); - } - - @Override - public boolean isWarnEnabled() { - return loggingContext.warning().isEnabled(); - } - - @Override - public void warn(String s) { - loggingContext.warning(s); - } - - @Override - public void warn(String s, Object o) { - loggingContext.warning(s, o); - } - - @Override - public void warn(String s, Object... objects) { - loggingContext.warning(s, objects); - } - - @Override - public void warn(String s, Object o, Object o1) { - loggingContext.warning(s, o, o1); - } - - @Override - public void warn(String s, Throwable throwable) { - if (loggingContext != null) { - loggingContext.warning(s, throwable); - } - } - - @Override - public boolean isWarnEnabled(Marker marker) { - return loggingContext.warning().isEnabled(); - } - - @Override - public void warn(Marker marker, String s) { - loggingContext.warning(s); - } - - @Override - public void warn(Marker marker, String s, Object o) { - loggingContext.warning(s, o); - } - - @Override - public void warn(Marker marker, String s, Object o, Object o1) { - loggingContext.warning(s, o, o1); - } - - @Override - public void warn(Marker marker, String s, Object... objects) { - loggingContext.warning(s, objects); - } - - @Override - public void warn(Marker marker, String s, Throwable throwable) { - loggingContext.warning(s, throwable); - } - - @Override - public boolean isErrorEnabled() { - if (loggingContext != null) { - return loggingContext.error().isEnabled(); - } else { - return false; - } - } - - @Override - public void error(String s) { - if (loggingContext != null) { - loggingContext.error(s); - } - } - - @Override - public void error(String s, Object o) { - if (loggingContext != null) { - loggingContext.error(s, o); - } - } - - @Override - public void error(String s, Object o, Object o1) { - loggingContext.error(s, o, o1); - } - - @Override - public void error(String s, Object... objects) { - if (loggingContext != null) { - loggingContext.error(s, objects); - } - } - - @Override - public void error(String s, Throwable throwable) { - if (loggingContext != null) { - loggingContext.error(s, throwable); - } - } - - @Override - public boolean isErrorEnabled(Marker marker) { - if (loggingContext != null) { - return loggingContext.error().isEnabled(); - } else { - return false; - } - } - - @Override - public void error(Marker marker, String s) { - loggingContext.error(s); - } - - @Override - public void error(Marker marker, String s, Object o) { - loggingContext.error(s, o); - } - - @Override - public void error(Marker marker, String s, Object o, Object o1) { - loggingContext.error(s, o, o1); - } - - @Override - public void error(Marker marker, String s, Object... objects) { - loggingContext.error(s, objects); - } - - @Override - public void error(Marker marker, String s, Throwable throwable) { - loggingContext.error(s, throwable); - } -} diff --git a/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider index c70584fc82..1ace08ba64 100644 --- a/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider +++ b/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider @@ -1 +1 @@ -com.devonfw.tools.ide.serviceprovider.TestProviderImpl +com.devonfw.tools.ide.log.Slf4jProviderIdeasy diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java index 26c2b4659a..71da701ccf 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java @@ -216,7 +216,7 @@ protected AbstractEnvironmentVariables createSystemVariables() { public IdeSystemTestImpl getSystem() { if (this.system == null) { - this.system = new IdeSystemTestImpl(this); + this.system = new IdeSystemTestImpl(); } return (IdeSystemTestImpl) this.system; } diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java index 88cc3b9c84..5576c0b410 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java @@ -26,7 +26,7 @@ public IdeSlf4jContext() { */ public IdeSlf4jContext(Path workingDirectory) { - super(new IdeStartContextImpl(IdeLogLevel.TRACE, level -> new IdeSubLoggerOut(level, null, true, IdeLogLevel.TRACE, null)), workingDirectory); + super(new IdeStartContextImpl(IdeLogLevel.TRACE, level -> new IdeSubLoggerOut(level, null, true, IdeLogLevel.TRACE, null)), workingDirectory, null); } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/environment/IdeSystemTestImpl.java b/cli/src/test/java/com/devonfw/tools/ide/environment/IdeSystemTestImpl.java index 0486ce956b..aa9f4566bb 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/environment/IdeSystemTestImpl.java +++ b/cli/src/test/java/com/devonfw/tools/ide/environment/IdeSystemTestImpl.java @@ -4,31 +4,30 @@ import java.util.Map; import java.util.Properties; -import com.devonfw.tools.ide.log.IdeLogger; - /** * Extends {@link IdeSystemImpl} for testing. It will not modify your {@link System} and allows to modify environment variables for testing. */ public class IdeSystemTestImpl extends IdeSystemImpl { /** - * @param logger the {@link IdeLogger}. + * The constructor. */ - public IdeSystemTestImpl(IdeLogger logger) { + public IdeSystemTestImpl() { - this(logger, new Properties(), new HashMap<>()); + this(new Properties(), new HashMap<>()); this.environmentVariables.put("PATH", System.getenv("PATH")); } /** - * @param logger the {@link IdeLogger}. + * The constructor. + * * @param systemProperties the {@link System#getProperties() system properties} for testing. * @param environmentVariables the {@link System#getenv() environment variables} for testing. */ - public IdeSystemTestImpl(IdeLogger logger, Properties systemProperties, + public IdeSystemTestImpl(Properties systemProperties, Map environmentVariables) { - super(logger, systemProperties, environmentVariables); + super(systemProperties, environmentVariables); } /** @@ -49,11 +48,10 @@ public Properties getProperties() { } /** - * @param logger the {@link IdeLogger}. * @return a new instance of {@link IdeSystemTestImpl} initialized with {@link System} values but decoupled so changes do not affect {@link System}. */ - public static IdeSystemTestImpl ofSystemDefaults(IdeLogger logger) { + public static IdeSystemTestImpl ofSystemDefaults() { - return new IdeSystemTestImpl(logger, new Properties(System.getProperties()), new HashMap<>(System.getenv())); + return new IdeSystemTestImpl(new Properties(System.getProperties()), new HashMap<>(System.getenv())); } } From 97cf467e5e2d9e5a5f011098900b93ff5502f3e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Thu, 19 Feb 2026 23:45:09 +0100 Subject: [PATCH 27/51] #404: bugfix --- .../main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java index 4b38dc4b27..63ac9e6187 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java @@ -24,7 +24,7 @@ public class Slf4jLoggerAdapter implements Logger { public Slf4jLoggerAdapter(String name) { this.name = name; - if (name.startsWith("com.devon.tools.ide.")) { + if (name.startsWith("com.devonfw.tools.ide.")) { this.ideLogger = IdeLogger.get(); this.julLogger = null; } else { From d63d92404dfd3468525a52e7ed44a22bde0b254d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Fri, 20 Feb 2026 19:33:25 +0100 Subject: [PATCH 28/51] #404: implement logfile and rework logging --- .../commandlet/AbstractUpdateCommandlet.java | 2 +- ...AbstractVersionOrEditionGetCommandlet.java | 2 +- .../tools/ide/commandlet/BuildCommandlet.java | 2 +- .../tools/ide/commandlet/Commandlet.java | 15 +- .../ide/commandlet/CompleteCommandlet.java | 2 +- .../ide/commandlet/ContextCommandlet.java | 8 +- .../ide/commandlet/CreateCommandlet.java | 2 +- .../ide/commandlet/EditionListCommandlet.java | 2 +- .../ide/commandlet/EditionSetCommandlet.java | 2 +- .../ide/commandlet/EnvironmentCommandlet.java | 2 +- .../tools/ide/commandlet/HelpCommandlet.java | 7 +- .../ide/commandlet/InstallCommandlet.java | 13 +- .../commandlet/InstallPluginCommandlet.java | 2 +- .../tools/ide/commandlet/ShellCommandlet.java | 2 +- .../ide/commandlet/StatusCommandlet.java | 2 +- .../ide/commandlet/UninstallCommandlet.java | 2 +- .../commandlet/UninstallPluginCommandlet.java | 2 +- .../ide/commandlet/UpdateCommandlet.java | 2 +- .../ide/commandlet/UpgradeCommandlet.java | 2 +- .../commandlet/UpgradeSettingsCommandlet.java | 2 +- .../ide/commandlet/VersionCommandlet.java | 2 +- .../ide/commandlet/VersionListCommandlet.java | 2 +- .../ide/commandlet/VersionSetCommandlet.java | 2 +- .../tools/ide/context/AbstractIdeContext.java | 143 +++++- .../devonfw/tools/ide/context/IdeContext.java | 3 + .../ide/context/IdeStartContextImpl.java | 42 +- .../git/repository/RepositoryCommandlet.java | 2 +- .../devonfw/tools/ide/log/IdeLogLevel.java | 109 ++++- .../com/devonfw/tools/ide/log/Markers.java | 46 -- .../tools/ide/log/Slf4jLoggerAdapter.java | 427 ++++-------------- .../tools/ide/log/Slf4jProviderIdeasy.java | 3 +- .../tools/ide/tool/ToolCommandlet.java | 2 +- .../tools/ide/tool/gcviewer/GcViewer.java | 2 +- .../tools/ide/tool/ide/IdeToolCommandlet.java | 4 +- .../com/devonfw/tools/ide/tool/jmc/Jmc.java | 16 +- .../devonfw/tools/ide/tool/sonar/Sonar.java | 2 +- .../tools/ide/variable/IdeVariables.java | 8 +- .../ide/context/AbstractIdeTestContext.java | 6 + 38 files changed, 433 insertions(+), 463 deletions(-) delete mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/Markers.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java index aa1bb59204..c5acfebabe 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java @@ -85,7 +85,7 @@ public AbstractUpdateCommandlet(IdeContext context) { } @Override - public void run() { + protected void doRun() { IdeStartContextImpl startContext = ((AbstractIdeContext) this.context).getStartContext(); startContext.setForcePull(forcePull.isTrue()); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java index 5fa05edbca..490a99f49c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java @@ -68,7 +68,7 @@ public boolean isProcessableOutput() { protected abstract Object getInstalledValue(ToolCommandlet commandlet); @Override - public void run() { + protected void doRun() { ToolCommandlet commandlet = this.tool.getValue(); IdeSubLogger logger = this.context.level(IdeLogLevel.PROCESSABLE); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/BuildCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/BuildCommandlet.java index 968b259c2a..99c7c131de 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/BuildCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/BuildCommandlet.java @@ -42,7 +42,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { Path buildPath = this.context.getCwd(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java index 8ad3176347..be8a338b20 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.Objects; +import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.nls.NlsBundle; import com.devonfw.tools.ide.property.KeywordProperty; @@ -212,10 +213,22 @@ public boolean isProcessableOutput() { return false; } + protected boolean isActivateJaveUtilLogging() { + return !isProcessableOutput(); + } + /** * Runs this {@link Commandlet}. */ - public abstract void run(); + public final void run() { + + if (isActivateJaveUtilLogging()) { + ((AbstractIdeContext) this.context).configureJavaUtilLogging(); + } + doRun(); + } + + protected abstract void doRun(); /** * @return {@code true} if this {@link Commandlet} is the valid candidate to be {@link #run()}, {@code false} otherwise. diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CompleteCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CompleteCommandlet.java index c588464e19..ec16ac4fa1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CompleteCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CompleteCommandlet.java @@ -47,7 +47,7 @@ public boolean isProcessableOutput() { } @Override - public void run() { + protected void doRun() { CliArguments arguments = CliArguments.ofCompletion(this.args.asArray()); List candidates = ((AbstractIdeContext) this.context).complete(arguments, true); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java index 1858430624..bbc5e48447 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java @@ -67,7 +67,13 @@ public boolean isIdeHomeRequired() { } @Override - public void run() { + protected boolean isActivateJaveUtilLogging() { + + return false; + } + + @Override + protected void doRun() { IdeLogLevel logLevel = determineLogLevel(); if (this.startContext == null) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java index 446f25fa21..bb993f9580 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java @@ -47,7 +47,7 @@ public boolean isIdeHomeRequired() { } @Override - public void run() { + protected void doRun() { String newProjectName = this.newProject.getValue(); Path newProjectPath = this.context.getIdeRoot().resolve(newProjectName); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionListCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionListCommandlet.java index eea3a261b5..c32ab97cdd 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionListCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionListCommandlet.java @@ -33,7 +33,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { ToolCommandlet commandlet = this.tool.getValue(); commandlet.listEditions(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionSetCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionSetCommandlet.java index 4ca8d81e36..08cbfdea7c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionSetCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionSetCommandlet.java @@ -41,7 +41,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { ToolCommandlet commandlet = this.tool.getValue(); String edition = this.edition.getValue(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java index 86b640374f..345be8d5dd 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java @@ -60,7 +60,7 @@ public boolean isProcessableOutput() { } @Override - public void run() { + protected void doRun() { if (this.context.getIdeHome() == null) { throw new CliExitException(); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java index 0cadd0c722..3f388f6c2f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java @@ -46,9 +46,14 @@ public boolean isIdeRootRequired() { return false; } + @Override + protected boolean isActivateJaveUtilLogging() { + + return false; + } @Override - public void run() { + protected void doRun() { this.context.printLogo(); NlsBundle bundle = NlsBundle.of(this.context); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallCommandlet.java index 8459a5d772..57ba14ba02 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallCommandlet.java @@ -2,6 +2,9 @@ import java.nio.file.Path; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.GraalVmHelper; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.property.ToolProperty; @@ -20,6 +23,8 @@ */ public class InstallCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(InstallCommandlet.class); + /** The tool to install. */ public final ToolProperty tool; @@ -52,18 +57,18 @@ public boolean isIdeRootRequired() { } @Override - public void run() { + protected void doRun() { if (this.tool.getValueCount() == 0) { IdeasyCommandlet ideasy = new IdeasyCommandlet(this.context); GraalVmHelper graalVmHelper = GraalVmHelper.get(); if (graalVmHelper.isNativeImage()) { - this.context.debug("Detected that IDEasy is running as graalvm native image..."); + LOG.debug("Detected that IDEasy is running as graalvm native image..."); } else { - this.context.debug("Detected that IDEasy is running in JVM..."); + LOG.debug("Detected that IDEasy is running in JVM..."); } Path cwd = graalVmHelper.getCwd(); - this.context.info("Installing IDEasy from {}", cwd); + LOG.info("Installing IDEasy from {}", cwd); if (!this.context.isForceMode()) { this.context.askToContinue("Sub-command install without any further arguments will perform the initial installation of IDEasy.\n" + "Since this is typically not to be called manually, you may have forgotten to specify the tool to install as extra argument.\n" diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallPluginCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallPluginCommandlet.java index 9471d7b4cc..2ac36a8a41 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallPluginCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallPluginCommandlet.java @@ -40,7 +40,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { ToolCommandlet commandlet = this.tool.getValue(); String plugin = this.plugin.getValue(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java index c88fbc5c67..85b466054d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java @@ -63,7 +63,7 @@ public boolean isIdeHomeRequired() { } @Override - public void run() { + protected void doRun() { try { Parser parser = new DefaultParser(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java index 65a12482fc..4a5dacc352 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java @@ -35,7 +35,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { Step step = this.context.newStep(true, "Show IDE_ROOT and IDE_HOME"); step.run(this.context::logIdeHomeAndRootStatus); step = this.context.newStep(true, "Check for updates of IDEasy"); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java index afe2562e86..ef2293872e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java @@ -38,7 +38,7 @@ public boolean isIdeRootRequired() { } @Override - public void run() { + protected void doRun() { int valueCount = this.tools.getValueCount(); if (valueCount == 0) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallPluginCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallPluginCommandlet.java index ba5b73eca3..40d3290c1f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallPluginCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallPluginCommandlet.java @@ -39,7 +39,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { ToolCommandlet commandlet = this.tool.getValue(); String plugin = this.plugin.getValue(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpdateCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpdateCommandlet.java index 91f2086bbc..2d1bc0c596 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpdateCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpdateCommandlet.java @@ -25,7 +25,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { new IdeMigrator().run(this.context); super.run(); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java index 3f60579c33..a3925eb323 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java @@ -38,7 +38,7 @@ public boolean isIdeHomeRequired() { } @Override - public void run() { + protected void doRun() { IdeasyCommandlet ideasy = new IdeasyCommandlet(this.context, this.mode.getValue()); ToolInstallation installation = ideasy.install(false); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java index 0468c07c53..220c0e79fa 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java @@ -43,7 +43,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { updateLegacyFolders(); updateProperties(); updateWorkspaceTemplates(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java index 6c334f540f..d5cef41b5e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java @@ -39,7 +39,7 @@ public boolean isProcessableOutput() { } @Override - public void run() { + protected void doRun() { this.context.level(IdeLogLevel.PROCESSABLE).log(IdeVersion.getVersionString()); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionListCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionListCommandlet.java index 1b4ab40ec3..3602d43445 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionListCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionListCommandlet.java @@ -33,7 +33,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { ToolCommandlet commandlet = this.tool.getValue(); commandlet.listVersions(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionSetCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionSetCommandlet.java index 4f45efa1db..1c12d1f44c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionSetCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionSetCommandlet.java @@ -44,7 +44,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { ToolCommandlet commandlet = this.tool.getValue(); VersionIdentifier versionIdentifier = this.version.getValue(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index a2bd9ec819..b817e89937 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -2,6 +2,9 @@ import static com.devonfw.tools.ide.variable.IdeVariables.IDE_MIN_VERSION; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.time.LocalDateTime; @@ -13,7 +16,15 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Objects; +import java.util.Properties; import java.util.function.Predicate; +import java.util.logging.LogManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.event.Level; +import org.slf4j.spi.LoggingEventBuilder; import com.devonfw.tools.ide.cli.CliAbortException; import com.devonfw.tools.ide.cli.CliArgument; @@ -80,6 +91,8 @@ */ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatter { + private static final Logger LOG = LoggerFactory.getLogger(AbstractIdeContext.class); + /** The default shell bash (Bourne Again SHell). */ public static final String BASH = "bash"; @@ -157,6 +170,8 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt private Path bash; + private boolean julConfigured; + /** * The constructor. * @@ -871,7 +886,44 @@ protected ProcessContext createProcessContext() { @Override public IdeSubLogger level(IdeLogLevel level) { - return this.startContext.level(level); + return new IdeSubLogger() { + @Override + public String log(Throwable error, String message, Object... args) { + + LoggingEventBuilder builder = LOG.atLevel(level.getSlf4jLevel()); + Marker marker = level.getSlf4jMarker(); + if (marker != null) { + builder = builder.addMarker(marker); + } + if (error != null) { + builder = builder.setCause(error); + } + if ((args != null) && (args.length > 0)) { + builder.log(message, args); + } else { + builder.log(message); + } + return message; + } + + @Override + public boolean isEnabled() { + + Level slf4jLevel = level.getSlf4jLevel(); + Marker marker = level.getSlf4jMarker(); + if (marker != null) { + assert slf4jLevel == Level.INFO; + return LOG.isInfoEnabled(marker); + } + return LOG.isEnabledForLevel(slf4jLevel); + } + + @Override + public IdeLogLevel getLevel() { + + return level; + } + }; } @Override @@ -1112,6 +1164,90 @@ public int run(CliArguments arguments) { } } + public void configureJavaUtilLogging() { + + if (this.julConfigured) { + return; + } + Properties properties = createJavaUtilLoggingProperties(); + if (properties == null) { + return; + } + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(512); + properties.store(out, null); + out.flush(); + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + LogManager.getLogManager().readConfiguration(in); + this.julConfigured = true; + } catch (IOException e) { + error(e); + } + } + + protected Properties createJavaUtilLoggingProperties() { + boolean logfile = false; + Boolean writeLogfile = IdeVariables.IDE_WRITE_LOGFILE.get(this); + if (Boolean.TRUE.equals(writeLogfile)) { + logfile = true; + this.startContext.setWriteLogfile(true); + } + return createJavaUtilLoggingProperties(false, logfile); + } + + protected final Properties createJavaUtilLoggingProperties(boolean console, boolean file) { + + Path idePath = getIdePath(); + if (file && (idePath == null)) { + file = false; + error("Cannot enable --logfile option since IDE_ROOT is undefined."); + } + if (!console && !file) { + return null; + } + Properties properties = new Properties(); + String level = "FINE"; + if (trace().isEnabled()) { + level = "FINER"; + } + // java.util.logging is so flawed: We cannot set the root level to a higher threshold than our own logger, instead we need to list all potential loggers + properties.setProperty(".level", level); + String extLevel = "WARNING"; + properties.setProperty("org.level", extLevel); + properties.setProperty("java.level", extLevel); + properties.setProperty("java.lang.level", extLevel); + properties.setProperty("java.lang.FooBar.level", extLevel); + // properties.setProperty("java.lang.ProcessBuilder.level", extLevel); + properties.setProperty("jdk.level", extLevel); + properties.setProperty("net.level", extLevel); + properties.setProperty("io.level", extLevel); + properties.setProperty("sf.level", extLevel); + properties.setProperty("sun.level", extLevel); + if (file && console) { + properties.setProperty("handlers", "java.util.logging.ConsoleHandler,java.util.logging.FileHandler"); + } else if (file) { + properties.setProperty("handlers", "java.util.logging.FileHandler"); + } else { + properties.setProperty("handlers", "java.util.logging.ConsoleHandler"); + } + if (file) { + properties.setProperty("java.util.logging.FileHandler.level", level); + properties.setProperty("java.util.logging.FileHandler.formatter", "java.util.logging.SimpleFormatter"); + properties.setProperty("java.util.logging.FileHandler.encoding", "UTF-8"); + LocalDateTime now = LocalDateTime.now(); + Path logsPath = idePath.resolve(FOLDER_LOGS).resolve(DateTimeUtil.formatDate(now, true)); + getFileAccess().mkdirs(logsPath); + properties.setProperty("java.util.logging.FileHandler.pattern", logsPath.resolve("ideasy-" + DateTimeUtil.formatTime(now) + ".log").toString()); + } + if (console) { + properties.setProperty("java.util.logging.ConsoleHandler.level", level); + properties.setProperty("java.util.logging.ConsoleHandler.formatter", "java.util.logging.SimpleFormatter"); + properties.setProperty("java.util.logging.ConsoleHandler.encoding", "UTF-8"); + } + properties.setProperty("java.util.logging.SimpleFormatter.format", "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL [%4$s] [%3$s] %5$s%6$s%n"); + return properties; + } + @Override public void runWithoutLogging(Runnable lambda, IdeLogLevel threshold) { @@ -1160,7 +1296,6 @@ settingsRepository, getSettingsCommitIdPath()))) { if (isSettingsRepositorySymlinkOrJunction()) { interaction( "Updates are available for the settings repository. Please pull the latest changes by yourself or by calling \"ide -f update\" to apply them."); - } else { interaction( "Updates are available for the settings repository. If you want to apply the latest changes, call \"ide update\""); @@ -1172,8 +1307,12 @@ settingsRepository, getSettingsCommitIdPath()))) { if (!success) { return ValidationResultValid.get(); } + if (!cmd.isProcessableOutput() && !(cmd instanceof HelpCommandlet)) { + configureJavaUtilLogging(); + } cmd.run(); } finally { + this.julConfigured = false; if (previousLogLevel != null) { this.startContext.setLogLevel(previousLogLevel); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java index 63da19862c..6accb0dfac 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java @@ -94,6 +94,9 @@ public interface IdeContext extends IdeStartContext { /** The name of the backups folder for backup. */ String FOLDER_BACKUPS = "backups"; + /** The name of the logs folder for log-files (in {@link #FOLDER_UNDERSCORE_IDE}). */ + String FOLDER_LOGS = "logs"; + /** The name of the downloads folder. */ String FOLDER_DOWNLOADS = "Downloads"; diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java index 8afde36c76..eb00d5f226 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java @@ -33,6 +33,8 @@ public class IdeStartContextImpl extends IdeLoggerImpl implements IdeStartContex private boolean noColorsMode; + private boolean writeLogfile; + private Locale locale; /** @@ -104,18 +106,6 @@ public boolean isForcePull() { return this.forcePull; } - @Override - public boolean isForcePlugins() { - - return this.forcePlugins; - } - - @Override - public boolean isForceRepositories() { - - return this.forceRepositories; - } - /** * @param forcePull new value of {@link #isForcePull()}. */ @@ -124,6 +114,12 @@ public void setForcePull(boolean forcePull) { this.forcePull = forcePull; } + @Override + public boolean isForcePlugins() { + + return this.forcePlugins; + } + /** * @param forcePlugins new value of {@link #isForcePlugins()}. */ @@ -132,6 +128,12 @@ public void setForcePlugins(boolean forcePlugins) { this.forcePlugins = forcePlugins; } + @Override + public boolean isForceRepositories() { + + return this.forceRepositories; + } + /** * @param forceRepositories new value of {@link #isForceRepositories()}. */ @@ -196,4 +198,20 @@ public void setNoColorsMode(boolean noColoursMode) { this.noColorsMode = noColoursMode; setLogColors(!noColoursMode); } + + /** + * @return {@code true} to write a logfile to disc, {@code false} otherwise. + */ + public boolean isWriteLogfile() { + + return this.writeLogfile; + } + + /** + * @param writeLogfile new value of {@link #isWriteLogfile()}. + */ + public void setWriteLogfile(boolean writeLogfile) { + this.writeLogfile = writeLogfile; + } + } diff --git a/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryCommandlet.java index 93b7872348..fedd2a2a7c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryCommandlet.java @@ -43,7 +43,7 @@ public String getName() { } @Override - public void run() { + protected void doRun() { Path repositoryFile = this.repository.getValue(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java index a6edec6b99..f36dd92acf 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java @@ -1,5 +1,9 @@ package com.devonfw.tools.ide.log; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.slf4j.event.Level; + import com.devonfw.tools.ide.context.IdeContext; /** @@ -10,44 +14,53 @@ public enum IdeLogLevel { /** {@link IdeLogLevel} for tracing (very detailed and verbose logging). */ - TRACE("\033[38;5;240m"), + TRACE("\033[38;5;240m", Level.TRACE, null, java.util.logging.Level.FINER), /** {@link IdeLogLevel} for debugging (more detailed logging). */ - DEBUG("\033[90m"), + DEBUG("\033[90m", Level.DEBUG, null, java.util.logging.Level.FINE), /** {@link IdeLogLevel} for general information (regular logging). */ - INFO(null), + INFO(null, Level.INFO, null, java.util.logging.Level.INFO), /** * {@link IdeLogLevel} for a step (logs the step name and groups the following log statements until the next step). */ - STEP("\033[35m"), + STEP("\033[35m", Level.INFO, MarkerFactory.getMarker("step"), java.util.logging.Level.INFO), /** {@link IdeLogLevel} for user interaction (e.g. questions or options). */ - INTERACTION("\033[96m"), + INTERACTION("\033[96m", Level.INFO, MarkerFactory.getMarker("interaction"), java.util.logging.Level.INFO), /** {@link IdeLogLevel} for success (an important aspect has been completed successfully). */ - SUCCESS("\033[92m"), + SUCCESS("\033[92m", Level.INFO, MarkerFactory.getMarker("success"), java.util.logging.Level.INFO), /** {@link IdeLogLevel} for a warning (something unexpected or abnormal happened but can be compensated). */ - WARNING("\033[93m"), + WARNING("\033[93m", Level.WARN, null, java.util.logging.Level.WARNING), /** * {@link IdeLogLevel} for an error (something failed and we cannot proceed or the user has to continue with extreme care). */ - ERROR("\033[91m"), + ERROR("\033[91m", Level.ERROR, null, java.util.logging.Level.SEVERE), /** {@link IdeLogLevel} for {@link com.devonfw.tools.ide.commandlet.Commandlet#isProcessableOutput() processable output} */ - PROCESSABLE(null); + PROCESSABLE(null, Level.INFO, MarkerFactory.getMarker("processable"), java.util.logging.Level.INFO); private final String color; + private final Level slf4jLevel; + + private final Marker slf4jMarker; + + private final java.util.logging.Level julLevel; + /** * The constructor. */ - private IdeLogLevel(String color) { + private IdeLogLevel(String color, Level slf4jLevel, Marker slf4jMarker, java.util.logging.Level julLevel) { this.color = color; + this.slf4jLevel = slf4jLevel; + this.slf4jMarker = slf4jMarker; + this.julLevel = julLevel; } /** @@ -66,6 +79,30 @@ public String getEndColor() { return "\033[0m"; // reset color } + /** + * @return the Slf4J {@link Level}. + */ + public Level getSlf4jLevel() { + + return this.slf4jLevel; + } + + /** + * @return the SLF4J {@link Marker}. Will be {@code null} for standard log-levels. + */ + public Marker getSlf4jMarker() { + + return this.slf4jMarker; + } + + /** + * @return the JUL {@link java.util.logging.Level}. + */ + public java.util.logging.Level getJulLevel() { + + return this.julLevel; + } + /** * @return {@code true} in case of a custom log-level, {@code false} otherwise (standard log-level supported by SLF4J and all reasonable loggers). */ @@ -74,4 +111,56 @@ public boolean isCustom() { return (this == STEP) || (this == INTERACTION) || (this == SUCCESS) || (this == PROCESSABLE); } + /** + * @param marker the {@link Marker}. + * @return the corresponding {@link IdeLogLevel}. + */ + public static IdeLogLevel getLevel(Marker marker) { + + if (marker == INTERACTION.slf4jMarker) { + return IdeLogLevel.INTERACTION; + } else if (marker == STEP.slf4jMarker) { + return IdeLogLevel.STEP; + } else if (marker == SUCCESS.slf4jMarker) { + return IdeLogLevel.SUCCESS; + } else if (marker == PROCESSABLE.slf4jMarker) { + return IdeLogLevel.PROCESSABLE; + } else { + return IdeLogLevel.INFO; // unknown marker + } + } + + /** + * @param level the SLF4J log {@link Level}. + * @param marker the SLF4J {@link Marker}. + * @return the {@link IdeLogLevel}. + */ + public static IdeLogLevel of(Level level, Marker marker) { + + return switch (level) { + case ERROR -> IdeLogLevel.ERROR; + case WARN -> IdeLogLevel.WARNING; + case INFO -> getLevel(marker); + case DEBUG -> IdeLogLevel.DEBUG; + case TRACE -> IdeLogLevel.TRACE; + default -> throw new IllegalStateException("" + level); + }; + } + + /** + * @param level the SLF4J log {@link Level}. + * @param marker the SLF4J {@link Marker}. + * @return the {@link IdeLogLevel}. + */ + public static java.util.logging.Level convertLevelFromSlf4jToJul(Level level, Marker marker) { + + return switch (level) { + case ERROR -> java.util.logging.Level.SEVERE; + case WARN -> java.util.logging.Level.WARNING; + case INFO -> java.util.logging.Level.INFO; + case DEBUG -> java.util.logging.Level.FINE; + case TRACE -> java.util.logging.Level.FINER; + default -> throw new IllegalStateException("" + level); + }; + } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Markers.java b/cli/src/main/java/com/devonfw/tools/ide/log/Markers.java deleted file mode 100644 index 681e320635..0000000000 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Markers.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.devonfw.tools.ide.log; - -import org.slf4j.Marker; -import org.slf4j.MarkerFactory; - -/** - * Markers for SLF4J to emulate IDEasy custom log-levels. Always use log-level INFO on SLF4J in combination with the {@link Markers} defined here. - */ -public final class Markers { - - private Markers() { - - } - - /** {@link Marker} for {@link IdeLogLevel#INTERACTION}. */ - public static final Marker INTERACTION = MarkerFactory.getMarker("interaction"); - - /** {@link Marker} for {@link IdeLogLevel#STEP}. */ - public static final Marker STEP = MarkerFactory.getMarker("step"); - - /** {@link Marker} for {@link IdeLogLevel#SUCCESS}. */ - public static final Marker SUCCESS = MarkerFactory.getMarker("success"); - - /** {@link Marker} for {@link IdeLogLevel#PROCESSABLE}. */ - public static final Marker PROCESSABLE = MarkerFactory.getMarker("processable"); - - /** - * @param marker the {@link Marker}. - * @return the corresponding {@link IdeLogLevel}. - */ - public static IdeLogLevel getLevel(Marker marker) { - - if (marker == INTERACTION) { - return IdeLogLevel.INTERACTION; - } else if (marker == STEP) { - return IdeLogLevel.STEP; - } else if (marker == SUCCESS) { - return IdeLogLevel.SUCCESS; - } else if (marker == PROCESSABLE) { - return IdeLogLevel.PROCESSABLE; - } else { - return IdeLogLevel.INFO; // unknown marker - } - } - -} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java index 63ac9e6187..748e721fc3 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java @@ -1,20 +1,24 @@ package com.devonfw.tools.ide.log; -import java.util.logging.Level; - import org.slf4j.Logger; import org.slf4j.Marker; +import org.slf4j.event.Level; +import org.slf4j.helpers.AbstractLogger; + +import com.devonfw.tools.ide.context.IdeStartContextImpl; /** * Implementation of {@link Logger}. */ -public class Slf4jLoggerAdapter implements Logger { +public class Slf4jLoggerAdapter extends AbstractLogger { + /** Package prefix of IDEasy: {@value} */ + public static final String IDEASY_PACKAGE_PREFIX = "com.devonfw.tools.ide."; private final String name; - private final IdeLogger ideLogger; + private final boolean internal; - private final java.util.logging.Logger julLogger; + private java.util.logging.Logger julLogger; /** * The constructor. @@ -24,13 +28,7 @@ public class Slf4jLoggerAdapter implements Logger { public Slf4jLoggerAdapter(String name) { this.name = name; - if (name.startsWith("com.devonfw.tools.ide.")) { - this.ideLogger = IdeLogger.get(); - this.julLogger = null; - } else { - this.ideLogger = null; - this.julLogger = java.util.logging.Logger.getLogger(name); - } + this.internal = name.startsWith(IDEASY_PACKAGE_PREFIX); } @Override @@ -40,402 +38,129 @@ public String getName() { } private String compose(String message, Object... args) { - return AbstractIdeSubLogger.compose(IdeLogArgFormatter.DEFAULT, InvalidLogMessageHandler.NONE, message, args); - } - - @Override - public boolean isTraceEnabled() { - if (this.julLogger != null) { - return this.julLogger.isLoggable(Level.FINER); - } else { - return this.ideLogger.trace().isEnabled(); - } - } - - @Override - public void trace(String message) { - if (this.julLogger != null) { - this.julLogger.fine(message); - } else { - this.ideLogger.trace(message); + if ((args == null) || args.length == 0) { + return message; } + return AbstractIdeSubLogger.compose(IdeLogArgFormatter.DEFAULT, InvalidLogMessageHandler.NONE, message, args); } @Override - public void trace(String message, Object arg1) { - trace(message, new Object[] { arg1 }); - } + protected String getFullyQualifiedCallerName() { - @Override - public void trace(String message, Object arg1, Object arg2) { - trace(message, new Object[] { arg1, arg2 }); + return null; } - @Override - public void trace(String message, Object... args) { - if (this.julLogger != null) { - this.julLogger.finer(compose(message, args)); - } else { - this.ideLogger.trace(message, args); - } - } + private java.util.logging.Logger getJulLogger() { - @Override - public void trace(String message, Throwable error) { - if (this.julLogger != null) { - this.julLogger.log(Level.FINER, message, error); - } else { - this.ideLogger.level(IdeLogLevel.TRACE).log(error, message); + if (this.julLogger == null) { + IdeLogger ideLogger = IdeLogger.get(); + if (ideLogger == null) { + return null; // initialization issue, logging happens too early + } else { + boolean create = false; + if (ideLogger instanceof IdeStartContextImpl startContext) { + boolean prod = (ideLogger.getClass() == IdeStartContextImpl.class); + if (startContext.isWriteLogfile()) { + create = this.internal || !prod; + } else if (!prod) { + create = !this.internal; // in test we create external loggers, for prod we suppress them + } + } + if (create) { + this.julLogger = java.util.logging.Logger.getLogger(name); + } + } } + return this.julLogger; } - @Override - public boolean isTraceEnabled(Marker marker) { - return isTraceEnabled(); - } - - @Override - public void trace(Marker marker, String message) { - trace(message); - } + private IdeLogger getIdeLogger() { - @Override - public void trace(Marker marker, String message, Object arg1) { - trace(message, arg1); - } - - @Override - public void trace(Marker marker, String message, Object arg1, Object arg2) { - trace(message, arg1, arg2); - } - - @Override - public void trace(Marker marker, String message, Object... args) { - trace(message, args); - } - - @Override - public void trace(Marker marker, String message, Throwable error) { - trace(message, error); - } - - @Override - public boolean isDebugEnabled() { - if (this.julLogger != null) { - return this.julLogger.isLoggable(Level.FINE); - } else { - return this.ideLogger.debug().isEnabled(); + if (this.internal) { + return IdeLogger.get(); } + return null; } @Override - public void debug(String message) { - if (this.julLogger != null) { - this.julLogger.fine(message); - } else { - this.ideLogger.debug(message); + protected void handleNormalizedLoggingCall(Level level, Marker marker, String message, Object[] args, Throwable error) { + IdeLogLevel ideLevel = IdeLogLevel.of(level, marker); + IdeLogger intLogger = getIdeLogger(); + if (intLogger != null) { + intLogger.level(ideLevel).log(error, message, args); } - } - - @Override - public void debug(String message, Object arg1) { - debug(message, new Object[] { arg1 }); - } - - @Override - public void debug(String message, Object arg1, Object arg2) { - debug(message, new Object[] { arg1, arg2 }); - } - - @Override - public void debug(String message, Object... args) { - if (this.julLogger != null) { - this.julLogger.fine(compose(message, args)); - } else { - this.ideLogger.debug(message, args); + java.util.logging.Logger extLogger = getJulLogger(); + if (extLogger != null) { + java.util.logging.Level julLevel = ideLevel.getJulLevel(); + if (extLogger.isLoggable(julLevel)) { + extLogger.log(julLevel, compose(message, args), error); + } } } - @Override - public void debug(String message, Throwable error) { - if (this.julLogger != null) { - this.julLogger.log(Level.FINE, message, error); - } else { - this.ideLogger.level(IdeLogLevel.DEBUG).log(error, message); + private boolean isLevelEnabled(Level level, Marker marker) { + IdeLogLevel ideLevel = IdeLogLevel.of(level, marker); + IdeLogger intLogger = getIdeLogger(); + if (intLogger != null) { + if (intLogger.level(ideLevel).isEnabled()) { + return true; + } } - } - - @Override - public boolean isDebugEnabled(Marker marker) { - return isDebugEnabled(); - } - - @Override - public void debug(Marker marker, String message) { - debug(message); - } - - @Override - public void debug(Marker marker, String message, Object arg1) { - debug(message, arg1); - } - - @Override - public void debug(Marker marker, String message, Object arg1, Object arg2) { - debug(message, arg1, arg2); - } - - @Override - public void debug(Marker marker, String message, Object... args) { - debug(message, args); - } - - @Override - public void debug(Marker marker, String message, Throwable error) { - debug(message, error); - } - - @Override - public boolean isInfoEnabled() { - if (this.julLogger != null) { - return this.julLogger.isLoggable(Level.INFO); - } else { - return this.ideLogger.info().isEnabled(); + java.util.logging.Logger extLogger = getJulLogger(); + if (extLogger != null) { + return extLogger.isLoggable(ideLevel.getJulLevel()); } + return false; } @Override - public void info(String message) { - if (this.julLogger != null) { - this.julLogger.info(message); - } else { - this.ideLogger.info(message); - } + public boolean isTraceEnabled() { + return isLevelEnabled(Level.TRACE, null); } @Override - public void info(String message, Object arg1) { - info(message, new Object[] { arg1 }); + public boolean isTraceEnabled(Marker marker) { + return isLevelEnabled(Level.TRACE, marker); } @Override - public void info(String message, Object arg1, Object arg2) { - info(message, new Object[] { arg1, arg2 }); + public boolean isDebugEnabled() { + return isLevelEnabled(Level.DEBUG, null); } @Override - public void info(String message, Object... args) { - if (this.julLogger != null) { - this.julLogger.info(compose(message, args)); - } else { - this.ideLogger.info(message, args); - } + public boolean isDebugEnabled(Marker marker) { + return isLevelEnabled(Level.DEBUG, marker); } @Override - public void info(String message, Throwable error) { - if (this.julLogger != null) { - this.julLogger.log(Level.INFO, message, error); - } else { - this.ideLogger.level(IdeLogLevel.INFO).log(error, message); - } + public boolean isInfoEnabled() { + return isLevelEnabled(Level.INFO, null); } @Override public boolean isInfoEnabled(Marker marker) { - if (this.julLogger != null) { - return isInfoEnabled(); - } else { - return this.ideLogger.level(Markers.getLevel(marker)).isEnabled(); - } - } - - @Override - public void info(Marker marker, String message) { - if (this.julLogger != null) { - this.julLogger.info(message); - } else { - this.ideLogger.level(Markers.getLevel(marker)).log(message); - } - } - - @Override - public void info(Marker marker, String message, Object arg1) { - info(marker, message, new Object[] { arg1 }); - } - - @Override - public void info(Marker marker, String message, Object arg1, Object arg2) { - info(marker, message, new Object[] { arg1, arg2 }); - } - - @Override - public void info(Marker marker, String message, Object... args) { - if (this.julLogger != null) { - this.julLogger.info(compose(message, args)); - } else { - this.ideLogger.level(Markers.getLevel(marker)).log(message, args); - } - } - - @Override - public void info(Marker marker, String message, Throwable error) { - if (this.julLogger != null) { - this.julLogger.log(Level.INFO, message, error); - } else { - this.ideLogger.level(Markers.getLevel(marker)).log(error, message); - } + return isLevelEnabled(Level.INFO, marker); } @Override public boolean isWarnEnabled() { - if (this.julLogger != null) { - return this.julLogger.isLoggable(Level.WARNING); - } else { - return this.ideLogger.warning().isEnabled(); - } - } - - @Override - public void warn(String message) { - if (this.julLogger != null) { - this.julLogger.warning(message); - } else { - this.ideLogger.warning(message); - } - } - - @Override - public void warn(String message, Object arg1) { - warn(message, new Object[] { arg1 }); - } - - @Override - public void warn(String message, Object arg1, Object arg2) { - warn(message, new Object[] { arg1, arg2 }); - } - - @Override - public void warn(String message, Object... args) { - if (this.julLogger != null) { - this.julLogger.warning(compose(message, args)); - } else { - this.ideLogger.warning(message, args); - } - } - - @Override - public void warn(String message, Throwable error) { - if (this.julLogger != null) { - this.julLogger.log(Level.WARNING, message, error); - } else { - this.ideLogger.level(IdeLogLevel.WARNING).log(error, message); - } + return isLevelEnabled(Level.WARN, null); } @Override public boolean isWarnEnabled(Marker marker) { - return isWarnEnabled(); - } - - @Override - public void warn(Marker marker, String message) { - warn(message); - } - - @Override - public void warn(Marker marker, String message, Object arg1) { - warn(message, arg1); - } - - @Override - public void warn(Marker marker, String message, Object arg1, Object arg2) { - warn(message, arg1, arg2); - } - - @Override - public void warn(Marker marker, String message, Object... args) { - warn(message, args); - } - - @Override - public void warn(Marker marker, String message, Throwable error) { - warn(message, error); + return isLevelEnabled(Level.WARN, marker); } @Override public boolean isErrorEnabled() { - if (this.julLogger != null) { - return this.julLogger.isLoggable(Level.SEVERE); - } else { - return this.ideLogger.error().isEnabled(); - } - } - - @Override - public void error(String message) { - if (this.julLogger != null) { - this.julLogger.severe(message); - } else { - this.ideLogger.error(message); - } - } - - @Override - public void error(String message, Object arg1) { - error(message, new Object[] { arg1 }); - } - - @Override - public void error(String message, Object arg1, Object arg2) { - error(message, new Object[] { arg1, arg2 }); - } - - @Override - public void error(String message, Object... args) { - if (this.julLogger != null) { - this.julLogger.severe(compose(message, args)); - } else { - this.ideLogger.error(message, args); - } - } - - @Override - public void error(String message, Throwable error) { - if (this.julLogger != null) { - this.julLogger.log(Level.SEVERE, message, error); - } else { - this.ideLogger.error(error, message); - } + return isLevelEnabled(Level.ERROR, null); } @Override public boolean isErrorEnabled(Marker marker) { - return isErrorEnabled(); - } - - @Override - public void error(Marker marker, String message) { - error(message); - } - - @Override - public void error(Marker marker, String message, Object arg1) { - error(message, arg1); - } - - @Override - public void error(Marker marker, String message, Object arg1, Object arg2) { - error(message, arg1, arg2); + return isLevelEnabled(Level.ERROR, marker); } - @Override - public void error(Marker marker, String message, Object... args) { - error(message, args); - } - - @Override - public void error(Marker marker, String message, Throwable error) { - error(message, error); - } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jProviderIdeasy.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jProviderIdeasy.java index 6754bf4af2..a42f21835e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jProviderIdeasy.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jProviderIdeasy.java @@ -2,6 +2,7 @@ import org.slf4j.ILoggerFactory; import org.slf4j.IMarkerFactory; +import org.slf4j.helpers.BasicMarkerFactory; import org.slf4j.helpers.NOPMDCAdapter; import org.slf4j.spi.MDCAdapter; import org.slf4j.spi.SLF4JServiceProvider; @@ -30,7 +31,7 @@ public ILoggerFactory getLoggerFactory() { @Override public IMarkerFactory getMarkerFactory() { - return null; + return new BasicMarkerFactory(); } @Override 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 7c7bd1b753..d19ae19ee2 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 @@ -156,7 +156,7 @@ protected final ToolEdition getToolWithConfiguredEdition() { } @Override - public void run() { + protected void doRun() { runTool(this.arguments.asList()); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/gcviewer/GcViewer.java b/cli/src/main/java/com/devonfw/tools/ide/tool/gcviewer/GcViewer.java index 6c55833153..6934ec2015 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/gcviewer/GcViewer.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/gcviewer/GcViewer.java @@ -32,7 +32,7 @@ protected boolean isExtract() { } @Override - public void run() { + protected void doRun() { getCommandlet(Java.class).install(); install(true); 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 4c9c78ae2e..3e8f5e455a 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 @@ -48,8 +48,8 @@ private boolean hasIde(Set tags) { } @Override - public final void run() { - super.run(); + protected final void doRun() { + super.doRun(); } @Override diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/Jmc.java b/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/Jmc.java index 096cf9946b..4e0b41e248 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/Jmc.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/Jmc.java @@ -1,12 +1,5 @@ package com.devonfw.tools.ide.tool.jmc; -import com.devonfw.tools.ide.common.Tag; -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.tool.LocalToolCommandlet; -import com.devonfw.tools.ide.tool.ToolCommandlet; - import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -14,6 +7,13 @@ import java.util.Set; import java.util.stream.Stream; +import com.devonfw.tools.ide.common.Tag; +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.tool.LocalToolCommandlet; +import com.devonfw.tools.ide.tool.ToolCommandlet; + /** * {@link ToolCommandlet} for JDK Mission Control, An advanced set of tools for * managing, monitoring, profiling, and troubleshooting Java applications. @@ -31,7 +31,7 @@ public Jmc(IdeContext context) { } @Override - public void run() { + protected void doRun() { runTool(ProcessMode.BACKGROUND, null, this.arguments.asList()); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/Sonar.java b/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/Sonar.java index c7637c90fb..bd8f778b8a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/Sonar.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/Sonar.java @@ -44,7 +44,7 @@ public ToolInstallation install(boolean silent) { } @Override - public void run() { + protected void doRun() { SonarCommand command = this.command.getValue(); 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 e7ef0e2167..86ee95027c 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 @@ -103,11 +103,17 @@ public interface IdeVariables { c -> Boolean.TRUE); /** - * {@link VariableDefinition} for support of legacy xml templates without XML merge namespace + * {@link VariableDefinition} for support of legacy xml templates without XML merge namespace. */ VariableDefinitionBoolean IDE_XML_MERGE_LEGACY_SUPPORT_ENABLED = new VariableDefinitionBoolean("IDE_XML_MERGE_LEGACY_SUPPORT_ENABLED", null, c -> Boolean.FALSE); + /** + * {@link VariableDefinition} to enable writing logfiles to disc. + */ + VariableDefinitionBoolean IDE_WRITE_LOGFILE = new VariableDefinitionBoolean("IDE_WRITE_LOGFILE", null, + c -> Boolean.TRUE); + /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getProjectName() DEVON_IDE_CUSTOM_TOOLS}. */ VariableDefinitionString DEVON_IDE_CUSTOM_TOOLS = new VariableDefinitionString("DEVON_IDE_CUSTOM_TOOLS"); diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java index 71da701ccf..ca4662b50a 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java @@ -407,4 +407,10 @@ public String getDefaultWindowsGitPath() { protected Path findBashInWindowsRegistry() { return null; } + + @Override + protected Properties createJavaUtilLoggingProperties() { + + return createJavaUtilLoggingProperties(true, false); + } } From 5b9cea51fe7ef884e8f329ef665d49d091acd92a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Fri, 20 Feb 2026 20:04:47 +0100 Subject: [PATCH 29/51] #404: bugfix --- .../tools/ide/context/AbstractIdeContext.java | 52 +++---------- .../tools/ide/log/IdeSubLoggerAdapter.java | 77 +++++++++++++++++++ .../tools/ide/log/Slf4jLoggerAdapter.java | 8 +- 3 files changed, 94 insertions(+), 43 deletions(-) create mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerAdapter.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index b817e89937..ee2f30758d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -22,9 +22,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.slf4j.Marker; -import org.slf4j.event.Level; -import org.slf4j.spi.LoggingEventBuilder; import com.devonfw.tools.ide.cli.CliAbortException; import com.devonfw.tools.ide.cli.CliArgument; @@ -54,6 +51,7 @@ import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.log.IdeLogger; import com.devonfw.tools.ide.log.IdeSubLogger; +import com.devonfw.tools.ide.log.IdeSubLoggerAdapter; import com.devonfw.tools.ide.merge.DirectoryMerger; import com.devonfw.tools.ide.migration.IdeMigrator; import com.devonfw.tools.ide.network.NetworkStatus; @@ -172,6 +170,8 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt private boolean julConfigured; + private final IdeSubLogger[] loggers; + /** * The constructor. * @@ -181,6 +181,13 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt public AbstractIdeContext(IdeStartContextImpl startContext, Path workingDirectory) { super(); + // init sub loggers + IdeLogLevel[] levels = IdeLogLevel.values(); + this.loggers = new IdeSubLogger[levels.length]; + for (IdeLogLevel level : levels) { + this.loggers[level.ordinal()] = new IdeSubLoggerAdapter(level, LOG); + } + this.startContext = startContext; this.startContext.setArgFormatter(this); this.privacyMap = new HashMap<>(); @@ -886,44 +893,7 @@ protected ProcessContext createProcessContext() { @Override public IdeSubLogger level(IdeLogLevel level) { - return new IdeSubLogger() { - @Override - public String log(Throwable error, String message, Object... args) { - - LoggingEventBuilder builder = LOG.atLevel(level.getSlf4jLevel()); - Marker marker = level.getSlf4jMarker(); - if (marker != null) { - builder = builder.addMarker(marker); - } - if (error != null) { - builder = builder.setCause(error); - } - if ((args != null) && (args.length > 0)) { - builder.log(message, args); - } else { - builder.log(message); - } - return message; - } - - @Override - public boolean isEnabled() { - - Level slf4jLevel = level.getSlf4jLevel(); - Marker marker = level.getSlf4jMarker(); - if (marker != null) { - assert slf4jLevel == Level.INFO; - return LOG.isInfoEnabled(marker); - } - return LOG.isEnabledForLevel(slf4jLevel); - } - - @Override - public IdeLogLevel getLevel() { - - return level; - } - }; + return this.loggers[level.ordinal()]; } @Override diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerAdapter.java new file mode 100644 index 0000000000..95c8a4a6e8 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerAdapter.java @@ -0,0 +1,77 @@ +package com.devonfw.tools.ide.log; + +import org.slf4j.Logger; +import org.slf4j.Marker; +import org.slf4j.event.Level; +import org.slf4j.spi.LoggingEventBuilder; + +/** + * {@link IdeSubLogger} that actually adapts to SLF4J that should again adapt to {@link IdeLogger} and JUL as needed. + */ +public class IdeSubLoggerAdapter implements IdeSubLogger { + + private final IdeLogLevel level; + + private final Logger LOG; + + /** + * The constructor. + * + * @param level the {@link IdeLogLevel}. + * @param logger the SLF4J {@link Logger}. + */ + public IdeSubLoggerAdapter(IdeLogLevel level, Logger logger) { + this.level = level; + this.LOG = logger; + } + + @Override + public String log(Throwable error, String message, Object... args) { + + Marker marker = level.getSlf4jMarker(); + if (marker != null) { + assert level.getSlf4jLevel() == Level.INFO; + if (error == null) { + if (Slf4jLoggerAdapter.isEmpty(args)) { + LOG.info(marker, message); + } else { + LOG.info(marker, message, args); + } + } else if (Slf4jLoggerAdapter.isEmpty(args)) { + LOG.info(marker, message, error); + } else { + LOG.info(marker, Slf4jLoggerAdapter.compose(message, args)); + } + } else { + LoggingEventBuilder builder = LOG.atLevel(level.getSlf4jLevel()); + if (error != null) { + builder = builder.setCause(error); + } + if (Slf4jLoggerAdapter.isEmpty(args)) { + builder.log(message); + } else { + builder.log(message, args); + } + } + return message; + } + + @Override + public boolean isEnabled() { + + Level slf4jLevel = level.getSlf4jLevel(); + Marker marker = level.getSlf4jMarker(); + if (marker != null) { + assert slf4jLevel == Level.INFO; + return LOG.isInfoEnabled(marker); + } + return LOG.isEnabledForLevel(slf4jLevel); + } + + @Override + public IdeLogLevel getLevel() { + + return level; + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java index 748e721fc3..4105ae4f6b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java @@ -37,8 +37,12 @@ public String getName() { return this.name; } - private String compose(String message, Object... args) { - if ((args == null) || args.length == 0) { + static boolean isEmpty(Object[] args) { + return (args == null) || (args.length == 0); + } + + static String compose(String message, Object... args) { + if (isEmpty(args)) { return message; } return AbstractIdeSubLogger.compose(IdeLogArgFormatter.DEFAULT, InvalidLogMessageHandler.NONE, message, args); From 04e4bdacddfa1e78f6e1fe27014f3a0b5bebe247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Fri, 20 Feb 2026 22:15:54 +0100 Subject: [PATCH 30/51] #404: use SLF4J, fixes --- .../com/devonfw/tools/ide/cli/Ideasy.java | 8 +- .../commandlet/AbstractUpdateCommandlet.java | 39 ++--- ...AbstractVersionOrEditionGetCommandlet.java | 36 +++-- .../ide/commandlet/ContextCommandlet.java | 8 + .../ide/commandlet/CreateCommandlet.java | 14 +- .../tools/ide/commandlet/HelpCommandlet.java | 43 +++--- .../ide/commandlet/StatusCommandlet.java | 39 +++-- .../ide/commandlet/UpdateCommandlet.java | 2 +- .../commandlet/UpgradeSettingsCommandlet.java | 24 +-- .../tools/ide/context/AbstractIdeContext.java | 3 - .../EnvironmentVariablesPropertiesFile.java | 29 ++-- .../devonfw/tools/ide/git/GitContextImpl.java | 52 ++++--- .../git/repository/RepositoryCommandlet.java | 29 ++-- .../devonfw/tools/ide/io/FileAccessImpl.java | 139 +++++++++--------- .../tools/ide/tool/IdeasyCommandlet.java | 88 ++++++----- .../tools/ide/tool/LocalToolCommandlet.java | 63 ++++---- ...ackageManagerBasedLocalToolCommandlet.java | 9 +- .../com/devonfw/tools/ide/tool/aws/Aws.java | 7 +- .../com/devonfw/tools/ide/tool/mvn/Mvn.java | 25 ++-- .../com/devonfw/tools/ide/tool/node/Node.java | 10 +- .../tool/plugin/PluginBasedCommandlet.java | 2 +- .../tools/ide/tool/plugin/ToolPlugins.java | 15 +- .../devonfw/tools/ide/tool/sonar/Sonar.java | 13 +- .../devonfw/tools/ide/tool/tomcat/Tomcat.java | 14 +- 24 files changed, 413 insertions(+), 298 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java b/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java index eabbde615c..eac889bcf3 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java +++ b/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java @@ -97,7 +97,11 @@ public int runOrThrow(String... args) { private void initContext(CliArguments arguments) { - ContextCommandlet contextCommandlet = new ContextCommandlet(); + IdeStartContextImpl startContext = null; + if (this.context != null) { + startContext = this.context.getStartContext(); + } + ContextCommandlet contextCommandlet = new ContextCommandlet(startContext); while (arguments.hasNext()) { CliArgument current = arguments.next(); String key = current.getKey(); @@ -118,7 +122,7 @@ private void initContext(CliArguments arguments) { } contextCommandlet.run(); if (this.context == null) { - IdeStartContextImpl startContext = contextCommandlet.getStartContext(); + startContext = contextCommandlet.getStartContext(); this.context = new IdeContextConsole(startContext); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java index c5acfebabe..68096a6bf9 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java @@ -9,6 +9,9 @@ import java.util.Set; import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; @@ -38,6 +41,8 @@ */ public abstract class AbstractUpdateCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(AbstractUpdateCommandlet.class); + private static final String MESSAGE_CODE_REPO_URL = """ No code repository was given after '--code'. Further details can be found here: https://github.com/devonfw/IDEasy/blob/main/documentation/settings.adoc @@ -116,7 +121,7 @@ private void updateConf() { if (Files.exists(legacyTemplatesFolder)) { templatesFolder = legacyTemplatesFolder; } else { - this.context.warning("Templates folder is missing in settings repository."); + LOG.warn("Templates folder is missing in settings repository."); return; } } @@ -141,10 +146,10 @@ private void setupConf(Path template, Path conf) { setupConf(child, confPath); } else if (Files.isRegularFile(child)) { if (Files.isRegularFile(confPath)) { - this.context.debug("Configuration {} already exists - skipping to copy from {}", confPath, child); + LOG.debug("Configuration {} already exists - skipping to copy from {}", confPath, child); } else { if (!basename.equals("settings.xml")) { - this.context.info("Copying template {} to {}.", child, conf); + LOG.info("Copying template {} to {}.", child, conf); this.context.getFileAccess().copy(child, conf); } } @@ -175,7 +180,7 @@ private void updateSettingsInStep() { gitContext.pull(settingsPath); this.context.getGitContext().saveCurrentCommitId(settingsPath, this.context.getSettingsCommitIdPath()); } else { - this.context.info("Skipping git pull in settings due to code repository. Use --force-pull to enforce pulling."); + LOG.info("Skipping git pull in settings due to code repository. Use --force-pull to enforce pulling."); } } else { GitUrl gitUrl = getOrAskSettingsUrl(); @@ -193,11 +198,11 @@ private GitUrl getOrAskSettingsUrl() { if (isCodeRepository()) { userPromt = "Code repository URL:"; defaultUrl = null; - this.context.info(MESSAGE_CODE_REPO_URL); + LOG.info(MESSAGE_CODE_REPO_URL); } else { userPromt = "Settings URL [" + IdeContext.DEFAULT_SETTINGS_REPO_URL + "]:"; defaultUrl = IdeContext.DEFAULT_SETTINGS_REPO_URL; - this.context.info(MESSAGE_SETTINGS_REPO_URL, this.context.getSettingsPath()); + LOG.info(MESSAGE_SETTINGS_REPO_URL, this.context.getSettingsPath()); } GitUrl gitUrl = null; if (repository != null) { @@ -208,7 +213,7 @@ private GitUrl getOrAskSettingsUrl() { repository = handleDefaultRepository(repository); gitUrl = GitUrl.of(repository); if (!gitUrl.isValid()) { - this.context.warning("The input URL is not valid, please try again."); + LOG.warn("The input URL is not valid, please try again."); } } return gitUrl; @@ -217,10 +222,10 @@ private GitUrl getOrAskSettingsUrl() { private String handleDefaultRepository(String repository) { if ("-".equals(repository)) { if (isCodeRepository()) { - this.context.warning("'-' is found after '--code'. This is invalid."); + LOG.warn("'-' is found after '--code'. This is invalid."); repository = null; } else { - this.context.info("'-' was found for settings repository, the default settings repository '{}' will be used.", IdeContext.DEFAULT_SETTINGS_REPO_URL); + LOG.info("'-' was found for settings repository, the default settings repository '{}' will be used.", IdeContext.DEFAULT_SETTINGS_REPO_URL); repository = IdeContext.DEFAULT_SETTINGS_REPO_URL; } } @@ -275,7 +280,7 @@ private void initializeRepository(GitUrl gitUrl) { private void updateSoftware() { if (this.skipTools.isTrue()) { - this.context.info("Skipping installation/update of tools as specified by the user."); + LOG.info("Skipping installation/update of tools as specified by the user."); return; } Step step = this.context.newStep("Install or update software"); @@ -303,7 +308,7 @@ private void doUpdateSoftwareStep(Step step) { ToolCommandlet toolCommandlet = commandletManager.getToolCommandlet(regularTool); if (toolCommandlet == null) { String displayName = (regularTool == null || regularTool.isBlank()) ? "" : "'" + regularTool + "'"; - this.context.error("Cannot install or update tool '{}''. No matching commandlet found. Please check your IDE_TOOLS configuration.", displayName); + LOG.error("Cannot install or update tool '{}''. No matching commandlet found. Please check your IDE_TOOLS configuration.", displayName); } else { toolCommandlets.add(toolCommandlet); } @@ -324,7 +329,7 @@ private void doUpdateSoftwareStep(Step step) { ExtraTools extraTools = ExtraToolsMapper.get().loadJsonFromFolder(this.context.getSettingsPath()); if (extraTools != null) { List toolNames = extraTools.getSortedToolNames(); - this.context.info("Found extra installation of the following tools: {}", toolNames); + LOG.info("Found extra installation of the following tools: {}", toolNames); for (String tool : toolNames) { List installations = extraTools.getExtraInstallations(tool); this.context.newStep("Install extra version(s) of " + tool).run(() -> installExtraToolInstallations(tool, installations)); @@ -358,9 +363,9 @@ private void updateRepositories() { if (this.skipRepositories.isTrue()) { if (this.forceRepositories.isTrue()) { - this.context.warning("Options to skip and force repositories are incompatible and should not be combined. Ignoring --force-repositories to proceed."); + LOG.warn("Options to skip and force repositories are incompatible and should not be combined. Ignoring --force-repositories to proceed."); } - this.context.info("Skipping setup of repositories as specified by the user."); + LOG.info("Skipping setup of repositories as specified by the user."); return; } RepositoryCommandlet repositoryCommandlet = this.context.getCommandletManager().getCommandlet(RepositoryCommandlet.class); @@ -372,13 +377,13 @@ private void createStartScripts() { List ides = IdeVariables.CREATE_START_SCRIPTS.get(this.context); if (ides == null) { - this.context.info("Variable CREATE_START_SCRIPTS is undefined - skipping start script creation."); + LOG.info("Variable CREATE_START_SCRIPTS is undefined - skipping start script creation."); return; } for (String ide : ides) { ToolCommandlet tool = this.context.getCommandletManager().getToolCommandlet(ide); if (tool == null) { - this.context.error("Undefined IDE '{}' configured in variable CREATE_START_SCRIPTS."); + LOG.error("Undefined IDE '{}' configured in variable CREATE_START_SCRIPTS.", ide); } else { createStartScript(ide); } @@ -387,7 +392,7 @@ private void createStartScripts() { private void createStartScript(String ide) { - this.context.info("Creating start scripts for {}", ide); + LOG.info("Creating start scripts for {}", ide); Path workspaces = this.context.getIdeHome().resolve(IdeContext.FOLDER_WORKSPACES); try (Stream childStream = Files.list(workspaces)) { Iterator iterator = childStream.iterator(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java index 490a99f49c..c8345b299e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java @@ -2,10 +2,13 @@ import java.util.Objects; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeSubLogger; import com.devonfw.tools.ide.property.FlagProperty; import com.devonfw.tools.ide.property.ToolProperty; import com.devonfw.tools.ide.tool.ToolCommandlet; @@ -17,6 +20,8 @@ */ public abstract class AbstractVersionOrEditionGetCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(AbstractVersionOrEditionGetCommandlet.class); + /** The tool to get the version of. */ public final ToolProperty tool; @@ -71,7 +76,7 @@ public boolean isProcessableOutput() { protected void doRun() { ToolCommandlet commandlet = this.tool.getValue(); - IdeSubLogger logger = this.context.level(IdeLogLevel.PROCESSABLE); + Marker marker = IdeLogLevel.PROCESSABLE.getSlf4jMarker(); Object configuredValue = getConfiguredValue(commandlet); Object installedValue = getInstalledValue(commandlet); boolean getInstalledValue = this.installed.isTrue(); @@ -81,42 +86,43 @@ protected void doRun() { } if (getInstalledValue == getConfiguredValue) { if (getInstalledValue) { // both --configured and --installed - logToolInfo(logger, commandlet, configuredValue, installedValue); + logToolInfo(commandlet, configuredValue, installedValue); } else if (this.context.debug().isEnabled()) { - logToolInfo(logger, commandlet, configuredValue, installedValue); + logToolInfo(commandlet, configuredValue, installedValue); } else { if (installedValue == null) { - logger.log(configuredValue.toString()); + LOG.info(marker, configuredValue.toString()); } else { - logger.log(installedValue.toString()); + LOG.info(marker, installedValue.toString()); } } } else { if (getInstalledValue) { if (installedValue == null) { - logToolInfo(logger, commandlet, configuredValue, null); + logToolInfo(commandlet, configuredValue, null); } else { - logger.log(installedValue.toString()); + LOG.info(marker, installedValue.toString()); } } else { - logger.log(configuredValue.toString()); + LOG.info(marker, configuredValue.toString()); } } } - private void logToolInfo(IdeSubLogger logger, ToolCommandlet commandlet, Object configuredValue, Object installedValue) { + private void logToolInfo(ToolCommandlet commandlet, Object configuredValue, Object installedValue) { String property = getPropertyToGet(); String toolName = commandlet.getName(); + Marker marker = IdeLogLevel.PROCESSABLE.getSlf4jMarker(); if (installedValue == null) { - logger.log("No installation of tool {} was found.", toolName); + LOG.info(marker, "No installation of tool {} was found.", toolName); } else { - logger.log("The installed {} for tool {} is {}", property, toolName, installedValue); + LOG.info(marker, "The installed {} for tool {} is {}", property, toolName, installedValue); } - logger.log("The configured {} for tool {} is {}", property, toolName, configuredValue); + LOG.info(marker, "The configured {} for tool {} is {}", property, toolName, configuredValue); if (!Objects.equals(configuredValue, installedValue)) { - logger.log("To install the configured {} call the following command:", property); - logger.log("ide install {}", toolName); + LOG.info(marker, "To install the configured {} call the following command:", property); + LOG.info(marker, "ide install {}", toolName); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java index bbc5e48447..ecd2df1daa 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java @@ -40,8 +40,16 @@ public class ContextCommandlet extends Commandlet { * The constructor. */ public ContextCommandlet() { + this(null); + } + + /** + * The constructor. + */ + public ContextCommandlet(IdeStartContextImpl startContext) { super(null); + this.startContext = startContext; this.batch = add(new FlagProperty("--batch", false, "-b")); this.force = add(new FlagProperty("--force", false, "-f")); this.trace = add(new FlagProperty("--trace", false, "-t")); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java index bb993f9580..0d07c2922b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java @@ -4,8 +4,12 @@ import java.nio.file.Path; import java.util.function.Predicate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.FileAccess; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.property.FlagProperty; import com.devonfw.tools.ide.property.StringProperty; import com.devonfw.tools.ide.version.IdeVersion; @@ -15,6 +19,8 @@ */ public class CreateCommandlet extends AbstractUpdateCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(CreateCommandlet.class); + /** {@link StringProperty} for the name of the new project */ public final StringProperty newProject; @@ -52,7 +58,7 @@ protected void doRun() { String newProjectName = this.newProject.getValue(); Path newProjectPath = this.context.getIdeRoot().resolve(newProjectName); - this.context.info("Creating new IDEasy project in {}", newProjectPath); + LOG.info("Creating new IDEasy project in {}", newProjectPath); if (!this.context.getFileAccess().isEmptyDir(newProjectPath)) { this.context.askToContinue("Directory " + newProjectPath + " already exists. Do you want to continue?"); } else { @@ -62,10 +68,10 @@ protected void doRun() { initializeProject(newProjectPath); this.context.setIdeHome(newProjectPath); this.context.verifyIdeMinVersion(true); - super.run(); + super.doRun(); this.context.verifyIdeMinVersion(true); this.context.getFileAccess().writeFileContent(IdeVersion.getVersionString(), newProjectPath.resolve(IdeContext.FILE_SOFTWARE_VERSION)); - this.context.success("Successfully created new project '{}'.", newProjectName); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully created new project '{}'.", newProjectName); logWelcomeMessage(); } @@ -95,7 +101,7 @@ private void logWelcomeMessage() { Predicate welcomePredicate = path -> String.valueOf(path.getFileName()).startsWith("welcome."); Path welcomeFilePath = this.context.getFileAccess().findFirst(settingsFolder, welcomePredicate, false); if (welcomeFilePath != null) { - this.context.info(this.context.getFileAccess().readFileContent(welcomeFilePath)); + LOG.info(this.context.getFileAccess().readFileContent(welcomeFilePath)); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java index 3f388f6c2f..ca3ced7395 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java @@ -4,6 +4,10 @@ import java.util.Collections; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.log.IdeSubLogger; @@ -19,6 +23,8 @@ */ public final class HelpCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(HelpCommandlet.class); + /** The optional commandlet to get help about. */ public final CommandletProperty commandlet; @@ -57,31 +63,32 @@ protected void doRun() { this.context.printLogo(); NlsBundle bundle = NlsBundle.of(this.context); - this.context.success(bundle.get("version-banner"), IdeVersion.getVersionString()); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), bundle.get("version-banner"), IdeVersion.getVersionString()); Commandlet cmd = this.commandlet.getValue(); if (cmd == null) { - this.context.info(bundle.get("usage") + " ide [option]* [[commandlet] [arg]*]"); - this.context.info(""); + String usage = bundle.get("usage") + " ide [option]* [[commandlet] [arg]*]"; + LOG.info(usage); + LOG.info(""); printCommandlets(bundle); } else { printCommandletHelp(bundle, cmd); } - this.context.info(""); - this.context.info(bundle.get("options")); + LOG.info(""); + LOG.info(bundle.get("options")); Args options = new Args(); - ContextCommandlet cxtCmd = new ContextCommandlet(); + ContextCommandlet cxtCmd = new ContextCommandlet(((AbstractIdeContext) this.context).getStartContext()); collectOptions(options, cxtCmd, bundle); if (cmd != null) { collectOptions(options, cmd, bundle); } options.print(); if (cmd == null) { - this.context.info(""); - this.context.info(bundle.getDetail(this.context.getCommandletManager().getCommandlet(HelpCommandlet.class))); + LOG.info(""); + LOG.info(bundle.getDetail(this.context.getCommandletManager().getCommandlet(HelpCommandlet.class))); } - this.context.info(""); - this.context.info(bundle.get("icd-hint")); + LOG.info(""); + LOG.info(bundle.get("icd-hint")); } private void printCommandletHelp(NlsBundle bundle, Commandlet cmd) { @@ -113,11 +120,11 @@ private void printCommandletHelp(NlsBundle bundle, Commandlet cmd) { } } } - this.context.info(usage.toString()); - this.context.info(bundle.get(cmd)); - this.context.info(bundle.getDetail(cmd)); - this.context.info(""); - this.context.info(bundle.get("values")); + LOG.info(usage.toString()); + LOG.info(bundle.get(cmd)); + LOG.info(bundle.getDetail(cmd)); + LOG.info(""); + LOG.info(bundle.get("values")); values.print(); cmd.printHelp(bundle); } @@ -142,10 +149,10 @@ private void printCommandlets(NlsBundle bundle) { } } - this.context.info(bundle.get("commandlets")); + LOG.info(bundle.get("commandlets")); commandlets.print(IdeLogLevel.INTERACTION); - this.context.info(""); - this.context.info(bundle.get("toolcommandlets")); + LOG.info(""); + LOG.info(bundle.get("toolcommandlets")); toolcommandlets.print(IdeLogLevel.INTERACTION); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java index 4a5dacc352..e5b8659fb1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java @@ -3,9 +3,13 @@ import java.nio.file.Files; import java.nio.file.Path; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.environment.EnvironmentVariables; import com.devonfw.tools.ide.git.GitContext; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.migration.IdeMigrator; import com.devonfw.tools.ide.os.SystemInfo; import com.devonfw.tools.ide.step.Step; @@ -17,6 +21,8 @@ */ public class StatusCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(StatusCommandlet.class); + /** * The constructor. * @@ -34,6 +40,12 @@ public String getName() { return "status"; } + @Override + protected boolean isActivateJaveUtilLogging() { + + return false; + } + @Override protected void doRun() { Step step = this.context.newStep(true, "Show IDE_ROOT and IDE_HOME"); @@ -62,7 +74,7 @@ private void checkForUpdate() { private void logSystemInfo() { SystemInfo systemInfo = this.context.getSystemInfo(); - this.context.info("Your operating system is {}({})@{} [{}@{}]", systemInfo.getOs(), systemInfo.getOsVersion(), systemInfo.getArchitecture(), + LOG.info("Your operating system is {}({})@{} [{}@{}]", systemInfo.getOs(), systemInfo.getOsVersion(), systemInfo.getArchitecture(), systemInfo.getOsName(), systemInfo.getArchitectureName()); } @@ -73,12 +85,12 @@ private void logSettingsLegacyStatus() { Path legacyProperties = variables.getLegacyPropertiesFilePath(); if (legacyProperties != null && Files.exists(legacyProperties)) { hasLegacyProperties = true; - this.context.warning("Found legacy properties {}", legacyProperties); + LOG.warn("Found legacy properties {}", legacyProperties); } variables = variables.getParent(); } if (hasLegacyProperties) { - this.context.warning( + LOG.warn( "Your settings are outdated and contain legacy configurations. Please consider upgrading your settings:\nhttps://github.com/devonfw/IDEasy/blob/main/documentation/settings.adoc#upgrade"); } } @@ -87,21 +99,21 @@ private void logSettingsGitStatus() { Path settingsPath = this.context.getSettingsGitRepository(); if (settingsPath == null) { if (this.context.getIdeHome() != null) { - this.context.error("No settings repository was found."); + LOG.error("No settings repository was found."); } } else { GitContext gitContext = this.context.getGitContext(); if (gitContext.isRepositoryUpdateAvailable(settingsPath, this.context.getSettingsCommitIdPath())) { if (!this.context.isSettingsRepositorySymlinkOrJunction()) { - this.context.warning("Your settings are not up-to-date, please run 'ide update'."); + LOG.warn("Your settings are not up-to-date, please run 'ide update'."); } } else { - this.context.success("Your settings are up-to-date."); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Your settings are up-to-date."); } String branch = gitContext.determineCurrentBranch(settingsPath); - this.context.debug("Your settings branch is {}", branch); + LOG.debug("Your settings branch is {}", branch); if (!"master".equals(branch) && !"main".equals(branch)) { - this.context.warning("Your settings are on a custom branch: {}", branch); + LOG.warn("Your settings are on a custom branch: {}", branch); } } } @@ -116,7 +128,8 @@ private void logMigrationStatus() { VersionIdentifier projectVersion = this.context.getProjectVersion(); VersionIdentifier targetVersion = migrator.getTargetVersion(); if (projectVersion.isLess(targetVersion)) { - this.context.interaction("Your project is on IDEasy version {} and needs an update to version {}!\nPlease run 'ide update' to migrate your project", + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), + "Your project is on IDEasy version {} and needs an update to version {}!\nPlease run 'ide update' to migrate your project", projectVersion, targetVersion); } } @@ -124,16 +137,16 @@ private void logMigrationStatus() { private void logGitBashLocationStatus() { Path bashPath = this.context.findBash(); if (bashPath != null) { - this.context.success("Found bash executable at: {}", bashPath); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Found bash executable at: {}", bashPath); } else { - this.context.error("No bash executable was found on your system!"); + LOG.error("No bash executable was found on your system!"); } GitContext gitContext = this.context.getGitContext(); Path gitPath = gitContext.findGit(); if (gitPath != null) { - this.context.success("Found git executable at: {}", gitPath); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Found git executable at: {}", gitPath); } else { - this.context.error("No git executable was found on your system!"); + LOG.error("No git executable was found on your system!"); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpdateCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpdateCommandlet.java index 2d1bc0c596..944a4c0eeb 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpdateCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpdateCommandlet.java @@ -27,6 +27,6 @@ public String getName() { @Override protected void doRun() { new IdeMigrator().run(this.context); - super.run(); + super.doRun(); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java index 220c0e79fa..d84566c873 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java @@ -8,11 +8,15 @@ import java.util.List; import java.util.function.Function; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.environment.EnvironmentVariables; import com.devonfw.tools.ide.environment.EnvironmentVariablesPropertiesFile; import com.devonfw.tools.ide.environment.EnvironmentVariablesType; import com.devonfw.tools.ide.io.FileAccess; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.merge.DirectoryMerger; import com.devonfw.tools.ide.tool.custom.CustomTools; import com.devonfw.tools.ide.tool.custom.CustomToolsMapper; @@ -25,6 +29,8 @@ */ public class UpgradeSettingsCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(UpgradeSettingsCommandlet.class); + /** * The constructor. * @@ -50,7 +56,7 @@ protected void doRun() { } private void updateLegacyFolders() { - this.context.info("Updating legacy folders if present..."); + LOG.info("Updating legacy folders if present..."); Path settingsPath = context.getSettingsPath(); updateLegacyFolder(settingsPath, IdeContext.FOLDER_LEGACY_REPOSITORIES, IdeContext.FOLDER_REPOSITORIES); updateLegacyFolder(settingsPath, IdeContext.FOLDER_LEGACY_TEMPLATES, IdeContext.FOLDER_TEMPLATES); @@ -65,16 +71,16 @@ private void updateLegacyFolder(Path folder, String legacyName, String newName) try { if (!Files.exists(newFolder)) { fileAccess.move(legacyFolder, newFolder, StandardCopyOption.REPLACE_EXISTING); - this.context.success("Successfully renamed folder '{}' to '{}' in {}.", legacyName, newName, folder); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully renamed folder '{}' to '{}' in {}.", legacyName, newName, folder); } } catch (IllegalStateException e) { - this.context.error(e, "Error renaming folder {} to {} in {}", legacyName, newName, folder); + LOG.error("Error renaming folder {} to {} in {}", legacyName, newName, folder, e); } } } private void updateWorkspaceTemplates() { - this.context.info("Updating workspace templates (replace legacy variables and change variable syntax)..."); + LOG.info("Updating workspace templates (replace legacy variables and change variable syntax)..."); FileAccess fileAccess = this.context.getFileAccess(); DirectoryMerger merger = this.context.getWorkspaceMerger(); @@ -154,7 +160,7 @@ private String mapLegacyIntellijEdition(String legacyEdition) { case "U" -> "ultimate"; case "C" -> "intellij"; default -> { - this.context.warning("Undefined legacy edition {}", legacyEdition); + LOG.warn("Undefined legacy edition {}", legacyEdition); yield "intellij"; } }; @@ -167,7 +173,7 @@ private String mapLegacyEclipseEdition(String legacyEdition) { case "jee" -> "jee"; case "cpp" -> "cpp"; default -> { - this.context.warning("Undefined legacy edition {}", legacyEdition); + LOG.warn("Undefined legacy edition {}", legacyEdition); yield "eclipse"; } }; @@ -187,7 +193,7 @@ private static void updatePropertiesLegacyEdition(EnvironmentVariablesProperties } private void cleanupLegacyProperties() { - this.context.info("Cleaning up legacy properties..."); + LOG.info("Cleaning up legacy properties..."); Path settingsPath = context.getSettingsPath(); Path repositoriesPath = settingsPath.resolve(IdeContext.FOLDER_REPOSITORIES); @@ -227,9 +233,9 @@ private void updateRepositoryPropertiesFile(Path filePath) throws IOException { if (updated) { try { Files.write(filePath, lines, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); - this.context.success("Successfully updated repository configuration file {}", filePath); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully updated repository configuration file {}", filePath); } catch (IOException e) { - this.context.error("Failed to write updated repository configuration file {}", filePath); + LOG.error("Failed to write updated repository configuration file {}", filePath); throw e; } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index ee2f30758d..41b95ff8ee 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -1277,9 +1277,6 @@ settingsRepository, getSettingsCommitIdPath()))) { if (!success) { return ValidationResultValid.get(); } - if (!cmd.isProcessableOutput() && !(cmd instanceof HelpCommandlet)) { - configureJavaUtilLogging(); - } cmd.run(); } finally { this.julConfigured = false; diff --git a/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFile.java b/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFile.java index cc78465e2b..a16baef36d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFile.java +++ b/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFile.java @@ -13,6 +13,9 @@ import java.util.Objects; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.variable.IdeVariables; import com.devonfw.tools.ide.variable.VariableDefinition; @@ -22,6 +25,8 @@ */ public final class EnvironmentVariablesPropertiesFile extends EnvironmentVariablesMap { + private static final Logger LOG = LoggerFactory.getLogger(EnvironmentVariablesPropertiesFile.class); + private static final String NEWLINE = "\n"; private final EnvironmentVariablesType type; @@ -117,10 +122,10 @@ private boolean load(Path file) { return false; } if (!Files.exists(file)) { - this.context.trace("Properties not found at {}", file); + LOG.trace("Properties not found at {}", file); return false; } - this.context.trace("Loading properties from {}", file); + LOG.trace("Loading properties from {}", file); boolean legacyProperties = file.getFileName().toString().equals(LEGACY_PROPERTIES); try (BufferedReader reader = Files.newBufferedReader(file)) { String line; @@ -132,14 +137,14 @@ private boolean load(Path file) { if (name != null) { VariableLine migratedVariableLine = migrateLine(variableLine, false); if (migratedVariableLine == null) { - this.context.warning("Illegal variable definition: {}", variableLine); + LOG.warn("Illegal variable definition: {}", variableLine); continue; } String migratedName = migratedVariableLine.getName(); String migratedValue = migratedVariableLine.getValue(); boolean legacyVariable = IdeVariables.isLegacyVariable(name); if (legacyVariable && !legacyProperties) { - this.context.warning("Legacy variable name is used to define variable {} in {} - please cleanup your configuration.", variableLine, + LOG.warn("Legacy variable name is used to define variable {} in {} - please cleanup your configuration.", variableLine, file); } String oldValue = this.variables.get(migratedName); @@ -147,10 +152,10 @@ private boolean load(Path file) { VariableDefinition variableDefinition = IdeVariables.get(name); if (legacyVariable) { // if the legacy name was configured we do not want to override the official variable! - this.context.warning("Both legacy variable {} and official variable {} are configured in {} - ignoring legacy variable declaration!", + LOG.warn("Both legacy variable {} and official variable {} are configured in {} - ignoring legacy variable declaration!", variableDefinition.getLegacyName(), variableDefinition.getName(), file); } else { - this.context.warning("Duplicate variable definition {} with old value '{}' and new value '{}' in {}", name, oldValue, migratedValue, + LOG.warn("Duplicate variable definition {} with old value '{}' and new value '{}' in {}", name, oldValue, migratedValue, file); this.variables.put(migratedName, migratedValue); } @@ -174,13 +179,13 @@ public void save() { boolean isLegacy = Boolean.TRUE.equals(this.legacyConfiguration); if (this.modifiedVariables.isEmpty() && !isLegacy) { - this.context.trace("No changes to save in properties file {}", this.propertiesFilePath); + LOG.trace("No changes to save in properties file {}", this.propertiesFilePath); return; } Path file = this.propertiesFilePath; if (isLegacy) { - this.context.info("Converting legacy properties to {}", this.propertiesFilePath); + LOG.info("Converting legacy properties to {}", this.propertiesFilePath); file = this.legacyPropertiesFilePath; } @@ -192,10 +197,10 @@ public void save() { for (VariableLine line : lines) { VariableLine newLine = migrateLine(line, true); if (newLine == null) { - this.context.debug("Removed variable line '{}' from {}", line, this.propertiesFilePath); + LOG.debug("Removed variable line '{}' from {}", line, this.propertiesFilePath); } else { if (newLine != line) { - this.context.debug("Changed variable line from '{}' to '{}' in {}", line, newLine, this.propertiesFilePath); + LOG.debug("Changed variable line from '{}' to '{}' in {}", line, newLine, this.propertiesFilePath); } writer.append(newLine.toString()); writer.append(NEWLINE); @@ -209,7 +214,7 @@ public void save() { for (String name : this.modifiedVariables) { String value = this.variables.get(name); if (value == null) { - this.context.trace("Internal error: removed variable {} was not found in {}", name, this.propertiesFilePath); + LOG.trace("Internal error: removed variable {} was not found in {}", name, this.propertiesFilePath); } else { boolean export = this.exportedVariables.contains(name); VariableLine line = VariableLine.of(export, name, value); @@ -228,7 +233,7 @@ private List loadVariableLines(Path file) { List lines = new ArrayList<>(); if (!Files.exists(file)) { // Skip reading if the file does not exist - this.context.debug("Properties file {} does not exist, skipping read.", file); + LOG.debug("Properties file {} does not exist, skipping read.", file); return lines; } try (BufferedReader reader = Files.newBufferedReader(file)) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/git/GitContextImpl.java b/cli/src/main/java/com/devonfw/tools/ide/git/GitContextImpl.java index dd11f0bbb3..00e9462882 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/git/GitContextImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/git/GitContextImpl.java @@ -7,8 +7,12 @@ import java.util.List; import java.util.Objects; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.os.SystemInfoImpl; import com.devonfw.tools.ide.process.ProcessContext; import com.devonfw.tools.ide.process.ProcessErrorHandling; @@ -21,6 +25,8 @@ */ public class GitContextImpl implements GitContext { + private static final Logger LOG = LoggerFactory.getLogger(GitContextImpl.class); + /** @see #getContext() */ protected final IdeContext context; private Path git; @@ -118,14 +124,14 @@ private void handleErrors(Path targetRepository, ProcessResult result) { if (!result.isSuccessful()) { String message = "Failed to update git repository at " + targetRepository; if (this.context.isOfflineMode()) { - this.context.warning(message); - this.context.interaction("Continuing as we are in offline mode - results may be outdated!"); + LOG.warn(message); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "Continuing as we are in offline mode - results may be outdated!"); } else { - this.context.error(message); + LOG.error(message); if (this.context.isOnline()) { - this.context.error("See above error for details. If you have local changes, please stash or revert and retry."); + LOG.error("See above error for details. If you have local changes, please stash or revert and retry."); } else { - this.context.error("It seems you are offline - please ensure Internet connectivity and retry or activate offline mode (-o or --offline)."); + LOG.error("It seems you are offline - please ensure Internet connectivity and retry or activate offline mode (-o or --offline)."); } this.context.askToContinue("Typically you should abort and fix the problem. Do you want to continue anyways?"); } @@ -162,13 +168,13 @@ public void clone(GitUrl gitUrl, Path repository) { public void pull(Path repository) { if (this.context.isOffline()) { - this.context.info("Skipping git pull on {} because offline", repository); + LOG.info("Skipping git pull on {} because offline", repository); return; } ProcessResult result = runGitCommand(repository, ProcessMode.DEFAULT, "--no-pager", "pull", "--quiet"); if (!result.isSuccessful()) { String branchName = determineCurrentBranch(repository); - this.context.warning("Git pull on branch {} failed for repository {}.", branchName, repository); + LOG.warn("Git pull on branch {} failed for repository {}.", branchName, repository); handleErrors(repository, result); } } @@ -186,7 +192,7 @@ public void fetch(Path repository, String remote, String branch) { ProcessResult result = runGitCommand(repository, ProcessMode.DEFAULT_CAPTURE, "fetch", Objects.requireNonNullElse(remote, "origin"), branch); if (!result.isSuccessful()) { - this.context.warning("Git fetch for '{}/{} failed.'.", remote, branch); + LOG.warn("Git fetch for '{}/{} failed.'.", remote, branch); } } @@ -214,10 +220,10 @@ public void reset(Path repository, String branchName, String remoteName) { ProcessResult result = runGitCommand(repository, ProcessMode.DEFAULT, "diff-index", "--quiet", "HEAD"); if (!result.isSuccessful()) { // reset to origin/master - this.context.warning("Git has detected modified files -- attempting to reset {} to '{}/{}'.", repository, remoteName, branchName); + LOG.warn("Git has detected modified files -- attempting to reset {} to '{}/{}'.", repository, remoteName, branchName); result = runGitCommand(repository, ProcessMode.DEFAULT, "reset", "--hard", remoteName + "/" + branchName); if (!result.isSuccessful()) { - this.context.warning("Git failed to reset {} to '{}/{}'.", remoteName, branchName, repository); + LOG.warn("Git failed to reset {} to '{}/{}'.", remoteName, branchName, repository); handleErrors(repository, result); } } @@ -230,7 +236,7 @@ public void cleanup(Path repository) { ProcessResult result = runGitCommand(repository, ProcessMode.DEFAULT_CAPTURE, "ls-files", "--other", "--directory", "--exclude-standard"); if (!result.getOut().isEmpty()) { // delete untracked files - this.context.warning("Git detected untracked files in {} and is attempting a cleanup.", repository); + LOG.warn("Git detected untracked files in {} and is attempting a cleanup.", repository); runGitCommand(repository, "clean", "-df"); } } @@ -277,7 +283,7 @@ public Path findGit() { if (gitPath != null) { this.git = gitPath; - this.context.trace("Found git at: {}", gitPath); + LOG.trace("Found git at: {}", gitPath); } return gitPath; @@ -286,27 +292,27 @@ public Path findGit() { private Path findGitOnWindowsViaBash() { Path gitPath; Path bashBinary = this.context.findBashRequired(); - this.context.trace("Trying to find git path on Windows"); + LOG.trace("Trying to find git path on Windows"); if (Files.exists(bashBinary)) { gitPath = bashBinary.getParent().resolve("git.exe"); if (Files.exists(gitPath)) { - this.context.trace("Git path was extracted from bash path at: {}", gitPath); + LOG.trace("Git path was extracted from bash path at: {}", gitPath); } else { - this.context.error("Git path: {} was extracted from bash path at: {} but it does not exist", gitPath, bashBinary); + LOG.error("Git path: {} was extracted from bash path at: {} but it does not exist", gitPath, bashBinary); return null; } } else { - this.context.error("Bash path was checked at: {} but it does not exist", bashBinary); + LOG.error("Bash path was checked at: {} but it does not exist", bashBinary); return null; } return gitPath; } private Path findGitInPath(Path gitPath) { - this.context.trace("Trying to find git executable within the PATH environment variable"); + LOG.trace("Trying to find git executable within the PATH environment variable"); Path binaryGitPath = this.context.getPath().findBinary(gitPath); if (gitPath == binaryGitPath) { - this.context.debug("No git executable could be found within the PATH environment variable"); + LOG.debug("No git executable could be found within the PATH environment variable"); return null; } return binaryGitPath; @@ -334,7 +340,7 @@ private String runGitCommandAndGetSingleOutput(String warningOnError, Path direc private String runGitCommandAndGetSingleOutput(String warningOnError, Path directory, ProcessMode mode, String... args) { ProcessErrorHandling errorHandling = ProcessErrorHandling.NONE; - if (this.context.debug().isEnabled()) { + if (LOG.isDebugEnabled()) { errorHandling = ProcessErrorHandling.LOG_WARNING; } ProcessResult result = runGitCommand(directory, mode, errorHandling, args); @@ -342,14 +348,14 @@ private String runGitCommandAndGetSingleOutput(String warningOnError, Path direc List out = result.getOut(); int size = out.size(); if (size == 1) { - return out.get(0); + return out.getFirst(); } else if (size == 0) { warningOnError += " - No output received from " + result.getCommand(); } else { warningOnError += " - Expected single line of output but received " + size + " lines from " + result.getCommand(); } } - this.context.warning(warningOnError); + LOG.warn(warningOnError); return null; } @@ -378,10 +384,10 @@ private ProcessResult runGitCommand(Path directory, ProcessMode mode, ProcessErr public void saveCurrentCommitId(Path repository, Path trackedCommitIdPath) { if ((repository == null) || (trackedCommitIdPath == null)) { - this.context.warning("Invalid usage of saveCurrentCommitId with null value"); + LOG.warn("Invalid usage of saveCurrentCommitId with null value"); return; } - this.context.trace("Saving commit Id of {} into {}", repository, trackedCommitIdPath); + LOG.trace("Saving commit Id of {} into {}", repository, trackedCommitIdPath); String currentCommitId = determineCurrentCommitId(repository); if (currentCommitId != null) { try { diff --git a/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryCommandlet.java index fedd2a2a7c..54c5e72dbf 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryCommandlet.java @@ -5,6 +5,9 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.commandlet.Commandlet; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.git.GitContext; @@ -20,6 +23,8 @@ */ public class RepositoryCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(RepositoryCommandlet.class); + /** the repository to setup. */ public final RepositoryProperty repository; @@ -54,7 +59,7 @@ protected void doRun() { // If no specific repository is provided, check for repositories folder Path repositoriesPath = this.context.getRepositoriesPath(); if (repositoriesPath == null) { - this.context.warning("Cannot find folder 'repositories' nor 'projects' in your settings."); + LOG.warn("Cannot find folder 'repositories' nor 'projects' in your settings."); return; } List propertiesFiles = this.context.getFileAccess() @@ -84,9 +89,9 @@ private void doImportRepository(Path repositoryFile, boolean forceMode, String r RepositoryConfig repositoryConfig = RepositoryConfig.loadProperties(repositoryFile, this.context); if (!repositoryConfig.active()) { if (forceMode) { - this.context.info("Setup of repository {} is forced, hence proceeding ...", repositoryId); + LOG.info("Setup of repository {} is forced, hence proceeding ...", repositoryId); } else { - this.context.info("Skipping repository {} because it is not active - use --force to setup all repositories ...", repositoryId); + LOG.info("Skipping repository {} because it is not active - use --force to setup all repositories ...", repositoryId); return; } } @@ -95,7 +100,7 @@ private void doImportRepository(Path repositoryFile, boolean forceMode, String r // error was already logged. return; } - this.context.debug("Repository configuration: {}", repositoryConfig); + LOG.debug("Repository configuration: {}", repositoryConfig); List workspaces = repositoryConfig.workspaces(); String repositoryRelativePath = repositoryConfig.path(); if (repositoryRelativePath == null) { @@ -113,16 +118,16 @@ private void doImportRepository(Path repositoryFile, boolean forceMode, String r if (firstRepository == null) { firstRepository = repositoryPath; } - this.context.info("Repository {} already exists in workspace {} at {}", repositoryId, workspaceName, repositoryPath); + LOG.info("Repository {} already exists in workspace {} at {}", repositoryId, workspaceName, repositoryPath); if (!(this.context.isForceMode() || this.context.isForceRepositories())) { - this.context.info("Ignoring repository {} in workspace {} - use --force or --force-repositories to rerun setup.", repositoryId, workspaceName); + LOG.info("Ignoring repository {} in workspace {} - use --force or --force-repositories to rerun setup.", repositoryId, workspaceName); continue; } } Path repositoryCreatedStatusFile = ideStatusDir.resolve("repository." + repositoryId + "." + workspaceName); if (Files.exists(repositoryCreatedStatusFile)) { if (!(this.context.isForceMode() || this.context.isForceRepositories())) { - this.context.info("Ignoring repository {} in workspace {} because it was already setup before - use --force or --force-repositories for recreation.", + LOG.info("Ignoring repository {} in workspace {} because it was already setup before - use --force or --force-repositories for recreation.", repositoryId, workspaceName); continue; } @@ -159,7 +164,8 @@ private boolean buildRepository(RepositoryConfig repositoryConfig, Path reposito ToolCommandlet commandlet = this.context.getCommandletManager().getToolCommandlet(command[0]); if (commandlet == null) { String displayName = (command[0] == null || command[0].isBlank()) ? "" : "'" + command[0] + "'"; - this.context.error("Cannot build repository. Required tool '{}' not found. Please check your repository's build_cmd configuration value.", displayName); + LOG.error("Cannot build repository. Required tool '{}' not found. Please check your repository's build_cmd configuration value.", + displayName); return; } commandlet.reset(); @@ -175,7 +181,7 @@ private boolean buildRepository(RepositoryConfig repositoryConfig, Path reposito commandlet.run(); }); } else { - this.context.debug("Build command not set. Skipping build for repository."); + LOG.debug("Build command not set. Skipping build for repository."); return true; } } @@ -184,7 +190,7 @@ private void importRepository(RepositoryConfig repositoryConfig, Path repository Set imports = repositoryConfig.imports(); if ((imports == null) || imports.isEmpty()) { - this.context.debug("Repository {} has no IDE configured for import.", repositoryId); + LOG.debug("Repository {} has no IDE configured for import.", repositoryId); return; } for (String ide : imports) { @@ -193,7 +199,8 @@ private void importRepository(RepositoryConfig repositoryConfig, Path repository ToolCommandlet commandlet = this.context.getCommandletManager().getToolCommandlet(ide); if (commandlet == null) { String displayName = (ide == null || ide.isBlank()) ? "" : "'" + ide + "'"; - step.error("Cannot import repository '{}'. Required IDE '{}' not found. Please check your repository's imports configuration.", repositoryId, displayName); + step.error("Cannot import repository '{}'. Required IDE '{}' not found. Please check your repository's imports configuration.", repositoryId, + displayName); } else if (commandlet instanceof IdeToolCommandlet ideCommandlet) { ideCommandlet.importRepository(repositoryPath); } else { diff --git a/cli/src/main/java/com/devonfw/tools/ide/io/FileAccessImpl.java b/cli/src/main/java/com/devonfw/tools/ide/io/FileAccessImpl.java index 0f664365ef..ca756df280 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/io/FileAccessImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/io/FileAccessImpl.java @@ -50,6 +50,8 @@ import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.context.IdeContext; @@ -70,6 +72,8 @@ */ public class FileAccessImpl extends HttpDownloader implements FileAccess { + private static final Logger LOG = LoggerFactory.getLogger(FileAccessImpl.class); + private static final String WINDOWS_FILE_LOCK_DOCUMENTATION_PAGE = "https://github.com/devonfw/IDEasy/blob/main/documentation/windows-file-lock.adoc"; private static final String WINDOWS_FILE_LOCK_WARNING = @@ -136,9 +140,9 @@ private void downloadViaHttp(String url, Path target) { private void downloadWithHttpVersion(String url, Path target, Version httpVersion) throws Exception { if (httpVersion == null) { - this.context.info("Trying to download {} from {}", target.getFileName(), url); + LOG.info("Trying to download {} from {}", target.getFileName(), url); } else { - this.context.info("Trying to download {} from {} with HTTP protocol version {}", target.getFileName(), url, httpVersion); + LOG.info("Trying to download {} from {} with HTTP protocol version {}", target.getFileName(), url, httpVersion); } mkdirs(target.getParent()); this.context.getNetworkStatus().invokeNetworkTask(() -> @@ -159,7 +163,7 @@ private void downloadFileWithProgressBar(String url, Path target, HttpResponse postExtractHook, boolean extract) { if (Files.isDirectory(archiveFile)) { - this.context.warning("Found directory for download at {} hence copying without extraction!", archiveFile); + LOG.warn("Found directory for download at {} hence copying without extraction!", archiveFile); copy(archiveFile, targetDir, FileCopyMode.COPY_TREE_CONTENT); postExtractHook(postExtractHook, targetDir); return; @@ -595,7 +599,7 @@ public void extract(Path archiveFile, Path targetDir, Consumer postExtract return; } Path tmpDir = createTempDir("extract-" + archiveFile.getFileName()); - this.context.trace("Trying to extract the file {} to {} and move it to {}.", archiveFile, tmpDir, targetDir); + LOG.trace("Trying to extract the file {} to {} and move it to {}.", archiveFile, tmpDir, targetDir); String filename = archiveFile.getFileName().toString(); TarCompression tarCompression = TarCompression.of(filename); if (tarCompression != null) { @@ -605,7 +609,7 @@ public void extract(Path archiveFile, Path targetDir, Consumer postExtract if (extension == null) { throw new IllegalStateException("Unknown archive format without extension - can not extract " + archiveFile); } else { - this.context.trace("Determined file extension {}", extension); + LOG.trace("Determined file extension {}", extension); } switch (extension) { case "zip" -> extractZip(archiveFile, tmpDir); @@ -656,7 +660,7 @@ private Path getProperInstallationSubDirOf(Path path, Path archiveFile) { @Override public void extractZip(Path file, Path targetDir) { - this.context.info("Extracting ZIP file {} to {}", file, targetDir); + LOG.info("Extracting ZIP file {} to {}", file, targetDir); URI uri = URI.create("jar:" + file.toUri()); try (FileSystem fs = FileSystems.newFileSystem(uri, FS_ENV)) { long size = 0; @@ -686,7 +690,7 @@ private void onFileCopiedFromZip(Path source, Path target, boolean directory, Id Files.setPosixFilePermissions(target, (Set) permissionSet); } } catch (Exception e) { - this.context.error(e, "Failed to transfer zip permissions for {}", target); + LOG.error("Failed to transfer zip permissions for {}", target, e); } } progressBar.stepBy(getFileSize(target)); @@ -725,7 +729,7 @@ public static String generatePermissionString(int permissions) { private void extractArchive(Path file, Path targetDir, Function> unpacker) { - this.context.info("Extracting TAR file {} to {}", file, targetDir); + LOG.info("Extracting TAR file {} to {}", file, targetDir); final List links = new ArrayList<>(); try (InputStream is = Files.newInputStream(file); @@ -796,7 +800,7 @@ private Path resolveRelativePathSecure(Path entryPath, Path root, String entryNa @Override public void extractDmg(Path file, Path targetDir) { - this.context.info("Extracting DMG file {} to {}", file, targetDir); + LOG.info("Extracting DMG file {} to {}", file, targetDir); assert this.context.getSystemInfo().isMac(); Path mountPath = this.context.getIdeHome().resolve(IdeContext.FOLDER_UPDATES).resolve(IdeContext.FOLDER_VOLUME); @@ -818,7 +822,7 @@ public void extractDmg(Path file, Path targetDir) { @Override public void extractMsi(Path file, Path targetDir) { - this.context.info("Extracting MSI file {} to {}", file, targetDir); + LOG.info("Extracting MSI file {} to {}", file, targetDir); this.context.newProcess().executable("msiexec").addArgs("/a", file, "/qn", "TARGETDIR=" + targetDir).run(); // msiexec also creates a copy of the MSI Path msiCopy = targetDir.resolve(file.getFileName()); @@ -828,7 +832,7 @@ public void extractMsi(Path file, Path targetDir) { @Override public void extractPkg(Path file, Path targetDir) { - this.context.info("Extracting PKG file {} to {}", file, targetDir); + LOG.info("Extracting PKG file {} to {}", file, targetDir); Path tmpDirPkg = createTempDir("ide-pkg-"); ProcessContext pc = this.context.newProcess(); // we might also be able to use cpio from commons-compression instead of external xar... @@ -955,10 +959,10 @@ private void compressRecursive(Path path, ArchiveOutput public void delete(Path path) { if (!Files.exists(path, LinkOption.NOFOLLOW_LINKS)) { - this.context.trace("Deleting {} skipped as the path does not exist.", path); + LOG.trace("Deleting {} skipped as the path does not exist.", path); return; } - this.context.debug("Deleting {} ...", path); + LOG.debug("Deleting {} ...", path); try { if (Files.isSymbolicLink(path) || isJunction(path)) { Files.delete(path); @@ -981,10 +985,10 @@ private void deleteRecursive(Path path) throws IOException { } } } - this.context.trace("Deleting {} ...", path); + LOG.trace("Deleting {} ...", path); boolean isSetWritable = setWritable(path, true); if (!isSetWritable) { - this.context.debug("Couldn't give write access to file: " + path); + LOG.debug("Couldn't give write access to file: {}", path); } Files.delete(path); } @@ -1034,7 +1038,7 @@ private Path findFirstRecursive(Path dir, Predicate filter, boolean recurs public Path findAncestor(Path path, Path baseDir, int subfolderCount) { if ((path == null) || (baseDir == null)) { - this.context.debug("Path should not be null for findAncestor."); + LOG.debug("Path should not be null for findAncestor."); return null; } if (subfolderCount <= 0) { @@ -1080,13 +1084,13 @@ public List listChildrenMapped(Path dir, Function filter) { Path filteredChild = filter.apply(child); if (filteredChild != null) { if (filteredChild == child) { - this.context.trace("Accepted file {}", child); + LOG.trace("Accepted file {}", child); } else { - this.context.trace("Accepted file {} and mapped to {}", child, filteredChild); + LOG.trace("Accepted file {} and mapped to {}", child, filteredChild); } children.add(filteredChild); } else { - this.context.trace("Ignoring file {} according to filter", child); + LOG.trace("Ignoring file {} according to filter", child); } } } catch (IOException e) { @@ -1115,7 +1119,7 @@ private long getFileSize(Path file) { try { return Files.size(file); } catch (IOException e) { - this.context.warning(e.getMessage(), e); + LOG.warn("Failed to determine size of file {}: {}", file, e.toString(), e); return 0; } } @@ -1182,11 +1186,11 @@ public boolean setWritable(Path file, boolean writable) { return true; } - this.context.debug("Failed to set writing permission for file {}", file); + LOG.debug("Failed to set writing permission for file {}", file); return false; } catch (IOException e) { - this.context.debug("Error occurred when trying to set writing permission for file " + file + ": " + e); + LOG.debug("Error occurred when trying to set writing permission for file {}: {}", file, e.toString(), e); return false; } } @@ -1217,10 +1221,10 @@ public void makeExecutable(Path path, boolean confirm) { } setFilePermissions(path, executablePermissions, false); } else { - this.context.trace("Executable flags already present so no need to set them for file {}", path); + LOG.trace("Executable flags already present so no need to set them for file {}", path); } } else { - this.context.warning("Cannot set executable flag on file that does not exist: {}", path); + LOG.warn("Cannot set executable flag on file that does not exist: {}", path); } } @@ -1251,7 +1255,7 @@ public PathPermissions getFilePermissions(Path path) { } pathPermissions = PathPermissions.of(permissions); } - this.context.trace("Read {}permissions of {} as {}.", info, path, pathPermissions); + LOG.trace("Read {}permissions of {} as {}.", info, path, pathPermissions); return pathPermissions; } @@ -1262,14 +1266,15 @@ public void setFilePermissions(Path path, PathPermissions permissions, boolean l return; } try { - this.context.debug("Setting permissions for {} to {}", path, permissions); + LOG.debug("Setting permissions for {} to {}", path, permissions); // Set the new permissions Files.setPosixFilePermissions(path, permissions.toPosix()); } catch (IOException e) { + String message = "Failed to set permissions to " + permissions + " for path " + path; if (logErrorAndContinue) { - this.context.warning().log(e, "Failed to set permissions to {} for path {}", permissions, path); + LOG.warn(message, e); } else { - throw new RuntimeException("Failed to set permissions to " + permissions + " for path " + path, e); + throw new RuntimeException(message, e); } } } @@ -1277,7 +1282,7 @@ public void setFilePermissions(Path path, PathPermissions permissions, boolean l private boolean skipPermissionsIfWindows(Path path) { if (SystemInfoImpl.INSTANCE.isWindows()) { - this.context.trace("Windows does not have file permissions hence omitting for {}", path); + LOG.trace("Windows does not have file permissions hence omitting for {}", path); return true; } return false; @@ -1304,14 +1309,14 @@ public void touch(Path file) { @Override public String readFileContent(Path file) { - this.context.trace("Reading content of file from {}", file); + LOG.trace("Reading content of file from {}", file); if (!Files.exists((file))) { - this.context.debug("File {} does not exist", file); + LOG.debug("File {} does not exist", file); return null; } try { String content = Files.readString(file); - this.context.trace("Completed reading {} character(s) from file {}", content.length(), file); + LOG.trace("Completed reading {} character(s) from file {}", content.length(), file); return content; } catch (IOException e) { throw new IllegalStateException("Failed to read file " + file, e); @@ -1327,13 +1332,13 @@ public void writeFileContent(String content, Path file, boolean createParentDir) if (content == null) { content = ""; } - this.context.trace("Writing content with {} character(s) to file {}", content.length(), file); + LOG.trace("Writing content with {} character(s) to file {}", content.length(), file); if (Files.exists(file)) { - this.context.info("Overriding content of file {}", file); + LOG.info("Overriding content of file {}", file); } try { Files.writeString(file, content); - this.context.trace("Wrote content to file {}", file); + LOG.trace("Wrote content to file {}", file); } catch (IOException e) { throw new RuntimeException("Failed to write file " + file, e); } @@ -1342,14 +1347,14 @@ public void writeFileContent(String content, Path file, boolean createParentDir) @Override public List readFileLines(Path file) { - this.context.trace("Reading content of file from {}", file); + LOG.trace("Reading lines of file from {}", file); if (!Files.exists(file)) { - this.context.warning("File {} does not exist", file); + LOG.warn("File {} does not exist", file); return null; } try { List content = Files.readAllLines(file); - this.context.trace("Completed reading {} lines from file {}", content.size(), file); + LOG.trace("Completed reading {} lines from file {}", content.size(), file); return content; } catch (IOException e) { throw new IllegalStateException("Failed to read file " + file, e); @@ -1365,13 +1370,13 @@ public void writeFileLines(List content, Path file, boolean createParent if (content == null) { content = List.of(); } - this.context.trace("Writing content with {} lines to file {}", content.size(), file); + LOG.trace("Writing content with {} lines to file {}", content.size(), file); if (Files.exists(file)) { - this.context.debug("Overriding content of file {}", file); + LOG.debug("Overriding content of file {}", file); } try { Files.write(file, content); - this.context.trace("Wrote content to file {}", file); + LOG.trace("Wrote lines to file {}", file); } catch (IOException e) { throw new RuntimeException("Failed to write file " + file, e); } @@ -1382,7 +1387,7 @@ public void readProperties(Path file, Properties properties) { try (Reader reader = Files.newBufferedReader(file)) { properties.load(reader); - this.context.debug("Successfully loaded {} properties from {}", properties.size(), file); + LOG.debug("Successfully loaded {} properties from {}", properties.size(), file); } catch (IOException e) { throw new IllegalStateException("Failed to read properties file: " + file, e); } @@ -1396,7 +1401,7 @@ public void writeProperties(Properties properties, Path file, boolean createPare } try (Writer writer = Files.newBufferedWriter(file)) { properties.store(writer, null); // do not get confused - Java still writes a date/time header that cannot be omitted - this.context.debug("Successfully saved {} properties to {}", properties.size(), file); + LOG.debug("Successfully saved {} properties to {}", properties.size(), file); } catch (IOException e) { throw new IllegalStateException("Failed to save properties file during tests.", e); } @@ -1406,7 +1411,7 @@ public void writeProperties(Properties properties, Path file, boolean createPare public void readIniFile(Path file, IniFile iniFile) { if (!Files.exists(file)) { - this.context.debug("INI file {} does not exist.", iniFile); + LOG.debug("INI file {} does not exist.", iniFile); return; } List iniLines = readFileLines(file); @@ -1441,10 +1446,10 @@ public Duration getFileAge(Path path) { long fileModifiedTime = Files.getLastModifiedTime(path).toMillis(); return Duration.ofMillis(currentTime - fileModifiedTime); } catch (IOException e) { - this.context.warning().log(e, "Could not get modification-time of {}.", path); + LOG.warn("Could not get modification-time of {}.", path, e); } } else { - this.context.debug("Path {} is missing - skipping modification-time and file age check.", path); + LOG.debug("Path {} is missing - skipping modification-time and file age check.", path); } return null; } @@ -1456,7 +1461,7 @@ public boolean isFileAgeRecent(Path path, Duration cacheDuration) { if (age == null) { return false; } - this.context.debug("The path {} was last updated {} ago and caching duration is {}.", path, age, cacheDuration); + LOG.debug("The path {} was last updated {} ago and caching duration is {}.", path, age, cacheDuration); return (age.toMillis() <= cacheDuration.toMillis()); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/IdeasyCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/IdeasyCommandlet.java index f7d45adcc3..6b56e658a3 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/IdeasyCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/IdeasyCommandlet.java @@ -9,6 +9,9 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.commandlet.UpgradeMode; import com.devonfw.tools.ide.common.SimpleSystemPath; @@ -17,6 +20,7 @@ import com.devonfw.tools.ide.io.FileAccess; import com.devonfw.tools.ide.io.ini.IniFile; import com.devonfw.tools.ide.io.ini.IniSection; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.os.WindowsHelper; import com.devonfw.tools.ide.os.WindowsPathSyntax; import com.devonfw.tools.ide.process.ProcessMode; @@ -37,6 +41,8 @@ */ public class IdeasyCommandlet extends MvnBasedLocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(IdeasyCommandlet.class); + /** The {@link MvnArtifact} for IDEasy. */ public static final MvnArtifact ARTIFACT = MvnArtifact.ofIdeasyCli("*!", "tar.gz", "${os}-${arch}"); @@ -121,7 +127,7 @@ protected ToolInstallation doInstall(ToolInstallRequest request) { if (IdeVersion.isUndefined() && !this.context.isForceMode()) { VersionIdentifier version = IdeVersion.getVersionIdentifier(); - this.context.warning("You are using IDEasy version {} which indicates local development - skipping upgrade.", version); + LOG.warn("You are using IDEasy version {} which indicates local development - skipping upgrade.", version); return toolAlreadyInstalled(request); } return super.doInstall(request); @@ -149,21 +155,22 @@ public VersionIdentifier getLatestVersion() { */ public boolean checkIfUpdateIsAvailable() { VersionIdentifier installedVersion = getInstalledVersion(); - this.context.success("Your version of IDEasy is {}.", installedVersion); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Your version of IDEasy is {}.", installedVersion); if (IdeVersion.isSnapshot()) { - this.context.warning("You are using a SNAPSHOT version of IDEasy. For stability consider switching to a stable release via 'ide upgrade --mode=stable'"); + LOG.warn("You are using a SNAPSHOT version of IDEasy. For stability consider switching to a stable release via 'ide upgrade --mode=stable'"); } if (this.context.isOffline()) { - this.context.warning("Skipping check for newer version of IDEasy because you are offline."); + LOG.warn("Skipping check for newer version of IDEasy because you are offline."); return false; } VersionIdentifier latestVersion = getLatestVersion(); if (installedVersion.equals(latestVersion)) { - this.context.success("Your are using the latest version of IDEasy and no update is available."); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Your are using the latest version of IDEasy and no update is available."); return false; } else { - this.context.interaction("Your version of IDEasy is {} but version {} is available. Please run the following command to upgrade to the latest version:\n" - + "ide upgrade", installedVersion, latestVersion); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), + "Your version of IDEasy is {} but version {} is available. Please run the following command to upgrade to the latest version:\n" + + "ide upgrade", installedVersion, latestVersion); return true; } } @@ -183,7 +190,7 @@ public void installIdeasy(Path cwd) { Path ideasyVersionPath = ideasySoftwarePath.resolve(IdeVersion.getVersionString()); FileAccess fileAccess = this.context.getFileAccess(); if (Files.isDirectory(ideasyVersionPath)) { - this.context.error("IDEasy is already installed at {} - if your installation is broken, delete it manually and rerun setup!", ideasyVersionPath); + LOG.error("IDEasy is already installed at {} - if your installation is broken, delete it manually and rerun setup!", ideasyVersionPath); } else { List installationArtifacts = new ArrayList<>(); boolean success = true; @@ -207,8 +214,8 @@ public void installIdeasy(Path cwd) { addToShellRc(BASHRC, ideRoot, null); addToShellRc(ZSHRC, ideRoot, "autoload -U +X bashcompinit && bashcompinit"); installIdeasyWindowsEnv(ideRoot, installationPath); - this.context.success("IDEasy has been installed successfully on your system."); - this.context.warning("IDEasy has been setup for new shells but it cannot work in your current shell(s).\n" + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "IDEasy has been installed successfully on your system."); + LOG.warn("IDEasy has been setup for new shells but it cannot work in your current shell(s).\n" + "Reboot or open a new terminal to make it work."); } @@ -220,13 +227,13 @@ private void installIdeasyWindowsEnv(Path ideRoot, Path installationPath) { helper.setUserEnvironmentValue(IdeVariables.IDE_ROOT.getName(), ideRoot.toString()); String userPath = helper.getUserEnvironmentValue(IdeVariables.PATH.getName()); if (userPath == null) { - this.context.error("Could not read user PATH from registry!"); + LOG.error("Could not read user PATH from registry!"); } else { - this.context.info("Found user PATH={}", userPath); + LOG.info("Found user PATH={}", userPath); Path ideasyBinPath = installationPath.resolve("bin"); SimpleSystemPath path = SimpleSystemPath.of(userPath, ';'); if (path.getEntries().isEmpty()) { - this.context.warning("ATTENTION:\n" + LOG.warn("ATTENTION:\n" + "Your user specific PATH variable seems to be empty.\n" + "You can double check this by pressing [Windows][r] and launch the program SystemPropertiesAdvanced.\n" + "Then click on 'Environment variables' and check if 'PATH' is set in the 'user variables' from the upper list.\n" @@ -264,7 +271,7 @@ public void setupWindowsTerminal() { try { installWindowsTerminal(); } catch (Exception e) { - this.context.error(e, "Failed to install Windows Terminal!"); + LOG.error("Failed to install Windows Terminal!", e); } } configureWindowsTerminalGitBash(); @@ -283,7 +290,7 @@ private boolean isWindowsTerminalInstalled() { .run(ProcessMode.DEFAULT_CAPTURE); return result.isSuccessful() && !result.getOut().isEmpty(); } catch (Exception e) { - this.context.debug("Failed to check Windows Terminal installation: {}", e.getMessage()); + LOG.debug("Failed to check Windows Terminal installation.", e); return false; } } @@ -293,18 +300,18 @@ private boolean isWindowsTerminalInstalled() { */ private void installWindowsTerminal() { try { - this.context.info("Installing Windows Terminal..."); + LOG.info("Installing Windows Terminal..."); ProcessResult result = this.context.newProcess() .executable("winget") .addArgs("install", "Microsoft.WindowsTerminal") .run(ProcessMode.DEFAULT); if (result.isSuccessful()) { - this.context.success("Windows Terminal has been installed successfully."); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Windows Terminal has been installed successfully."); } else { - this.context.warning("Failed to install Windows Terminal. Please install it manually from Microsoft Store."); + LOG.warn("Failed to install Windows Terminal. Please install it manually from Microsoft Store."); } } catch (Exception e) { - this.context.warning("Failed to install Windows Terminal: {}. Please install it manually from Microsoft Store.", e.getMessage()); + LOG.warn("Failed to install Windows Terminal: {}. Please install it manually from Microsoft Store.", e.toString()); } } @@ -314,21 +321,21 @@ private void installWindowsTerminal() { protected void configureWindowsTerminalGitBash() { Path settingsPath = getWindowsTerminalSettingsPath(); if (settingsPath == null || !Files.exists(settingsPath)) { - this.context.warning("Windows Terminal settings file not found. Cannot configure Git Bash integration."); + LOG.warn("Windows Terminal settings file not found. Cannot configure Git Bash integration."); return; } try { Path bashPath = this.context.findBash(); if (bashPath == null) { - this.context.warning("Git Bash not found. Cannot configure Windows Terminal integration."); + LOG.warn("Git Bash not found. Cannot configure Windows Terminal integration."); return; } configureGitBashProfile(settingsPath, bashPath.toString()); - this.context.success("Git Bash has been configured in Windows Terminal."); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Git Bash has been configured in Windows Terminal."); } catch (Exception e) { - this.context.warning("Failed to configure Git Bash in Windows Terminal: {}", e.getMessage()); + LOG.warn("Failed to configure Git Bash in Windows Terminal: {}", e.getMessage()); } } @@ -398,7 +405,7 @@ private void configureGitBashProfile(Path settingsPath, String bashPath) throws // Add Git Bash profile if it doesn't exist if (gitBashProfileExists) { - this.context.info("Git Bash profile already exists in {}.", settingsPath); + LOG.info("Git Bash profile already exists in {}.", settingsPath); } else { ObjectNode gitBashProfile = mapper.createObjectNode(); String newGuid = "{2ece5bfe-50ed-5f3a-ab87-5cd4baafed2b}"; @@ -431,10 +438,10 @@ private String getGitBashIconPath(String bashPathString) { if (parent != null) { Path iconPath = parent.resolve("mingw64/share/git/git-for-windows.ico"); if (Files.exists(iconPath)) { - this.context.debug("Found git-bash icon at {}", iconPath); + LOG.debug("Found git-bash icon at {}", iconPath); return iconPath.toString(); } - this.context.debug("Git Bash icon not found at {}. Using default icon.", iconPath); + LOG.debug("Git Bash icon not found at {}. Using default icon.", iconPath); } return "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png"; } @@ -495,9 +502,9 @@ private void removeFromShellRc(String filename, Path ideRoot) { private void modifyShellRc(String filename, Path ideRoot, boolean add, String extraLine) { if (add) { - this.context.info("Configuring IDEasy in {}", filename); + LOG.info("Configuring IDEasy in {}", filename); } else { - this.context.info("Removing IDEasy from {}", filename); + LOG.info("Removing IDEasy from {}", filename); } Path rcFile = this.context.getUserHome().resolve(filename); FileAccess fileAccess = this.context.getFileAccess(); @@ -517,7 +524,7 @@ private void modifyShellRc(String filename, Path ideRoot, boolean add, String ex String line = iterator.next(); line = line.trim(); if (isObsoleteRcLine(line)) { - this.context.info("Removing obsolete line from {}: {}", filename, line); + LOG.info("Removing obsolete line from {}: {}", filename, line); iterator.remove(); removeCount++; } else if (line.equals(extraLine)) { @@ -534,7 +541,7 @@ private void modifyShellRc(String filename, Path ideRoot, boolean add, String ex lines.add(BASH_CODE_SOURCE_FUNCTIONS); } fileAccess.writeFileLines(lines, rcFile); - this.context.debug("Successfully updated {}", filename); + LOG.debug("Successfully updated {}", filename); } private static boolean isObsoleteRcLine(String line) { @@ -558,7 +565,7 @@ private boolean addInstallationArtifact(Path cwd, String artifactName, boolean r if (Files.exists(artifactPath)) { installationArtifacts.add(artifactPath); } else if (required) { - this.context.error("Missing required file {}", artifactName); + LOG.error("Missing required file {}", artifactName); return false; } return true; @@ -593,8 +600,8 @@ public void uninstallIdeasy() { uninstallIdeasyWindowsEnv(ideRoot); uninstallIdeasyIdePath(idePath); deleteDownloadCache(); - this.context.success("IDEasy has been uninstalled from your system."); - this.context.interaction("ATTENTION:\n" + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "IDEasy has been uninstalled from your system."); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "ATTENTION:\n" + "In order to prevent data-loss, we do not delete your projects and git repositories!\n" + "To entirely get rid of IDEasy, also check your IDE_ROOT folder at:\n" + "{}", ideRoot); @@ -602,7 +609,7 @@ public void uninstallIdeasy() { private void deleteDownloadCache() { Path downloadPath = this.context.getDownloadPath(); - this.context.info("Deleting download cache from {}", downloadPath); + LOG.info("Deleting download cache from {}", downloadPath); this.context.getFileAccess().delete(downloadPath); } @@ -610,10 +617,11 @@ private void uninstallIdeasyIdePath(Path idePath) { if (this.context.getSystemInfo().isWindows()) { this.context.newProcess().executable("bash").addArgs("-c", "sleep 10 && rm -rf \"" + WindowsPathSyntax.MSYS.format(idePath) + "\"").run(ProcessMode.BACKGROUND); - this.context.interaction("To prevent windows file locking errors, we perform an asynchronous deletion of {} in background now.\n" - + "Please close all terminals and wait a minute for the deletion to complete before running other commands.", idePath); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), + "To prevent windows file locking errors, we perform an asynchronous deletion of {} in background now.\n" + + "Please close all terminals and wait a minute for the deletion to complete before running other commands.", idePath); } else { - this.context.info("Finally deleting {}", idePath); + LOG.info("Finally deleting {}", idePath); this.context.getFileAccess().delete(idePath); } } @@ -626,9 +634,9 @@ private void uninstallIdeasyWindowsEnv(Path ideRoot) { helper.removeUserEnvironmentValue(IdeVariables.IDE_ROOT.getName()); String userPath = helper.getUserEnvironmentValue(IdeVariables.PATH.getName()); if (userPath == null) { - this.context.error("Could not read user PATH from registry!"); + LOG.error("Could not read user PATH from registry!"); } else { - this.context.info("Found user PATH={}", userPath); + LOG.info("Found user PATH={}", userPath); String newUserPath = userPath; if (!userPath.isEmpty()) { SimpleSystemPath path = SimpleSystemPath.of(userPath, ';'); @@ -636,7 +644,7 @@ private void uninstallIdeasyWindowsEnv(Path ideRoot) { newUserPath = path.toString(); } if (newUserPath.equals(userPath)) { - this.context.error("Could not find IDEasy in PATH:\n{}", userPath); + LOG.error("Could not find IDEasy in PATH:\n{}", userPath); } else { helper.setUserEnvironmentValue(IdeVariables.PATH.getName(), newUserPath); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/LocalToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/LocalToolCommandlet.java index ea0c55c9fa..1d16ea7cd3 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/LocalToolCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/LocalToolCommandlet.java @@ -6,10 +6,14 @@ import java.util.Collection; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliOfflineException; import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.FileAccess; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.process.ProcessContext; import com.devonfw.tools.ide.step.Step; import com.devonfw.tools.ide.tool.repository.ToolRepository; @@ -23,6 +27,8 @@ */ public abstract class LocalToolCommandlet extends ToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(LocalToolCommandlet.class); + /** * The constructor. * @@ -102,7 +108,7 @@ private ToolInstallation doInstallStep(ToolInstallRequest request) { if (request.isAlreadyInstalled()) { return installation; } else { - this.context.debug("Installation from {} to {}.", request.getInstalled(), request.getRequested()); + LOG.debug("Installation from {} to {}.", request.getInstalled(), request.getRequested()); } FileAccess fileAccess = this.context.getFileAccess(); boolean ignoreSoftwareRepo = isIgnoreSoftwareRepo(); @@ -172,7 +178,7 @@ public ToolInstallation installTool(ToolInstallRequest request) { return toolAlreadyInstalled(request); } else { ToolEditionAndVersion installed = request.getInstalled(); - this.context.debug("Installation from {} to {}.", installed, requested); + LOG.debug("Installation from {} to {}.", installed, requested); } Path installationPath = getInstallationPath(edition, resolvedVersion); @@ -186,16 +192,16 @@ public ToolInstallation installTool(ToolInstallRequest request) { if (!ignoreSoftwareRepo) { assert resolvedVersion.equals(getInstalledVersion(installationPath)) : "Found version " + getInstalledVersion(installationPath) + " in " + toolVersionFile + " but expected " + resolvedVersion; - this.context.debug("Version {} of tool {} is already installed at {}", resolvedVersion, toolEdition, installationPath); + LOG.debug("Version {} of tool {} is already installed at {}", resolvedVersion, toolEdition, installationPath); return createToolInstallation(installationPath, resolvedVersion, false, processContext, additionalInstallation); } } else { // Makes sure that IDEasy will not delete itself if (this.tool.equals(IdeasyCommandlet.TOOL_NAME)) { - this.context.warning("Your IDEasy installation is missing the version file at {}", toolVersionFile); + LOG.warn("Your IDEasy installation is missing the version file at {}", toolVersionFile); return createToolInstallation(installationPath, resolvedVersion, false, processContext, additionalInstallation); } else if (!isIgnoreMissingSoftwareVersionFile()) { - this.context.warning("Deleting corrupted installation at {}", installationPath); + LOG.warn("Deleting corrupted installation at {}", installationPath); fileAccess.delete(installationPath); } } @@ -207,7 +213,8 @@ public ToolInstallation installTool(ToolInstallRequest request) { // If we are offline and cannot download, check if we can continue with an existing installation ToolEditionAndVersion installed = request.getInstalled(); if ((installed != null) && (installed.getResolvedVersion() != null)) { - this.context.warning("Cannot download {} in version {} because we are offline. Continuing with already installed version {}.", this.tool, resolvedVersion, installed.getResolvedVersion()); + LOG.warn("Cannot download {} in version {} because we are offline. Continuing with already installed version {}.", this.tool, + resolvedVersion, installed.getResolvedVersion()); // If offline and could not download, actualInstalledVersion will be the old version, not resolvedVersion // In that case, we need to recalculate the installation path for the actually installed version actualInstalledVersion = installed.getResolvedVersion(); @@ -238,11 +245,11 @@ protected void performToolInstallation(ToolInstallRequest request, Path installa Path downloadedToolFile = downloadTool(requested.getEdition().edition(), resolvedVersion); boolean extract = isExtract(); if (!extract) { - this.context.trace("Extraction is disabled for '{}' hence just moving the downloaded file {}.", this.tool, downloadedToolFile); + LOG.trace("Extraction is disabled for '{}' hence just moving the downloaded file {}.", this.tool, downloadedToolFile); } if (Files.isDirectory(installationPath)) { if (this.tool.equals(IdeasyCommandlet.TOOL_NAME)) { - this.context.warning("Your IDEasy installation is missing the version file."); + LOG.warn("Your IDEasy installation is missing the version file."); } else { fileAccess.backup(installationPath); } @@ -250,7 +257,7 @@ protected void performToolInstallation(ToolInstallRequest request, Path installa fileAccess.mkdirs(installationPath.getParent()); fileAccess.extract(downloadedToolFile, installationPath, this::postExtract, extract); this.context.writeVersionFile(resolvedVersion, installationPath); - this.context.debug("Installed {} in version {} at {}", this.tool, resolvedVersion, installationPath); + LOG.debug("Installed {} in version {} at {}", this.tool, resolvedVersion, installationPath); } /** @@ -287,7 +294,7 @@ public ToolInstallation installAsDependency(VersionRange versionRange, ToolInsta + configuredVersion + " and this tool does not support the software repository."); } - this.context.info( + LOG.info( "The tool {} requires {} in the version range {}, but your project uses version {}, which does not match." + " Therefore, we install a compatible version in that range.", parentRequest.getRequested().getEdition(), this.tool, versionRange, configuredVersion); @@ -308,9 +315,9 @@ protected void installToolDependencies(ToolInstallRequest request) { ToolEdition toolEdition = requested.getEdition(); Collection dependencies = getToolRepository().findDependencies(this.tool, toolEdition.edition(), version); int size = dependencies.size(); - this.context.debug("Tool {} has {} other tool(s) as dependency", toolEdition, size); + LOG.debug("Tool {} has {} other tool(s) as dependency", toolEdition, size); for (ToolDependency dependency : dependencies) { - this.context.trace("Ensuring dependency {} for tool {}", dependency.tool(), toolEdition); + LOG.trace("Ensuring dependency {} for tool {}", dependency.tool(), toolEdition); LocalToolCommandlet dependencyTool = this.context.getCommandletManager().getRequiredLocalToolCommandlet(dependency.tool()); dependencyTool.installAsDependency(dependency.versionRange(), request); } @@ -346,7 +353,7 @@ protected VersionIdentifier getInstalledVersion(Path toolPath) { if (Files.exists(legacyToolVersionFile)) { toolVersionFile = legacyToolVersionFile; } else { - this.context.warning("Tool {} is missing version file in {}", getName(), toolVersionFile); + LOG.warn("Tool {} is missing version file in {}", getName(), toolVersionFile); return null; } } @@ -373,7 +380,7 @@ protected String getInstalledEdition(Path toolPath) { // if the realPath changed, a link has been resolved if (realPath.equals(toolPath)) { if (!isIgnoreSoftwareRepo()) { - this.context.warning("Tool {} is not installed via software repository (maybe from devonfw-ide). Please consider reinstalling it.", this.tool); + LOG.warn("Tool {} is not installed via software repository (maybe from devonfw-ide). Please consider reinstalling it.", this.tool); } // I do not see any reliable way how we could determine the edition of a tool that does not use software repo or that was installed by devonfw-ide return getConfiguredEdition(); @@ -384,7 +391,7 @@ protected String getInstalledEdition(Path toolPath) { edition = this.tool; } if (!getToolRepository().getSortedEditions(this.tool).contains(edition)) { - this.context.warning("Undefined edition {} of tool {}", edition, this.tool); + LOG.warn("Undefined edition {} of tool {}", edition, this.tool); } return edition; } @@ -413,7 +420,7 @@ private Path getInstalledSoftwareRepoPath(Path toolPath) { // if the installPath changed, a link has been resolved if (installPath.equals(toolPath)) { if (!isIgnoreSoftwareRepo()) { - this.context.warning("Tool {} is not installed via software repository (maybe from devonfw-ide). Please consider reinstalling it.", this.tool); + LOG.warn("Tool {} is not installed via software repository (maybe from devonfw-ide). Please consider reinstalling it.", this.tool); } // I do not see any reliable way how we could determine the edition of a tool that does not use software repo or that was installed by devonfw-ide return null; @@ -429,13 +436,13 @@ Path getValidInstalledSoftwareRepoPath(Path installPath, Path softwareRepoPath) // installPath can't be shorter than softwareRepoPath if (toolInstallNameCount < softwareRepoNameCount) { - this.context.warning("The installation path is not located within the software repository {}.", installPath); + LOG.warn("The installation path is not located within the software repository {}.", installPath); return null; } // ensure installPath starts with $IDE_ROOT/_ide/software/ for (int i = 0; i < softwareRepoNameCount; i++) { if (!softwareRepoPath.getName(i).toString().equals(installPath.getName(i).toString())) { - this.context.warning("The installation path is not located within the software repository {}.", installPath); + LOG.warn("The installation path is not located within the software repository {}.", installPath); return null; } } @@ -449,7 +456,7 @@ Path getValidInstalledSoftwareRepoPath(Path installPath, Path softwareRepoPath) } return validInstallPath; } else { - this.context.warning("The installation path is faulty {}.", installPath); + LOG.warn("The installation path is faulty {}.", installPath); return null; } } @@ -457,7 +464,7 @@ Path getValidInstalledSoftwareRepoPath(Path installPath, Path softwareRepoPath) private boolean isToolNotInstalled(Path toolPath) { if ((toolPath == null) || !Files.isDirectory(toolPath)) { - this.context.debug("Tool {} not installed in {}", this.tool, toolPath); + LOG.debug("Tool {} not installed in {}", this.tool, toolPath); return true; } return false; @@ -468,11 +475,11 @@ public void uninstall() { try { Path toolPath = getToolPath(); if (!Files.exists(toolPath)) { - this.context.warning("An installed version of {} does not exist.", this.tool); + LOG.warn("An installed version of {} does not exist.", this.tool); return; } if (this.context.isForceMode() && !isIgnoreSoftwareRepo()) { - this.context.warning( + LOG.warn( "You triggered an uninstall of {} in version {} with force mode!\n" + "This will physically delete the currently installed version from the machine.\n" + "This may cause issues with other projects, that use the same version of that tool." @@ -480,9 +487,9 @@ public void uninstall() { uninstallFromSoftwareRepository(toolPath); } performUninstall(toolPath); - this.context.success("Successfully uninstalled {}", this.tool); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully uninstalled {}", this.tool); } catch (Exception e) { - this.context.error(e, "Failed to uninstall {}", this.tool); + LOG.error("Failed to uninstall {}", this.tool, e); } } @@ -501,12 +508,12 @@ protected void performUninstall(Path toolPath) { private void uninstallFromSoftwareRepository(Path toolPath) { Path repoPath = getInstalledSoftwareRepoPath(toolPath); if ((repoPath == null) || !Files.exists(repoPath)) { - this.context.warning("An installed version of {} does not exist in software repository.", this.tool); + LOG.warn("An installed version of {} does not exist in software repository.", this.tool); return; } - this.context.info("Physically deleting {} as requested by the user via force mode.", repoPath); + LOG.info("Physically deleting {} as requested by the user via force mode.", repoPath); this.context.getFileAccess().delete(repoPath); - this.context.success("Successfully deleted {} from your computer.", repoPath); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully deleted {} from your computer.", repoPath); } @Override @@ -546,7 +553,7 @@ protected Path findWrapper(String wrapperFileName) { while ((dir != null) && (findBuildDescriptor(dir) != null)) { Path wrapper = dir.resolve(wrapperFileName); if (Files.exists(wrapper)) { - context.debug("Using wrapper: {}", wrapper); + LOG.debug("Using wrapper: {}", wrapper); return wrapper; } dir = dir.getParent(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/PackageManagerBasedLocalToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/PackageManagerBasedLocalToolCommandlet.java index 0e8c879786..10769d760e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/PackageManagerBasedLocalToolCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/PackageManagerBasedLocalToolCommandlet.java @@ -4,6 +4,9 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cache.CachedValue; import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; @@ -20,6 +23,8 @@ */ public abstract class PackageManagerBasedLocalToolCommandlet

extends LocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(PackageManagerBasedLocalToolCommandlet.class); + private final CachedValue installedVersion; /** @@ -156,7 +161,7 @@ private VersionIdentifier determineInstalledVersion() { try { return computeInstalledVersion(); } catch (Exception e) { - this.context.debug().log(e, "Failed to compute installed version of {}", this.tool); + LOG.debug("Failed to compute installed version of {}", this.tool, e); return null; } } @@ -198,7 +203,7 @@ protected final void performUninstall(Path toolPath) { runPackageManager(request).failOnError(); this.installedVersion.invalidate(); } else { - this.context.info("IDEasy does not support uninstalling the tool {} since this will break your installation.\n" + LOG.info("IDEasy does not support uninstalling the tool {} since this will break your installation.\n" + "If you really want to uninstall it, please uninstall its parent tool via:\n" + "ide uninstall {}", this.tool, getParentTool().getName()); } 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 index 13043a6261..8dc31d374d 100644 --- 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 @@ -4,6 +4,9 @@ import java.nio.file.Path; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.FileAccess; @@ -19,6 +22,8 @@ */ public class Aws extends LocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(Aws.class); + /** * The constructor. * @@ -69,7 +74,7 @@ protected void postExtract(Path extractedDir) { @Override public void printHelp(NlsBundle bundle) { - this.context.info("To get detailed help about the usage of the AWS CLI, use \"aws help\""); + LOG.info("To get detailed help about the usage of the AWS CLI, use \"aws help\""); } @Override diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java b/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java index 03d940c37f..3a9eb2ad4c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java @@ -10,6 +10,9 @@ import java.util.Set; import java.util.regex.Matcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.git.GitContext; @@ -29,14 +32,12 @@ */ public class Mvn extends LocalToolCommandlet { - /** - * The name of the mvn folder - */ + private static final Logger LOG = LoggerFactory.getLogger(Mvn.class); + + /** The name of the mvn folder. */ public static final String MVN_CONFIG_FOLDER = "mvn"; - /** - * The name of the m2 repository - */ + /** The name of the m2 repository. */ public static final String MVN_CONFIG_LEGACY_FOLDER = ".m2"; /** The name of the settings-security.xml */ @@ -48,9 +49,7 @@ public class Mvn extends LocalToolCommandlet { /** The pom.xml file name. */ public static final String POM_XML = "pom.xml"; - /** - * The name of the settings.xml - */ + /** The name of the file settings.xml. */ public static final String SETTINGS_FILE = "settings.xml"; private static final String DOCUMENTATION_PAGE_CONF = "https://github.com/devonfw/IDEasy/blob/main/documentation/conf.adoc"; @@ -135,7 +134,7 @@ private void createSettingsFile(Path settingsFile, Path settingsTemplateFile, Pa return; } if (!Files.exists(settingsTemplateFile)) { - this.context.warning("Missing maven settings template at {}. ", settingsTemplateFile); + LOG.warn("Missing maven settings template at {}. ", settingsTemplateFile); return; } Step step = this.context.newStep("Create mvn settings file at " + settingsFile); @@ -150,7 +149,7 @@ private void doCreateSettingsFile(Path settingsFile, Path settingsTemplateFile, GitContext gitContext = this.context.getGitContext(); String gitSettingsUrl = gitContext.retrieveGitUrl(this.context.getSettingsPath()); if (gitSettingsUrl == null) { - this.context.warning("Failed to determine git remote URL for settings folder."); + LOG.warn("Failed to determine git remote URL for settings folder."); } else if (!gitSettingsUrl.equals(GitContext.DEFAULT_SETTINGS_GIT_URL) && Files.exists(settingsSecurityFile)) { Set variables = findVariables(content); for (String variable : variables) { @@ -170,7 +169,7 @@ private String getEncryptedPassword(String variable) { String input = this.context.askForInput("Please enter secret value for variable " + variable + ":"); String encryptedPassword = retrievePassword("--encrypt-password", input); - this.context.info("Encrypted as " + encryptedPassword); + LOG.info("Encrypted as {}", encryptedPassword); return encryptedPassword; } @@ -214,7 +213,7 @@ public Path getMavenTemplatesFolder() { if (!Files.isDirectory(templatesConfMvnFolder)) { Path templatesConfMvnLegacyFolder = templatesConfFolder.resolve(MVN_CONFIG_LEGACY_FOLDER); if (!Files.isDirectory(templatesConfMvnLegacyFolder)) { - this.context.warning("No maven templates found neither in {} nor in {} - configuration broken", templatesConfMvnFolder, + LOG.warn("No maven templates found neither in {} nor in {} - configuration broken", templatesConfMvnFolder, templatesConfMvnLegacyFolder); return null; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/node/Node.java b/cli/src/main/java/com/devonfw/tools/ide/tool/node/Node.java index d4ea787276..02338ff73c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/node/Node.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/node/Node.java @@ -2,8 +2,12 @@ import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.nls.NlsBundle; import com.devonfw.tools.ide.process.ProcessResult; import com.devonfw.tools.ide.tool.LocalToolCommandlet; @@ -17,6 +21,8 @@ */ public class Node extends LocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(Node.class); + /** * The constructor. * @@ -40,14 +46,14 @@ protected void postInstallOnNewInstallation(ToolInstallRequest request) { .addArg(getToolPath().toString()); ProcessResult result = npm.runPackageManager(packageManagerRequest, true); if (result.isSuccessful()) { - this.context.success("Setting npm config prefix to: {} was successful", getToolPath()); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Setting npm config prefix to: {} was successful", getToolPath()); } } @Override public void printHelp(NlsBundle bundle) { - this.context.info("For a list of supported options and arguments, use \"node --help\""); + LOG.info("For a list of supported options and arguments, use \"node --help\""); } @Override diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/PluginBasedCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/PluginBasedCommandlet.java index 694d8c374a..0fc33f88b9 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/PluginBasedCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/PluginBasedCommandlet.java @@ -42,7 +42,7 @@ public PluginBasedCommandlet(IdeContext context, String tool, Set tags) { public ToolPlugins getPlugins() { if (this.plugins == null) { - ToolPlugins toolPlugins = new ToolPlugins(this.context); + ToolPlugins toolPlugins = new ToolPlugins(); // Load project-specific plugins Path pluginsPath = getPluginsConfigPath(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/ToolPlugins.java b/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/ToolPlugins.java index 4374210eb3..ca626ad6be 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/ToolPlugins.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/ToolPlugins.java @@ -5,27 +5,24 @@ import java.util.HashMap; import java.util.Map; -import com.devonfw.tools.ide.context.IdeContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A wrapper class for holding two maps of plugin descriptors: one keyed by plugin ID and the other keyed by plugin name. */ public class ToolPlugins { + private static final Logger LOG = LoggerFactory.getLogger(ToolPlugins.class); + private final Map mapById; private final Map mapByName; - - private final IdeContext context; - /** * The constructor. - * - * @param context the {@link IdeContext}. */ - public ToolPlugins(IdeContext context) { + public ToolPlugins() { super(); - this.context = context; this.mapById = new HashMap<>(); this.mapByName = new HashMap<>(); } @@ -72,7 +69,7 @@ protected void add(ToolPluginDescriptor descriptor) { private void put(String key, ToolPluginDescriptor descriptor, Map map) { ToolPluginDescriptor duplicate = map.put(key, descriptor); if (duplicate != null) { - this.context.info("Plugin with key {} was {} but got overridden by {}", key, duplicate, descriptor); + LOG.info("Plugin with key {} was {} but got overridden by {}", key, duplicate, descriptor); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/Sonar.java b/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/Sonar.java index bd8f778b8a..5e2063e177 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/Sonar.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/sonar/Sonar.java @@ -5,6 +5,9 @@ import java.util.Properties; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.property.EnumProperty; @@ -13,8 +16,14 @@ import com.devonfw.tools.ide.tool.java.Java; import com.devonfw.tools.ide.tool.mvn.Mvn; +/** + * {@link LocalToolCommandlet} for SonarQube. + */ public class Sonar extends LocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(Sonar.class); + + /** The {@link SonarCommand} to run. */ public final EnumProperty command; /** @@ -88,13 +97,13 @@ protected String getBinaryName() { private void printSonarWebPort() { - this.context.info("SonarQube is running at localhost on the following port (default 9000):"); + LOG.info("SonarQube is running at localhost on the following port (default 9000):"); Path sonarPropertiesPath = getToolPath().resolve("conf/sonar.properties"); Properties sonarProperties = this.context.getFileAccess().readProperties(sonarPropertiesPath); String sonarWebPort = sonarProperties.getProperty("sonar.web.port"); if (sonarWebPort != null) { - this.context.info(sonarWebPort); + LOG.info(sonarWebPort); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/tomcat/Tomcat.java b/cli/src/main/java/com/devonfw/tools/ide/tool/tomcat/Tomcat.java index 5d3ddd5719..abab95ec13 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/tomcat/Tomcat.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/tomcat/Tomcat.java @@ -9,6 +9,8 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -30,6 +32,8 @@ */ public class Tomcat extends LocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(Tomcat.class); + private static final String CATALINA = "catalina"; private static final String CATALINA_BAT = CATALINA + ".bat"; private static final String CATALINA_BASH_SCRIPT = CATALINA + ".sh"; @@ -83,8 +87,8 @@ private void printTomcatPort() { String portNumber = findTomcatPort(); if (!portNumber.isEmpty()) { - this.context.info("Tomcat is running at localhost on HTTP port {}:", portNumber); - this.context.info("http://localhost:{}", portNumber); + LOG.info("Tomcat is running at localhost on HTTP port {}:", portNumber); + LOG.info("http://localhost:{}", portNumber); } } @@ -102,14 +106,14 @@ private String findTomcatPort() { Element ConnectorElement = (Element) connectorNodes.item(0); portNumber = ConnectorElement.getAttribute("port"); } else { - this.context.warning("Port element not found in server.xml"); + LOG.warn("Port element not found in server.xml"); } } catch (ParserConfigurationException | IOException | SAXException e) { - this.context.error(e); + LOG.error(e.toString(), e); } } if (portNumber.isEmpty()) { - this.context.warning("Could not find HTTP port in {}", tomcatPropertiesPath); + LOG.warn("Could not find HTTP port in {}", tomcatPropertiesPath); } return portNumber; } From eff4c822e4b1d105690dd7b5ff12845857594096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Sat, 21 Feb 2026 22:03:00 +0100 Subject: [PATCH 31/51] #404: fixed JUL issue with ProcessBuilder --- .../tools/ide/context/AbstractIdeContext.java | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 41b95ff8ee..f98d8e8c71 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -1176,23 +1176,13 @@ protected final Properties createJavaUtilLoggingProperties(boolean console, bool return null; } Properties properties = new Properties(); - String level = "FINE"; + String intLevel = "FINE"; if (trace().isEnabled()) { - level = "FINER"; + intLevel = "FINER"; } - // java.util.logging is so flawed: We cannot set the root level to a higher threshold than our own logger, instead we need to list all potential loggers - properties.setProperty(".level", level); String extLevel = "WARNING"; - properties.setProperty("org.level", extLevel); - properties.setProperty("java.level", extLevel); - properties.setProperty("java.lang.level", extLevel); - properties.setProperty("java.lang.FooBar.level", extLevel); - // properties.setProperty("java.lang.ProcessBuilder.level", extLevel); - properties.setProperty("jdk.level", extLevel); - properties.setProperty("net.level", extLevel); - properties.setProperty("io.level", extLevel); - properties.setProperty("sf.level", extLevel); - properties.setProperty("sun.level", extLevel); + properties.setProperty(".level", extLevel); + properties.setProperty("com.devonfw.tools.ide.level", intLevel); if (file && console) { properties.setProperty("handlers", "java.util.logging.ConsoleHandler,java.util.logging.FileHandler"); } else if (file) { @@ -1201,7 +1191,7 @@ protected final Properties createJavaUtilLoggingProperties(boolean console, bool properties.setProperty("handlers", "java.util.logging.ConsoleHandler"); } if (file) { - properties.setProperty("java.util.logging.FileHandler.level", level); + properties.setProperty("java.util.logging.FileHandler.level", intLevel); properties.setProperty("java.util.logging.FileHandler.formatter", "java.util.logging.SimpleFormatter"); properties.setProperty("java.util.logging.FileHandler.encoding", "UTF-8"); LocalDateTime now = LocalDateTime.now(); @@ -1210,7 +1200,7 @@ protected final Properties createJavaUtilLoggingProperties(boolean console, bool properties.setProperty("java.util.logging.FileHandler.pattern", logsPath.resolve("ideasy-" + DateTimeUtil.formatTime(now) + ".log").toString()); } if (console) { - properties.setProperty("java.util.logging.ConsoleHandler.level", level); + properties.setProperty("java.util.logging.ConsoleHandler.level", intLevel); properties.setProperty("java.util.logging.ConsoleHandler.formatter", "java.util.logging.SimpleFormatter"); properties.setProperty("java.util.logging.ConsoleHandler.encoding", "UTF-8"); } From 542ee4680db4fb9e45cd828d33359ddfe0702eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Sun, 22 Feb 2026 18:56:33 +0100 Subject: [PATCH 32/51] #404: #1713: completely removed IdeLogger and IdeSubLogger, do all logging with SLF4J --- .../com/devonfw/tools/ide/cli/Ideasy.java | 21 +- ...AbstractVersionOrEditionGetCommandlet.java | 2 +- .../tools/ide/commandlet/Commandlet.java | 4 +- .../ide/commandlet/CommandletManagerImpl.java | 9 +- .../ide/commandlet/ContextCommandlet.java | 3 +- .../ide/commandlet/EnvironmentCommandlet.java | 21 +- .../tools/ide/commandlet/HelpCommandlet.java | 14 +- .../commandlet/InstallPluginCommandlet.java | 7 +- .../tools/ide/commandlet/ShellCommandlet.java | 18 +- .../ide/commandlet/UninstallCommandlet.java | 8 +- .../commandlet/UninstallPluginCommandlet.java | 7 +- .../ide/commandlet/UpgradeCommandlet.java | 8 +- .../commandlet/UpgradeSettingsCommandlet.java | 2 +- .../ide/commandlet/VersionCommandlet.java | 7 +- .../CompletionCandidateCollectorDefault.java | 7 +- .../tools/ide/context/AbstractIdeContext.java | 210 +++++++-------- .../devonfw/tools/ide/context/IdeContext.java | 6 +- .../tools/ide/context/IdeContextConsole.java | 27 +- .../tools/ide/context/IdeStartContext.java | 22 +- .../ide/context/IdeStartContextImpl.java | 110 +++++++- .../AbstractEnvironmentVariables.java | 23 +- .../environment/EnvironmentVariablesMap.java | 11 +- .../EnvironmentVariablesPropertiesFile.java | 10 +- .../tools/ide/environment/VariableLine.java | 20 +- .../devonfw/tools/ide/git/GitOperation.java | 21 +- .../git/repository/RepositoryProperties.java | 21 +- .../tools/ide/log/AbstractIdeSubLogger.java | 203 -------------- .../devonfw/tools/ide/log/IdeLogLevel.java | 43 ++- .../tools/ide/log/IdeLogListenerBuffer.java | 30 ++- .../com/devonfw/tools/ide/log/IdeLogger.java | 250 ------------------ .../devonfw/tools/ide/log/IdeLoggerImpl.java | 133 ---------- .../devonfw/tools/ide/log/IdeSubLogger.java | 55 ---- .../tools/ide/log/IdeSubLoggerAdapter.java | 77 ------ .../tools/ide/log/IdeSubLoggerOut.java | 60 ----- .../tools/ide/log/JulConsoleHandler.java | 49 ++++ .../devonfw/tools/ide/log/JulLogLevel.java | 48 ++++ .../tools/ide/log/Slf4jLoggerAdapter.java | 154 +++++++---- .../ide/log/Slf4jLoggerFactoryIdeasy.java | 2 +- .../tools/ide/merge/DirectoryMerger.java | 8 +- .../devonfw/tools/ide/merge/FileMerger.java | 11 +- .../devonfw/tools/ide/merge/JsonMerger.java | 17 +- .../tools/ide/merge/PropertiesMerger.java | 17 +- .../tools/ide/merge/xml/XmlMerger.java | 12 +- .../ide/merge/xml/matcher/IdComputer.java | 10 +- .../tools/ide/migration/IdeMigrator.java | 14 +- .../tools/ide/network/NetworkProxy.java | 17 +- .../tools/ide/network/NetworkStatusImpl.java | 29 +- .../com/devonfw/tools/ide/nls/NlsBundle.java | 7 +- .../com/devonfw/tools/ide/os/MacOsHelper.java | 16 +- .../tools/ide/os/WindowsHelperImpl.java | 9 +- .../tools/ide/process/ProcessContext.java | 18 +- .../tools/ide/process/ProcessContextImpl.java | 26 +- .../tools/ide/process/ProcessResult.java | 16 +- .../tools/ide/process/ProcessResultImpl.java | 33 +-- .../devonfw/tools/ide/property/Property.java | 11 +- .../tools/ide/security/ToolVersionChoice.java | 14 +- .../java/com/devonfw/tools/ide/step/Step.java | 29 +- .../com/devonfw/tools/ide/step/StepImpl.java | 103 +++----- .../tools/ide/tool/GlobalToolCommandlet.java | 35 ++- .../tools/ide/tool/LocalToolCommandlet.java | 11 +- .../tools/ide/tool/ToolCommandlet.java | 82 +++--- .../tools/ide/tool/ToolInstallRequest.java | 11 +- .../ide/tool/custom/CustomToolsMapper.java | 12 +- .../devonfw/tools/ide/tool/docker/Docker.java | 20 +- .../tools/ide/tool/eclipse/Eclipse.java | 13 +- .../tools/ide/tool/ide/IdeToolCommandlet.java | 11 +- .../tool/ide/IdeaBasedIdeToolCommandlet.java | 8 +- .../ide/tool/ide/IdeaPluginDownloader.java | 7 +- .../tools/ide/tool/intellij/Intellij.java | 8 +- .../com/devonfw/tools/ide/tool/jmc/Jmc.java | 9 +- .../tools/ide/tool/lazydocker/LazyDocker.java | 2 +- .../tools/ide/tool/mvn/MvnRepository.java | 2 +- .../ide/tool/npm/NpmBasedCommandlet.java | 9 +- .../ide/tool/pip/PipBasedCommandlet.java | 11 +- .../tool/plugin/PluginBasedCommandlet.java | 21 +- .../ide/tool/plugin/ToolPluginDescriptor.java | 15 +- .../devonfw/tools/ide/tool/python/Python.java | 7 +- .../repository/AbstractToolRepository.java | 33 ++- .../devonfw/tools/ide/tool/vscode/Vscode.java | 10 +- .../tools/ide/url/model/UrlMetadata.java | 9 +- .../url/model/file/json/ToolDependencies.java | 10 +- .../ide/url/model/file/json/ToolSecurity.java | 16 +- .../AbstractVariableDefinitionList.java | 7 +- .../variable/VariableDefinitionBoolean.java | 7 +- .../tools/ide/version/VersionIdentifier.java | 13 +- .../ide/context/AbstractIdeContextTest.java | 5 +- .../ide/context/AbstractIdeTestContext.java | 19 +- .../tools/ide/context/IdeContextTest.java | 14 +- .../tools/ide/context/IdeSlf4jContext.java | 32 --- .../tools/ide/context/IdeTestContext.java | 16 +- .../tools/ide/context/IdeTestContextMock.java | 11 +- .../ide/context/ProcessContextTestImpl.java | 2 +- .../EnvironmentVariablesPropertiesMock.java | 11 +- .../ide/environment/VariableLineTest.java | 5 +- .../tools/ide/io/FileAccessImplTest.java | 2 +- .../tools/ide/io/IdeProgressBarTest.java | 21 +- .../ide/log/IdeLogListenerCollector.java | 0 .../tools/ide/log/IdeSlf4jRootLogger.java | 41 --- .../tools/ide/log/IdeSubLoggerSlf4j.java | 60 ----- .../devonfw/tools/ide/log/IdeTestLogger.java | 38 --- .../tools/ide/log/IdeTestStartContext.java | 32 +++ .../tools/ide/migration/IdeMigratorTest.java | 8 +- .../devonfw/tools/ide/os/MacOsHelperTest.java | 8 +- .../tools/ide/os/WindowsHelperImplTest.java | 6 +- .../com/devonfw/tools/ide/step/StepTest.java | 2 +- .../tool/custom/CustomToolsMapperTest.java | 9 +- .../tools/ide/tool/dotnet/DotNetTest.java | 1 - .../tool/ide/IdeToolDummyCommandletTest.java | 4 +- .../tools/ide/tool/intellij/IntellijTest.java | 2 +- .../tools/ide/tool/pycharm/PycharmTest.java | 2 +- .../tool/repository/ToolRepositoryMock.java | 9 +- .../tools/ide/tool/spring/SpringTest.java | 2 - .../ide/url/model/AbstractUrlModelTest.java | 4 +- 113 files changed, 1211 insertions(+), 1694 deletions(-) delete mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java delete mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/IdeLogger.java delete mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/IdeLoggerImpl.java delete mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLogger.java delete mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerAdapter.java delete mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/log/JulLogLevel.java delete mode 100644 cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java rename cli/src/{main => test}/java/com/devonfw/tools/ide/log/IdeLogListenerCollector.java (100%) delete mode 100644 cli/src/test/java/com/devonfw/tools/ide/log/IdeSlf4jRootLogger.java delete mode 100644 cli/src/test/java/com/devonfw/tools/ide/log/IdeSubLoggerSlf4j.java delete mode 100644 cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java create mode 100644 cli/src/test/java/com/devonfw/tools/ide/log/IdeTestStartContext.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java b/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java index eac889bcf3..6f508ee919 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java +++ b/cli/src/main/java/com/devonfw/tools/ide/cli/Ideasy.java @@ -3,12 +3,15 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.commandlet.ContextCommandlet; import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.context.IdeContextConsole; import com.devonfw.tools.ide.context.IdeStartContextImpl; -import com.devonfw.tools.ide.log.IdeLogLevel; +import com.devonfw.tools.ide.log.JulLogLevel; import com.devonfw.tools.ide.property.FlagProperty; import com.devonfw.tools.ide.property.Property; @@ -17,6 +20,8 @@ */ public final class Ideasy { + private static final Logger LOG = LoggerFactory.getLogger(Ideasy.class); + private AbstractIdeContext context; /** @@ -37,15 +42,6 @@ public Ideasy() { this.context = context; } - private IdeContext context() { - - if (this.context == null) { - // fallback in case of exception before initialization - return new IdeContextConsole(IdeLogLevel.INFO, null, false); - } - return this.context; - } - /** * Non-static variant of {@link #main(String...) main method} without invoking {@link System#exit(int)} so it can be tested. * @@ -61,7 +57,7 @@ public int run(String... args) { exitStatus = error.getExitCode(); String errorMessage = error.getMessage(); if ((errorMessage != null) && !errorMessage.isBlank()) { - context().error(errorMessage); + LOG.error(errorMessage); } } catch (Throwable error) { exitStatus = 255; @@ -77,7 +73,7 @@ public int run(String... args) { + "If the error is not on your end (network connectivity, lack of permissions, etc.) please file a bug:\n" // + "https://github.com/devonfw/IDEasy/issues/new?template=bug_report.yml&title=" + URLEncoder.encode(title, StandardCharsets.UTF_8); - context().error(error, message); + LOG.error(message, error); } return exitStatus; } @@ -134,6 +130,7 @@ private void initContext(CliArguments arguments) { */ public static void main(String... args) { + JulLogLevel.init(); int exitStatus = new Ideasy().run(args); System.exit(exitStatus); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java index c8345b299e..b336228378 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java @@ -87,7 +87,7 @@ protected void doRun() { if (getInstalledValue == getConfiguredValue) { if (getInstalledValue) { // both --configured and --installed logToolInfo(commandlet, configuredValue, installedValue); - } else if (this.context.debug().isEnabled()) { + } else if (LOG.isDebugEnabled()) { logToolInfo(commandlet, configuredValue, installedValue); } else { if (installedValue == null) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java index be8a338b20..01ea4ce046 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java @@ -222,8 +222,8 @@ protected boolean isActivateJaveUtilLogging() { */ public final void run() { - if (isActivateJaveUtilLogging()) { - ((AbstractIdeContext) this.context).configureJavaUtilLogging(); + if (this.context != null) { // for ContextCommandlet we do not have a context yet + ((AbstractIdeContext) this.context).configureJavaUtilLogging(isActivateJaveUtilLogging()); } doRun(); } 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 87be7ca2f8..ed9083e5af 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 @@ -8,6 +8,9 @@ import java.util.Map; import java.util.NoSuchElementException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliArgument; import com.devonfw.tools.ide.cli.CliArguments; import com.devonfw.tools.ide.completion.CompletionCandidateCollector; @@ -58,6 +61,8 @@ */ public class CommandletManagerImpl implements CommandletManager { + private static final Logger LOG = LoggerFactory.getLogger(CommandletManagerImpl.class); + private final IdeContext context; private final Map, Commandlet> commandletTypeMap; @@ -184,7 +189,7 @@ private void registerKeyword(String keyword, Commandlet commandlet) { Commandlet duplicate = this.firstKeywordMap.putIfAbsent(keyword, commandlet); if (duplicate != null) { - this.context.debug("Duplicate keyword {} already used by {} so it cannot be associated also with {}", keyword, duplicate, commandlet); + LOG.debug("Duplicate keyword {} already used by {} so it cannot be associated also with {}", keyword, duplicate, commandlet); } } @@ -288,7 +293,7 @@ private Commandlet findNext() { if (properties.isEmpty()) { assert false : cmd.getClass().getSimpleName() + " has no properties!"; } else { - Property property = properties.get(0); + Property property = properties.getFirst(); if (property instanceof KeywordProperty) { boolean matches = property.apply(arguments.copy(), context, cmd, this.collector); if (matches) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java index ecd2df1daa..905ab704d0 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java @@ -5,7 +5,6 @@ import com.devonfw.tools.ide.context.IdeStartContextImpl; import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.log.IdeLogListenerBuffer; -import com.devonfw.tools.ide.log.IdeSubLoggerOut; import com.devonfw.tools.ide.property.FlagProperty; import com.devonfw.tools.ide.property.LocaleProperty; @@ -86,7 +85,7 @@ protected void doRun() { IdeLogLevel logLevel = determineLogLevel(); if (this.startContext == null) { IdeLogListenerBuffer listener = new IdeLogListenerBuffer(); - this.startContext = new IdeStartContextImpl(logLevel, level -> new IdeSubLoggerOut(level, null, true, logLevel, listener)); + this.startContext = new IdeStartContextImpl(logLevel, listener); } else if (this.context != null) { IdeStartContextImpl newStartContext = ((AbstractIdeContext) this.context).getStartContext(); assert (this.startContext == newStartContext); // fast fail during development via assert diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java index 345be8d5dd..96d71bcda6 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java @@ -5,6 +5,9 @@ import java.util.Map; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliExitException; import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; @@ -12,7 +15,6 @@ import com.devonfw.tools.ide.environment.VariableLine; import com.devonfw.tools.ide.environment.VariableSource; import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeSubLogger; import com.devonfw.tools.ide.os.WindowsPathSyntax; import com.devonfw.tools.ide.process.EnvironmentContext; import com.devonfw.tools.ide.process.EnvironmentVariableCollectorContext; @@ -26,6 +28,8 @@ */ public final class EnvironmentCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(EnvironmentCommandlet.class); + /** {@link FlagProperty} to enable Bash (MSys) path conversion on Windows. */ public final FlagProperty bash; @@ -67,7 +71,6 @@ protected void doRun() { boolean winCmd = false; WindowsPathSyntax pathSyntax = null; - IdeSubLogger logger = this.context.level(IdeLogLevel.PROCESSABLE); if (this.context.getSystemInfo().isWindows()) { if (this.bash.isTrue()) { pathSyntax = WindowsPathSyntax.MSYS; @@ -85,11 +88,11 @@ protected void doRun() { new VariableSource(EnvironmentVariablesType.TOOL, this.context.getSoftwarePath()), pathSyntax); setEnvironmentVariablesInLocalTools(environmentVariableCollectorContext); - printLines(variableMap, logger, winCmd); + printLines(variableMap, winCmd); } - private void printLines(Map variableMap, IdeSubLogger logger, boolean winCmd) { - if (this.context.debug().isEnabled()) { + private void printLines(Map variableMap, boolean winCmd) { + if (LOG.isDebugEnabled()) { Map> type2lines = variableMap.values().stream().collect(Collectors.groupingBy(l -> l.getSource().type())); for (EnvironmentVariablesType type : EnvironmentVariablesType.values()) { List lines = type2lines.get(type); @@ -98,10 +101,10 @@ private void printLines(Map variableMap, IdeSubLogger logg sortVariables(lines); for (VariableLine line : lines) { if (!sourcePrinted) { - this.context.debug("from {}:", line.getSource()); + LOG.debug("from {}:", line.getSource()); sourcePrinted = true; } - logger.log(format(line, winCmd)); + LOG.info(IdeLogLevel.PROCESSABLE.getSlf4jMarker(), format(line, winCmd)); } } } @@ -109,7 +112,7 @@ private void printLines(Map variableMap, IdeSubLogger logg List variables = new ArrayList<>(variableMap.values()); sortVariables(variables); for (VariableLine line : variables) { - logger.log(format(line, winCmd)); + LOG.info(IdeLogLevel.PROCESSABLE.getSlf4jMarker(), format(line, winCmd)); } } } @@ -144,7 +147,7 @@ private void setEnvironmentVariablesInLocalTools(EnvironmentContext environmentC tool.setEnvironment(environmentContext, toolInstallation, false); } } catch (Exception e) { - this.context.warning("An error occurred while setting the environment variables in local tools:", e); + LOG.warn("An error occurred while setting the environment variables in local tools:", e); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java index ca3ced7395..16dab3f3bd 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java @@ -6,11 +6,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.event.Level; import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeSubLogger; import com.devonfw.tools.ide.nls.NlsBundle; import com.devonfw.tools.ide.property.CommandletProperty; import com.devonfw.tools.ide.property.KeywordProperty; @@ -243,9 +244,16 @@ void print() { void print(IdeLogLevel level) { - IdeSubLogger logger = HelpCommandlet.this.context.level(level); for (Arg arg : get()) { - logger.log(format(arg)); + String message = format(arg); + Level slf4jLevel = level.getSlf4jLevel(); + Marker marker = level.getSlf4jMarker(); + if (marker == null) { + LOG.atLevel(slf4jLevel).log(message); + } else { + assert slf4jLevel == Level.INFO; + LOG.info(marker, message); + } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallPluginCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallPluginCommandlet.java index 2ac36a8a41..ac4b466256 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallPluginCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/InstallPluginCommandlet.java @@ -1,5 +1,8 @@ package com.devonfw.tools.ide.commandlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.property.PluginProperty; import com.devonfw.tools.ide.property.ToolProperty; @@ -14,6 +17,8 @@ */ public class InstallPluginCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(InstallPluginCommandlet.class); + /** The tool to install. */ public final ToolProperty tool; @@ -48,7 +53,7 @@ protected void doRun() { Step step = context.newStep("Install plugin: " + plugin); step.run(() -> cmd.installPlugin(cmd.getPlugin(plugin), step)); } else { - context.warning("Tool {} does not support installation of plugins.", commandlet.getName()); + LOG.warn("Tool {} does not support installation of plugins.", commandlet.getName()); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java index 85b466054d..9667c9e269 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java @@ -19,6 +19,8 @@ import org.jline.terminal.Terminal; import org.jline.terminal.TerminalBuilder; import org.jline.widget.AutosuggestionWidgets; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.devonfw.tools.ide.cli.CliArgument; import com.devonfw.tools.ide.cli.CliArguments; @@ -35,6 +37,8 @@ */ public final class ShellCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(ShellCommandlet.class); + private static final int AUTOCOMPLETER_MAX_RESULTS = 50; private static final int RC_EXIT = 987654321; @@ -173,7 +177,7 @@ private int changeDirectory(CliArguments cliArgs) { */ private boolean apply(CliArgument argument, Commandlet commandlet) { - this.context.trace("Trying to match arguments to commandlet {}", commandlet.getName()); + LOG.trace("Trying to match arguments to commandlet {}", commandlet.getName()); CliArgument currentArgument = argument; Iterator> valueIterator = commandlet.getValues().iterator(); Property currentProperty = null; @@ -183,7 +187,7 @@ private boolean apply(CliArgument argument, Commandlet commandlet) { endOpts = true; } else { String arg = currentArgument.get(); - this.context.trace("Trying to match argument '{}'", currentArgument); + LOG.trace("Trying to match argument '{}'", currentArgument); if ((currentProperty != null) && (currentProperty.isExpectValue())) { currentProperty.setValueAsString(arg, this.context); if (!currentProperty.isMultiValued()) { @@ -196,17 +200,17 @@ private boolean apply(CliArgument argument, Commandlet commandlet) { } if (property == null) { if (!valueIterator.hasNext()) { - this.context.trace("No option or next value found"); + LOG.trace("No option or next value found"); return false; } currentProperty = valueIterator.next(); - this.context.trace("Next value candidate is {}", currentProperty); + LOG.trace("Next value candidate is {}", currentProperty); if (currentProperty instanceof KeywordProperty keyword) { if (keyword.matches(arg)) { keyword.setValue(Boolean.TRUE); - this.context.trace("Keyword matched"); + LOG.trace("Keyword matched"); } else { - this.context.trace("Missing keyword"); + LOG.trace("Missing keyword"); return false; } } else { @@ -219,7 +223,7 @@ private boolean apply(CliArgument argument, Commandlet commandlet) { currentProperty = null; } } else { - this.context.trace("Found option by name"); + LOG.trace("Found option by name"); String value = currentArgument.getValue(); if (value != null) { property.setValueAsString(value, this.context); diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java index ef2293872e..3871d7da60 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java @@ -1,5 +1,8 @@ package com.devonfw.tools.ide.commandlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.property.ToolProperty; import com.devonfw.tools.ide.tool.IdeasyCommandlet; @@ -10,6 +13,8 @@ */ public class UninstallCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(UninstallCommandlet.class); + /** The tool to uninstall. */ public final ToolProperty tools; @@ -56,9 +61,8 @@ protected void doRun() { if (toolCommandlet.isInstalled()) { toolCommandlet.uninstall(); } else { - this.context.warning("Couldn't uninstall " + toolCommandlet.getName() + " because we could not find an installation"); + LOG.warn("Couldn't uninstall " + toolCommandlet.getName() + " because we could not find an installation"); } - } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallPluginCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallPluginCommandlet.java index 40d3290c1f..fc9bf3b4c6 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallPluginCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallPluginCommandlet.java @@ -1,5 +1,8 @@ package com.devonfw.tools.ide.commandlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.property.PluginProperty; import com.devonfw.tools.ide.property.ToolProperty; @@ -13,6 +16,8 @@ */ public class UninstallPluginCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(UninstallPluginCommandlet.class); + /** The tool to install. */ public final ToolProperty tool; @@ -46,7 +51,7 @@ protected void doRun() { if (commandlet instanceof PluginBasedCommandlet cmd) { cmd.uninstallPlugin(cmd.getPlugin(plugin)); } else { - context.warning("Tool {} does not support plugins.", tool.getName()); + LOG.warn("Tool {} does not support plugins.", tool.getName()); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java index a3925eb323..4c253d230e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java @@ -1,6 +1,10 @@ package com.devonfw.tools.ide.commandlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.property.EnumProperty; import com.devonfw.tools.ide.tool.IdeasyCommandlet; import com.devonfw.tools.ide.tool.ToolInstallation; @@ -10,6 +14,8 @@ */ public class UpgradeCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(UpgradeCommandlet.class); + /** Optional {@link UpgradeMode}. */ public final EnumProperty mode; @@ -43,7 +49,7 @@ protected void doRun() { IdeasyCommandlet ideasy = new IdeasyCommandlet(this.context, this.mode.getValue()); ToolInstallation installation = ideasy.install(false); if (installation.newInstallation()) { - this.context.interaction("It is recommended to run 'ide update' on your IDEasy projects now."); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "It is recommended to run 'ide update' on your IDEasy projects now."); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java index d84566c873..aa4939278e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java @@ -102,7 +102,7 @@ private void updateProperties() { // updates DEVON_IDE_CUSTOM_TOOLS to new ide-custom-tools.json String devonCustomTools = IdeVariables.DEVON_IDE_CUSTOM_TOOLS.get(this.context); if (devonCustomTools != null) { - CustomTools customTools = CustomToolsMapper.parseCustomToolsFromLegacyConfig(devonCustomTools, context); + CustomTools customTools = CustomToolsMapper.parseCustomToolsFromLegacyConfig(devonCustomTools); if (customTools != null) { CustomToolsMapper.get().saveJsonToFolder(customTools, this.context.getSettingsPath()); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java index d5cef41b5e..f8ba48dc24 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java @@ -1,5 +1,8 @@ package com.devonfw.tools.ide.commandlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.version.IdeVersion; @@ -9,6 +12,8 @@ */ public class VersionCommandlet extends Commandlet { + private static final Logger LOG = LoggerFactory.getLogger(VersionCommandlet.class); + /** * The constructor. * @@ -41,6 +46,6 @@ public boolean isProcessableOutput() { @Override protected void doRun() { - this.context.level(IdeLogLevel.PROCESSABLE).log(IdeVersion.getVersionString()); + LOG.info(IdeLogLevel.PROCESSABLE.getSlf4jMarker(), IdeVersion.getVersionString()); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/completion/CompletionCandidateCollectorDefault.java b/cli/src/main/java/com/devonfw/tools/ide/completion/CompletionCandidateCollectorDefault.java index e5163dc6e4..33f6fc25fb 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/completion/CompletionCandidateCollectorDefault.java +++ b/cli/src/main/java/com/devonfw/tools/ide/completion/CompletionCandidateCollectorDefault.java @@ -4,6 +4,9 @@ import java.util.Collections; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.commandlet.Commandlet; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.property.Property; @@ -13,6 +16,8 @@ */ public class CompletionCandidateCollectorDefault implements CompletionCandidateCollector { + private static final Logger LOG = LoggerFactory.getLogger(CompletionCandidateCollectorDefault.class); + private final List candidates; private final IdeContext context; @@ -45,7 +50,7 @@ public void add(String text, String description, Property property, Commandle CompletionCandidate candidate = createCandidate(text, description, property, commandlet); this.candidates.add(candidate); - this.context.trace("Added {} for auto-completion of property {}.{}", candidate, commandlet, property); + LOG.trace("Added {} for auto-completion of property {}.{}", candidate, commandlet, property); } @Override diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index f98d8e8c71..f3b5172b73 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -49,9 +49,7 @@ import com.devonfw.tools.ide.io.FileAccessImpl; import com.devonfw.tools.ide.log.IdeLogArgFormatter; import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeLogger; -import com.devonfw.tools.ide.log.IdeSubLogger; -import com.devonfw.tools.ide.log.IdeSubLoggerAdapter; +import com.devonfw.tools.ide.log.IdeLogListener; import com.devonfw.tools.ide.merge.DirectoryMerger; import com.devonfw.tools.ide.migration.IdeMigrator; import com.devonfw.tools.ide.network.NetworkStatus; @@ -89,7 +87,7 @@ */ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatter { - private static final Logger LOG = LoggerFactory.getLogger(AbstractIdeContext.class); + static final Logger LOG = LoggerFactory.getLogger(AbstractIdeContext.class); /** The default shell bash (Bourne Again SHell). */ public static final String BASH = "bash"; @@ -170,23 +168,15 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt private boolean julConfigured; - private final IdeSubLogger[] loggers; - /** * The constructor. * - * @param startContext the {@link IdeLogger}. + * @param startContext the {@link IdeStartContextImpl}. * @param workingDirectory the optional {@link Path} to current working directory. */ public AbstractIdeContext(IdeStartContextImpl startContext, Path workingDirectory) { super(); - // init sub loggers - IdeLogLevel[] levels = IdeLogLevel.values(); - this.loggers = new IdeSubLogger[levels.length]; - for (IdeLogLevel level : levels) { - this.loggers[level.ordinal()] = new IdeSubLoggerAdapter(level, LOG); - } this.startContext = startContext; this.startContext.setArgFormatter(this); @@ -205,7 +195,7 @@ public AbstractIdeContext(IdeStartContextImpl startContext, Path workingDirector if (Files.isDirectory(workingDirectory)) { workingDirectory = this.fileAccess.toCanonicalPath(workingDirectory); } else { - warning("Current working directory does not exist: {}", workingDirectory); + LOG.warn("Current working directory does not exist: {}", workingDirectory); } this.cwd = workingDirectory; // detect IDE_HOME and WORKSPACE @@ -249,7 +239,7 @@ protected IdeHomeAndWorkspace findIdeHome(Path workingDirectory) { Path ideRootPath = getIdeRootPathFromEnv(false); while (currentDir != null) { - trace("Looking for IDE_HOME in {}", currentDir); + LOG.trace("Looking for IDE_HOME in {}", currentDir); if (isIdeHome(currentDir)) { if (FOLDER_WORKSPACES.equals(name1) && !name2.isEmpty()) { workspace = name2; @@ -299,7 +289,7 @@ private Path findIdeRoot(Path ideHomePath) { Path ideRootPathFromEnv = getIdeRootPathFromEnv(true); ideRootPath = ideHomePath.getParent(); if ((ideRootPathFromEnv != null) && !ideRootPath.toString().equals(ideRootPathFromEnv.toString())) { - warning( + LOG.warn( "Variable IDE_ROOT is set to '{}' but for your project '{}' the path '{}' would have been expected.\n" + "Please check your 'user.dir' or working directory setting and make sure that it matches your IDE_ROOT variable.", ideRootPathFromEnv, @@ -330,19 +320,19 @@ protected Path getIdeRootPathFromEnv(boolean withSanityCheck) { String rootName = rootPath.getName(nameIndex).toString(); String absoluteRootName = absoluteRootPath.getName(nameIndex + delta).toString(); if (!rootName.equals(absoluteRootName)) { - warning("IDE_ROOT is set to {} but was expanded to absolute path {} and does not match for segment {} and {} - fix your IDEasy installation!", + LOG.warn("IDE_ROOT is set to {} but was expanded to absolute path {} and does not match for segment {} and {} - fix your IDEasy installation!", rootPath, absoluteRootPath, rootName, absoluteRootName); break; } } } else { - warning("IDE_ROOT is set to {} but was expanded to a shorter absolute path {}", rootPath, + LOG.warn("IDE_ROOT is set to {} but was expanded to a shorter absolute path {}", rootPath, absoluteRootPath); } } return absoluteRootPath; } else if (withSanityCheck) { - warning("IDE_ROOT is set to {} that is not an existing directory - fix your IDEasy installation!", rootPath); + LOG.warn("IDE_ROOT is set to {} that is not an existing directory - fix your IDEasy installation!", rootPath); } } return null; @@ -622,7 +612,7 @@ public Path getSettingsGitRepository() { Path settingsPath = getSettingsPath(); // check whether the settings path has a .git folder only if its not a symbolic link or junction if ((settingsPath != null) && !Files.exists(settingsPath.resolve(".git")) && !isSettingsRepositorySymlinkOrJunction()) { - error("Settings repository exists but is not a git repository."); + LOG.error("Settings repository exists but is not a git repository."); return null; } return settingsPath; @@ -838,7 +828,7 @@ public DirectoryMerger getWorkspaceMerger() { } /** - * @return the {@link #getDefaultExecutionDirectory() default execution directory} in which a command process is executed. + * @return the default execution directory in which a command process is executed. */ @Override public Path getDefaultExecutionDirectory() { @@ -891,20 +881,26 @@ protected ProcessContext createProcessContext() { } @Override - public IdeSubLogger level(IdeLogLevel level) { + public IdeLogLevel getLogLevel() { - return this.loggers[level.ordinal()]; + return this.startContext.getLogLevel(); + } + + @Override + public IdeLogListener getLogListener() { + + return this.startContext.getLogListener(); } @Override public void logIdeHomeAndRootStatus() { if (this.ideRoot != null) { - success("IDE_ROOT is set to {}", this.ideRoot); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "IDE_ROOT is set to {}", this.ideRoot); } if (this.ideHome == null) { - warning(getMessageNotInsideIdeProject()); + LOG.warn(getMessageNotInsideIdeProject()); } else { - success("IDE_HOME is set to {}", this.ideHome); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "IDE_HOME is set to {}", this.ideHome); } } @@ -962,7 +958,7 @@ public String askForInput(String message, String defaultValue) { while (true) { if (!message.isBlank()) { - interaction(message); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), message); } if (isBatchMode()) { if (isForceMode()) { @@ -982,12 +978,11 @@ public String askForInput(String message, String defaultValue) { } } - @SuppressWarnings("unchecked") @Override public O question(O[] options, String question, Object... args) { assert (options.length > 0); - interaction(question, args); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), question, args); return displayOptionsAndGetAnswer(options); } @@ -1001,24 +996,24 @@ private O displayOptionsAndGetAnswer(O[] options) { addMapping(mapping, key, option); String numericKey = Integer.toString(i); if (numericKey.equals(key)) { - trace("Options should not be numeric: " + key); + LOG.trace("Options should not be numeric: " + key); } else { addMapping(mapping, numericKey, option); } - interaction("Option " + numericKey + ": " + title); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "Option " + numericKey + ": " + title); } O option = null; if (isBatchMode()) { if (isForceMode()) { option = options[0]; - interaction("" + option); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "" + option); } } else { while (option == null) { String answer = readLine(); option = mapping.get(answer); if (option == null) { - warning("Invalid answer: '" + answer + "' - please try again."); + LOG.warn("Invalid answer: '" + answer + "' - please try again."); } } } @@ -1082,7 +1077,7 @@ public void endStep(StepImpl step) { if (this.currentStep != null) { currentStepName = this.currentStep.getName(); } - warning("endStep called with wrong step '{}' but expected '{}'", step.getName(), currentStepName); + LOG.warn("endStep called with wrong step '{}' but expected '{}'", step.getName(), currentStepName); } } @@ -1114,7 +1109,7 @@ public int run(CliArguments arguments) { this.startContext.activateLogging(); verifyIdeMinVersion(false); if (result != null) { - error(result.getErrorMessage()); + LOG.error(result.getErrorMessage()); } step.error("Invalid arguments: {}", current.getArgs()); HelpCommandlet help = this.commandletManager.getCommandlet(HelpCommandlet.class); @@ -1134,15 +1129,12 @@ public int run(CliArguments arguments) { } } - public void configureJavaUtilLogging() { + public void configureJavaUtilLogging(boolean logfile) { if (this.julConfigured) { return; } - Properties properties = createJavaUtilLoggingProperties(); - if (properties == null) { - return; - } + Properties properties = createJavaUtilLoggingProperties(logfile); try { ByteArrayOutputStream out = new ByteArrayOutputStream(512); properties.store(out, null); @@ -1150,18 +1142,21 @@ public void configureJavaUtilLogging() { ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); LogManager.getLogManager().readConfiguration(in); this.julConfigured = true; + this.startContext.activateLogging(); } catch (IOException e) { - error(e); + LOG.error("Failed to configure logging: " + e, e); } } - protected Properties createJavaUtilLoggingProperties() { - boolean logfile = false; - Boolean writeLogfile = IdeVariables.IDE_WRITE_LOGFILE.get(this); - if (Boolean.TRUE.equals(writeLogfile)) { - logfile = true; - this.startContext.setWriteLogfile(true); + protected Properties createJavaUtilLoggingProperties(boolean logfile) { + + if (logfile) { + Boolean writeLogfile = IdeVariables.IDE_WRITE_LOGFILE.get(this); + if (Boolean.FALSE.equals(writeLogfile)) { + logfile = false; + } } + this.startContext.setWriteLogfile(logfile); return createJavaUtilLoggingProperties(false, logfile); } @@ -1170,25 +1165,17 @@ protected final Properties createJavaUtilLoggingProperties(boolean console, bool Path idePath = getIdePath(); if (file && (idePath == null)) { file = false; - error("Cannot enable --logfile option since IDE_ROOT is undefined."); - } - if (!console && !file) { - return null; + LOG.error("Cannot enable --logfile option since IDE_ROOT is undefined."); } Properties properties = new Properties(); - String intLevel = "FINE"; - if (trace().isEnabled()) { - intLevel = "FINER"; - } + String intLevel = getLogLevel().getJulLevel().getName(); String extLevel = "WARNING"; properties.setProperty(".level", extLevel); properties.setProperty("com.devonfw.tools.ide.level", intLevel); - if (file && console) { - properties.setProperty("handlers", "java.util.logging.ConsoleHandler,java.util.logging.FileHandler"); - } else if (file) { - properties.setProperty("handlers", "java.util.logging.FileHandler"); + if (file) { + properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler,java.util.logging.FileHandler"); } else { - properties.setProperty("handlers", "java.util.logging.ConsoleHandler"); + properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler"); } if (file) { properties.setProperty("java.util.logging.FileHandler.level", intLevel); @@ -1199,11 +1186,7 @@ protected final Properties createJavaUtilLoggingProperties(boolean console, bool getFileAccess().mkdirs(logsPath); properties.setProperty("java.util.logging.FileHandler.pattern", logsPath.resolve("ideasy-" + DateTimeUtil.formatTime(now) + ".log").toString()); } - if (console) { - properties.setProperty("java.util.logging.ConsoleHandler.level", intLevel); - properties.setProperty("java.util.logging.ConsoleHandler.formatter", "java.util.logging.SimpleFormatter"); - properties.setProperty("java.util.logging.ConsoleHandler.encoding", "UTF-8"); - } + properties.setProperty("com.devonfw.tools.ide.log.JulConsoleHandler.level", intLevel); properties.setProperty("java.util.logging.SimpleFormatter.format", "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL [%4$s] [%3$s] %5$s%6$s%n"); return properties; } @@ -1230,7 +1213,7 @@ private ValidationResult applyAndRun(CliArguments arguments, Commandlet cmd) { result = cmd.validate(); } if (result.isValid()) { - debug("Running commandlet {}", cmd); + LOG.debug("Running commandlet {}", cmd); if (cmd.isIdeHomeRequired() && (this.ideHome == null)) { throw new CliException(getMessageNotInsideIdeProject(), ProcessResult.NO_IDE_HOME); } else if (cmd.isIdeRootRequired() && (this.ideRoot == null)) { @@ -1238,28 +1221,26 @@ private ValidationResult applyAndRun(CliArguments arguments, Commandlet cmd) { } try { if (cmd.isProcessableOutput()) { - if (!debug().isEnabled()) { + if (!LOG.isDebugEnabled()) { // unless --debug or --trace was supplied, processable output commandlets will disable all log-levels except INFO to prevent other logs interfere previousLogLevel = this.startContext.setLogLevel(IdeLogLevel.PROCESSABLE); } - this.startContext.activateLogging(); } else { - this.startContext.activateLogging(); if (cmd.isIdeHomeRequired()) { - debug(getMessageIdeHomeFound()); + LOG.debug(getMessageIdeHomeFound()); } Path settingsRepository = getSettingsGitRepository(); if (settingsRepository != null) { if (getGitContext().isRepositoryUpdateAvailable(settingsRepository, getSettingsCommitIdPath()) || ( getGitContext().fetchIfNeeded(settingsRepository) && getGitContext().isRepositoryUpdateAvailable( settingsRepository, getSettingsCommitIdPath()))) { + String msg; if (isSettingsRepositorySymlinkOrJunction()) { - interaction( - "Updates are available for the settings repository. Please pull the latest changes by yourself or by calling \"ide -f update\" to apply them."); + msg = "Updates are available for the settings repository. Please pull the latest changes by yourself or by calling \"ide -f update\" to apply them."; } else { - interaction( - "Updates are available for the settings repository. If you want to apply the latest changes, call \"ide update\""); + msg = "Updates are available for the settings repository. If you want to apply the latest changes, call \"ide update\""; } + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), msg); } } } @@ -1275,7 +1256,7 @@ settingsRepository, getSettingsCommitIdPath()))) { } } } else { - trace("Commandlet did not match"); + LOG.trace("Commandlet did not match"); } return result; } @@ -1296,13 +1277,11 @@ private boolean ensureLicenseAgreement(Commandlet cmd) { // printing anything anymore in such case. return false; } - boolean logLevelInfoDisabled = !this.startContext.info().isEnabled(); - if (logLevelInfoDisabled) { - this.startContext.setLogLevel(IdeLogLevel.INFO, true); - } - boolean logLevelInteractionDisabled = !this.startContext.interaction().isEnabled(); - if (logLevelInteractionDisabled) { - this.startContext.setLogLevel(IdeLogLevel.INTERACTION, true); + IdeLogLevel oldLogLevel = this.startContext.getLogLevel(); + IdeLogLevel newLogLevel = oldLogLevel; + if (oldLogLevel.ordinal() > IdeLogLevel.INFO.ordinal()) { + newLogLevel = IdeLogLevel.INFO; + this.startContext.setLogLevel(newLogLevel); } StringBuilder sb = new StringBuilder(1180); sb.append(LOGO).append(""" @@ -1320,7 +1299,7 @@ This product (with its included 3rd party components) is open-source software an sb.append("\n\nAlso it is included in the documentation that you can find here:\n"). append(getIdePath().resolve("IDEasy.pdf").toString()).append("\n"); } - info(sb.toString()); + LOG.info(sb.toString()); askToContinue("Do you accept these terms of use and all license agreements?"); sb.setLength(0); @@ -1332,11 +1311,8 @@ This product (with its included 3rd party components) is open-source software an } catch (Exception e) { throw new RuntimeException("Failed to save license agreement!", e); } - if (logLevelInfoDisabled) { - this.startContext.setLogLevel(IdeLogLevel.INFO, false); - } - if (logLevelInteractionDisabled) { - this.startContext.setLogLevel(IdeLogLevel.INTERACTION, false); + if (oldLogLevel != newLogLevel) { + this.startContext.setLogLevel(oldLogLevel); } return true; } @@ -1355,7 +1331,7 @@ public void verifyIdeMinVersion(boolean throwException) { if (throwException) { throw new CliException(message); } else { - warning(message); + LOG.warn(message); } } } @@ -1395,7 +1371,7 @@ public List complete(CliArguments arguments, boolean includ private void completeCommandlet(CliArguments arguments, Commandlet cmd, CompletionCandidateCollector collector) { - trace("Trying to match arguments for auto-completion for commandlet {}", cmd.getName()); + LOG.trace("Trying to match arguments for auto-completion for commandlet {}", cmd.getName()); Iterator> valueIterator = cmd.getValues().iterator(); valueIterator.next(); // skip first property since this is the keyword property that already matched to find the commandlet List> properties = cmd.getProperties(); @@ -1408,7 +1384,7 @@ private void completeCommandlet(CliArguments arguments, Commandlet cmd, Completi } CliArgument currentArgument = arguments.current(); while (!currentArgument.isEnd()) { - trace("Trying to match argument '{}'", currentArgument); + LOG.trace("Trying to match argument '{}'", currentArgument); if (currentArgument.isOption() && !arguments.isEndOptions()) { if (currentArgument.isCompletion()) { Iterator> optionIterator = optionProperties.iterator(); @@ -1430,7 +1406,7 @@ private void completeCommandlet(CliArguments arguments, Commandlet cmd, Completi } } if (option == null) { - trace("No such option was found."); + LOG.trace("No such option was found."); return; } } @@ -1439,11 +1415,11 @@ private void completeCommandlet(CliArguments arguments, Commandlet cmd, Completi Property valueProperty = valueIterator.next(); boolean success = valueProperty.apply(arguments, this, cmd, collector); if (!success) { - trace("Completion cannot match any further."); + LOG.trace("Completion cannot match any further."); return; } } else { - trace("No value left for completion."); + LOG.trace("No value left for completion."); return; } } @@ -1459,7 +1435,7 @@ private void completeCommandlet(CliArguments arguments, Commandlet cmd, Completi */ public ValidationResult apply(CliArguments arguments, Commandlet cmd) { - trace("Trying to match arguments to commandlet {}", cmd.getName()); + LOG.trace("Trying to match arguments to commandlet {}", cmd.getName()); CliArgument currentArgument = arguments.current(); Iterator> propertyIterator = cmd.getValues().iterator(); Property property = null; @@ -1467,7 +1443,7 @@ public ValidationResult apply(CliArguments arguments, Commandlet cmd) { property = propertyIterator.next(); } while (!currentArgument.isEnd()) { - trace("Trying to match argument '{}'", currentArgument); + LOG.trace("Trying to match argument '{}'", currentArgument); Property currentProperty = property; if (!arguments.isEndOptions()) { Property option = cmd.getOption(currentArgument.getKey()); @@ -1476,12 +1452,12 @@ public ValidationResult apply(CliArguments arguments, Commandlet cmd) { } } if (currentProperty == null) { - trace("No option or next value found"); + LOG.trace("No option or next value found"); ValidationState state = new ValidationState(null); state.addErrorMessage("No matching property found"); return state; } - trace("Next property candidate to match argument is {}", currentProperty); + LOG.trace("Next property candidate to match argument is {}", currentProperty); if (currentProperty == property) { if (!property.isMultiValued()) { if (propertyIterator.hasNext()) { @@ -1521,7 +1497,7 @@ public Path findBash() { } } if (bashPath == null) { - error("No bash executable could be found on your system."); + LOG.error("No bash executable could be found on your system."); } else { this.bash = bashPath; } @@ -1529,21 +1505,21 @@ public Path findBash() { } private Path findBashOnBashPath() { - trace("Trying to find BASH_PATH environment variable."); + LOG.trace("Trying to find BASH_PATH environment variable."); Path bash; String bashPathVariableName = IdeVariables.BASH_PATH.getName(); String bashVariable = getVariables().get(bashPathVariableName); if (bashVariable != null) { bash = Path.of(bashVariable); if (Files.exists(bash)) { - debug("{} environment variable was found and points to: {}", bashPathVariableName, bash); + LOG.debug("{} environment variable was found and points to: {}", bashPathVariableName, bash); return bash; } else { - error("The environment variable {} points to a non existing file: {}", bashPathVariableName, bash); + LOG.error("The environment variable {} points to a non existing file: {}", bashPathVariableName, bash); return null; } } else { - debug("{} environment variable was not found", bashPathVariableName); + LOG.debug("{} environment variable was not found", bashPathVariableName); return null; } } @@ -1564,7 +1540,7 @@ private boolean checkPathToIgnoreLowercase(Path path, String toIgnore) { * @return Path to bash.exe if found in PATH environment variable, {@code null} if bash.exe was not found. */ private Path findBashInPath() { - trace("Trying to find bash in PATH environment variable."); + LOG.trace("Trying to find bash in PATH environment variable."); Path bash; String pathVariableName = IdeVariables.PATH.getName(); if (pathVariableName != null) { @@ -1574,20 +1550,20 @@ private Path findBashInPath() { Path bashPath = getPath().findBinary(plainBash, pathsToIgnore); bash = bashPath.toAbsolutePath(); if (bashPath.equals(plainBash)) { - warning("No usable bash executable was found in your PATH environment variable!"); + LOG.warn("No usable bash executable was found in your PATH environment variable!"); bash = null; } else { if (Files.exists(bashPath)) { - debug("A proper bash executable was found in your PATH environment variable at: {}", bash); + LOG.debug("A proper bash executable was found in your PATH environment variable at: {}", bash); } else { bash = null; - error("A path to a bash executable was found in your PATH environment variable at: {} but the file is not existing.", bash); + LOG.error("A path to a bash executable was found in your PATH environment variable at: {} but the file is not existing.", bash); } } } else { bash = null; // this should never happen... - error("PATH environment variable was not found"); + LOG.error("PATH environment variable was not found"); } return bash; } @@ -1598,14 +1574,14 @@ private Path findBashInPath() { * @return Path to bash.exe if found in registry, {@code null} if bash.exe was found. */ protected Path findBashInWindowsRegistry() { - trace("Trying to find bash in Windows registry"); + LOG.trace("Trying to find bash in Windows registry"); // If not found in the default location, try the registry query String[] bashVariants = { "GitForWindows", "Cygwin\\setup" }; String[] registryKeys = { "HKEY_LOCAL_MACHINE", "HKEY_CURRENT_USER" }; for (String bashVariant : bashVariants) { - trace("Trying to find bash variant: {}", bashVariant); + LOG.trace("Trying to find bash variant: {}", bashVariant); for (String registryKey : registryKeys) { - trace("Trying to find bash from registry key: {}", registryKey); + LOG.trace("Trying to find bash from registry key: {}", registryKey); String toolValueName = ("GitForWindows".equals(bashVariant)) ? "InstallPath" : "rootdir"; String registryPath = registryKey + "\\Software\\" + bashVariant; @@ -1613,14 +1589,14 @@ protected Path findBashInWindowsRegistry() { if (path != null) { Path bashPath = Path.of(path + "\\bin\\bash.exe"); if (Files.exists(bashPath)) { - debug("Found bash at: {}", bashPath); + LOG.debug("Found bash at: {}", bashPath); return bashPath; } else { - error("Found bash at: {} but it is not pointing to an existing file", bashPath); + LOG.error("Found bash at: {} but it is not pointing to an existing file", bashPath); return null; } } else { - info("No bash executable could be found in the Windows registry."); + LOG.info("No bash executable could be found in the Windows registry."); } } } @@ -1630,13 +1606,13 @@ protected Path findBashInWindowsRegistry() { private Path findBashOnWindowsDefaultGitPath() { // Check if Git Bash exists in the default location - trace("Trying to find bash on the Windows default git path."); + LOG.trace("Trying to find bash on the Windows default git path."); Path defaultPath = Path.of(getDefaultWindowsGitPath()); if (!defaultPath.toString().isEmpty() && Files.exists(defaultPath)) { - trace("Found default path to git bash on Windows at: {}", getDefaultWindowsGitPath()); + LOG.trace("Found default path to git bash on Windows at: {}", getDefaultWindowsGitPath()); return defaultPath; } - debug("No bash was found on the Windows default git path."); + LOG.debug("No bash was found on the Windows default git path."); return null; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java index 6accb0dfac..58f317bd3e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java @@ -230,7 +230,7 @@ default boolean isOnline() { */ default void printLogo() { - info(LOGO); + AbstractIdeContext.LOG.info(LOGO); } /** @@ -538,7 +538,8 @@ default Path getSettingsTemplatePath() { if (Files.isDirectory(templatesFolderLegacy)) { templatesFolder = templatesFolderLegacy; } else { - warning("No templates found in settings git repo neither in {} nor in {} - configuration broken", templatesFolder, templatesFolderLegacy); + AbstractIdeContext.LOG.warn("No templates found in settings git repo neither in {} nor in {} - configuration broken", templatesFolder, + templatesFolderLegacy); return null; } } @@ -831,4 +832,5 @@ default Path getNpmConfigUserConfig() { Npm npm = getCommandletManager().getCommandlet(Npm.class); return npm.getOrCreateNpmConfigUserConfig(); } + } diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContextConsole.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContextConsole.java index a04ea542f1..10e386d1eb 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContextConsole.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContextConsole.java @@ -2,35 +2,20 @@ import java.util.Scanner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.io.IdeProgressBar; import com.devonfw.tools.ide.io.IdeProgressBarConsole; -import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeSubLoggerOut; /** * Default implementation of {@link IdeContext} using the console. */ public class IdeContextConsole extends AbstractIdeContext { - private final Scanner scanner; - - /** - * The constructor. - * - * @param minLogLevel the minimum {@link IdeLogLevel} to enable. Should be {@link IdeLogLevel#INFO} by default. - * @param out the {@link Appendable} to {@link Appendable#append(CharSequence) write} log messages to. - * @param colored - {@code true} for colored output according to {@link IdeLogLevel}, {@code false} otherwise. - */ - public IdeContextConsole(IdeLogLevel minLogLevel, Appendable out, boolean colored) { + private static final Logger LOG = LoggerFactory.getLogger(IdeContextConsole.class); - super(new IdeStartContextImpl(minLogLevel, level -> new IdeSubLoggerOut(level, out, colored, minLogLevel, null)), null); - if (System.console() == null) { - debug("System console not available - using System.in as fallback"); - this.scanner = new Scanner(System.in); - } else { - this.scanner = null; - } - } + private final Scanner scanner; /** * The constructor. @@ -41,7 +26,7 @@ public IdeContextConsole(IdeStartContextImpl startContext) { super(startContext, null); if (System.console() == null) { - debug("System console not available - using System.in as fallback"); + LOG.debug("System console not available - using System.in as fallback"); this.scanner = new Scanner(System.in); } else { this.scanner = null; diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContext.java index 97e61f6677..5d6d13f57b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContext.java @@ -2,15 +2,27 @@ import java.util.Locale; -import com.devonfw.tools.ide.log.IdeLogger; +import com.devonfw.tools.ide.log.IdeLogLevel; +import com.devonfw.tools.ide.log.IdeLogListener; import com.devonfw.tools.ide.network.ReadOfflineMode; /** - * Extends {@link IdeLogger} with the options configurable via {@link com.devonfw.tools.ide.cli.Ideasy} CLI (see - * {@link com.devonfw.tools.ide.commandlet.ContextCommandlet}). The {@link IdeStartContext} is therefore the object configured at bootstrapping and then used to - * create the actual {@link IdeContext} from it. + * Contains the options configurable via {@link com.devonfw.tools.ide.cli.Ideasy} CLI. The {@link IdeStartContext} is therefore the object configured at + * bootstrapping and then used to create the actual {@link IdeContext} from it. + * + * @see com.devonfw.tools.ide.commandlet.ContextCommandlet */ -public interface IdeStartContext extends IdeLogger, ReadOfflineMode { +public interface IdeStartContext extends ReadOfflineMode { + + /** + * @return the {@link IdeLogListener}. + */ + IdeLogListener getLogListener(); + + /** + * @return the minimum allowed {@link IdeLogLevel} (threshold). + */ + IdeLogLevel getLogLevel(); /** * @return {@code true} in case of quiet mode (reduced output), {@code false} otherwise. diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java index eb00d5f226..048b040856 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java @@ -1,17 +1,24 @@ package com.devonfw.tools.ide.context; import java.util.Locale; -import java.util.function.Function; -import com.devonfw.tools.ide.log.AbstractIdeSubLogger; +import com.devonfw.tools.ide.log.IdeLogArgFormatter; import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeLoggerImpl; -import com.devonfw.tools.ide.log.IdeSubLogger; +import com.devonfw.tools.ide.log.IdeLogListener; +import com.devonfw.tools.ide.log.IdeLogListenerBuffer; /** * Implementation of {@link IdeStartContext}. */ -public class IdeStartContextImpl extends IdeLoggerImpl implements IdeStartContext { +public class IdeStartContextImpl implements IdeStartContext { + + private static IdeStartContextImpl instance; + + protected final IdeLogListener logListener; + + private IdeLogLevel logLevel; + + private IdeLogArgFormatter argFormatter; private boolean skipUpdatesMode; @@ -38,12 +45,88 @@ public class IdeStartContextImpl extends IdeLoggerImpl implements IdeStartContex private Locale locale; /** - * @param minLogLevel the minimum enabled {@link IdeLogLevel}. - * @param factory the factory to create active {@link IdeSubLogger} instances. + * @param logLevel the minimum enabled {@link #getLogLevel() log level}. + * @param logListener the {@link #getLogListener() logListener}. */ - public IdeStartContextImpl(IdeLogLevel minLogLevel, Function factory) { + public IdeStartContextImpl(IdeLogLevel logLevel, IdeLogListener logListener) { - super(minLogLevel, factory); + super(); + this.logLevel = logLevel; + this.logListener = logListener; + this.argFormatter = IdeLogArgFormatter.DEFAULT; + IdeStartContextImpl.instance = this; + } + + @Override + public IdeLogListener getLogListener() { + + return this.logListener; + } + + @Override + public IdeLogLevel getLogLevel() { + + return this.logLevel; + } + + /** + * Sets the log level. + * + * @param logLevel {@link IdeLogLevel} + * @return the previous set logLevel {@link IdeLogLevel} + */ + public IdeLogLevel setLogLevel(IdeLogLevel logLevel) { + + IdeLogLevel previousLogLevel = this.logLevel; + if ((previousLogLevel == null) || (previousLogLevel.ordinal() > IdeLogLevel.INFO.ordinal())) { + previousLogLevel = IdeLogLevel.INFO; + } + this.logLevel = logLevel; + return previousLogLevel; + } + + /** + * @return the {@link IdeLogArgFormatter}. + */ + public IdeLogArgFormatter getArgFormatter() { + + return this.argFormatter; + } + + /** + * Internal method to set the {@link IdeLogArgFormatter}. + * + * @param argFormatter the new {@link IdeLogArgFormatter}. + */ + public void setArgFormatter(IdeLogArgFormatter argFormatter) { + + this.argFormatter = argFormatter; + } + + /** + * Ensure the logging system is initialized. + */ + public void activateLogging() { + + if (this.logListener instanceof IdeLogListenerBuffer buffer) { + // https://github.com/devonfw/IDEasy/issues/754 + buffer.flushAndEndBuffering(); + } + } + + /** + * Disables the logging system (temporary). + * + * @param threshold the {@link IdeLogLevel} acting as threshold. + * @see com.devonfw.tools.ide.context.IdeContext#runWithoutLogging(Runnable, IdeLogLevel) + */ + public void deactivateLogging(IdeLogLevel threshold) { + + if (this.logListener instanceof IdeLogListenerBuffer buffer) { + buffer.startBuffering(threshold); + } else { + throw new IllegalStateException(); + } } @Override @@ -196,7 +279,6 @@ public boolean isNoColorsMode() { public void setNoColorsMode(boolean noColoursMode) { this.noColorsMode = noColoursMode; - setLogColors(!noColoursMode); } /** @@ -214,4 +296,12 @@ public void setWriteLogfile(boolean writeLogfile) { this.writeLogfile = writeLogfile; } + /** + * @return the current {@link IdeStartContextImpl} instance. + */ + public static IdeStartContextImpl get() { + + return instance; + } + } diff --git a/cli/src/main/java/com/devonfw/tools/ide/environment/AbstractEnvironmentVariables.java b/cli/src/main/java/com/devonfw/tools/ide/environment/AbstractEnvironmentVariables.java index bce471f30d..6b12926a1f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/environment/AbstractEnvironmentVariables.java +++ b/cli/src/main/java/com/devonfw/tools/ide/environment/AbstractEnvironmentVariables.java @@ -7,8 +7,11 @@ import java.util.Map; import java.util.regex.Matcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.event.Level; + import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.variable.IdeVariables; import com.devonfw.tools.ide.variable.VariableDefinition; import com.devonfw.tools.ide.variable.VariableSyntax; @@ -19,6 +22,8 @@ */ public abstract class AbstractEnvironmentVariables implements EnvironmentVariables { + private static final Logger LOG = LoggerFactory.getLogger(AbstractEnvironmentVariables.class); + /** * When we replace variable expressions with their value the resulting {@link String} can change in size (shrink or grow). By adding a bit of extra capacity * we reduce the chance that the capacity is too small and a new buffer array has to be allocated and array-copy has to be performed. @@ -225,15 +230,15 @@ private String resolveWithSyntax(final String value, final Object src, final int String variableName = syntax.getVariable(matcher); String variableValue = resolvedVars.getValue(variableName, false); if (variableValue == null) { - IdeLogLevel logLevel = IdeLogLevel.WARNING; + Level logLevel = Level.WARN; if (context.legacySupport && (syntax == VariableSyntax.CURLY)) { - logLevel = IdeLogLevel.INFO; + logLevel = Level.INFO; } String var = matcher.group(); if (recursion > 1) { - this.context.level(logLevel).log("Undefined variable {} in '{}' at '{}={}'", var, context.rootSrc, src, value); + LOG.atLevel(logLevel).log("Undefined variable {} in '{}' at '{}={}'", var, context.rootSrc, src, value); } else { - this.context.level(logLevel).log("Undefined variable {} in '{}'", var, src); + LOG.atLevel(logLevel).log("Undefined variable {} in '{}'", var, src); } continue; } @@ -265,8 +270,7 @@ private String resolveWithSyntax(final String value, final Object src, final int } while (matcher.find()); matcher.appendTail(sb); - String resolved = sb.toString(); - return resolved; + return sb.toString(); } /** @@ -307,7 +311,6 @@ protected String getValue(String name, boolean ignoreDefaultValue) { public String inverseResolve(String string, Object src, VariableSyntax syntax) { String result = string; - // TODO add more variables to IdeVariables like JAVA_HOME for (VariableDefinition variable : IdeVariables.VARIABLES) { if (variable != IdeVariables.PATH) { String name = variable.getName(); @@ -321,7 +324,7 @@ public String inverseResolve(String string, Object src, VariableSyntax syntax) { } } if (!result.equals(string)) { - this.context.trace("Inverse resolved '{}' to '{}' from {}.", string, result, src); + LOG.trace("Inverse resolved '{}' to '{}' from {}.", string, result, src); } return result; } @@ -334,7 +337,7 @@ public VersionIdentifier getToolVersion(String tool) { if (value == null) { return VersionIdentifier.LATEST; } else if (value.isEmpty()) { - this.context.warning("Variable {} is configured with empty value, please fix your configuration.", variable); + LOG.warn("Variable {} is configured with empty value, please fix your configuration.", variable); return VersionIdentifier.LATEST; } VersionIdentifier version = VersionIdentifier.of(value); diff --git a/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesMap.java b/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesMap.java index 71ad26a6fb..a823229bb1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesMap.java +++ b/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesMap.java @@ -2,6 +2,9 @@ import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.os.WindowsPathSyntax; @@ -10,6 +13,8 @@ */ abstract class EnvironmentVariablesMap extends AbstractEnvironmentVariables { + private static final Logger LOG = LoggerFactory.getLogger(EnvironmentVariablesMap.class); + /** * The constructor. * @@ -31,14 +36,14 @@ public String getFlat(String name) { String value = getVariables().get(name); if (value == null) { - this.context.trace("{}: Variable {} is undefined.", getSource(), name); + LOG.trace("{}: Variable {} is undefined.", getSource(), name); } else { - this.context.trace("{}: Variable {}={}", getSource(), name, value); + LOG.trace("{}: Variable {}={}", getSource(), name, value); WindowsPathSyntax pathSyntax = this.context.getPathSyntax(); if (pathSyntax != null) { String normalized = pathSyntax.normalize(value); if (!value.equals(normalized)) { - this.context.trace("Normalized {} using {} to {}", value, pathSyntax, normalized); + LOG.trace("Normalized {} using {} to {}", value, pathSyntax, normalized); value = normalized; } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFile.java b/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFile.java index a16baef36d..092b0423d7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFile.java +++ b/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFile.java @@ -132,7 +132,7 @@ private boolean load(Path file) { do { line = reader.readLine(); if (line != null) { - VariableLine variableLine = VariableLine.of(line, this.context, getSource()); + VariableLine variableLine = VariableLine.of(line, getSource()); String name = variableLine.getName(); if (name != null) { VariableLine migratedVariableLine = migrateLine(variableLine, false); @@ -241,7 +241,7 @@ private List loadVariableLines(Path file) { do { line = reader.readLine(); if (line != null) { - VariableLine variableLine = VariableLine.of(line, this.context, getSource()); + VariableLine variableLine = VariableLine.of(line, getSource()); lines.add(variableLine); } } while (line != null); @@ -341,9 +341,9 @@ public String set(String name, String value, boolean export) { String oldValue = this.variables.put(name, value); boolean flagChanged = export != this.exportedVariables.contains(name); if (Objects.equals(value, oldValue) && !flagChanged) { - this.context.trace("Set variable '{}={}' caused no change in {}", name, value, this.propertiesFilePath); + LOG.trace("Set variable '{}={}' caused no change in {}", name, value, this.propertiesFilePath); } else { - this.context.debug("Set variable '{}={}' in {}", name, value, this.propertiesFilePath); + LOG.debug("Set variable '{}={}' in {}", name, value, this.propertiesFilePath); this.modifiedVariables.add(name); if (export && (value != null)) { this.exportedVariables.add(name); @@ -364,7 +364,7 @@ public void remove(String name) { if (oldValue != null) { this.modifiedVariables.add(name); this.exportedVariables.remove(name); - this.context.debug("Removed variable name of '{}' in {}", name, this.propertiesFilePath); + LOG.debug("Removed variable name of '{}' in {}", name, this.propertiesFilePath); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/environment/VariableLine.java b/cli/src/main/java/com/devonfw/tools/ide/environment/VariableLine.java index c26539a996..4f807f1b4a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/environment/VariableLine.java +++ b/cli/src/main/java/com/devonfw/tools/ide/environment/VariableLine.java @@ -3,8 +3,8 @@ import java.util.Arrays; import java.util.List; -import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.log.IdeLogger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Container that represents a line from a properties (ide.properties) file. We do not use {@link java.util.Properties} as we need support for exported @@ -12,6 +12,8 @@ */ public abstract class VariableLine { + private static final Logger LOG = LoggerFactory.getLogger(VariableLine.class); + /** * @return {@code true} if the variable is exported (e.g. "export MAVEN_OPTS=-Xmx20248m"), {@code false} otherwise. */ @@ -81,7 +83,7 @@ public VariableLine withExport(boolean newExport) { static final class Variable extends VariableLine { - private boolean export; + private final boolean export; private final String name; @@ -239,11 +241,10 @@ public String toString() { * Parses a {@link VariableLine} from {@link String}. * * @param line the {@link VariableLine} as {@link String} to parse. - * @param logger the {@link IdeLogger}. * @param source the source where the given {@link String} to parse is from (e.g. the file path). * @return the parsed {@link VariableLine}. */ - public static VariableLine of(String line, IdeLogger logger, VariableSource source) { + public static VariableLine of(String line, VariableSource source) { int len = line.length(); int start = 0; @@ -291,7 +292,7 @@ public static VariableLine of(String line, IdeLogger logger, VariableSource sour } end++; } - logger.warning("Ignoring corrupted line '{}' in {}", line, source); + LOG.warn("Ignoring corrupted line '{}' in {}", line, source); return new Garbage(line); } @@ -331,7 +332,6 @@ public static boolean isBashArray(String value) { * Returns a list of String Variables. * * @param value String to parse - * @param context the {@link IdeContext} for logging warnings (may be {@code null}). * @return List of variables. */ public static List parseArray(String value) { @@ -346,9 +346,9 @@ public static List parseArray(String value) { } } return Arrays.stream(csv.split(separator)) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .toList(); + .map(String::trim) + .filter(s -> !s.isEmpty()) + .toList(); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/git/GitOperation.java b/cli/src/main/java/com/devonfw/tools/ide/git/GitOperation.java index a682ae4c45..6eed32cbda 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/git/GitOperation.java +++ b/cli/src/main/java/com/devonfw/tools/ide/git/GitOperation.java @@ -4,6 +4,9 @@ import java.nio.file.Path; import java.time.Duration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; /** @@ -35,6 +38,8 @@ protected boolean execute(IdeContext context, GitUrl gitUrl, Path targetReposito } }; + private static final Logger LOG = LoggerFactory.getLogger(GitOperation.class); + private final String name; private final String timestampFilename; @@ -127,12 +132,12 @@ boolean executeIfNeeded(IdeContext context, GitUrl gitUrl, Path targetRepository try { context.getFileAccess().touch(timestampPath); } catch (IllegalStateException e) { - context.warning(e.getMessage()); + LOG.warn(e.getMessage()); } } return result; } else { - context.trace("Skipped git {}.", this.name); + LOG.trace("Skipped git {}.", this.name); return false; } } @@ -146,16 +151,16 @@ private boolean isNeeded(Path targetRepository, IdeContext context) { return true; } if (context.isOffline()) { - context.info("Skipping git {} on {} because we are offline.", this.name, targetRepository); + LOG.info("Skipping git {} on {} because we are offline.", this.name, targetRepository); return false; } else if (context.isForceMode() || context.isForcePull()) { - context.debug("Enforcing git {} on {} because force mode is active.", this.name, targetRepository); + LOG.debug("Enforcing git {} on {} because force mode is active.", this.name, targetRepository); return true; } if (!hasGitDirectory) { if (isRequireGitFolder()) { if (context.getSettingsGitRepository() == null) { - context.warning("Missing .git folder in {}.", targetRepository); + LOG.warn("Missing .git folder in {}.", targetRepository); } } else { logEnforceGitOperationBecauseGitFolderNotPresent(targetRepository, context); @@ -164,17 +169,17 @@ private boolean isNeeded(Path targetRepository, IdeContext context) { } Path timestampFilePath = gitDirectory.resolve(this.timestampFilename); if (context.getFileAccess().isFileAgeRecent(timestampFilePath, this.cacheDuration)) { - context.debug("Skipping git {} on {} because last fetch was just recently to avoid overhead.", this.name, + LOG.debug("Skipping git {} on {} because last fetch was just recently to avoid overhead.", this.name, targetRepository); return false; } else { - context.debug("Will need to do git {} on {} because last fetch was some time ago.", this.name, targetRepository); + LOG.debug("Will need to do git {} on {} because last fetch was some time ago.", this.name, targetRepository); return true; } } private void logEnforceGitOperationBecauseGitFolderNotPresent(Path targetRepository, IdeContext context) { - context.debug("Enforcing git {} on {} because .git folder is not present.", this.name, targetRepository); + LOG.debug("Enforcing git {} on {} because .git folder is not present.", this.name, targetRepository); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryProperties.java b/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryProperties.java index f9e07cc526..e6db096b76 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryProperties.java +++ b/cli/src/main/java/com/devonfw/tools/ide/git/repository/RepositoryProperties.java @@ -10,6 +10,9 @@ import java.util.Set; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.context.IdeContext; @@ -18,12 +21,12 @@ */ final class RepositoryProperties { + private static final Logger LOG = LoggerFactory.getLogger(RepositoryProperties.class); + private final Path file; private final Properties properties; - private final IdeContext context; - /** * The constructor. * @@ -31,19 +34,17 @@ final class RepositoryProperties { * @param context the {@link IdeContext}. */ public RepositoryProperties(Path file, IdeContext context) { - this(file, context, context.getFileAccess().readProperties(file)); + this(file, context.getFileAccess().readProperties(file)); } /** * @param file the {@link Path} to the properties file. - * @param context the {@link IdeContext}. * @param properties the actual {@link Properties} loaded from the file. */ - RepositoryProperties(Path file, IdeContext context, Properties properties) { + RepositoryProperties(Path file, Properties properties) { super(); this.file = file; this.properties = properties; - this.context = context; } /** @@ -90,7 +91,7 @@ private String getLegacyProperty(String legacyName, String name) { String value = this.properties.getProperty(legacyName); if (value != null) { - this.context.warning("The properties file {} uses the legacy property {} instead of {}", this.file, legacyName, name); + LOG.warn("The properties file {} uses the legacy property {} instead of {}", this.file, legacyName, name); } return value; } @@ -110,7 +111,7 @@ public Set getImports() { String legacyImportProperty = getLegacyProperty(RepositoryConfig.PROPERTY_ECLIPSE, RepositoryConfig.PROPERTY_IMPORT); if ("import".equals(legacyImportProperty)) { - this.context.warning("Property {} is deprecated and should be replaced with {} (invert key and value).", RepositoryConfig.PROPERTY_ECLIPSE, + LOG.warn("Property {} is deprecated and should be replaced with {} (invert key and value).", RepositoryConfig.PROPERTY_ECLIPSE, RepositoryConfig.PROPERTY_IMPORT); return Set.of("eclipse"); } else { @@ -127,7 +128,7 @@ public List getWorkspaces() { if (workspaceProperty == null) { workspaceProperty = this.properties.getProperty("workspace"); if (workspaceProperty != null) { - this.context.debug("Property workspace is legacy, please change property name to workspaces in {}", this.file); + LOG.debug("Property workspace is legacy, please change property name to workspaces in {}", this.file); } } if ((workspaceProperty != null) && !workspaceProperty.isEmpty()) { @@ -139,7 +140,7 @@ public List getWorkspaces() { if (added) { list.add(workspace); } else { - this.context.warning("Ignoring duplicate workspace {} from {}", workspace, workspaceProperty); + LOG.warn("Ignoring duplicate workspace {} from {}", workspace, workspaceProperty); } } return Collections.unmodifiableList(list); diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java b/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java deleted file mode 100644 index 0a2f308d7b..0000000000 --- a/cli/src/main/java/com/devonfw/tools/ide/log/AbstractIdeSubLogger.java +++ /dev/null @@ -1,203 +0,0 @@ -package com.devonfw.tools.ide.log; - -import com.devonfw.tools.ide.cli.CliException; - -/** - * Abstract base implementation of {@link IdeSubLogger}. - */ -public abstract class AbstractIdeSubLogger implements IdeSubLogger { - - /** @see #getLevel() */ - protected final IdeLogLevel level; - - protected final IdeLogExceptionDetails exceptionDetails; - - final IdeLogListener listener; - - protected boolean colored; - - private boolean enabled; - - private IdeLogArgFormatter argFormatter; - - /** - * The constructor. - * - * @param level the {@link #getLevel() log-level}. - * @param colored - see {@link #isColored()}. - * @param exceptionDetails the {@link IdeLogExceptionDetails} configuring how to handle exceptions. - * @param listener the {@link IdeLogListener} to send log-events to. - */ - public AbstractIdeSubLogger(IdeLogLevel level, boolean colored, IdeLogExceptionDetails exceptionDetails, IdeLogListener listener) { - - super(); - this.level = level; - this.exceptionDetails = exceptionDetails; - this.argFormatter = IdeLogArgFormatter.DEFAULT; - if (listener == null) { - this.listener = IdeLogListenerNone.INSTANCE; - } else { - this.listener = listener; - } - this.colored = colored; - this.enabled = true; - } - - @Override - public IdeLogLevel getLevel() { - - return this.level; - } - - @Override - public boolean isEnabled() { - - return this.enabled; - } - - void setEnabled(boolean enabled) { - - this.enabled = enabled; - } - - void setColored(boolean colored) { - - this.colored = colored; - } - - /** - * Should only be used internally by logger implementation. - * - * @param message the message template. - * @param args the dynamic arguments to fill in. - * @return the resolved message with the parameters filled in. - */ - protected String compose(String message, Object... args) { - return compose(this.argFormatter, this::invalidMessage, message, args); - } - - /** - * Should only be used internally by logger implementation. - * - * @param message the message template. - * @param args the dynamic arguments to fill in. - * @return the resolved message with the parameters filled in. - */ - static String compose(IdeLogArgFormatter formatter, InvalidLogMessageHandler handler, String message, Object... args) { - - int pos = message.indexOf("{}"); - if (pos < 0) { - if (args.length > 0) { - handler.invalidMessage(message, false, args); - } - return message; - } - int argIndex = 0; - int start = 0; - int length = message.length(); - StringBuilder sb = new StringBuilder(length + 48); - while (pos >= 0) { - sb.append(message, start, pos); - sb.append(formatter.formatArgument(args[argIndex++])); - start = pos + 2; - pos = message.indexOf("{}", start); - if ((argIndex >= args.length) && (pos > 0)) { - handler.invalidMessage(message, true, args); - pos = -1; - } - } - if (start < length) { - String rest = message.substring(start); - sb.append(rest); - } - if (argIndex < args.length) { - handler.invalidMessage(message, false, args); - } - return sb.toString(); - } - - private void invalidMessage(String message, boolean more, Object[] args) { - - warning("Invalid log message with " + args.length + " argument(s) but " + (more ? "more" : "less") - + " placeholders: " + message); - } - - private void warning(String message) { - - boolean colored = isColored(); - if (colored) { - System.err.print(IdeLogLevel.ERROR.getEndColor()); - System.err.print(IdeLogLevel.ERROR.getStartColor()); - } - System.err.println(message); - if (colored) { - System.err.print(IdeLogLevel.ERROR.getEndColor()); - } - } - - /** - * @return {@code true} if colored logging is used, {@code false} otherwise. - */ - public boolean isColored() { - - return this.colored; - } - - @Override - public String log(Throwable error, String message, Object... args) { - - if (!this.enabled) { - // performance optimization: do not fill in arguments if disabled - return message; - } - String actualMessage = message; - if (error != null) { - if (isOmitStacktrace(error)) { - if (message == null) { - actualMessage = error.getMessage(); - } - error = null; - } else if (message == null) { - actualMessage = error.toString(); - } - } - if (actualMessage == null) { - actualMessage = "Internal error: Both message and error is null - nothing to log!"; - // fail fast if assertions are enabled, so developers of IDEasy will find the bug immediately but in productive use better log the error and continue - assert false : actualMessage; - } else if ((args != null) && (args.length > 0)) { - actualMessage = compose(actualMessage, args); - } - boolean accept = this.listener.onLog(this.level, actualMessage, message, args, error); - if (accept) { - doLog(actualMessage, error); - } - return actualMessage; - } - - private boolean isOmitStacktrace(Throwable error) { - - return (error instanceof CliException); - } - - /** - * @param message the formatted message to log. - * @param error the optional {@link Throwable} to log or {@code null} for no error. - */ - protected abstract void doLog(String message, Throwable error); - - /** - * @param argFormatter the new {@link IdeLogArgFormatter} to use. - */ - void setArgFormatter(IdeLogArgFormatter argFormatter) { - - this.argFormatter = argFormatter; - } - - @Override - public String toString() { - - return getClass().getSimpleName() + "@" + this.level; - } - -} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java index f36dd92acf..fee2ba376e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java @@ -4,45 +4,43 @@ import org.slf4j.MarkerFactory; import org.slf4j.event.Level; -import com.devonfw.tools.ide.context.IdeContext; - /** - * {@link Enum} with the available log-levels. + * {@link Enum} with the available log-levels for IDEasy. * - * @see IdeContext#level(IdeLogLevel) + * @see Slf4jLoggerAdapter */ public enum IdeLogLevel { /** {@link IdeLogLevel} for tracing (very detailed and verbose logging). */ - TRACE("\033[38;5;240m", Level.TRACE, null, java.util.logging.Level.FINER), + TRACE("\033[38;5;240m", Level.TRACE, null, JulLogLevel.TRACE), /** {@link IdeLogLevel} for debugging (more detailed logging). */ - DEBUG("\033[90m", Level.DEBUG, null, java.util.logging.Level.FINE), + DEBUG("\033[90m", Level.DEBUG, null, JulLogLevel.DEBUG), /** {@link IdeLogLevel} for general information (regular logging). */ - INFO(null, Level.INFO, null, java.util.logging.Level.INFO), + INFO(null, Level.INFO, null, JulLogLevel.INFO), /** * {@link IdeLogLevel} for a step (logs the step name and groups the following log statements until the next step). */ - STEP("\033[35m", Level.INFO, MarkerFactory.getMarker("step"), java.util.logging.Level.INFO), + STEP("\033[35m", Level.INFO, MarkerFactory.getMarker("STEP"), JulLogLevel.STEP), /** {@link IdeLogLevel} for user interaction (e.g. questions or options). */ - INTERACTION("\033[96m", Level.INFO, MarkerFactory.getMarker("interaction"), java.util.logging.Level.INFO), + INTERACTION("\033[96m", Level.INFO, MarkerFactory.getMarker("INTERACTION"), JulLogLevel.INTERACTION), /** {@link IdeLogLevel} for success (an important aspect has been completed successfully). */ - SUCCESS("\033[92m", Level.INFO, MarkerFactory.getMarker("success"), java.util.logging.Level.INFO), + SUCCESS("\033[92m", Level.INFO, MarkerFactory.getMarker("SUCCESS"), JulLogLevel.SUCCESS), /** {@link IdeLogLevel} for a warning (something unexpected or abnormal happened but can be compensated). */ - WARNING("\033[93m", Level.WARN, null, java.util.logging.Level.WARNING), + WARNING("\033[93m", Level.WARN, null, JulLogLevel.WARNING), /** * {@link IdeLogLevel} for an error (something failed and we cannot proceed or the user has to continue with extreme care). */ - ERROR("\033[91m", Level.ERROR, null, java.util.logging.Level.SEVERE), + ERROR("\033[91m", Level.ERROR, null, JulLogLevel.ERROR), /** {@link IdeLogLevel} for {@link com.devonfw.tools.ide.commandlet.Commandlet#isProcessableOutput() processable output} */ - PROCESSABLE(null, Level.INFO, MarkerFactory.getMarker("processable"), java.util.logging.Level.INFO); + PROCESSABLE(null, Level.INFO, MarkerFactory.getMarker("PROCESSABLE"), JulLogLevel.PROCESSABLE); private final String color; @@ -148,19 +146,16 @@ public static IdeLogLevel of(Level level, Marker marker) { } /** - * @param level the SLF4J log {@link Level}. - * @param marker the SLF4J {@link Marker}. + * @param level the JUL {@link Level}. * @return the {@link IdeLogLevel}. */ - public static java.util.logging.Level convertLevelFromSlf4jToJul(Level level, Marker marker) { + public static IdeLogLevel of(java.util.logging.Level level) { - return switch (level) { - case ERROR -> java.util.logging.Level.SEVERE; - case WARN -> java.util.logging.Level.WARNING; - case INFO -> java.util.logging.Level.INFO; - case DEBUG -> java.util.logging.Level.FINE; - case TRACE -> java.util.logging.Level.FINER; - default -> throw new IllegalStateException("" + level); - }; + for (IdeLogLevel ideLevel : values()) { + if (ideLevel.julLevel == level) { + return ideLevel; + } + } + throw new IllegalStateException("" + level); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java index b7dc7a1f35..68f0944070 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java @@ -3,6 +3,11 @@ import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.spi.LoggingEventBuilder; + /** * Implements {@link IdeLogListener} to buffer log events during bootstrapping and then flush them once the logger is properly configured. * @@ -10,6 +15,8 @@ */ public class IdeLogListenerBuffer implements IdeLogListener { + private static final Logger LOG = LoggerFactory.getLogger(IdeLogListenerBuffer.class); + protected final List buffer; protected IdeLogLevel threshold; @@ -49,26 +56,33 @@ protected boolean isBuffering() { } /** - * This method is supposed to be called once after the {@link IdeLogger} has been properly initialized or after invocation of - * {@link #startBuffering(IdeLogLevel)}. - * - * @param logger the initialized {@link IdeLogger}. + * This method is supposed to be called once after invocation of {@link #startBuffering(IdeLogLevel)}. */ - public void flushAndEndBuffering(IdeLogger logger) { + public void flushAndEndBuffering() { // disable buffering further log events this.buffering = false; // write all cached log events to the logger again for processing for (IdeLogEntry entry : this.buffer) { - logger.level(entry.level()).log(entry.error(), entry.message()); + IdeLogLevel level = entry.level(); + LoggingEventBuilder builder = LOG.atLevel(level.getSlf4jLevel()); + Marker marker = level.getSlf4jMarker(); + if (marker != null) { + builder = builder.addMarker(marker); + } + builder = builder.setCause(entry.error()); + if (entry.args() != null) { + builder.log(entry.rawMessage(), entry.args()); + } else { + builder.log(entry.rawMessage()); + } } this.buffer.clear(); this.threshold = IdeLogLevel.TRACE; } /** - * Re-enables the buffering of the logger so nothing gets logged and log messages are only collected until {@link #flushAndEndBuffering(IdeLogger)} is - * called. + * Re-enables the buffering of the logger so nothing gets logged and log messages are only collected until {@link #flushAndEndBuffering()} is called. * * @param threshold the {@link IdeLogLevel} acting as threshold. * @see com.devonfw.tools.ide.context.IdeContext#runWithoutLogging(Runnable, IdeLogLevel) diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogger.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogger.java deleted file mode 100644 index 883a43d1f7..0000000000 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogger.java +++ /dev/null @@ -1,250 +0,0 @@ -package com.devonfw.tools.ide.log; - -/** - * Interface for interaction with the user allowing to input and output information. - */ -public interface IdeLogger { - - /** - * @param level the {@link IdeLogLevel}. - * @return the requested {@link IdeLogLevel} for the given {@link IdeLogLevel}. - * @see IdeSubLogger#getLevel() - */ - IdeSubLogger level(IdeLogLevel level); - - /** - * @return the {@link #level(IdeLogLevel) logger} for {@link IdeLogLevel#TRACE}. - */ - default IdeSubLogger trace() { - - return level(IdeLogLevel.TRACE); - } - - /** - * @param message the {@link IdeSubLogger#log(String) message to log} with {@link IdeLogLevel#TRACE}. - */ - default void trace(String message) { - - trace().log(message); - } - - /** - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#TRACE}. - * @param args the dynamic arguments to fill in. - */ - default void trace(String message, Object... args) { - - trace().log(message, args); - } - - /** - * @return the {@link #level(IdeLogLevel) logger} for {@link IdeLogLevel#DEBUG}. - */ - default IdeSubLogger debug() { - - return level(IdeLogLevel.DEBUG); - } - - /** - * @param message the {@link IdeSubLogger#log(String) message to log} with {@link IdeLogLevel#DEBUG}. - */ - default void debug(String message) { - - debug().log(message); - } - - /** - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#DEBUG}. - * @param args the dynamic arguments to fill in. - */ - default void debug(String message, Object... args) { - - debug().log(message, args); - } - - /** - * @return the {@link #level(IdeLogLevel) logger} for {@link IdeLogLevel#INFO}. - */ - default IdeSubLogger info() { - - return level(IdeLogLevel.INFO); - } - - /** - * @param message the {@link IdeSubLogger#log(String) message to log} with {@link IdeLogLevel#INFO}. - */ - default void info(String message) { - - info().log(message); - } - - /** - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#INFO}. - * @param args the dynamic arguments to fill in. - */ - default void info(String message, Object... args) { - - info().log(message, args); - } - - /** - * @return the {@link #level(IdeLogLevel) logger} for {@link IdeLogLevel#STEP}. - */ - default IdeSubLogger step() { - - return level(IdeLogLevel.STEP); - } - - /** - * @param message the {@link IdeSubLogger#log(String) message to log} with {@link IdeLogLevel#STEP}. - */ - default void step(String message) { - - step().log(message); - } - - /** - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#STEP}. - * @param args the dynamic arguments to fill in. - */ - default void step(String message, Object... args) { - - step().log(message, args); - } - - /** - * @return the {@link #level(IdeLogLevel) logger} for {@link IdeLogLevel#INTERACTION}. - */ - default IdeSubLogger interaction() { - - return level(IdeLogLevel.INTERACTION); - } - - /** - * @param message the {@link IdeSubLogger#log(String) message to log} with {@link IdeLogLevel#INTERACTION}. - */ - default void interaction(String message) { - - interaction().log(message); - } - - /** - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#INTERACTION}. - * @param args the dynamic arguments to fill in. - */ - default void interaction(String message, Object... args) { - - interaction().log(message, args); - } - - /** - * @return the {@link #level(IdeLogLevel) logger} for {@link IdeLogLevel#SUCCESS}. - */ - default IdeSubLogger success() { - - return level(IdeLogLevel.SUCCESS); - } - - /** - * @param message the {@link IdeSubLogger#log(String) message to log} with {@link IdeLogLevel#SUCCESS}. - */ - default void success(String message) { - - success().log(message); - } - - /** - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#SUCCESS}. - * @param args the dynamic arguments to fill in. - */ - default void success(String message, Object... args) { - - success().log(message, args); - } - - /** - * @return the {@link #level(IdeLogLevel) logger} for {@link IdeLogLevel#WARNING}. - */ - default IdeSubLogger warning() { - - return level(IdeLogLevel.WARNING); - } - - /** - * @param message the {@link IdeSubLogger#log(String) message to log} with {@link IdeLogLevel#WARNING}. - */ - default void warning(String message) { - - warning().log(message); - } - - /** - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#WARNING}. - * @param args the dynamic arguments to fill in. - */ - default void warning(String message, Object... args) { - - warning().log(message, args); - } - - /** - * @return the {@link #level(IdeLogLevel) logger} for {@link IdeLogLevel#ERROR}. - */ - default IdeSubLogger error() { - - return level(IdeLogLevel.ERROR); - } - - /** - * @param message the {@link IdeSubLogger#log(String) message to log} with {@link IdeLogLevel#ERROR}. - */ - default void error(String message) { - - error().log(message); - } - - /** - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#ERROR}. - * @param args the dynamic arguments to fill in. - */ - default void error(String message, Object... args) { - - error().log(message, args); - } - - /** - * @param error the {@link Throwable} that caused the error. - */ - default void error(Throwable error) { - - error(error, null); - } - - /** - * @param error the {@link Throwable} that caused the error. - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#ERROR}. - */ - default void error(Throwable error, String message) { - - error().log(error, message); - } - - /** - * @param error the {@link Throwable} that caused the error. - * @param message the {@link IdeSubLogger#log(String, Object...) message to log} with {@link IdeLogLevel#ERROR}. - * @param args the dynamic arguments to fill in. - */ - default void error(Throwable error, String message, Object... args) { - - error().log(error, message, args); - } - - /** - * @return the current {@link IdeLogger} instance. - */ - static IdeLogger get() { - - return IdeLoggerImpl.getInstance(); - } - -} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLoggerImpl.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLoggerImpl.java deleted file mode 100644 index 06593cdb11..0000000000 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLoggerImpl.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.devonfw.tools.ide.log; - -import java.util.Objects; -import java.util.function.Function; - -/** - * Implementation of {@link IdeLogger}. - */ -public class IdeLoggerImpl implements IdeLogger { - - private final AbstractIdeSubLogger[] loggers; - - protected final IdeLogListener listener; - - private static IdeLogger instance; - - /** - * @param minLogLevel the minimum enabled {@link IdeLogLevel}. - * @param factory the factory to create active {@link IdeSubLogger} instances. - */ - public IdeLoggerImpl(IdeLogLevel minLogLevel, Function factory) { - - super(); - IdeLogLevel[] levels = IdeLogLevel.values(); - this.loggers = new AbstractIdeSubLogger[levels.length]; - IdeLogListener listener = null; - for (IdeLogLevel level : levels) { - this.loggers[level.ordinal()] = factory.apply(level); - if (listener == null) { - listener = this.loggers[level.ordinal()].listener; - } - } - this.listener = listener; - setLogLevel(minLogLevel); - IdeLoggerImpl.instance = this; - } - - @Override - public IdeSubLogger level(IdeLogLevel level) { - - IdeSubLogger logger = this.loggers[level.ordinal()]; - Objects.requireNonNull(logger); - return logger; - } - - /** - * Sets the log level. - * - * @param logLevel {@link IdeLogLevel} - * @return the previous set logLevel {@link IdeLogLevel} - */ - public IdeLogLevel setLogLevel(IdeLogLevel logLevel) { - - IdeLogLevel previousLogLevel = null; - for (IdeLogLevel level : IdeLogLevel.values()) { - boolean enabled = level.ordinal() >= logLevel.ordinal(); - if ((previousLogLevel == null) && this.loggers[level.ordinal()].isEnabled()) { - previousLogLevel = level; - } - setLogLevel(level, enabled); - } - if ((previousLogLevel == null) || (previousLogLevel.ordinal() > IdeLogLevel.INFO.ordinal())) { - previousLogLevel = IdeLogLevel.INFO; - } - return previousLogLevel; - } - - /** - * @param colored the new {@link AbstractIdeSubLogger#isColored() colored flag}. - */ - protected void setLogColors(boolean colored) { - - for (IdeLogLevel level : IdeLogLevel.values()) { - this.loggers[level.ordinal()].setColored(colored); - } - } - - /** - * @param logLevel the {@link IdeLogLevel} to modify. - * @param enabled - {@code true} to enable, {@code false} to disable. - */ - public void setLogLevel(IdeLogLevel logLevel, boolean enabled) { - - this.loggers[logLevel.ordinal()].setEnabled(enabled); - } - - /** - * Ensure the logging system is initialized. - */ - public void activateLogging() { - - if (this.listener instanceof IdeLogListenerBuffer buffer) { - // https://github.com/devonfw/IDEasy/issues/754 - buffer.flushAndEndBuffering(this); - } - } - - /** - * Disables the logging system (temporary). - * - * @param threshold the {@link IdeLogLevel} acting as threshold. - * @see com.devonfw.tools.ide.context.IdeContext#runWithoutLogging(Runnable, IdeLogLevel) - */ - public void deactivateLogging(IdeLogLevel threshold) { - - if (this.listener instanceof IdeLogListenerBuffer buffer) { - buffer.startBuffering(threshold); - } else { - throw new IllegalStateException(); - } - } - - /** - * Internal method to set the {@link IdeLogArgFormatter}. - * - * @param argFormatter the {@link IdeLogArgFormatter}. - */ - public void setArgFormatter(IdeLogArgFormatter argFormatter) { - - for (AbstractIdeSubLogger logger : this.loggers) { - logger.setArgFormatter(argFormatter); - } - } - - /** - * @return the current {@link IdeLogger} instance. - */ - static IdeLogger getInstance() { - - return instance; - } - -} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLogger.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLogger.java deleted file mode 100644 index a3caf808cb..0000000000 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLogger.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.devonfw.tools.ide.log; - -/** - * Interface for a logger to {@link #log(String) log a message} on a specific {@link #getLevel() log-level}. - */ -public interface IdeSubLogger { - - /** - * @param message the message to log. - */ - default void log(String message) { - - log(null, message); - } - - /** - * @param message the message to log. - * @param args the dynamic arguments to fill in. - * @return the message headline that was logged. - */ - default String log(String message, Object... args) { - - return log(null, message, args); - } - - /** - * @param error the {@link Throwable} that was catched and should be logged or {@code null} for no error. - * @param message the message to log. - * @return the message headline that was logged. - */ - default String log(Throwable error, String message) { - - return log(error, message, (Object[]) null); - } - - /** - * @param error the {@link Throwable} that was catched and should be logged or {@code null} for no error. - * @param message the message to log. - * @param args the dynamic arguments to fill in. - * @return the message headline that was logged. - */ - String log(Throwable error, String message, Object... args); - - /** - * @return {@code true} if this logger is enabled, {@code false} otherwise (this logger does nothing and all {@link #log(String) logged messages} with be - * ignored). - */ - boolean isEnabled(); - - /** - * @return the {@link IdeLogLevel} of this logger. - */ - IdeLogLevel getLevel(); - -} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerAdapter.java deleted file mode 100644 index 95c8a4a6e8..0000000000 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerAdapter.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.devonfw.tools.ide.log; - -import org.slf4j.Logger; -import org.slf4j.Marker; -import org.slf4j.event.Level; -import org.slf4j.spi.LoggingEventBuilder; - -/** - * {@link IdeSubLogger} that actually adapts to SLF4J that should again adapt to {@link IdeLogger} and JUL as needed. - */ -public class IdeSubLoggerAdapter implements IdeSubLogger { - - private final IdeLogLevel level; - - private final Logger LOG; - - /** - * The constructor. - * - * @param level the {@link IdeLogLevel}. - * @param logger the SLF4J {@link Logger}. - */ - public IdeSubLoggerAdapter(IdeLogLevel level, Logger logger) { - this.level = level; - this.LOG = logger; - } - - @Override - public String log(Throwable error, String message, Object... args) { - - Marker marker = level.getSlf4jMarker(); - if (marker != null) { - assert level.getSlf4jLevel() == Level.INFO; - if (error == null) { - if (Slf4jLoggerAdapter.isEmpty(args)) { - LOG.info(marker, message); - } else { - LOG.info(marker, message, args); - } - } else if (Slf4jLoggerAdapter.isEmpty(args)) { - LOG.info(marker, message, error); - } else { - LOG.info(marker, Slf4jLoggerAdapter.compose(message, args)); - } - } else { - LoggingEventBuilder builder = LOG.atLevel(level.getSlf4jLevel()); - if (error != null) { - builder = builder.setCause(error); - } - if (Slf4jLoggerAdapter.isEmpty(args)) { - builder.log(message); - } else { - builder.log(message, args); - } - } - return message; - } - - @Override - public boolean isEnabled() { - - Level slf4jLevel = level.getSlf4jLevel(); - Marker marker = level.getSlf4jMarker(); - if (marker != null) { - assert slf4jLevel == Level.INFO; - return LOG.isInfoEnabled(marker); - } - return LOG.isEnabledForLevel(slf4jLevel); - } - - @Override - public IdeLogLevel getLevel() { - - return level; - } - -} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java deleted file mode 100644 index 91cae563f1..0000000000 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.devonfw.tools.ide.log; - -import java.io.IOException; - -/** - * Default implementation of {@link IdeSubLogger} that can write to an {@link Appendable} such as {@link System#out} or in case of testing a - * {@link java.io.StringWriter}. - */ -public class IdeSubLoggerOut extends AbstractIdeSubLogger { - - private final Appendable out; - - /** - * The constructor. - * - * @param level the {@link #getLevel() log-level}. - * @param out the {@link Appendable} to {@link Appendable#append(CharSequence) write} log messages to. - * @param colored - {@code true} for colored output according to {@link IdeLogLevel}, {@code false} otherwise. - * @param minLogLevel the minimum log level (threshold). - * @param listener the {@link IdeLogListener} to listen to. - */ - public IdeSubLoggerOut(IdeLogLevel level, Appendable out, boolean colored, IdeLogLevel minLogLevel, IdeLogListener listener) { - - super(level, colored, IdeLogExceptionDetails.of(level, minLogLevel), listener); - if (out == null) { - // this is on of the very rare excuses where System.out or System.err is allowed to be used! - if (level == IdeLogLevel.ERROR) { - this.out = System.err; - } else { - this.out = System.out; - } - } else { - this.out = out; - } - } - - @Override - public void doLog(String message, Throwable error) { - - try { - String startColor = null; - if (this.colored) { - startColor = this.level.getStartColor(); - if (startColor != null) { - this.out.append(startColor); - } - } - if (error != null) { - message = this.exceptionDetails.format(message, error); - } - this.out.append(message); - if (startColor != null) { - this.out.append(this.level.getEndColor()); - } - this.out.append("\n"); - } catch (IOException e) { - throw new IllegalStateException("Failed to log message: " + message, e); - } - } -} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java b/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java new file mode 100644 index 0000000000..df86e1be7d --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java @@ -0,0 +1,49 @@ +package com.devonfw.tools.ide.log; + +import java.io.PrintStream; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * Custom {@link Handler} for java.util.logging to log to console. + */ +public class JulConsoleHandler extends Handler { + + @Override + public void publish(LogRecord record) { + Level julLevel = record.getLevel(); + IdeLogLevel ideLevel = IdeLogLevel.of(julLevel); + PrintStream out = System.out; + if (ideLevel == IdeLogLevel.ERROR) { + out = System.err; + } + String message = record.getMessage(); + Throwable error = record.getThrown(); + String startColor = null; + if (Slf4jLoggerAdapter.isColored()) { + startColor = ideLevel.getStartColor(); + if (startColor != null) { + out.append(startColor); + } + } + if (error != null) { + message = IdeLogExceptionDetails.of(ideLevel, Slf4jLoggerAdapter.getLogLevel()).format(message, error); + } + out.append(message); + if (startColor != null) { + out.append(ideLevel.getEndColor()); + } + out.append("\n"); + } + + @Override + public void flush() { + + } + + @Override + public void close() { + + } +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/JulLogLevel.java b/cli/src/main/java/com/devonfw/tools/ide/log/JulLogLevel.java new file mode 100644 index 0000000000..85f9585d0a --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/log/JulLogLevel.java @@ -0,0 +1,48 @@ +package com.devonfw.tools.ide.log; + +import java.util.logging.Level; + +/** + * {@link Level} from java.util.logging corresponding to {@link IdeLogLevel}. + */ +public class JulLogLevel extends Level { + + /** @see IdeLogLevel#TRACE */ + public static final Level TRACE = new JulLogLevel("TRACE", 401); + + /** @see IdeLogLevel#DEBUG */ + public static final Level DEBUG = new JulLogLevel("DEBUG", 501); + + /** @see IdeLogLevel#INFO */ + public static final Level INFO = Level.INFO; + + /** @see IdeLogLevel#STEP */ + public static final Level STEP = new JulLogLevel("STEP", 801); + + /** @see IdeLogLevel#INTERACTION */ + public static final Level INTERACTION = new JulLogLevel("INTERACTION", 802); + + /** @see IdeLogLevel#SUCCESS */ + public static final Level SUCCESS = new JulLogLevel("SUCCESS", 803); + + /** @see IdeLogLevel#WARNING */ + public static final Level WARNING = Level.WARNING; + + /** @see IdeLogLevel#WARNING */ + public static final Level ERROR = new JulLogLevel("ERROR", 1001); + + /** @see IdeLogLevel#PROCESSABLE */ + public static final Level PROCESSABLE = new JulLogLevel("PROCESSABLE", 2000); + + private JulLogLevel(String name, int value) { + + super(name, value); + } + + /** + * Ensures that all custom log-levels are initialized. + */ + public static void init() { + + } +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java index 4105ae4f6b..0e9e7ee80c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java @@ -1,16 +1,20 @@ package com.devonfw.tools.ide.log; -import org.slf4j.Logger; +import java.util.List; +import java.util.logging.Logger; + import org.slf4j.Marker; import org.slf4j.event.Level; +import org.slf4j.event.LoggingEvent; import org.slf4j.helpers.AbstractLogger; +import org.slf4j.spi.LoggingEventAware; import com.devonfw.tools.ide.context.IdeStartContextImpl; /** - * Implementation of {@link Logger}. + * Implementation of SLF4J {@link AbstractLogger} for IDEasy. */ -public class Slf4jLoggerAdapter extends AbstractLogger { +public class Slf4jLoggerAdapter extends AbstractLogger implements LoggingEventAware { /** Package prefix of IDEasy: {@value} */ public static final String IDEASY_PACKAGE_PREFIX = "com.devonfw.tools.ide."; @@ -18,7 +22,7 @@ public class Slf4jLoggerAdapter extends AbstractLogger { private final boolean internal; - private java.util.logging.Logger julLogger; + private Logger julLogger; /** * The constructor. @@ -29,6 +33,7 @@ public Slf4jLoggerAdapter(String name) { this.name = name; this.internal = name.startsWith(IDEASY_PACKAGE_PREFIX); + this.julLogger = Logger.getLogger(name); } @Override @@ -41,80 +46,125 @@ static boolean isEmpty(Object[] args) { return (args == null) || (args.length == 0); } - static String compose(String message, Object... args) { + /** + * Should only be used internally by logger implementation. + * + * @param message the message template. + * @param args the dynamic arguments to fill in. + * @return the resolved message with the parameters filled in. + */ + private String compose(IdeLogArgFormatter formatter, String message, Object... args) { + if (isEmpty(args)) { return message; } - return AbstractIdeSubLogger.compose(IdeLogArgFormatter.DEFAULT, InvalidLogMessageHandler.NONE, message, args); + int pos = message.indexOf("{}"); + if (pos < 0) { + if (args.length > 0) { + invalidMessage(message, false, args); + } + return message; + } + int argIndex = 0; + int start = 0; + int length = message.length(); + StringBuilder sb = new StringBuilder(length + 48); + while (pos >= 0) { + sb.append(message, start, pos); + sb.append(formatter.formatArgument(args[argIndex++])); + start = pos + 2; + pos = message.indexOf("{}", start); + if ((argIndex >= args.length) && (pos > 0)) { + invalidMessage(message, true, args); + pos = -1; + } + } + if (start < length) { + String rest = message.substring(start); + sb.append(rest); + } + if (argIndex < args.length) { + invalidMessage(message, false, args); + } + return sb.toString(); } - @Override - protected String getFullyQualifiedCallerName() { + private void invalidMessage(String message, boolean more, Object[] args) { - return null; + warning("Invalid log message with " + args.length + " argument(s) but " + (more ? "more" : "less") + + " placeholders: " + message); } - private java.util.logging.Logger getJulLogger() { - - if (this.julLogger == null) { - IdeLogger ideLogger = IdeLogger.get(); - if (ideLogger == null) { - return null; // initialization issue, logging happens too early - } else { - boolean create = false; - if (ideLogger instanceof IdeStartContextImpl startContext) { - boolean prod = (ideLogger.getClass() == IdeStartContextImpl.class); - if (startContext.isWriteLogfile()) { - create = this.internal || !prod; - } else if (!prod) { - create = !this.internal; // in test we create external loggers, for prod we suppress them - } - } - if (create) { - this.julLogger = java.util.logging.Logger.getLogger(name); - } - } + private void warning(String message) { + + boolean colored = isColored(); + if (colored) { + System.err.print(IdeLogLevel.ERROR.getEndColor()); + System.err.print(IdeLogLevel.ERROR.getStartColor()); + } + System.err.println(message); + if (colored) { + System.err.print(IdeLogLevel.ERROR.getEndColor()); } - return this.julLogger; } - private IdeLogger getIdeLogger() { - - if (this.internal) { - return IdeLogger.get(); + static boolean isColored() { + IdeStartContextImpl startContext = IdeStartContextImpl.get(); + if (startContext != null) { + return !startContext.isNoColorsMode(); } + return false; + } + + @Override + protected String getFullyQualifiedCallerName() { + return null; } @Override protected void handleNormalizedLoggingCall(Level level, Marker marker, String message, Object[] args, Throwable error) { IdeLogLevel ideLevel = IdeLogLevel.of(level, marker); - IdeLogger intLogger = getIdeLogger(); - if (intLogger != null) { - intLogger.level(ideLevel).log(error, message, args); + IdeLogListener listener = IdeLogListenerNone.INSTANCE; + IdeStartContextImpl startContext = IdeStartContextImpl.get(); + IdeLogArgFormatter argFormatter = IdeLogArgFormatter.DEFAULT; + if (startContext != null) { + listener = startContext.getLogListener(); + argFormatter = startContext.getArgFormatter(); } - java.util.logging.Logger extLogger = getJulLogger(); - if (extLogger != null) { + String composedMessage = compose(argFormatter, message, args); + boolean accept = listener.onLog(ideLevel, composedMessage, message, args, error); + if (accept) { java.util.logging.Level julLevel = ideLevel.getJulLevel(); - if (extLogger.isLoggable(julLevel)) { - extLogger.log(julLevel, compose(message, args), error); - } + this.julLogger.log(julLevel, composedMessage, error); + } + } + + @Override + public void log(LoggingEvent event) { + + List markers = event.getMarkers(); + Marker marker = null; + if ((markers != null) && !markers.isEmpty()) { + assert markers.size() == 1; + marker = markers.getFirst(); } + handleNormalizedLoggingCall(event.getLevel(), marker, event.getMessage(), event.getArgumentArray(), event.getThrowable()); } private boolean isLevelEnabled(Level level, Marker marker) { IdeLogLevel ideLevel = IdeLogLevel.of(level, marker); - IdeLogger intLogger = getIdeLogger(); - if (intLogger != null) { - if (intLogger.level(ideLevel).isEnabled()) { - return true; - } - } - java.util.logging.Logger extLogger = getJulLogger(); - if (extLogger != null) { - return extLogger.isLoggable(ideLevel.getJulLevel()); + IdeLogLevel threshold = getLogLevel(); + return ideLevel.ordinal() >= threshold.ordinal(); + } + + static IdeLogLevel getLogLevel() { + IdeLogLevel threshold = IdeLogLevel.TRACE; + IdeStartContextImpl startContext = IdeStartContextImpl.get(); + if (startContext != null) { + threshold = startContext.getLogLevel(); } - return false; + return threshold; } @Override diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerFactoryIdeasy.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerFactoryIdeasy.java index b20dd39b92..4a33ac436b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerFactoryIdeasy.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerFactoryIdeasy.java @@ -4,7 +4,7 @@ import org.slf4j.Logger; /** - * Implementation of {@link ILoggerFactory}. + * Implementation of SLF4J {@link ILoggerFactory} for IDEasy. */ public class Slf4jLoggerFactoryIdeasy implements ILoggerFactory { 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 426f271fa2..5108a85c0d 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 @@ -11,6 +11,8 @@ import java.util.stream.Stream; import org.jline.utils.Log; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.environment.EnvironmentVariables; @@ -27,6 +29,8 @@ */ public class DirectoryMerger extends AbstractWorkspaceMerger { + private static final Logger LOG = LoggerFactory.getLogger(DirectoryMerger.class); + private final Map extension2mergerMap; private final FallbackMerger fallbackMerger; @@ -81,9 +85,9 @@ private FileMerger getMerger(Path file) { String filename = file.getFileName().toString(); String extension = FilenameUtil.getExtension(filename); if (extension == null) { - this.context.debug("No extension for {}", file); + LOG.debug("No extension for {}", file); } else { - this.context.trace("Extension is {}", extension); + LOG.trace("Extension is {}", extension); FileMerger merger = this.extension2mergerMap.get(extension); if (merger != null) { return merger; 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 0eba942bb6..63767d319d 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 @@ -6,6 +6,9 @@ import java.nio.file.StandardCopyOption; import java.util.regex.Matcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.environment.EnvironmentVariables; import com.devonfw.tools.ide.variable.IdeVariables; @@ -17,6 +20,8 @@ */ public abstract class FileMerger extends AbstractWorkspaceMerger { + private static final Logger LOG = LoggerFactory.getLogger(FileMerger.class); + protected final boolean legacySupport; /** @@ -49,7 +54,7 @@ public final int merge(Path setup, Path update, EnvironmentVariables variables, try { doMerge(setup, update, variables, workspace); } catch (Exception e) { - this.context.error(e, "Failed to merge workspace file {} with update template {} and setup file {}!", workspace, update, setup); + LOG.error("Failed to merge workspace file {} with update template {} and setup file {}!", workspace, update, setup, e); return 1; } return 0; @@ -71,9 +76,9 @@ public void upgrade(Path workspaceFile) { try { boolean modified = doUpgrade(workspaceFile); if (modified) { - this.context.debug("Successfully migrated file {}", workspaceFile); + LOG.debug("Successfully migrated file {}", workspaceFile); } else { - this.context.trace("Nothing to migrate in file {}", workspaceFile); + LOG.trace("Nothing to migrate in file {}", workspaceFile); } } catch (Exception e) { throw new IllegalStateException("Failed to update file " + workspaceFile, e); 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 9b9e883929..ae30bd0d69 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 @@ -24,6 +24,9 @@ import jakarta.json.JsonWriterFactory; import jakarta.json.stream.JsonGenerator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.environment.EnvironmentVariables; import com.fasterxml.jackson.core.util.DefaultIndenter; @@ -39,6 +42,8 @@ */ public class JsonMerger extends FileMerger { + private static final Logger LOG = LoggerFactory.getLogger(JsonMerger.class); + /** * The constructor. * @@ -76,9 +81,9 @@ protected void doMerge(Path setup, Path update, EnvironmentVariables variables, JsonStructure result = (JsonStructure) mergeAndResolve(json, mergeJson, variables, status, template.toString()); if (status.updated) { save(result, workspace); - this.context.debug("Saved created/updated file {}", workspace); + LOG.debug("Saved created/updated file {}", workspace); } else { - this.context.trace("No changes for file {}", workspace); + LOG.trace("No changes for file {}", workspace); } } @@ -125,9 +130,9 @@ public void inverseMerge(Path workspace, EnvironmentVariables variables, boolean workspace.getFileName()); if (status.updated) { save(result, updateFile); - this.context.debug("Saved changes from {} to {}", workspace.getFileName(), updateFile); + LOG.debug("Saved changes from {} to {}", workspace.getFileName(), updateFile); } else { - this.context.trace("No changes for {}", updateFile); + LOG.trace("No changes for {}", updateFile); } } @@ -150,7 +155,7 @@ private JsonValue mergeAndResolve(JsonValue json, JsonValue mergeJson, Environme case STRING -> mergeAndResolveString((JsonString) json, (JsonString) mergeJson, variables, status, src); case NUMBER, FALSE, TRUE, NULL -> mergeAndResolveNativeType(json, mergeJson, variables, status); default -> { - this.context.error("Undefined JSON type {}", json.getClass()); + LOG.error("Undefined JSON type {}", json.getClass()); yield null; } }; @@ -286,7 +291,7 @@ private ObjectNode upgradeJsonObject(ObjectNode jsonObject) { if (migratedChild != child) { result = null; if (migratedChild != null) { - jsonObject.put(fieldName, migratedChild); + jsonObject.set(fieldName, migratedChild); } } } 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 378fb95008..1ed2d25686 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 @@ -5,6 +5,9 @@ import java.util.Properties; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.environment.EnvironmentVariables; import com.devonfw.tools.ide.environment.SortedProperties; @@ -15,6 +18,8 @@ */ public class PropertiesMerger extends FileMerger { + private static final Logger LOG = LoggerFactory.getLogger(PropertiesMerger.class); + /** * The constructor. * @@ -34,7 +39,7 @@ protected void doMerge(Path setup, Path update, EnvironmentVariables resolver, P Path template = setup; if (Files.exists(workspace)) { if (!updateFileExists) { - this.context.trace("Nothing to do as update file does not exist: {}", update); + LOG.trace("Nothing to do as update file does not exist: {}", update); return; // nothing to do ... } fileAccess.readProperties(workspace, properties); @@ -47,7 +52,7 @@ protected void doMerge(Path setup, Path update, EnvironmentVariables resolver, P } resolve(properties, resolver, template.toString()); fileAccess.writeProperties(properties, workspace, true); - this.context.trace("Saved merged properties to: {}", workspace); + LOG.trace("Saved merged properties to: {}", workspace); } private void resolve(Properties properties, EnvironmentVariables variables, Object src) { @@ -63,11 +68,11 @@ private void resolve(Properties properties, EnvironmentVariables variables, Obje public void inverseMerge(Path workspace, EnvironmentVariables variables, boolean addNewProperties, Path update) { if (!Files.exists(workspace)) { - this.context.trace("Workspace file does not exist: {}", workspace); + LOG.trace("Workspace file does not exist: {}", workspace); return; } if (!Files.exists(update)) { - this.context.trace("Update file does not exist: {}", update); + LOG.trace("Update file does not exist: {}", update); return; } Object src = workspace.getFileName(); @@ -94,9 +99,9 @@ public void inverseMerge(Path workspace, EnvironmentVariables variables, boolean } if (updated) { fileAccess.writeProperties(mergedProperties, update); - this.context.debug("Saved changes from: {} to: {}", workspace.getFileName(), update); + LOG.debug("Saved changes from: {} to: {}", workspace.getFileName(), update); } else { - this.context.trace("No changes for: {}", update); + LOG.trace("No changes for: {}", update); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/xml/XmlMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/xml/XmlMerger.java index 2ccc3b57f0..971943395f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/xml/XmlMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/xml/XmlMerger.java @@ -13,6 +13,8 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -32,6 +34,8 @@ */ public class XmlMerger extends FileMerger implements XmlMergeSupport { + private static final Logger LOG = LoggerFactory.getLogger(XmlMerger.class); + private static final DocumentBuilder DOCUMENT_BUILDER; private static final TransformerFactory TRANSFORMER_FACTORY; @@ -114,7 +118,7 @@ public Document merge(XmlMergeDocument templateDocument, XmlMergeDocument worksp Document resultDocument; Path template = templateDocument.getPath(); Path source = workspaceDocument.getPath(); - this.context.debug("Merging {} into {} ...", template, source); + LOG.debug("Merging {} into {} ...", template, source); Element templateRoot = templateDocument.getRoot(); QName templateQName = XmlMergeSupport.getQualifiedName(templateRoot); Document document = workspaceDocument.getDocument(); @@ -146,7 +150,7 @@ public Document merge(XmlMergeDocument templateDocument, XmlMergeDocument worksp strategy = XmlMergeStrategy.KEEP; } } else { - this.context.warning( + LOG.warn( "XML merge namespace not found in file {}. If you are working in a legacy devonfw-ide project, please set IDE_XML_MERGE_LEGACY_SUPPORT_ENABLED=true to " + "proceed correctly.", source); } @@ -155,7 +159,7 @@ public Document merge(XmlMergeDocument templateDocument, XmlMergeDocument worksp strategy.merge(templateRoot, workspaceRoot, elementMatcher); resultDocument = document; } else { - this.context.error("Cannot merge XML template {} with root {} into XML file {} with root {} as roots do not match.", templateDocument.getPath(), + LOG.error("Cannot merge XML template {} with root {} into XML file {} with root {} as roots do not match.", templateDocument.getPath(), templateQName, workspaceDocument.getPath(), workspaceQName); return null; } @@ -369,7 +373,7 @@ private void checkForXmlNamespace(Document document, Path workspaceFile) { } } } - this.context.warning( + LOG.warn( "The XML file {} does not contain the XML merge namespace and seems outdated. For details see:\n" + "https://github.com/devonfw/IDEasy/blob/main/documentation/configurator.adoc#xml-merger", workspaceFile); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/xml/matcher/IdComputer.java b/cli/src/main/java/com/devonfw/tools/ide/merge/xml/matcher/IdComputer.java index e021f708e4..fea8c45abc 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/xml/matcher/IdComputer.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/xml/matcher/IdComputer.java @@ -7,6 +7,8 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -18,6 +20,8 @@ */ public class IdComputer { + private static final Logger LOG = LoggerFactory.getLogger(IdComputer.class); + /** Name of the {@link com.devonfw.tools.ide.environment.EnvironmentVariables variable} to fail on ambiguous merge. */ public static final String FAIL_ON_AMBIGOUS_MERGE = "FAIL_ON_AMBIGOUS_MERGE"; @@ -71,11 +75,13 @@ public Element evaluateExpression(Element templateElement, Element workspaceElem } else if (length == 0) { return null; } else { - String message = length + " matches found for XPath " + xpathExpr + " in workspace XML file '" + workspacePath + "' at " + XmlMergeSupport.getXPath(workspaceElement, true) + " for template file '" + templatePath + "'"; + String message = + length + " matches found for XPath " + xpathExpr + " in workspace XML file '" + workspacePath + "' at " + XmlMergeSupport.getXPath(workspaceElement, + true) + " for template file '" + templatePath + "'"; if ("true".equals(this.context.getVariables().get(FAIL_ON_AMBIGOUS_MERGE))) { throw new IllegalStateException(message); } else { - this.context.warning(message); + LOG.warn(message); } return (Element) nodeList.item(0); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/migration/IdeMigrator.java b/cli/src/main/java/com/devonfw/tools/ide/migration/IdeMigrator.java index c371fa9bd2..16cdeb46f5 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/migration/IdeMigrator.java +++ b/cli/src/main/java/com/devonfw/tools/ide/migration/IdeMigrator.java @@ -2,7 +2,11 @@ import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.migration.v2025.Mig202502001; import com.devonfw.tools.ide.migration.v2025.Mig202510001; import com.devonfw.tools.ide.step.Step; @@ -14,6 +18,8 @@ */ public class IdeMigrator implements IdeMigration { + private static final Logger LOG = LoggerFactory.getLogger(IdeMigrator.class); + /** {@link VersionIdentifier} to use as fallback if {@link IdeContext#FILE_SOFTWARE_VERSION} does not exist. */ public static final VersionIdentifier START_VERSION = VersionIdentifier.of("2025.01.001-beta"); @@ -53,7 +59,7 @@ public VersionIdentifier getTargetVersion() { public void run(IdeContext context) { if (context.getIdeHome() == null) { - context.debug("Skipping migration since IDE_HOME is undefined."); + LOG.debug("Skipping migration since IDE_HOME is undefined."); return; } VersionIdentifier currentVersion = context.getProjectVersion(); @@ -80,13 +86,13 @@ public void run(IdeContext context) { throw new IllegalStateException("Failed: " + step.getName()); } } else { - context.debug("Skipping migration {} since we are already at version {}", targetVersion, currentVersion); + LOG.debug("Skipping migration {} since we are already at version {}", targetVersion, currentVersion); } } if (migrationCount > 0) { - context.success("Successfully applied {} migration(s) to project {}", migrationCount, context.getProjectName()); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully applied {} migration(s) to project {}", migrationCount, context.getProjectName()); } else { - context.debug("No migration to apply to project {}", context.getProjectName()); + LOG.debug("No migration to apply to project {}", context.getProjectName()); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/network/NetworkProxy.java b/cli/src/main/java/com/devonfw/tools/ide/network/NetworkProxy.java index 80d78ada47..4efcd33683 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/network/NetworkProxy.java +++ b/cli/src/main/java/com/devonfw/tools/ide/network/NetworkProxy.java @@ -4,15 +4,19 @@ import java.net.URL; import java.util.Locale; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.environment.IdeSystem; -import com.devonfw.tools.ide.log.IdeLogLevel; /** * Simple class to {@link #configure()} network proxy. */ public class NetworkProxy { + private static final Logger LOG = LoggerFactory.getLogger(NetworkProxy.class); + private static final String PROXY_DOCUMENTATION_PAGE = "https://github.com/devonfw/IDEasy/blob/main/documentation/proxy-support.adoc"; private final IdeContext context; @@ -44,12 +48,12 @@ private void setupNetworkProxy(String protocol) { String systemPropertyProxyHost = protocol + ".proxyHost"; String configuredValue = System.getProperty(systemPropertyProxyHost); if (configuredValue != null) { - this.context.trace("Proxy already configured via system property {}={}", systemPropertyProxyHost, configuredValue); + LOG.trace("Proxy already configured via system property {}={}", systemPropertyProxyHost, configuredValue); return; } String proxyUrlString = getProxyUrlFromEnvironmentVariable(protocol); if (proxyUrlString == null) { - this.context.trace("No {} proxy configured.", protocol); + LOG.trace("No {} proxy configured.", protocol); return; } try { @@ -75,9 +79,8 @@ private void setupNetworkProxy(String protocol) { system.setProperty(protocol + ".nonProxyHosts", this.nonProxyHosts); } } catch (MalformedURLException e) { - context.level(IdeLogLevel.WARNING) - .log(e, "Invalid {} proxy configuration detected with URL {}. Proxy configuration will be skipped.\n" - + "For further details, see " + PROXY_DOCUMENTATION_PAGE, protocol, proxyUrlString); + LOG.warn("Invalid {} proxy configuration detected with URL {}. Proxy configuration will be skipped.\n" + + "For further details, see " + PROXY_DOCUMENTATION_PAGE, protocol, proxyUrlString, e); } } @@ -118,7 +121,7 @@ private String getEnvironmentVariable(String name) { String value = this.context.getSystem().getEnv(name); if (value != null) { - this.context.trace("Found environment variable {}={}", name, value); + LOG.trace("Found environment variable {}={}", name, value); } return value; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/network/NetworkStatusImpl.java b/cli/src/main/java/com/devonfw/tools/ide/network/NetworkStatusImpl.java index 24c72c21bd..7fb1bb4a3d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/network/NetworkStatusImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/network/NetworkStatusImpl.java @@ -6,15 +6,21 @@ import java.util.concurrent.Callable; import javax.net.ssl.SSLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cache.CachedValue; import com.devonfw.tools.ide.cli.CliOfflineException; import com.devonfw.tools.ide.context.AbstractIdeContext; +import com.devonfw.tools.ide.log.IdeLogLevel; /** * Implementation of {@link NetworkStatus}. */ public class NetworkStatusImpl implements NetworkStatus { + private static final Logger LOG = LoggerFactory.getLogger(NetworkStatusImpl.class); + private final AbstractIdeContext context; private NetworkProxy networkProxy; @@ -73,8 +79,8 @@ private Throwable doOnlineCheck() { connection.getContent(); return null; } catch (Exception e) { - if (this.context.debug().isEnabled()) { - this.context.debug().log(e, "Error when trying to connect to {}", this.onlineCheckUrl); + if (LOG.isDebugEnabled()) { + LOG.debug("Error when trying to connect to {}", this.onlineCheckUrl, e); } return e; } @@ -92,27 +98,28 @@ private void configureNetworkProxy() { public void logStatusMessage() { if (isOfflineMode()) { - this.context.warning("You are offline because you have enabled offline mode via CLI option."); + LOG.warn("You are offline because you have enabled offline mode via CLI option."); return; } Throwable error = getError(); if (error == null) { - this.context.success("You are online."); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "You are online."); return; } String message = "You are offline because of the following error:"; - if (this.context.debug().isEnabled()) { - this.context.error(error, message); + if (LOG.isDebugEnabled()) { + LOG.error(message, error); } else { - this.context.error(message); - this.context.error(error.toString()); + LOG.error(message); + LOG.error(error.toString()); } if (error instanceof SSLException) { - this.context.warning( + LOG.warn( "You are having TLS issues. We guess you are forced to use a VPN tool breaking end-to-end encryption causing this effect. As a workaround you can create and configure a truststore as described here:"); - this.context.interaction("https://github.com/devonfw/IDEasy/blob/main/documentation/proxy-support.adoc#tls-certificate-issues"); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "https://github.com/devonfw/IDEasy/blob/main/documentation/proxy-support.adoc#tls-certificate-issues"); } else { - this.context.interaction("Please check potential proxy settings, ensure you are properly connected to the internet and retry this operation."); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), + "Please check potential proxy settings, ensure you are properly connected to the internet and retry this operation."); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/nls/NlsBundle.java b/cli/src/main/java/com/devonfw/tools/ide/nls/NlsBundle.java index 545b853430..006ff936df 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/nls/NlsBundle.java +++ b/cli/src/main/java/com/devonfw/tools/ide/nls/NlsBundle.java @@ -3,6 +3,9 @@ import java.util.Locale; import java.util.ResourceBundle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.commandlet.Commandlet; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.property.Property; @@ -12,6 +15,8 @@ */ public class NlsBundle { + private static final Logger LOG = LoggerFactory.getLogger(NlsBundle.class); + private final IdeContext context; private final String fqn; @@ -62,7 +67,7 @@ public NlsBundle(IdeContext context, String name, Locale locale) { public String get(String key) { if (!this.bundle.containsKey(key)) { - this.context.warning("Cound not find key '{}' in ResourceBundle {}.properties", key, this.fqn); + LOG.warn("Cound not find key '{}' in ResourceBundle {}.properties", key, this.fqn); return "?" + key; } return this.bundle.getString(key); diff --git a/cli/src/main/java/com/devonfw/tools/ide/os/MacOsHelper.java b/cli/src/main/java/com/devonfw/tools/ide/os/MacOsHelper.java index 08b7a8380b..1d631427d5 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/os/MacOsHelper.java +++ b/cli/src/main/java/com/devonfw/tools/ide/os/MacOsHelper.java @@ -7,9 +7,11 @@ import java.util.Set; import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.FileAccess; -import com.devonfw.tools.ide.log.IdeLogger; import com.devonfw.tools.ide.tool.ToolCommandlet; import com.devonfw.tools.ide.tool.repository.ToolRepository; @@ -18,6 +20,8 @@ */ public final class MacOsHelper { + private static final Logger LOG = LoggerFactory.getLogger(MacOsHelper.class); + private static final Set INVALID_LINK_FOLDERS = Set.of(IdeContext.FOLDER_CONTENTS, IdeContext.FOLDER_RESOURCES, IdeContext.FOLDER_BIN); @@ -25,8 +29,6 @@ public final class MacOsHelper { private final SystemInfo systemInfo; - private final IdeLogger logger; - /** * The constructor. * @@ -34,7 +36,7 @@ public final class MacOsHelper { */ public MacOsHelper(IdeContext context) { - this(context.getFileAccess(), context.getSystemInfo(), context); + this(context.getFileAccess(), context.getSystemInfo()); } /** @@ -42,14 +44,12 @@ public MacOsHelper(IdeContext context) { * * @param fileAccess the {@link FileAccess} instance. * @param systemInfo the {@link SystemInfo} instance. - * @param logger the {@link IdeLogger} instance. */ - public MacOsHelper(FileAccess fileAccess, SystemInfo systemInfo, IdeLogger logger) { + public MacOsHelper(FileAccess fileAccess, SystemInfo systemInfo) { super(); this.fileAccess = fileAccess; this.systemInfo = systemInfo; - this.logger = logger; } /** @@ -100,7 +100,7 @@ public Path findRootToolPath(ToolCommandlet commandlet, IdeContext context) { private Path findLinkDir(Path contentsDir, Path rootDir, String tool) { - this.logger.debug("Found MacOS app in {}", contentsDir); + LOG.debug("Found MacOS app in {}", contentsDir); Path resourcesAppBin = contentsDir.resolve(IdeContext.FOLDER_RESOURCES).resolve(IdeContext.FOLDER_APP) .resolve(IdeContext.FOLDER_BIN); if (Files.isDirectory(resourcesAppBin)) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/os/WindowsHelperImpl.java b/cli/src/main/java/com/devonfw/tools/ide/os/WindowsHelperImpl.java index fc7ef12850..ee6d55eb2f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/os/WindowsHelperImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/os/WindowsHelperImpl.java @@ -2,6 +2,9 @@ import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.process.ProcessErrorHandling; @@ -13,6 +16,8 @@ */ public class WindowsHelperImpl implements WindowsHelper { + private static final Logger LOG = LoggerFactory.getLogger(WindowsHelperImpl.class); + /** Registry key for the users environment variables. */ public static final String HKCU_ENVIRONMENT = "HKCU\\Environment"; @@ -40,9 +45,9 @@ public void removeUserEnvironmentValue(String key) { ProcessResult result = this.context.newProcess().executable("reg").addArgs("delete", HKCU_ENVIRONMENT, "/v", key, "/f") .errorHandling(ProcessErrorHandling.LOG_WARNING).run(ProcessMode.DEFAULT_CAPTURE); if (result.isSuccessful()) { - this.context.debug("Removed environment variable {}", key); + LOG.debug("Removed environment variable {}", key); } else { - result.log(IdeLogLevel.WARNING, this.context); + result.log(IdeLogLevel.WARNING); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/process/ProcessContext.java b/cli/src/main/java/com/devonfw/tools/ide/process/ProcessContext.java index 75e45189be..914dd518af 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/process/ProcessContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/process/ProcessContext.java @@ -5,7 +5,7 @@ import java.util.Objects; import java.util.function.Predicate; -import com.devonfw.tools.ide.log.IdeSubLogger; +import com.devonfw.tools.ide.log.IdeLogLevel; /** * Wrapper for {@link ProcessBuilder} to simplify its usage and avoid common mistakes and pitfalls. @@ -185,40 +185,40 @@ default List runAndGetOutput(String executable, String... arguments) { /** * Runs the given {@code executable} with the given {@code arguments} and returns the output from its {@link ProcessResult#getOut() standard output}. * - * @param logger the {@link IdeSubLogger} used to log errors instead of throwing an exception. + * @param logLevel the {@link IdeLogLevel} used to log errors instead of throwing an exception. * @param executable the executable program. * @param arguments the program arguments. * @return the output printed from the command. * @throws IllegalStateException if the command failed. */ - default List runAndGetOutput(IdeSubLogger logger, String executable, String... arguments) { + default List runAndGetOutput(IdeLogLevel logLevel, String executable, String... arguments) { executable(executable).addArgs(arguments); - if (logger == null) { + if (logLevel == null) { errorHandling(ProcessErrorHandling.THROW_ERR); } ProcessResult result = run(ProcessMode.DEFAULT_CAPTURE); - return result.getOutput(logger); + return result.getOutput(logLevel); } /** * Runs the given {@code executable} with the given {@code arguments} and returns the expected single line from its * {@link ProcessResult#getOut() standard output}. * - * @param logger the {@link IdeSubLogger} used to log errors instead of throwing an exception. + * @param logLevel the {@link IdeLogLevel} used to log errors instead of throwing an exception. * @param executable the executable program. * @param arguments the program arguments. * @return the single line printed from the command. * @throws IllegalStateException if the command did not print a single line as expected. */ - default String runAndGetSingleOutput(IdeSubLogger logger, String executable, String... arguments) { + default String runAndGetSingleOutput(IdeLogLevel logLevel, String executable, String... arguments) { executable(executable).addArgs(arguments); - if (logger == null) { + if (logLevel == null) { errorHandling(ProcessErrorHandling.THROW_ERR); } ProcessResult result = run(ProcessMode.DEFAULT_CAPTURE); - return result.getSingleOutput(logger); + return result.getSingleOutput(logLevel); } /** diff --git a/cli/src/main/java/com/devonfw/tools/ide/process/ProcessContextImpl.java b/cli/src/main/java/com/devonfw/tools/ide/process/ProcessContextImpl.java index 6c67a4e71f..d61cd85fc7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/process/ProcessContextImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/process/ProcessContextImpl.java @@ -17,6 +17,9 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliProcessException; import com.devonfw.tools.ide.common.SystemPath; import com.devonfw.tools.ide.context.IdeContext; @@ -32,6 +35,8 @@ */ public class ProcessContextImpl implements ProcessContext { + private static final Logger LOG = LoggerFactory.getLogger(ProcessContextImpl.class); + private static final String PREFIX_USR_BIN_ENV = "/usr/bin/env "; private static final Predicate EXIT_CODE_ACCEPTOR = rc -> rc == ProcessResult.SUCCESS; @@ -101,7 +106,7 @@ public ProcessContext directory(Path directory) { if (directory != null) { this.processBuilder.directory(directory.toFile()); } else { - this.context.debug( + LOG.debug( "Could not set the process builder's working directory! Directory of the current java process is used."); } @@ -132,7 +137,7 @@ public ProcessContext withEnvVar(String key, String value) { if (IdeVariables.PATH.getName().equals(key)) { this.overriddenPath = value; } else { - this.context.trace("Setting process environment variable {}={}", key, value); + LOG.trace("Setting process environment variable {}={}", key, value); this.processBuilder.environment().put(key, value); } return this; @@ -175,16 +180,16 @@ public ProcessResult run(ProcessMode processMode) { systemPath = systemPath.withPath(this.overriddenPath, this.extraPathEntries); } String path = systemPath.toString(); - this.context.trace("Setting PATH for process execution of {} to {}", this.executable.getFileName(), path); + LOG.trace("Setting PATH for process execution of {} to {}", this.executable.getFileName(), path); this.executable = systemPath.findBinary(this.executable); this.processBuilder.environment().put(IdeVariables.PATH.getName(), path); List args = new ArrayList<>(this.arguments.size() + 4); String interpreter = addExecutable(args); args.addAll(this.arguments); String command = createCommand(); - if (this.context.debug().isEnabled()) { + if (LOG.isDebugEnabled()) { String message = createCommandMessage(interpreter, " ..."); - this.context.debug(message); + LOG.debug(message); } try { @@ -374,8 +379,8 @@ private String addExecutable(List args) { args.add(this.context.findBashRequired().toString()); } if ("msi".equalsIgnoreCase(fileExtension)) { - args.add(0, "/i"); - args.add(0, "msiexec"); + args.addFirst("/i"); + args.addFirst("msiexec"); } args.add(this.executable.toString()); return interpreter; @@ -387,8 +392,8 @@ private void performLogging(ProcessResult result, int exitCode, String interpret IdeLogLevel ideLogLevel = this.errorHandling.getLogLevel(); String message = createCommandMessage(interpreter, "\nfailed with exit code " + exitCode + "!"); - context.level(ideLogLevel).log(message); - result.log(ideLogLevel, context); + LOG.atLevel(ideLogLevel.getSlf4jLevel()).log(message); + result.log(ideLogLevel); if (this.errorHandling == ProcessErrorHandling.THROW_CLI) { throw new CliProcessException(message, result); @@ -404,8 +409,7 @@ private void modifyArgumentsOnBackgroundProcess(ProcessMode processMode) { Path bash = this.context.findBash(); if (bash == null) { - this.context.warning( - "Cannot start background process via bash because no bash installation was found. Hence, output will be discarded."); + LOG.warn("Cannot start background process via bash because no bash installation was found. Hence, output will be discarded."); this.processBuilder.redirectOutput(Redirect.DISCARD).redirectError(Redirect.DISCARD); return; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/process/ProcessResult.java b/cli/src/main/java/com/devonfw/tools/ide/process/ProcessResult.java index 8b9fe1650b..0c52cbb0b2 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/process/ProcessResult.java +++ b/cli/src/main/java/com/devonfw/tools/ide/process/ProcessResult.java @@ -4,9 +4,7 @@ import java.util.function.Predicate; 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. @@ -79,16 +77,16 @@ default String getSingleOutput() { } /** - * @param logger the {@link IdeSubLogger logger} to use. + * @param logLevel the {@link IdeLogLevel} to use. * @return the first captured standard out. Will be {@code null} if not captured but redirected. */ - String getSingleOutput(IdeSubLogger logger); + String getSingleOutput(IdeLogLevel logLevel); /** - * @param logger the {@link IdeSubLogger logger} to use. + * @param logLevel the {@link IdeLogLevel} to use. * @return the first captured standard out. Will be {@code null} if not captured but redirected. */ - List getOutput(IdeSubLogger logger); + List getOutput(IdeLogLevel logLevel); /** * @return the {@link List} with the lines captured on standard out. Will be {@code null} if not captured but redirected. @@ -110,18 +108,16 @@ default String getSingleOutput() { * Logs output and error messages on the provided log level. * * @param level the {@link IdeLogLevel} to use e.g. IdeLogLevel.ERROR. - * @param context the {@link IdeContext} to use. */ - void log(IdeLogLevel level, IdeContext context); + void log(IdeLogLevel level); /** * Logs output and error messages on the provided log level. * * @param outLevel the {@link IdeLogLevel} to use for {@link #getOut()}. - * @param context the {@link IdeContext} to use. * @param errorLevel the {@link IdeLogLevel} to use for {@link #getErr()}. */ - void log(IdeLogLevel outLevel, IdeContext context, IdeLogLevel errorLevel); + void log(IdeLogLevel outLevel, IdeLogLevel errorLevel); /** * Throws a {@link CliProcessException} if not {@link #isSuccessful() successful} and otherwise does nothing. diff --git a/cli/src/main/java/com/devonfw/tools/ide/process/ProcessResultImpl.java b/cli/src/main/java/com/devonfw/tools/ide/process/ProcessResultImpl.java index 9c4538905c..ece2516626 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/process/ProcessResultImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/process/ProcessResultImpl.java @@ -4,16 +4,19 @@ import java.util.List; import java.util.Objects; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + 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}. */ public class ProcessResultImpl implements ProcessResult { + private static final Logger LOG = LoggerFactory.getLogger(ProcessResultImpl.class); + private final String executable; private final String command; @@ -74,7 +77,7 @@ public int getExitCode() { } @Override - public String getSingleOutput(IdeSubLogger logger) throws IllegalStateException { + public String getSingleOutput(IdeLogLevel logLevel) throws IllegalStateException { String errorMessage; if (this.isSuccessful()) { List out = this.getOut(); @@ -99,16 +102,16 @@ public String getSingleOutput(IdeSubLogger logger) throws IllegalStateException } else { errorMessage = "Command " + this.getCommand() + " failed with exit code " + this.getExitCode(); } - if (logger == null) { + if (logLevel == null) { throw new IllegalStateException(errorMessage); } else { - logger.log(errorMessage); + doLog(logLevel, errorMessage); return null; } } @Override - public List getOutput(IdeSubLogger logger) throws IllegalStateException { + public List getOutput(IdeLogLevel logLevel) throws IllegalStateException { String errorMessage; if (this.isSuccessful()) { List out = this.getOut(); @@ -116,10 +119,10 @@ public List getOutput(IdeSubLogger logger) throws IllegalStateException } else { errorMessage = "Command " + this.getCommand() + " failed with exit code " + this.getExitCode(); } - if (logger == null) { + if (logLevel == null) { throw new IllegalStateException(errorMessage); } else { - logger.log(errorMessage); + doLog(logLevel, errorMessage); return null; } } @@ -149,30 +152,30 @@ public boolean isSuccessful() { } @Override - public void log(IdeLogLevel level, IdeContext context) { - log(level, context, level); + public void log(IdeLogLevel level) { + log(level, level); } @Override - public void log(IdeLogLevel outLevel, IdeContext context, IdeLogLevel errorLevel) { + public void log(IdeLogLevel outLevel, IdeLogLevel errorLevel) { if (!this.outputMessages.isEmpty()) { for (OutputMessage outputMessage : this.outputMessages) { if (outputMessage.error()) { - doLog(errorLevel, outputMessage.message(), context); + doLog(errorLevel, outputMessage.message()); } else { - doLog(outLevel, outputMessage.message(), context); + doLog(outLevel, outputMessage.message()); } } } } - private void doLog(IdeLogLevel level, String message, IdeContext context) { + private void doLog(IdeLogLevel level, String message) { // remove !MESSAGE from log message if (message.startsWith("!MESSAGE ")) { message = message.substring(9); } - context.level(level).log(message); + LOG.atLevel(level.getSlf4jLevel()).log(message); } @Override diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/Property.java b/cli/src/main/java/com/devonfw/tools/ide/property/Property.java index aa1edd7d52..dbda7b1271 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/property/Property.java +++ b/cli/src/main/java/com/devonfw/tools/ide/property/Property.java @@ -5,6 +5,9 @@ import java.util.Objects; import java.util.function.Consumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliArgument; import com.devonfw.tools.ide.cli.CliArguments; import com.devonfw.tools.ide.commandlet.Commandlet; @@ -27,6 +30,8 @@ */ public abstract class Property { + private static final Logger LOG = LoggerFactory.getLogger(Property.class); + private static final String INVALID_ARGUMENT = "Invalid CLI argument '{}' for property '{}' of commandlet '{}'"; private static final String INVALID_ARGUMENT_WITH_EXCEPTION_MESSAGE = INVALID_ARGUMENT + ": {}"; @@ -186,7 +191,7 @@ public V getValue() { if (this.value.isEmpty()) { return null; } else { - return this.value.get(0); + return this.value.getFirst(); } } @@ -306,9 +311,9 @@ public final boolean assignValueAsString(String valueAsString, IdeContext contex return true; } catch (Exception e) { if (e instanceof IllegalArgumentException) { - context.warning(INVALID_ARGUMENT, valueAsString, getNameOrAlias(), commandlet.getName()); + LOG.warn(INVALID_ARGUMENT, valueAsString, getNameOrAlias(), commandlet.getName()); } else { - context.warning(INVALID_ARGUMENT_WITH_EXCEPTION_MESSAGE, valueAsString, getNameOrAlias(), commandlet.getName(), e.getMessage()); + LOG.warn(INVALID_ARGUMENT_WITH_EXCEPTION_MESSAGE, valueAsString, getNameOrAlias(), commandlet.getName(), e.getMessage()); } return false; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/security/ToolVersionChoice.java b/cli/src/main/java/com/devonfw/tools/ide/security/ToolVersionChoice.java index 6ee2959a07..fb95358857 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/security/ToolVersionChoice.java +++ b/cli/src/main/java/com/devonfw/tools/ide/security/ToolVersionChoice.java @@ -1,6 +1,9 @@ package com.devonfw.tools.ide.security; -import com.devonfw.tools.ide.log.IdeLogger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.tool.ToolEditionAndVersion; import com.devonfw.tools.ide.url.model.file.json.Cve; import com.devonfw.tools.ide.version.VersionIdentifier; @@ -15,6 +18,8 @@ */ public record ToolVersionChoice(ToolEditionAndVersion toolEditionAndVersion, String option, ToolVulnerabilities vulnerabilities) { + private static final Logger LOG = LoggerFactory.getLogger(ToolVersionChoice.class); + /** @see #ofCurrent(ToolEditionAndVersion, ToolVulnerabilities) */ public static final String CVE_OPTION_CURRENT = "current"; @@ -52,17 +57,16 @@ public static ToolVersionChoice ofNearest(ToolEditionAndVersion toolEditionAndVe } /** - * @param logger the {@link IdeLogger}. * @return {@code true} if {@link ToolVulnerabilities#EMPTY empty} (no vulnerabilities), {@code false} otherwise. */ - public boolean logAndCheckIfEmpty(IdeLogger logger) { + public boolean logAndCheckIfEmpty() { String message = this.vulnerabilities.toString(this.toolEditionAndVersion); if (this.vulnerabilities.getIssues().isEmpty()) { - logger.success(message); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), message); return true; } else { - logger.warning(message); + LOG.warn(message); return false; } } 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 b95bc25da9..19760d9723 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 @@ -3,8 +3,6 @@ import java.util.concurrent.Callable; import java.util.function.Supplier; -import com.devonfw.tools.ide.log.IdeSubLogger; - /** * Interface for a {@link Step} of the process. Allows to split larger processes into smaller steps that are traced and measured. Also prevents that if one step * fails, the overall process can still continue so a sub-step (e.g. "plugin installation" or "git update") does not automatically block the entire process. At @@ -70,6 +68,15 @@ default boolean isFailure() { */ boolean isSilent(); + /** + * Should be called to end this {@link Step} {@link #getSuccess() successfully}. May be called only once. + * + * @param silent to suppress the success message from being logged. + */ + default void success(boolean silent) { + success(); + } + /** * Should be called to end this {@link Step} {@link #getSuccess() successfully}. May be called only once. */ @@ -96,11 +103,6 @@ default void success(String message) { */ void success(String message, Object... args); - /** - * @return the {@link IdeSubLogger} for success messages allowing generic code sharing logger fallback. - */ - IdeSubLogger asSuccess(); - /** * Ensures this {@link Step} is properly ended. Has to be called from a finally block. Do not call manually but always use {@link #run(Runnable)} or * {@link #call(Callable)}. @@ -133,7 +135,7 @@ default void error(String message, Object... 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}. + * @param error the caught {@link Throwable}. */ default void error(Throwable error) { @@ -144,7 +146,7 @@ default void error(Throwable error) { * 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 error the caught {@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) { @@ -169,7 +171,7 @@ default void error(Throwable error, String 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 error the catched {@link Throwable}. May be {@code null} if only a {@code message} is provided. + * @param error the caught {@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}. */ @@ -182,18 +184,13 @@ default void error(Throwable error, String message, Object... 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 error the caught {@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 {@link IdeSubLogger} for error messages allowing generic code sharing logger fallback. - */ - IdeSubLogger asError(); - /** * @return the parent {@link Step} or {@code null} if there is no parent. */ 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 e31275625f..8e334444a3 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 @@ -5,16 +5,21 @@ import java.util.Arrays; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.event.Level; + import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeSubLogger; /** * Regular implementation of {@link Step}. */ public final class StepImpl implements Step { + private static final Logger LOG = LoggerFactory.getLogger(StepImpl.class); + private final AbstractIdeContext context; private final StepImpl parent; @@ -58,12 +63,12 @@ public StepImpl(AbstractIdeContext context, StepImpl parent, String name, boolea parent.children.add(this); } if (params.length == 0) { - this.context.trace("Starting step {}...", name); + LOG.trace("Starting step {}...", name); } else { - this.context.trace("Starting step {} with params {}...", name, Arrays.toString(params)); + LOG.trace("Starting step {} with params {}...", name, Arrays.toString(params)); } if (!this.silent) { - this.context.step("Start: {}", name); + LOG.info(IdeLogLevel.STEP.getSlf4jMarker(), "Start: {}", name); } } @@ -118,63 +123,12 @@ public void success(String message, Object... args) { end(Boolean.TRUE, null, false, message, args); } - @Override - public IdeSubLogger asSuccess() { - - return new IdeSubLogger() { - @Override - public String log(Throwable error, String message, Object... args) { - - assert (error == null); - success(message, args); - return message; - } - - @Override - public boolean isEnabled() { - - return true; - } - - @Override - public IdeLogLevel getLevel() { - - return IdeLogLevel.SUCCESS; - } - }; - } - @Override public void error(Throwable error, boolean suppress, String message, Object... args) { end(Boolean.FALSE, error, suppress, message, args); } - @Override - public IdeSubLogger asError() { - - return new IdeSubLogger() { - @Override - public String log(Throwable error, String message, Object... args) { - - error(error, message, args); - return message; - } - - @Override - public boolean isEnabled() { - - return true; - } - - @Override - public IdeLogLevel getLevel() { - - return IdeLogLevel.ERROR; - } - }; - } - @Override public void close() { @@ -187,7 +141,7 @@ private void end(Boolean newSuccess, Throwable error, boolean suppress, String m if (!firstCallOfEnd) { assert (this.duration > 0); if ((newSuccess != null) && (newSuccess != this.success)) { - this.context.warning("Step '{}' already ended with {} and now ended again with {}.", this.name, this.success, newSuccess); + LOG.warn("Step '{}' already ended with {} and now ended again with {}.", this.name, this.success, newSuccess); } else { return; } @@ -206,13 +160,13 @@ private void end(Boolean newSuccess, Throwable error, boolean suppress, String m if (newSuccess.booleanValue()) { assert (error == null); if (message != null) { - this.context.success(message, args); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), message, args); } else if (!this.silent) { - this.context.success("Successfully ended step '{}'.", this.name); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully ended step '{}'.", this.name); } - this.context.debug("Step '{}' ended successfully.", this.name); + LOG.debug("Step '{}' ended successfully.", this.name); } else { - IdeSubLogger logger; + Level level; if ((message != null) || (error != null)) { if (suppress) { if (error != null) { @@ -220,19 +174,26 @@ private void end(Boolean newSuccess, Throwable error, boolean suppress, String m } else { this.errorMessage = message; } - logger = this.context.debug(); + level = Level.DEBUG; } else { - this.errorMessage = this.context.error().log(error, message, args); + if (message == null) { + message = error.getMessage(); + } + if (args == null) { + LOG.atError().setCause(error).log(message); + } else { + LOG.atError().setCause(error).log(message, args); + } if (error == null) { - logger = this.context.debug(); + level = Level.DEBUG; } else { - logger = this.context.error(); + level = Level.ERROR; } } } else { - logger = this.context.info(); + level = Level.INFO; } - logger.log("Step '{}' ended with failure.", this.name); + LOG.atLevel(level).log("Step '{}' ended with failure.", this.name); } if (firstCallOfEnd) { this.context.endStep(this); @@ -246,8 +207,8 @@ private void end(Boolean newSuccess, Throwable error, boolean suppress, String m */ public void logSummary(boolean suppressSuccess) { - if (this.context.trace().isEnabled()) { - this.context.trace(toString()); + if (LOG.isTraceEnabled()) { + LOG.trace(toString()); } if (this.context.isQuietMode() || (this.children.isEmpty())) { return; @@ -256,10 +217,10 @@ public void logSummary(boolean suppressSuccess) { logErrorSummary(0, summary); if (summary.getError() == 0) { if (!suppressSuccess) { - this.context.success("Successfully completed {}", getNameWithParams()); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully completed {}", getNameWithParams()); } } else { - this.context.error(summary.toString()); + LOG.error(summary.toString()); } } @@ -272,7 +233,7 @@ private void logErrorSummary(int depth, StepSummary summary) { if (error == null) { error = "unexpected error"; } - this.context.error("{}Step '{}' failed: {}", getIndent(depth), getNameWithParams(), error); + LOG.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/GlobalToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java index 824276ceb1..4385b49acf 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java @@ -6,13 +6,19 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.FileAccess; +import com.devonfw.tools.ide.log.IdeLogLevel; 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.step.Step; import com.devonfw.tools.ide.tool.repository.ToolRepository; import com.devonfw.tools.ide.version.VersionIdentifier; @@ -21,6 +27,8 @@ */ public abstract class GlobalToolCommandlet extends ToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(GlobalToolCommandlet.class); + /** * The constructor. * @@ -59,7 +67,7 @@ protected boolean runWithPackageManager(boolean silent, List getInstallPackageManagerCommands() { @Override public VersionIdentifier getInstalledVersion() { //TODO: handle "get-version " - this.context.error("Couldn't get installed version of " + this.getName()); + LOG.error("Couldn't get installed version of " + this.getName()); return null; } @Override public String getInstalledEdition() { //TODO: handle "get-edition " - this.context.error("Couldn't get installed edition of " + this.getName()); + LOG.error("Couldn't get installed edition of " + this.getName()); return null; } @@ -207,6 +220,6 @@ protected Path getInstallationPath(String edition, VersionIdentifier resolvedVer @Override public void uninstall() { //TODO: handle "uninstall " - this.context.error("Couldn't uninstall " + this.getName()); + LOG.error("Couldn't uninstall " + this.getName()); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/LocalToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/LocalToolCommandlet.java index 1d16ea7cd3..ded3cb26a1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/LocalToolCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/LocalToolCommandlet.java @@ -134,10 +134,13 @@ private ToolInstallation doInstallStep(ToolInstallRequest request) { ToolEdition toolEdition = requested.getEdition(); Step step = request.getStep(); if (installedVersion == null) { - asSuccess(step).log("Successfully installed {} in version {} at {}", toolEdition, resolvedVersion, toolPath); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully installed {} in version {} at {}", toolEdition, resolvedVersion, toolPath); } else { - asSuccess(step).log("Successfully installed {} in version {} replacing previous version {} of {} at {}", toolEdition, resolvedVersion, - installedVersion, installed.getEdition(), toolPath); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully installed {} in version {} replacing previous version {} of {} at {}", toolEdition, + resolvedVersion, installedVersion, installed.getEdition(), toolPath); + } + if (step != null) { + step.success(true); } return installation; } @@ -163,7 +166,7 @@ protected boolean isIgnoreSoftwareRepo() { public ToolInstallation installTool(ToolInstallRequest request) { completeRequest(request); // most likely already done, but if installTool was called directly and not from install - if (request.isInstallLoop(this.context)) { + if (request.isInstallLoop()) { return toolAlreadyInstalled(request); } ToolEditionAndVersion requested = request.getRequested(); 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 d19ae19ee2..0da418e472 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 @@ -10,6 +10,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.event.Level; + import com.devonfw.tools.ide.commandlet.Commandlet; import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.common.Tags; @@ -17,7 +21,7 @@ import com.devonfw.tools.ide.environment.EnvironmentVariables; import com.devonfw.tools.ide.environment.EnvironmentVariablesFiles; import com.devonfw.tools.ide.io.FileCopyMode; -import com.devonfw.tools.ide.log.IdeSubLogger; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.nls.NlsBundle; import com.devonfw.tools.ide.os.MacOsHelper; import com.devonfw.tools.ide.process.EnvironmentContext; @@ -42,6 +46,8 @@ */ public abstract class ToolCommandlet extends Commandlet implements Tags { + private static final Logger LOG = LoggerFactory.getLogger(ToolCommandlet.class); + /** @see #getName() */ protected final String tool; @@ -220,7 +226,7 @@ public ProcessResult runTool(ToolInstallRequest request, ProcessMode processMode // if the CVE check has already been done, we can assume that the install(request) has already been called before // most likely a postInstall* method was overridden calling this method with the same request what is a programming error // we render this warning so the error gets detected and can be fixed but we do not block the user by skipping the installation. - this.context.warning().log(new RuntimeException(), "Preventing infinity loop during installation of {}", request.getRequested()); + LOG.warn("Preventing infinity loop during installation of {}", request.getRequested(), new RuntimeException()); } else { install(request); } @@ -291,7 +297,7 @@ public ToolInstallation install(boolean silent) { public ToolInstallation install(ToolInstallRequest request) { completeRequest(request); - if (request.isInstallLoop(this.context)) { + if (request.isInstallLoop()) { return toolAlreadyInstalled(request); } return doInstall(request); @@ -547,14 +553,14 @@ protected ToolInstallation toolAlreadyInstalled(ToolInstallRequest request) { * @param request the {@link ToolInstallRequest}. */ protected void logToolAlreadyInstalled(ToolInstallRequest request) { - IdeSubLogger logger; + Level level; if (request.isSilent()) { - logger = this.context.debug(); + level = Level.DEBUG; } else { - logger = this.context.info(); + level = Level.INFO; } ToolEditionAndVersion installed = request.getInstalled(); - logger.log("Version {} of tool {} is already installed", installed.getVersion(), installed.getEdition()); + LOG.atLevel(level).log("Version {} of tool {} is already installed", installed.getVersion(), installed.getEdition()); } /** @@ -619,10 +625,10 @@ protected VersionIdentifier cveCheck(ToolInstallRequest request) { } ToolSecurity toolSecurity = this.context.getDefaultToolRepository().findSecurity(this.tool, toolEdition.edition()); double minSeverity = IdeVariables.CVE_MIN_SEVERITY.get(context); - ToolVulnerabilities currentVulnerabilities = toolSecurity.findCves(resolvedVersion, this.context, minSeverity); + ToolVulnerabilities currentVulnerabilities = toolSecurity.findCves(resolvedVersion, minSeverity); ToolVersionChoice currentChoice = ToolVersionChoice.ofCurrent(requested, currentVulnerabilities); request.setCveCheckDone(); - if (currentChoice.logAndCheckIfEmpty(this.context)) { + if (currentChoice.logAndCheckIfEmpty()) { return resolvedVersion; } boolean alreadyInstalled = request.isAlreadyInstalled(); @@ -631,7 +637,7 @@ protected VersionIdentifier cveCheck(ToolInstallRequest request) { // currently for a transitive dependency it does not make sense to suggest alternative versions, since the choice is not stored anywhere, // and we then would ask the user again every time the tool having this dependency is started. So we only log the problem and the user needs to react // (e.g. upgrade the tool with the dependency that is causing this). - this.context.interaction("Please run 'ide -f install {}' to check for update suggestions!", this.tool); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "Please run 'ide -f install {}' to check for update suggestions!", this.tool); return resolvedVersion; } ToolVersionChoice latest = null; @@ -646,7 +652,7 @@ protected VersionIdentifier cveCheck(ToolInstallRequest request) { } if (acceptVersion(version, allowedVersions, requireStableVersion)) { - ToolVulnerabilities newVulnerabilities = toolSecurity.findCves(version, this.context, minSeverity); + ToolVulnerabilities newVulnerabilities = toolSecurity.findCves(version, minSeverity); if (newVulnerabilities.isSafer(latestVulnerabilities)) { // we found a better/safer version ToolEditionAndVersion toolEditionAndVersion = new ToolEditionAndVersion(toolEdition, version); @@ -667,7 +673,7 @@ protected VersionIdentifier cveCheck(ToolInstallRequest request) { } } if ((latest == null) && (nearest == null)) { - this.context.warning( + LOG.warn( "Could not find any other version resolving your CVEs.\nPlease keep attention to this tool and consider updating as soon as security fixes are available."); if (alreadyInstalled) { // we came here via "ide -f install ..." but no alternative is available @@ -687,17 +693,16 @@ protected VersionIdentifier cveCheck(ToolInstallRequest request) { if (addSuggestions) { choices.add(nearest); } - nearest.logAndCheckIfEmpty(this.context); + nearest.logAndCheckIfEmpty(); } if (latest != null) { if (addSuggestions) { choices.add(latest); } - latest.logAndCheckIfEmpty(this.context); + latest.logAndCheckIfEmpty(); } ToolVersionChoice[] choicesArray = choices.toArray(ToolVersionChoice[]::new); - this.context.warning( - "Please note that by selecting an unsafe version to install, you accept the risk to be attacked."); + LOG.warn("Please note that by selecting an unsafe version to install, you accept the risk to be attacked."); ToolVersionChoice answer = this.context.question(choicesArray, "Which version do you want to install?"); VersionIdentifier version = answer.toolEditionAndVersion().getResolvedVersion(); requested.setResolvedVersion(version); @@ -762,7 +767,7 @@ public void listEditions() { List editions = getToolRepository().getSortedEditions(getName()); for (String edition : editions) { - this.context.info(edition); + LOG.info(edition); } } @@ -773,7 +778,7 @@ public void listVersions() { List versions = getToolRepository().getSortedVersions(getName(), getConfiguredEdition(), this); for (VersionIdentifier vi : versions) { - this.context.info(vi.toString()); + LOG.info(vi.toString()); } } @@ -797,7 +802,7 @@ public void setVersion(String version) { } VersionIdentifier configuredVersion = VersionIdentifier.of(version); if (!configuredVersion.isPattern() && !configuredVersion.isValid()) { - this.context.warning("Version {} seems to be invalid", version); + LOG.warn("Version {} seems to be invalid", version); } setVersion(configuredVersion, true); } @@ -838,12 +843,12 @@ public void setVersion(VersionIdentifier version, boolean hint, EnvironmentVaria settingsVariables.save(); EnvironmentVariables declaringVariables = variables.findVariable(name); if ((declaringVariables != null) && (declaringVariables != settingsVariables)) { - this.context.warning("The variable {} is overridden in {}. Please remove the overridden declaration in order to make the change affect.", name, + LOG.warn("The variable {} is overridden in {}. Please remove the overridden declaration in order to make the change affect.", name, declaringVariables.getSource()); } if (hint) { - this.context.info("To install that version call the following command:"); - this.context.info("ide install {}", this.tool); + LOG.info("To install that version call the following command:"); + LOG.info("ide install {}", this.tool); } } @@ -887,7 +892,7 @@ public void setEdition(String edition, boolean hint, EnvironmentVariablesFiles d } if (!getToolRepository().getSortedEditions(this.tool).contains(edition)) { - this.context.warning("Edition {} seems to be invalid", edition); + LOG.warn("Edition {} seems to be invalid", edition); } EnvironmentVariables variables = this.context.getVariables(); EnvironmentVariables settingsVariables = variables.getByType(destination.toType()); @@ -895,15 +900,15 @@ public void setEdition(String edition, boolean hint, EnvironmentVariablesFiles d settingsVariables.set(name, edition, false); settingsVariables.save(); - this.context.info("{}={} has been set in {}", name, edition, settingsVariables.getSource()); + LOG.info("{}={} has been set in {}", name, edition, settingsVariables.getSource()); EnvironmentVariables declaringVariables = variables.findVariable(name); if ((declaringVariables != null) && (declaringVariables != settingsVariables)) { - this.context.warning("The variable {} is overridden in {}. Please remove the overridden declaration in order to make the change affect.", name, + LOG.warn("The variable {} is overridden in {}. Please remove the overridden declaration in order to make the change affect.", name, declaringVariables.getSource()); } if (hint) { - this.context.info("To install that edition call the following command:"); - this.context.info("ide install {}", this.tool); + LOG.info("To install that edition call the following command:"); + LOG.info("ide install {}", this.tool); } } @@ -1008,29 +1013,16 @@ protected VersionIdentifier resolveVersionWithPattern(String output, Pattern pat } /** - * @param step the {@link Step} to get {@link Step#asSuccess() success logger} from. May be {@code null}. - * @return the {@link IdeSubLogger} from {@link Step#asSuccess()} or {@link IdeContext#success()} as fallback. + * @deprecated directly log success message and then report success on step if not null. */ - protected IdeSubLogger asSuccess(Step step) { + @Deprecated + protected void success(Step step, String message, Object... args) { if (step == null) { - return this.context.success(); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), message, args); } else { - return step.asSuccess(); + step.success(message, args); } } - - /** - * @param step the {@link Step} to get {@link Step#asError() error logger} from. May be {@code null}. - * @return the {@link IdeSubLogger} from {@link Step#asError()} or {@link IdeContext#error()} as fallback. - */ - protected IdeSubLogger asError(Step step) { - - if (step == null) { - return this.context.error(); - } else { - return step.asError(); - } - } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/ToolInstallRequest.java b/cli/src/main/java/com/devonfw/tools/ide/tool/ToolInstallRequest.java index ba958820c0..083d6b47f7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/ToolInstallRequest.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/ToolInstallRequest.java @@ -2,7 +2,9 @@ import java.nio.file.Path; -import com.devonfw.tools.ide.log.IdeLogger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.process.ProcessContext; import com.devonfw.tools.ide.step.Step; import com.devonfw.tools.ide.version.GenericVersionRange; @@ -14,6 +16,8 @@ */ public final class ToolInstallRequest { + private static final Logger LOG = LoggerFactory.getLogger(ToolInstallRequest.class); + private final ToolInstallRequest parent; private final boolean silent; @@ -69,10 +73,9 @@ private ToolInstallRequest(ToolInstallRequest parent, boolean silent, boolean di } /** - * @param logger the {@link IdeLogger} used to log an installation loop if found. * @return {@code true} if an installation loop was found and logged, {@code false} otherwise. */ - public boolean isInstallLoop(IdeLogger logger) { + public boolean isInstallLoop() { if ((this.requested == null) || (this.requested.getEdition() == null)) { throw new IllegalStateException(); // this method was called too early @@ -80,7 +83,7 @@ public boolean isInstallLoop(IdeLogger logger) { StringBuilder sb = new StringBuilder(); boolean loopFound = detectInstallLoopRecursively(this.requested, sb); if (loopFound) { - logger.warning("Found installation loop:\n" + LOG.warn("Found installation loop:\n" + "{}\n" + "This typically indicates an internal bug in IDEasy.\n" + "Please report this bug, when you see this and include this entire warning message.\n" diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/custom/CustomToolsMapper.java b/cli/src/main/java/com/devonfw/tools/ide/tool/custom/CustomToolsMapper.java index 605847de9d..e29d5f3e86 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/custom/CustomToolsMapper.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/custom/CustomToolsMapper.java @@ -3,6 +3,9 @@ import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.environment.VariableLine; import com.devonfw.tools.ide.json.JsonMapping; @@ -17,6 +20,8 @@ */ public class CustomToolsMapper extends StandardJsonObjectMapper { + private static final Logger LOG = LoggerFactory.getLogger(CustomToolsMapper.class); + private static final CustomToolsMapper INSTANCE = new CustomToolsMapper(); private final ObjectMapper MAPPER = JsonMapping.create(); @@ -101,10 +106,9 @@ private static CustomToolMetadata convert(CustomTool customTool, String reposito * Retrieves custom tools from a devonfw-ide legacy config. * * @param customToolsContent String of custom tools - * @param context the {@link IdeContext}. * @return {@link CustomTools}. */ - public static CustomTools parseCustomToolsFromLegacyConfig(String customToolsContent, IdeContext context) { + public static CustomTools parseCustomToolsFromLegacyConfig(String customToolsContent) { List customToolEntries = VariableLine.parseArray(customToolsContent); if (customToolEntries.isEmpty()) { return null; @@ -114,12 +118,12 @@ public static CustomTools parseCustomToolsFromLegacyConfig(String customToolsCon for (String customToolConfig : customToolEntries) { CustomTool customTool = parseCustomToolFromLegacyConfig(customToolConfig); if (customTool == null) { - context.warning("Invalid custom tool entry: {}", customToolConfig); + LOG.warn("Invalid custom tool entry: {}", customToolConfig); } else { String url = customTool.url(); if (defaultUrl == null) { if ((url == null) || url.isEmpty()) { - context.warning("First custom tool entry has no URL specified: {}", customToolConfig); + LOG.warn("First custom tool entry has no URL specified: {}", customToolConfig); } else { defaultUrl = url; customTool = customTool.withoutUrl(); diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java b/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java index 84c2de715d..01b3881c82 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java @@ -1,16 +1,17 @@ package com.devonfw.tools.ide.tool.docker; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.os.SystemArchitecture; import com.devonfw.tools.ide.os.WindowsHelper; -import com.devonfw.tools.ide.os.WindowsHelperImpl; import com.devonfw.tools.ide.tool.GlobalToolCommandlet; import com.devonfw.tools.ide.tool.NativePackageManager; import com.devonfw.tools.ide.tool.PackageManagerCommand; @@ -24,11 +25,12 @@ */ public class Docker extends GlobalToolCommandlet { - private static final String PODMAN = "podman"; + private static final Logger LOG = LoggerFactory.getLogger(Docker.class); + private static final String PODMAN = "podman"; private static final Pattern RDCTL_CLIENT_VERSION_PATTERN = Pattern.compile("client version:\\s*v([\\d.]+)", Pattern.CASE_INSENSITIVE); - + private static final Pattern DOCKER_DESKTOP_LINUX_VERSION_PATTERN = Pattern.compile("^([0-9]+(?:\\.[0-9]+){1,2})"); /** @@ -98,7 +100,7 @@ protected List getInstallPackageManagerCommands() { public VersionIdentifier getInstalledVersion() { if (!isDockerInstalled()) { - this.context.error("Couldn't get installed version of " + this.getName()); + LOG.error("Couldn't get installed version of " + this.getName()); return null; } @@ -112,7 +114,7 @@ public VersionIdentifier getInstalledVersion() { }; if (parsedVersion == null) { - this.context.error("Couldn't get installed version of " + this.getName()); + LOG.error("Couldn't get installed version of " + this.getName()); } return parsedVersion; @@ -146,7 +148,7 @@ private VersionIdentifier getRancherDesktopClientVersion() { public String getInstalledEdition() { if (!isDockerInstalled()) { - this.context.error("Couldn't get installed edition of " + this.getName()); + LOG.error("Couldn't get installed edition of {}", this.getName()); return null; } @@ -172,9 +174,9 @@ private List getPackageManagerCommandsUninstall() { List pmCommands = new ArrayList<>(); pmCommands.add( - new PackageManagerCommand(NativePackageManager.ZYPPER, Arrays.asList("sudo zypper remove rancher-desktop"))); + new PackageManagerCommand(NativePackageManager.ZYPPER, List.of("sudo zypper remove rancher-desktop"))); pmCommands.add( - new PackageManagerCommand(NativePackageManager.APT, Arrays.asList("sudo apt -y autoremove rancher-desktop"))); + new PackageManagerCommand(NativePackageManager.APT, List.of("sudo apt -y autoremove rancher-desktop"))); return pmCommands; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/Eclipse.java b/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/Eclipse.java index 62e2358e36..8a84596012 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/Eclipse.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/eclipse/Eclipse.java @@ -8,6 +8,9 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; @@ -27,6 +30,8 @@ */ public class Eclipse extends IdeToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(Eclipse.class); + // version must correspond to eclipse-import.xml private static final String GROOVY_VERSION = "3.0.23"; @@ -93,13 +98,13 @@ public boolean installPlugin(ToolPluginDescriptor plugin, Step step, ProcessCont if (result.isSuccessful()) { for (String line : result.getOut()) { if (line.contains("Overall install request is satisfiable")) { - this.context.success("Successfully installed plugin: {}", plugin.name()); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully installed plugin: {}", plugin.name()); step.success(); return true; } } } - result.log(IdeLogLevel.DEBUG, context, IdeLogLevel.ERROR); + result.log(IdeLogLevel.DEBUG, IdeLogLevel.ERROR); step.error("Failed to install plugin {} ({}): exit code was {}", plugin.name(), plugin.id(), result.getExitCode()); return false; } @@ -121,8 +126,8 @@ protected void configureWorkspace() { private static boolean isLocked(Path lockfile) { if (Files.isRegularFile(lockfile)) { - try (RandomAccessFile raFile = new RandomAccessFile(lockfile.toFile(), "rw")) { - FileLock fileLock = raFile.getChannel().tryLock(0, 1, false); + try (RandomAccessFile raFile = new RandomAccessFile(lockfile.toFile(), "rw"); + FileLock fileLock = raFile.getChannel().tryLock(0, 1, false)) { // success, file was not locked so we immediately unlock again... fileLock.release(); return false; 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 3e8f5e455a..6f0256c581 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 @@ -5,6 +5,9 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.FileAccess; @@ -24,6 +27,8 @@ */ public abstract class IdeToolCommandlet extends PluginBasedCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(IdeToolCommandlet.class); + /** * The constructor. * @@ -73,7 +78,7 @@ protected void configureWorkspace() { FileAccess fileAccess = this.context.getFileAccess(); Path workspaceFolder = this.context.getWorkspacePath(); if (!fileAccess.isExpectedFolder(workspaceFolder)) { - this.context.warning("Current workspace does not exist: {}", workspaceFolder); + LOG.warn("Current workspace does not exist: {}", workspaceFolder); return; // should actually never happen... } Step step = this.context.newStep("Configuring workspace " + workspaceFolder.getFileName() + " for IDE " + this.tool); @@ -110,10 +115,10 @@ private int mergeWorkspaceSingle(Path templatesFolder, Path workspaceFolder, int Path setupFolder = templatesFolder.resolve(IdeContext.FOLDER_SETUP); Path updateFolder = templatesFolder.resolve(IdeContext.FOLDER_UPDATE); if (!Files.isDirectory(setupFolder) && !Files.isDirectory(updateFolder)) { - this.context.trace("Skipping empty or non-existing workspace template folder {}.", templatesFolder); + LOG.trace("Skipping empty or non-existing workspace template folder {}.", templatesFolder); return errors; } - this.context.debug("Merging workspace templates from {}...", templatesFolder); + LOG.debug("Merging workspace templates from {}...", templatesFolder); return errors + this.context.getWorkspaceMerger().merge(setupFolder, updateFolder, this.context.getVariables(), workspaceFolder); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeaBasedIdeToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeaBasedIdeToolCommandlet.java index 3064204d33..62ef7911bd 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeaBasedIdeToolCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeaBasedIdeToolCommandlet.java @@ -4,8 +4,12 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.process.ProcessContext; import com.devonfw.tools.ide.process.ProcessMode; import com.devonfw.tools.ide.process.ProcessResult; @@ -18,6 +22,8 @@ */ public class IdeaBasedIdeToolCommandlet extends IdeToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(IdeaBasedIdeToolCommandlet.class); + /** * The constructor. * @@ -42,7 +48,7 @@ public boolean installPlugin(ToolPluginDescriptor plugin, final Step step, Proce } ProcessResult result = runTool(pc, ProcessMode.DEFAULT, args); if (result.isSuccessful()) { - this.context.success("Successfully installed plugin: {}", plugin.name()); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully installed plugin: {}", plugin.name()); step.success(); return true; } else { diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeaPluginDownloader.java b/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeaPluginDownloader.java index e7ef401085..216c6a26b0 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeaPluginDownloader.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeaPluginDownloader.java @@ -14,6 +14,9 @@ import java.time.Duration; import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.FileAccess; import com.devonfw.tools.ide.os.MacOsHelper; @@ -26,6 +29,8 @@ */ public class IdeaPluginDownloader { + private static final Logger LOG = LoggerFactory.getLogger(IdeaPluginDownloader.class); + private static final String BUILD_FILE = "build.txt"; private final IdeContext context; private final IdeaBasedIdeToolCommandlet commandlet; @@ -130,7 +135,7 @@ private Path downloadPlugin(FileAccess fileAccess, String downloadUrl, Path tmpD private void extractDownloadedPlugin(FileAccess fileAccess, Path downloadedFile, String pluginId) throws IOException { Path targetDir = this.commandlet.getPluginsInstallationPath().resolve(pluginId); if (Files.exists(targetDir)) { - context.info("Plugin already installed, target directory already existing: {}", targetDir); + LOG.info("Plugin already installed, target directory already existing: {}", targetDir); } else { fileAccess.extract(downloadedFile, targetDir); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/intellij/Intellij.java b/cli/src/main/java/com/devonfw/tools/ide/tool/intellij/Intellij.java index 7943fd317f..ba089a640f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/intellij/Intellij.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/intellij/Intellij.java @@ -6,6 +6,8 @@ import java.util.Map.Entry; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import com.devonfw.tools.ide.cli.CliException; @@ -30,6 +32,8 @@ */ public class Intellij extends IdeaBasedIdeToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(Intellij.class); + private static final String IDEA = "idea"; private static final String IDEA64_EXE = IDEA + "64.exe"; @@ -118,12 +122,12 @@ public void importRepository(Path repositoryPath) { Path buildDescriptor = buildTool.findBuildDescriptor(repositoryPath); if (buildDescriptor != null) { String templateFilename = entry.getValue(); - this.context.debug("Found build descriptor {} so merging template {}", buildDescriptor, templateFilename); + LOG.debug("Found build descriptor {} so merging template {}", buildDescriptor, templateFilename); mergeConfig(repositoryPath, templateFilename); return; } } - this.context.warning("No supported build descriptor was found for project import in {}", repositoryPath); + LOG.warn("No supported build descriptor was found for project import in {}", repositoryPath); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/Jmc.java b/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/Jmc.java index 4e0b41e248..f374f56285 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/Jmc.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/jmc/Jmc.java @@ -7,6 +7,9 @@ import java.util.Set; import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.FileAccess; @@ -20,6 +23,8 @@ */ public class Jmc extends LocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(Jmc.class); + /** * The constructor. * @@ -47,9 +52,7 @@ protected void postExtract(Path extractedDir) { moveFilesAndDirs(oldBinaryPath, extractedDir); fileAccess.delete(oldBinaryPath); } else { - this.context.debug( - "JMC binary folder not found at {} - ignoring as this legacy problem may be resolved in newer versions.", - oldBinaryPath); + LOG.debug("JMC binary folder not found at {} - ignoring as this legacy problem may be resolved in newer versions.", oldBinaryPath); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/lazydocker/LazyDocker.java b/cli/src/main/java/com/devonfw/tools/ide/tool/lazydocker/LazyDocker.java index b6a87ef072..4619a7bce9 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/lazydocker/LazyDocker.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/lazydocker/LazyDocker.java @@ -54,7 +54,7 @@ private void verifyDockerVersion(ProcessResult result, VersionIdentifier minimum // we have this pattern a lot that we want to get a single line output of a successful ProcessResult. // we should create a generic method in ProcessResult for this use-case. if (!result.isSuccessful()) { - result.log(IdeLogLevel.WARNING, this.context); + result.log(IdeLogLevel.WARNING); } if (result.getOut().isEmpty()) { throw new CliException("Docker is not installed, but required for lazydocker.\n" // diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/MvnRepository.java b/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/MvnRepository.java index 3274855bd6..fb8de6f82e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/MvnRepository.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/MvnRepository.java @@ -199,7 +199,7 @@ public VersionIdentifier resolveVersion(MvnArtifact artifact, GenericVersionRang artifact = artifact.withVersion(versionString); } List versions = fetchVersions(artifact); - VersionIdentifier resolvedVersion = VersionIdentifier.resolveVersionPattern(version, versions, this.context); + VersionIdentifier resolvedVersion = VersionIdentifier.resolveVersionPattern(version, versions); versionString = resolvedVersion.toString(); if (versionString.endsWith("-SNAPSHOT")) { artifact = artifact.withVersion(versionString); diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/npm/NpmBasedCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/npm/NpmBasedCommandlet.java index 24b3d1911d..93eeb39768 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/npm/NpmBasedCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/npm/NpmBasedCommandlet.java @@ -4,6 +4,9 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.process.ProcessContext; @@ -21,6 +24,8 @@ */ public abstract class NpmBasedCommandlet extends NodeBasedCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(NpmBasedCommandlet.class); + /** * The constructor. * @@ -52,7 +57,7 @@ protected VersionIdentifier computeInstalledVersion() { private VersionIdentifier runPackageManagerGetInstalledVersion(String npmPackage) { if (!Files.isDirectory(this.context.getSoftwarePath().resolve("node"))) { - this.context.trace("Since node is not installed, also package {} for tool {} cannot be installed.", npmPackage, this.tool); + LOG.trace("Since node is not installed, also package {} for tool {} cannot be installed.", npmPackage, this.tool); return null; } PackageManagerRequest request = new PackageManagerRequest("list", npmPackage).addArg("list").addArg("-g").addArg(npmPackage).addArg("--depth=0") @@ -74,7 +79,7 @@ private VersionIdentifier runPackageManagerGetInstalledVersion(String npmPackage return VersionIdentifier.of(parsedVersion); } } else { - this.context.debug("The npm package {} for tool {} is not installed.", npmPackage, this.tool); + LOG.debug("The npm package {} for tool {} is not installed.", npmPackage, this.tool); } return null; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipBasedCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipBasedCommandlet.java index 47b09afd1c..b94a4124d0 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipBasedCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipBasedCommandlet.java @@ -4,6 +4,9 @@ import java.nio.file.Path; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.log.IdeLogLevel; @@ -24,6 +27,8 @@ */ public abstract class PipBasedCommandlet extends PackageManagerBasedLocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(PipBasedCommandlet.class); + private static final String PIP_SHOW_VERSION_PREFIX = "Version:"; /** @@ -54,7 +59,7 @@ protected Class getPackageManagerClass() { case "pip" -> Pip.class; case "uv" -> Uv.class; default -> { - this.context.warning("Undefined value: PIP_EDITION={}", edition); + LOG.warn("Undefined value: PIP_EDITION={}", edition); yield Pip.class; } }; @@ -115,8 +120,8 @@ protected VersionIdentifier computeInstalledVersion() { } } } - this.context.debug("Could not find version from pip show output:"); - processResult.log(IdeLogLevel.DEBUG, this.context); + LOG.debug("Could not find version from pip show output:"); + processResult.log(IdeLogLevel.DEBUG); return null; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/PluginBasedCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/PluginBasedCommandlet.java index 0fc33f88b9..75eec695b1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/PluginBasedCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/PluginBasedCommandlet.java @@ -6,6 +6,9 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; @@ -22,6 +25,8 @@ */ public abstract class PluginBasedCommandlet extends LocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(PluginBasedCommandlet.class); + private ToolPlugins plugins; /** @@ -109,7 +114,7 @@ protected void postInstall(ToolInstallRequest request) { List markerFiles = fileAccess.listChildren(this.context.getIdeHome().resolve(IdeContext.FOLDER_DOT_IDE), Files::isRegularFile); for (Path path : markerFiles) { if (path.getFileName().toString().startsWith("plugin." + getName())) { - this.context.debug("Plugin marker file {} got deleted.", path); + LOG.debug("Plugin marker file {} got deleted.", path); fileAccess.delete(path); } } @@ -133,14 +138,14 @@ protected void installPlugins(Collection plugins, ProcessC Path pluginMarkerFile = retrievePluginMarkerFilePath(plugin); boolean pluginMarkerFileExists = pluginMarkerFile != null && Files.exists(pluginMarkerFile); if (pluginMarkerFileExists) { - this.context.debug("Markerfile for IDE {} and plugin '{}' already exists.", getName(), plugin.name()); + LOG.debug("Markerfile for IDE {} and plugin '{}' already exists.", getName(), plugin.name()); } if (plugin.active()) { if (this.context.isForcePlugins() || !pluginMarkerFileExists) { Step step = this.context.newStep("Install plugin " + plugin.name()); step.run(() -> doInstallPluginStep(plugin, step, pc)); } else { - this.context.debug("Skipping installation of plugin '{}' due to existing marker file: {}", plugin.name(), pluginMarkerFile); + LOG.debug("Skipping installation of plugin '{}' due to existing marker file: {}", plugin.name(), pluginMarkerFile); } } else { if (!pluginMarkerFileExists) { @@ -211,22 +216,22 @@ public void uninstallPlugin(ToolPluginDescriptor plugin) { boolean error = false; Path pluginsPath = getPluginsInstallationPath(); if (!Files.isDirectory(pluginsPath)) { - this.context.debug("Omitting to uninstall plugin {} ({}) as plugins folder does not exist at {}", + LOG.debug("Omitting to uninstall plugin {} ({}) as plugins folder does not exist at {}", plugin.name(), plugin.id(), pluginsPath); error = true; } FileAccess fileAccess = this.context.getFileAccess(); Path match = fileAccess.findFirst(pluginsPath, p -> p.getFileName().toString().startsWith(plugin.id()), false); if (match == null) { - this.context.debug("Omitting to uninstall plugin {} ({}) as plugins folder does not contain a match at {}", + LOG.debug("Omitting to uninstall plugin {} ({}) as plugins folder does not contain a match at {}", plugin.name(), plugin.id(), pluginsPath); error = true; } if (error) { - context.error("Could not uninstall plugin " + plugin + " because we could not find an installation"); + LOG.error("Could not uninstall plugin {} because we could not find an installation", plugin); } else { fileAccess.delete(match); - context.info("Successfully uninstalled plugin " + plugin); + LOG.info("Successfully uninstalled plugin {}", plugin); } } @@ -257,6 +262,6 @@ public ToolPluginDescriptor getPlugin(String key) { */ protected void handleInstallForInactivePlugin(ToolPluginDescriptor plugin) { - this.context.debug("Omitting installation of inactive plugin {} ({}).", plugin.name(), plugin.id()); + LOG.debug("Omitting installation of inactive plugin {} ({}).", plugin.name(), plugin.id()); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/ToolPluginDescriptor.java b/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/ToolPluginDescriptor.java index da7fc8d056..7d115a540c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/ToolPluginDescriptor.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/plugin/ToolPluginDescriptor.java @@ -5,10 +5,12 @@ import java.util.Properties; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.common.Tags; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.log.IdeLogger; /** * Implementation of {@link ToolPluginDescriptor}. @@ -21,6 +23,8 @@ */ public record ToolPluginDescriptor(String id, String name, String url, boolean active, Set tags) implements Tags { + private static final Logger LOG = LoggerFactory.getLogger(ToolPluginDescriptor.class); + @Override public Set getTags() { @@ -42,16 +46,15 @@ public static ToolPluginDescriptor of(Path propertiesFile, IdeContext context, b String id = getString(properties, "id", "plugin_id"); String url = getString(properties, "url", "plugin_url"); if (needUrl && ((url == null) || url.isBlank())) { - context.warning("Missing plugin URL in {}", propertiesFile); + LOG.warn("Missing plugin URL in {}", propertiesFile); } - boolean active = getBoolean(properties, "active", "plugin_active", propertiesFile, context); + boolean active = getBoolean(properties, "active", "plugin_active", propertiesFile); String tagsCsv = getString(properties, "tags", "plugin_tags"); Set tags = Tag.parseCsv(tagsCsv); return new ToolPluginDescriptor(id, name, url, active, tags); } - private static boolean getBoolean(Properties properties, String key, String legacyKey, Path propertiesFile, - IdeLogger logger) { + private static boolean getBoolean(Properties properties, String key, String legacyKey, Path propertiesFile) { String value = getString(properties, key, legacyKey); if (value == null) { @@ -63,7 +66,7 @@ private static boolean getBoolean(Properties properties, String key, String lega } else if ("false".equals(lower)) { return false; } - logger.warning("Invalid boolean value '{}' for property '{}' in {}", value, key, propertiesFile); + LOG.warn("Invalid boolean value '{}' for property '{}' in {}", value, key, propertiesFile); return false; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/python/Python.java b/cli/src/main/java/com/devonfw/tools/ide/tool/python/Python.java index 78df0ea958..caa38b5a3e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/python/Python.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/python/Python.java @@ -5,6 +5,9 @@ import java.nio.file.StandardCopyOption; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; @@ -22,6 +25,8 @@ */ public class Python extends LocalToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(Python.class); + private final VersionIdentifier PYTHON_MIN_VERSION = VersionIdentifier.of("3.8.2"); /** @@ -53,7 +58,7 @@ protected void performToolInstallation(ToolInstallRequest request, Path installa renameVenvFolderToPython(fileAccess, softwarePath, installationPath); this.context.writeVersionFile(resolvedVersion, installationPath); createWindowsSymlinkBinFolder(fileAccess, installationPath); - this.context.debug("Installed {} in version {} at {}", this.tool, resolvedVersion, installationPath); + LOG.debug("Installed {} in version {} at {}", this.tool, resolvedVersion, installationPath); } @Override diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java b/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java index f1cc935a36..d50d9622d9 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java @@ -8,6 +8,10 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.event.Level; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.cli.CliOfflineException; import com.devonfw.tools.ide.context.IdeContext; @@ -32,6 +36,8 @@ */ public abstract class AbstractToolRepository implements ToolRepository { + private static final Logger LOG = LoggerFactory.getLogger(AbstractToolRepository.class); + private static final int MAX_TEMP_DOWNLOADS = 9; /** The owning {@link IdeContext}. */ @@ -88,14 +94,14 @@ protected Path doDownload(UrlDownloadFileMetadata metadata) { Path downloadCache = this.context.getDownloadPath().resolve(getId()); this.context.getFileAccess().mkdirs(downloadCache); Path target = downloadCache.resolve(downloadFilename); - + if (Files.exists(target)) { // File is already cached if (this.context.getNetworkStatus().isOffline()) { - this.context.debug("Using cached download of {} in version {} from {} (offline mode)", + LOG.debug("Using cached download of {} in version {} from {} (offline mode)", metadata.getTool(), metadata.getVersion(), target); } else { - this.context.interaction("Artifact already exists at {}\nTo force update please delete the file and run again.", target); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "Artifact already exists at {}\nTo force update please delete the file and run again.", target); } } else { if (this.context.getNetworkStatus().isOffline()) { @@ -130,7 +136,7 @@ private Path download(UrlDownloadFileMetadata metadata, Path target) { error = e; } if (i < max) { - this.context.error(error, "Failed to download from " + url); + LOG.error("Failed to download from " + url, error); } } throw new IllegalStateException("Download of " + target.getFileName() + " failed after trying " + size + " URL(s).", error); @@ -178,8 +184,7 @@ protected String createDownloadFilename(String tool, String edition, VersionIden } else { extension = "zip"; } - this.context.warning("Could not determine file extension from URL {} - guess was {} but may be incorrect.", url, - extension); + LOG.warn("Could not determine file extension from URL {} - guess was {} but may be incorrect.", url, extension); } sb.append("."); sb.append(extension); @@ -256,11 +261,11 @@ private void verifyChecksums(Path file, UrlChecksums expectedChecksums, Object v checksumVerified = true; } if (!checksumVerified) { - IdeLogLevel level = IdeLogLevel.WARNING; + Level level = Level.WARN; if (isLatestVersion(version)) { - level = IdeLogLevel.DEBUG; + level = Level.DEBUG; } - this.context.level(level).log("No checksum found for {}", file); + LOG.atLevel(level).log("No checksum found for {}", file); } } @@ -275,7 +280,7 @@ protected void verifyChecksum(Path file, UrlGenericChecksum expectedChecksum) { String hashAlgorithm = expectedChecksum.getHashAlgorithm(); String actualChecksum = this.context.getFileAccess().checksum(file, hashAlgorithm); if (expectedChecksum.getChecksum().equals(actualChecksum)) { - this.context.success("{} checksum {} is correct.", hashAlgorithm, actualChecksum); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "{} checksum {} is correct.", hashAlgorithm, actualChecksum); } else { throw new CliException("Downloaded file " + file + " has the wrong " + hashAlgorithm + " checksum!\n" // + "Expected " + expectedChecksum + "\n" // @@ -291,7 +296,7 @@ protected void verifyChecksum(Path file, UrlGenericChecksum expectedChecksum) { public VersionIdentifier resolveVersion(String tool, String edition, GenericVersionRange version, ToolCommandlet toolCommandlet) { List versions = getSortedVersions(tool, edition, toolCommandlet); - return VersionIdentifier.resolveVersionPattern(version, versions, this.context); + return VersionIdentifier.resolveVersionPattern(version, versions); } @Override @@ -304,9 +309,9 @@ public Collection findDependencies(String tool, String edition, dependencies = urlTool.getDependencyFile().getDependencies(); } if (dependencies != ToolDependencies.getEmpty()) { - this.context.trace("Found dependencies in {}", dependencies); + LOG.trace("Found dependencies in {}", dependencies); } - return dependencies.findDependencies(version, this.context); + return dependencies.findDependencies(version); } @Override @@ -318,7 +323,7 @@ public ToolSecurity findSecurity(String tool, String edition) { security = urlTool.getSecurityFile().getSecurity(); } if (security != ToolSecurity.getEmpty()) { - this.context.trace("Found dependencies in {}", security); + LOG.trace("Found CVE information in {}", security); } return security; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/vscode/Vscode.java b/cli/src/main/java/com/devonfw/tools/ide/tool/vscode/Vscode.java index f626eaaf44..24ebfd9fcf 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/vscode/Vscode.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/vscode/Vscode.java @@ -6,9 +6,13 @@ import java.util.List; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.io.IdeProgressBar; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.process.ProcessContext; import com.devonfw.tools.ide.process.ProcessMode; import com.devonfw.tools.ide.process.ProcessResult; @@ -22,6 +26,8 @@ */ public class Vscode extends IdeToolCommandlet { + private static final Logger LOG = LoggerFactory.getLogger(Vscode.class); + /** * The constructor. * @@ -61,11 +67,11 @@ public boolean installPlugin(ToolPluginDescriptor plugin, Step step, ProcessCont extensionsCommands.add(plugin.id()); ProcessResult result = runTool(pc, ProcessMode.DEFAULT_CAPTURE, extensionsCommands); if (result.isSuccessful()) { - this.context.success("Successfully installed plugin: {}", plugin.name()); + LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully installed plugin: {}", plugin.name()); step.success(); return true; } else { - this.context.warning("An error occurred while installing plugin: {}", plugin.name()); + LOG.warn("An error occurred while installing plugin: {}", plugin.name()); return false; } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/model/UrlMetadata.java b/cli/src/main/java/com/devonfw/tools/ide/url/model/UrlMetadata.java index 5160e14712..48167a7150 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/model/UrlMetadata.java +++ b/cli/src/main/java/com/devonfw/tools/ide/url/model/UrlMetadata.java @@ -9,6 +9,9 @@ import java.util.List; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.os.SystemInfo; @@ -25,6 +28,8 @@ */ public class UrlMetadata implements AbstractUrlMetadata { + private static final Logger LOG = LoggerFactory.getLogger(UrlMetadata.class); + private final IdeContext context; private final UrlRepository repository; @@ -80,7 +85,7 @@ public List getSortedEditions(String tool) { List list = new ArrayList<>(); UrlTool urlTool = this.repository.getChild(tool); if (urlTool == null) { - this.context.warning("Can't get sorted editions for tool {} because it does not exist in {}.", tool, this.repository.getPath()); + LOG.warn("Can't get sorted editions for tool {} because it does not exist in {}.", tool, this.repository.getPath()); } else { for (UrlEdition urlEdition : urlTool.getChildren()) { list.add(urlEdition.getName()); @@ -128,7 +133,7 @@ private List computeSortedVersions(String tool, String editio public VersionIdentifier resolveVersion(String tool, String edition, GenericVersionRange version, ToolCommandlet toolCommandlet) { List versions = getSortedVersions(tool, edition, toolCommandlet); - return VersionIdentifier.resolveVersionPattern(version, versions, this.context); + return VersionIdentifier.resolveVersionPattern(version, versions); } /** diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolDependencies.java b/cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolDependencies.java index 92600ed96b..ab48f98299 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolDependencies.java +++ b/cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolDependencies.java @@ -8,8 +8,10 @@ import java.util.Map; import java.util.TreeMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.json.JsonMapping; -import com.devonfw.tools.ide.log.IdeLogger; import com.devonfw.tools.ide.version.VersionIdentifier; import com.devonfw.tools.ide.version.VersionRange; import com.fasterxml.jackson.core.type.TypeReference; @@ -22,6 +24,8 @@ */ public class ToolDependencies { + private static final Logger LOG = LoggerFactory.getLogger(ToolDependencies.class); + private static final ObjectMapper MAPPER = JsonMapping.create(); private static final ToolDependencies EMPTY = new ToolDependencies(Collections.emptyMap(), Path.of("empty")); @@ -40,7 +44,7 @@ private ToolDependencies(Map> dependencies, P * @param version the {@link VersionIdentifier} of the tool to install. * @return The {@link List} of {@link ToolDependency}s for the given tool version. */ - public List findDependencies(VersionIdentifier version, IdeLogger logger) { + public List findDependencies(VersionIdentifier version) { for (Map.Entry> entry : this.dependencies.entrySet()) { VersionRange versionRange = entry.getKey(); @@ -50,7 +54,7 @@ public List findDependencies(VersionIdentifier version, IdeLogge } int size = dependencies.size(); if (size > 0) { - logger.warning("No match for version {} while {} version ranges are configured in {} - configuration error?!", version, size, this.path); + LOG.warn("No match for version {} while {} version ranges are configured in {} - configuration error?!", version, size, this.path); } return Collections.emptyList(); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolSecurity.java b/cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolSecurity.java index 929846f489..0e90f47a73 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolSecurity.java +++ b/cli/src/main/java/com/devonfw/tools/ide/url/model/file/json/ToolSecurity.java @@ -11,9 +11,11 @@ import java.util.TreeMap; import java.util.function.Predicate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.json.JsonMapping; import com.devonfw.tools.ide.json.JsonObject; -import com.devonfw.tools.ide.log.IdeLogger; import com.devonfw.tools.ide.security.ToolVulnerabilities; import com.devonfw.tools.ide.variable.IdeVariables; import com.devonfw.tools.ide.version.VersionIdentifier; @@ -27,6 +29,8 @@ */ public class ToolSecurity implements JsonObject { + private static final Logger LOG = LoggerFactory.getLogger(ToolSecurity.class); + static final String PROPERTY_ISSUES = "issues"; private static final ObjectMapper MAPPER = JsonMapping.create(); @@ -108,11 +112,10 @@ public void clearIssues() { * Finds all {@link Cve}s for the given {@link VersionIdentifier} that also match the given {@link Predicate}. * * @param version the {@link VersionIdentifier} to check. - * @param logger the {@link IdeLogger}. * @param predicate the {@link Predicate} deciding which matching {@link Cve}s are {@link Predicate#test(Object) accepted}. * @return all {@link Cve}s for the given {@link VersionIdentifier}. */ - public ToolVulnerabilities findCves(VersionIdentifier version, IdeLogger logger, Predicate predicate) { + public ToolVulnerabilities findCves(VersionIdentifier version, Predicate predicate) { List cvesOfVersion = new ArrayList<>(); for (Cve cve : this.issues) { for (VersionRange range : cve.versions()) { @@ -120,7 +123,7 @@ public ToolVulnerabilities findCves(VersionIdentifier version, IdeLogger logger, if (predicate.test(cve)) { cvesOfVersion.add(cve); } else { - logger.info("Ignoring CVE {} with severity {}", cve.id(), cve.severity()); + LOG.info("Ignoring CVE {} with severity {}", cve.id(), cve.severity()); } } } @@ -132,12 +135,11 @@ public ToolVulnerabilities findCves(VersionIdentifier version, IdeLogger logger, * Finds all {@link Cve}s for the given {@link VersionIdentifier} and {@code minSeverity}. * * @param version the {@link VersionIdentifier} to check. - * @param logger the {@link IdeLogger}. * @param minSeverity the {@link IdeVariables#CVE_MIN_SEVERITY minimum severity}. * @return the {@link ToolVulnerabilities} for the given {@link VersionIdentifier}. */ - public ToolVulnerabilities findCves(VersionIdentifier version, IdeLogger logger, double minSeverity) { - return findCves(version, logger, cve -> cve.severity() >= minSeverity); + public ToolVulnerabilities findCves(VersionIdentifier version, double minSeverity) { + return findCves(version, cve -> cve.severity() >= minSeverity); } /** diff --git a/cli/src/main/java/com/devonfw/tools/ide/variable/AbstractVariableDefinitionList.java b/cli/src/main/java/com/devonfw/tools/ide/variable/AbstractVariableDefinitionList.java index 2cbecac83e..e9b0f53c48 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/variable/AbstractVariableDefinitionList.java +++ b/cli/src/main/java/com/devonfw/tools/ide/variable/AbstractVariableDefinitionList.java @@ -5,6 +5,9 @@ import java.util.List; import java.util.function.Function; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; /** @@ -12,6 +15,8 @@ */ public abstract class AbstractVariableDefinitionList extends AbstractVariableDefinition> { + private static final Logger LOG = LoggerFactory.getLogger(AbstractVariableDefinitionList.class); + /** * The constructor. * @@ -87,7 +92,7 @@ protected List parseList(String value, IdeContext context) { try { list.add(parseValue(item.trim(), context)); } catch (Exception e) { - context.warning().log(e, "Invalid value '{}' for element of variable {}", item, getName()); + LOG.warn("Invalid value '{}' for element of variable {}", item, getName(), e); return null; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/variable/VariableDefinitionBoolean.java b/cli/src/main/java/com/devonfw/tools/ide/variable/VariableDefinitionBoolean.java index ae318e0f11..9ef45bcde5 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/variable/VariableDefinitionBoolean.java +++ b/cli/src/main/java/com/devonfw/tools/ide/variable/VariableDefinitionBoolean.java @@ -3,6 +3,9 @@ import java.util.Locale; import java.util.function.Function; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; /** @@ -10,6 +13,8 @@ */ public class VariableDefinitionBoolean extends AbstractVariableDefinition { + private static final Logger LOG = LoggerFactory.getLogger(VariableDefinitionBoolean.class); + /** * The constructor. * @@ -85,7 +90,7 @@ public Boolean fromString(String value, IdeContext context) { case "true", "yes" -> Boolean.TRUE; case "false", "no" -> Boolean.FALSE; default -> { - context.warning("Variable {} has invalid boolean value {} - using false as fallback"); + LOG.warn("Variable {} has invalid boolean value {} - using false as fallback", getName(), value); yield Boolean.FALSE; } }; diff --git a/cli/src/main/java/com/devonfw/tools/ide/version/VersionIdentifier.java b/cli/src/main/java/com/devonfw/tools/ide/version/VersionIdentifier.java index 8644ef13d1..bafadc950e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/version/VersionIdentifier.java +++ b/cli/src/main/java/com/devonfw/tools/ide/version/VersionIdentifier.java @@ -3,8 +3,10 @@ import java.util.List; import java.util.Objects; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.cli.CliException; -import com.devonfw.tools.ide.log.IdeLogger; import com.devonfw.tools.ide.tool.ToolCommandlet; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -15,6 +17,8 @@ */ public final class VersionIdentifier implements VersionObject, GenericVersionRange { + private static final Logger LOG = LoggerFactory.getLogger(VersionIdentifier.class); + /** {@link VersionIdentifier} "*" that will resolve to the latest stable version. */ public static final VersionIdentifier LATEST = new VersionIdentifier(VersionSegment.of("*")); @@ -64,24 +68,23 @@ private VersionIdentifier(VersionSegment start) { * @param versions the * {@link com.devonfw.tools.ide.tool.repository.ToolRepository#getSortedVersions(String, String, ToolCommandlet) available versions, sorted in descending * order}. - * @param logger the {@link IdeLogger}. * @return the resolved version */ - public static VersionIdentifier resolveVersionPattern(GenericVersionRange version, List versions, IdeLogger logger) { + public static VersionIdentifier resolveVersionPattern(GenericVersionRange version, List versions) { if (version == null) { version = LATEST; } if (!version.isPattern()) { for (VersionIdentifier vi : versions) { if (vi.equals(version)) { - logger.debug("Resolved version {} to version {}", version, vi); + LOG.debug("Resolved version {} to version {}", version, vi); return vi; } } } for (VersionIdentifier vi : versions) { if (version.contains(vi)) { - logger.debug("Resolved version pattern {} to version {}", version, vi); + LOG.debug("Resolved version pattern {} to version {}", version, vi); return vi; } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java index 51f204d60c..294a587b18 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java @@ -17,6 +17,7 @@ import com.devonfw.tools.ide.io.FileAccessImpl; import com.devonfw.tools.ide.io.FileCopyMode; import com.devonfw.tools.ide.io.IdeProgressBarTestImpl; +import com.devonfw.tools.ide.io.IdeProgressBarTestImpl.ProgressEvent; import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.tool.repository.ToolRepositoryMock; import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; @@ -158,11 +159,11 @@ protected static IdeTestContextAssertion assertThat(IdeTestContext context) { return new IdeTestContextAssertion(context); } - private static List assertProgressEventsAndSize(AbstractIdeTestContext context, String taskName, int chunkCount, + private static List assertProgressEventsAndSize(AbstractIdeTestContext context, String taskName, int chunkCount, long maxSize) { IdeProgressBarTestImpl progressBar = context.getProgressBarMap().get(taskName); assertThat(progressBar).as(taskName).isNotNull(); - List eventList = progressBar.getEventList(); + List eventList = progressBar.getEventList(); assertThat(eventList).hasSize(chunkCount + 1); // extra case for unknown file size (indefinite progress bar) if (progressBar.getMaxSize() != -1L) { diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java index ca4662b50a..4337995f08 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java @@ -6,6 +6,9 @@ import java.util.Map; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.commandlet.Commandlet; import com.devonfw.tools.ide.commandlet.CommandletManager; import com.devonfw.tools.ide.commandlet.TestCommandletManager; @@ -18,7 +21,7 @@ import com.devonfw.tools.ide.environment.IdeSystemTestImpl; import com.devonfw.tools.ide.io.IdeProgressBar; import com.devonfw.tools.ide.io.IdeProgressBarTestImpl; -import com.devonfw.tools.ide.log.IdeLogger; +import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.network.NetworkStatusMock; import com.devonfw.tools.ide.os.SystemInfo; import com.devonfw.tools.ide.os.SystemInfoImpl; @@ -35,6 +38,8 @@ */ public class AbstractIdeTestContext extends AbstractIdeContext { + private static final Logger LOG = LoggerFactory.getLogger(AbstractIdeTestContext.class); + /** {@link Path} to use as workingDirectory for mocking. */ public static final Path PATH_MOCK = Path.of("/"); @@ -63,13 +68,13 @@ public class AbstractIdeTestContext extends AbstractIdeContext { /** * The constructor. * - * @param logger the {@link IdeLogger}. + * @param startContext the {@link IdeStartContextImpl}. * @param workingDirectory the optional {@link Path} to current working directory. * @param wireMockRuntimeInfo wireMock server on a random port. */ - public AbstractIdeTestContext(IdeStartContextImpl logger, Path workingDirectory, WireMockRuntimeInfo wireMockRuntimeInfo) { + public AbstractIdeTestContext(IdeStartContextImpl startContext, Path workingDirectory, WireMockRuntimeInfo wireMockRuntimeInfo) { - super(logger, workingDirectory); + super(startContext, workingDirectory); this.answers = new String[0]; this.progressBarMap = new HashMap<>(); this.systemInfo = super.getSystemInfo(); @@ -119,7 +124,7 @@ protected IdeHomeAndWorkspace findIdeHome(Path workingDirectory) { // Validate that the detected IDE home (if any) is within test boundaries Path ideHome = result.home(); if (ideHome != null && testBoundary != null && !ideHome.startsWith(testBoundary)) { - debug("Test isolation violation: Detected IDE home '{}' is outside test boundary '{}'.\n" + LOG.debug("Test isolation violation: Detected IDE home '{}' is outside test boundary '{}'.\n" + "This indicates the test project structure is incomplete or improperly configured.\n" + "A valid IDE home directories is determined by isIdeHome() method.\n" + "Please ensure your test project has the required structure.", ideHome, testBoundary); @@ -157,7 +162,7 @@ protected String readLine() { throw new IllegalStateException("End of answers reached!"); } String answer = this.answers[this.answerIndex++]; - interaction(answer); + LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), answer); return answer; } @@ -409,7 +414,7 @@ protected Path findBashInWindowsRegistry() { } @Override - protected Properties createJavaUtilLoggingProperties() { + protected Properties createJavaUtilLoggingProperties(boolean logfile) { return createJavaUtilLoggingProperties(true, false); } diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeContextTest.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeContextTest.java index 9aeaa0e761..a81b81b47f 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeContextTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/IdeContextTest.java @@ -4,6 +4,8 @@ import java.util.Properties; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.devonfw.tools.ide.cli.CliArguments; import com.devonfw.tools.ide.common.SystemPath; @@ -22,6 +24,8 @@ */ class IdeContextTest extends AbstractIdeContextTest { + private static final Logger LOG = LoggerFactory.getLogger(IdeContextTest.class); + /** * Test of {@link IdeContext} initialization from basic project. */ @@ -182,19 +186,19 @@ void testRunWithoutLogging() { String testDebugMessage = "Test debug message that will be suppressed because of threshold"; IdeTestContext context = newContext(PROJECT_BASIC, null, false); // act - context.warning(testWarningMessage); + LOG.warn(testWarningMessage); // assert assertThat(context).logAtWarning().hasMessage(testWarningMessage); // and act context.runWithoutLogging(() -> { - context.warning(testWarningMessage2); - context.info(testInfoMessage); - context.debug(testDebugMessage); + LOG.warn(testWarningMessage2); + LOG.info(testInfoMessage); + LOG.debug(testDebugMessage); assertThat(context).log().hasNoMessage(testWarningMessage2); assertThat(context).log().hasNoMessage(testInfoMessage); assertThat(context).log().hasNoMessage(testDebugMessage); }, IdeLogLevel.INFO); - context.warning(testWarningMessage3); + LOG.warn(testWarningMessage3); assertThat(context).log() .hasEntries(IdeLogEntry.ofWarning(testWarningMessage), IdeLogEntry.ofWarning(testWarningMessage2), IdeLogEntry.ofInfo(testInfoMessage), diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java deleted file mode 100644 index 5576c0b410..0000000000 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.devonfw.tools.ide.context; - -import java.nio.file.Path; - -import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeSubLoggerOut; - -/** - * Implementation of {@link IdeContext} for testing. - */ -public class IdeSlf4jContext extends AbstractIdeTestContext { - - private static final Path PATH_MOCK = Path.of("/"); - - /** - * The constructor. - */ - public IdeSlf4jContext() { - this(PATH_MOCK); - } - - /** - * The constructor. - * - * @param workingDirectory the optional {@link Path} to current working directory. - */ - public IdeSlf4jContext(Path workingDirectory) { - - super(new IdeStartContextImpl(IdeLogLevel.TRACE, level -> new IdeSubLoggerOut(level, null, true, IdeLogLevel.TRACE, null)), workingDirectory, null); - } - -} diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java index 918b9b4245..995a7fc489 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java @@ -7,7 +7,7 @@ import com.devonfw.tools.ide.git.GitContext; import com.devonfw.tools.ide.git.GitContextMock; import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeTestLogger; +import com.devonfw.tools.ide.log.IdeTestStartContext; import com.devonfw.tools.ide.process.ProcessContext; import com.devonfw.tools.ide.tool.mvn.MvnRepository; import com.devonfw.tools.ide.tool.npm.NpmRepository; @@ -20,7 +20,7 @@ */ public class IdeTestContext extends AbstractIdeTestContext { - private final IdeTestLogger logger; + private final IdeTestStartContext logger; private GitContext gitContext; @@ -52,13 +52,13 @@ public IdeTestContext(Path workingDirectory, WireMockRuntimeInfo wireMockRuntime */ public IdeTestContext(Path workingDirectory, IdeLogLevel logLevel, WireMockRuntimeInfo wireMockRuntimeInfo) { - this(new IdeTestLogger(logLevel), workingDirectory, wireMockRuntimeInfo); + this(new IdeTestStartContext(logLevel), workingDirectory, wireMockRuntimeInfo); } - private IdeTestContext(IdeTestLogger logger, Path workingDirectory, WireMockRuntimeInfo wireMockRuntimeInfo) { + private IdeTestContext(IdeTestStartContext startContext, Path workingDirectory, WireMockRuntimeInfo wireMockRuntimeInfo) { - super(logger, workingDirectory, wireMockRuntimeInfo); - this.logger = logger; + super(startContext, workingDirectory, wireMockRuntimeInfo); + this.logger = startContext; this.gitContext = new GitContextMock(); } @@ -90,9 +90,9 @@ public static IdeTestContext of() { } /** - * @return the {@link IdeTestLogger}. + * @return the {@link IdeTestStartContext}. */ - public IdeTestLogger getLogger() { + public IdeTestStartContext getLogger() { return logger; } diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextMock.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextMock.java index 75c92e6829..89a0f5e313 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextMock.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextMock.java @@ -1,17 +1,24 @@ package com.devonfw.tools.ide.context; +import java.nio.file.Path; + +import com.devonfw.tools.ide.log.IdeLogLevel; +import com.devonfw.tools.ide.log.IdeLogListenerNone; + /** * Mock instance of {@link com.devonfw.tools.ide.context.IdeContext}. * * @see #get() */ -public class IdeTestContextMock extends IdeSlf4jContext { +public class IdeTestContextMock extends AbstractIdeTestContext { private static final IdeTestContextMock INSTANCE = new IdeTestContextMock(); + private static final Path PATH_MOCK = Path.of("/"); + private IdeTestContextMock() { - super(); + super(new IdeStartContextImpl(IdeLogLevel.TRACE, IdeLogListenerNone.INSTANCE), PATH_MOCK, null); } @Override diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/ProcessContextTestImpl.java b/cli/src/test/java/com/devonfw/tools/ide/context/ProcessContextTestImpl.java index a12b721a37..1d1d63ec16 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/ProcessContextTestImpl.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/ProcessContextTestImpl.java @@ -32,7 +32,7 @@ public ProcessResult run(ProcessMode processMode) { ProcessResult result = super.run(ProcessMode.DEFAULT_CAPTURE); // this hack is still required to capture test script output if (result.isSuccessful() && (processMode == ProcessMode.DEFAULT || processMode == ProcessMode.BACKGROUND)) { - result.log(IdeLogLevel.INFO, context); + result.log(IdeLogLevel.INFO); } return result; } diff --git a/cli/src/test/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesMock.java b/cli/src/test/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesMock.java index 59f57753b7..25181a7619 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesMock.java +++ b/cli/src/test/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesMock.java @@ -7,6 +7,9 @@ import java.util.Objects; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; /** @@ -14,6 +17,8 @@ */ public final class EnvironmentVariablesPropertiesMock extends EnvironmentVariablesMap { + private static final Logger LOG = LoggerFactory.getLogger(EnvironmentVariablesPropertiesMock.class); + private static final Path PROPERTIES_FILE_PATH = Path.of(DEFAULT_PROPERTIES); private static final Path LEGACY_PROPERTIES_FILE_PATH = Path.of(LEGACY_PROPERTIES); @@ -49,7 +54,7 @@ public EnvironmentVariablesPropertiesMock(AbstractEnvironmentVariables parent, E public void save() { if (this.modifiedVariables.isEmpty()) { - this.context.trace("No changes to save in properties file {}", getPropertiesFilePath()); + LOG.trace("No changes to save in properties file {}", getPropertiesFilePath()); return; } this.modifiedVariables.clear(); @@ -103,9 +108,9 @@ public String set(String name, String value, boolean export) { String oldValue = this.variables.put(name, value); boolean flagChanged = export != this.exportedVariables.contains(name); if (Objects.equals(value, oldValue) && !flagChanged) { - this.context.trace("Set variable '{}={}' caused no change in {}", name, value, getPropertiesFilePath()); + LOG.trace("Set variable '{}={}' caused no change in {}", name, value, getPropertiesFilePath()); } else { - this.context.debug("Set variable '{}={}' in {}", name, value, getPropertiesFilePath()); + LOG.debug("Set variable '{}={}' in {}", name, value, getPropertiesFilePath()); this.modifiedVariables.add(name); if (export && (value != null)) { this.exportedVariables.add(name); diff --git a/cli/src/test/java/com/devonfw/tools/ide/environment/VariableLineTest.java b/cli/src/test/java/com/devonfw/tools/ide/environment/VariableLineTest.java index d8cdce43f0..00d44ca7a3 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/environment/VariableLineTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/environment/VariableLineTest.java @@ -7,18 +7,15 @@ import com.devonfw.tools.ide.environment.VariableLine.Empty; import com.devonfw.tools.ide.environment.VariableLine.Garbage; import com.devonfw.tools.ide.environment.VariableLine.Variable; -import com.devonfw.tools.ide.log.IdeSlf4jRootLogger; /** * Test of {@link VariableLine}. */ class VariableLineTest extends Assertions { - private static final IdeSlf4jRootLogger LOGGER = IdeSlf4jRootLogger.of(); - private VariableLine line(String line) { - return VariableLine.of(line, LOGGER, new VariableSource(EnvironmentVariablesType.RESOLVED, null)); + return VariableLine.of(line, new VariableSource(EnvironmentVariablesType.RESOLVED, null)); } /** diff --git a/cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java b/cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java index 6e6b4d4739..270818aa1a 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java @@ -798,7 +798,7 @@ void testIsJunctionHandlesBrokenLinks(@TempDir Path tempDir) throws IOException fileAccess.symlink(newSource, brokenLink, false); assertThat(brokenLink.toRealPath()).isEqualTo(newSource); } else { - context.info("Test adapted for Windows environment - testing basic junction functionality"); + System.out.println("Test adapted for Windows environment - testing basic junction functionality"); // On Windows, just test that basic junction functionality works Path sourceDir = tempDir.resolve("source"); Path junctionLink = tempDir.resolve("junction"); diff --git a/cli/src/test/java/com/devonfw/tools/ide/io/IdeProgressBarTest.java b/cli/src/test/java/com/devonfw/tools/ide/io/IdeProgressBarTest.java index 2e4626b805..94ccd02d53 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/io/IdeProgressBarTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/io/IdeProgressBarTest.java @@ -26,48 +26,49 @@ class IdeProgressBarTest extends AbstractIdeContextTest { private static final String TEST_URL = "/os/windows_x64_url.tgz"; + @TempDir + Path tempDir; + /** * Tests if a download of a file with a valid content length was displaying an {@link IdeProgressBar} properly. * - * @param tempDir temporary directory to use. * @param wmRuntimeInfo wireMock server on a random port */ @Test - void testProgressBarDownloadWithValidContentLength(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) { + void testProgressBarDownloadWithValidContentLength(WireMockRuntimeInfo wmRuntimeInfo) { stubFor(any(urlMatching("/os/.*")).willReturn( aResponse().withStatus(200).withBody(new byte[MAX_LENGTH]).withHeader("Content-Length", String.valueOf(MAX_LENGTH)))); - IdeContext context = newContext(tempDir); + IdeContext context = newContext(this.tempDir); FileAccess impl = context.getFileAccess(); - impl.download(wmRuntimeInfo.getHttpBaseUrl() + TEST_URL, tempDir.resolve("windows_x64_url.tgz")); - assertThat(tempDir.resolve("windows_x64_url.tgz")).exists(); + impl.download(wmRuntimeInfo.getHttpBaseUrl() + TEST_URL, this.tempDir.resolve("windows_x64_url.tgz")); + assertThat(this.tempDir.resolve("windows_x64_url.tgz")).exists(); assertProgressBar(context, "Downloading", MAX_LENGTH); } /** * Tests if {@link FileAccess#download(String, Path)} with missing content length is working properly. * - * @param tempDir temporary directory to use. * @param wmRuntimeInfo wireMock server on a random port */ @Test - void testProgressBarDownloadWithMissingContentLength(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) { + void testProgressBarDownloadWithMissingContentLength(WireMockRuntimeInfo wmRuntimeInfo) { //arrange String taskName = "Downloading"; stubFor(any(urlMatching("/os/.*")).willReturn(aResponse().withStatus(200).withBody(new byte[MAX_LENGTH]))); - IdeTestContext context = newContext(tempDir); + IdeTestContext context = newContext(this.tempDir); FileAccess impl = context.getFileAccess(); //act String testUrl = wmRuntimeInfo.getHttpBaseUrl() + TEST_URL; - impl.download(testUrl, tempDir.resolve("windows_x64_url.tgz")); + impl.download(testUrl, this.tempDir.resolve("windows_x64_url.tgz")); //assert assertUnknownProgressBar(context, "Downloading", MAX_LENGTH); assertThat(context).logAtWarning().hasMessage( "Content-Length was not provided by download from " + testUrl); - assertThat(tempDir.resolve("windows_x64_url.tgz")).exists(); + assertThat(this.tempDir.resolve("windows_x64_url.tgz")).exists(); IdeProgressBarTestImpl progressBar = context.getProgressBarMap().get(taskName); assertThat(progressBar.getMaxSize()).isEqualTo(-1); diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerCollector.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeLogListenerCollector.java similarity index 100% rename from cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerCollector.java rename to cli/src/test/java/com/devonfw/tools/ide/log/IdeLogListenerCollector.java diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeSlf4jRootLogger.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeSlf4jRootLogger.java deleted file mode 100644 index 5aa4e17336..0000000000 --- a/cli/src/test/java/com/devonfw/tools/ide/log/IdeSlf4jRootLogger.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.devonfw.tools.ide.log; - -import java.util.HashMap; -import java.util.Map; - -/** - * {@link IdeLogger} that delegates to SLF4J used for testing. - */ -public class IdeSlf4jRootLogger implements IdeLogger { - - private static final IdeSlf4jRootLogger INSTANCE = new IdeSlf4jRootLogger(); - - private final Map loggers; - - /** - * The constructor. - */ - public IdeSlf4jRootLogger() { - - super(); - this.loggers = new HashMap<>(); - for (IdeLogLevel level : IdeLogLevel.values()) { - this.loggers.put(level, new IdeSubLoggerSlf4j(level, null)); - } - } - - @Override - public IdeSubLogger level(IdeLogLevel level) { - - return this.loggers.get(level); - } - - /** - * @return the singleton instance. - */ - public static IdeSlf4jRootLogger of() { - - return INSTANCE; - } - -} diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeSubLoggerSlf4j.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeSubLoggerSlf4j.java deleted file mode 100644 index e39bb3f283..0000000000 --- a/cli/src/test/java/com/devonfw/tools/ide/log/IdeSubLoggerSlf4j.java +++ /dev/null @@ -1,60 +0,0 @@ -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 IdeSubLoggerSlf4j extends AbstractIdeSubLogger { - - private static final Logger LOG = LoggerFactory.getLogger(IdeSubLoggerSlf4j.class); - - private final Level logLevel; - - /** - * The constructor. - * - * @param level the {@link #getLevel() log-level}. - */ - public IdeSubLoggerSlf4j(IdeLogLevel level) { - this(level, null); - } - - /** - * The constructor. - * - * @param level the {@link #getLevel() log-level}. - */ - public IdeSubLoggerSlf4j(IdeLogLevel level, IdeLogListener listener) { - - super(level, false, IdeLogExceptionDetails.NONE, listener); - this.logLevel = switch (level) { - case TRACE -> Level.TRACE; - case DEBUG -> Level.DEBUG; - case WARNING -> Level.WARN; - case ERROR -> Level.ERROR; - default -> Level.INFO; - }; - } - - @Override - protected void doLog(String message, Throwable error) { - - LoggingEventBuilder builder = LOG.atLevel(this.logLevel); - String msg = message; - if (error != null) { - builder = builder.setCause(error); - if (msg == null) { - msg = error.toString(); - } - } - if (this.level.isCustom()) { - msg = this.level.name() + ":" + message; - } - builder.log(msg); - } - -} diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java deleted file mode 100644 index ed2e3f18c4..0000000000 --- a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.devonfw.tools.ide.log; - -import java.util.ArrayList; -import java.util.List; - -import com.devonfw.tools.ide.context.IdeStartContextImpl; - -/** - * Extends {@link IdeStartContextImpl} for testing. - */ -public class IdeTestLogger extends IdeStartContextImpl { - - private final IdeLogListenerCollector collector; - - public IdeTestLogger() { - - this(IdeLogLevel.DEBUG); - } - - public IdeTestLogger(IdeLogLevel minLogLevel) { - - this(new ArrayList<>(), minLogLevel, new IdeLogListenerCollector()); - } - - private IdeTestLogger(List entries, IdeLogLevel minLogLevel, IdeLogListenerCollector collector) { - - super(minLogLevel, level -> new IdeSubLoggerOut(level, null, true, minLogLevel, collector)); - this.collector = collector; - } - - /** - * @return the {@link List} of {@link IdeLogEntry} that have been logged for test assertions. - */ - public List getEntries() { - - return this.collector.getEntries(); - } -} diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestStartContext.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestStartContext.java new file mode 100644 index 0000000000..bb419bd82f --- /dev/null +++ b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestStartContext.java @@ -0,0 +1,32 @@ +package com.devonfw.tools.ide.log; + +import java.util.List; + +import com.devonfw.tools.ide.context.IdeStartContextImpl; + +/** + * Extends {@link IdeStartContextImpl} for testing. + */ +public class IdeTestStartContext extends IdeStartContextImpl { + + private final IdeLogListenerCollector collector; + + public IdeTestStartContext(IdeLogLevel logLevel) { + + this(logLevel, new IdeLogListenerCollector()); + } + + private IdeTestStartContext(IdeLogLevel minLogLevel, IdeLogListenerCollector logListener) { + + super(minLogLevel, logListener); + this.collector = logListener; + } + + /** + * @return the {@link List} of {@link IdeLogEntry} that have been logged for test assertions. + */ + public List getEntries() { + + return this.collector.getEntries(); + } +} diff --git a/cli/src/test/java/com/devonfw/tools/ide/migration/IdeMigratorTest.java b/cli/src/test/java/com/devonfw/tools/ide/migration/IdeMigratorTest.java index 87b6d7cc3f..01365bc96e 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/migration/IdeMigratorTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/migration/IdeMigratorTest.java @@ -3,6 +3,8 @@ import java.util.List; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeContext; @@ -14,6 +16,8 @@ */ class IdeMigratorTest extends AbstractIdeContextTest { + private static final Logger LOG = LoggerFactory.getLogger(IdeMigratorTest.class); + /** Test that no migration is executed when outside of project. */ @Test void testDoesNothingWithoutIdeHome() { @@ -77,7 +81,7 @@ public Dummy202501002() { @Override public void run(IdeContext context) { - context.info("202501002 migration was done"); + LOG.info("202501002 migration was done"); } } @@ -90,7 +94,7 @@ public Dummy202502003() { @Override public void run(IdeContext context) { - context.info("202502003 migration completed"); + LOG.info("202502003 migration completed"); } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/os/MacOsHelperTest.java b/cli/src/test/java/com/devonfw/tools/ide/os/MacOsHelperTest.java index d694301281..3c11e90a0d 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/os/MacOsHelperTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/os/MacOsHelperTest.java @@ -23,7 +23,7 @@ void testJava() { // arrange String tool = "java"; Path rootDir = APPS_DIR.resolve(tool); - MacOsHelper helper = new MacOsHelper(CONTEXT.getFileAccess(), SystemInfoMock.MAC_X64, CONTEXT); + MacOsHelper helper = new MacOsHelper(CONTEXT.getFileAccess(), SystemInfoMock.MAC_X64); // act Path linkDir = helper.findLinkDir(rootDir, tool); // assert @@ -37,7 +37,7 @@ void testSpecial() { // arrange String tool = "special"; Path rootDir = APPS_DIR.resolve(tool); - MacOsHelper helper = new MacOsHelper(CONTEXT.getFileAccess(), SystemInfoMock.MAC_X64, CONTEXT); + MacOsHelper helper = new MacOsHelper(CONTEXT.getFileAccess(), SystemInfoMock.MAC_X64); // act Path linkDir = helper.findLinkDir(rootDir, tool); // assert @@ -51,7 +51,7 @@ void testNotMac() { // arrange String tool = "java"; Path rootDir = APPS_DIR.resolve(tool); - MacOsHelper helper = new MacOsHelper(CONTEXT.getFileAccess(), SystemInfoMock.LINUX_X64, CONTEXT); + MacOsHelper helper = new MacOsHelper(CONTEXT.getFileAccess(), SystemInfoMock.LINUX_X64); // act Path linkDir = helper.findLinkDir(rootDir, tool); // assert @@ -65,7 +65,7 @@ void testJmc() { // arrange String tool = "jmc"; Path rootDir = APPS_DIR.resolve(tool); - MacOsHelper helper = new MacOsHelper(CONTEXT.getFileAccess(), SystemInfoMock.MAC_X64, CONTEXT); + MacOsHelper helper = new MacOsHelper(CONTEXT.getFileAccess(), SystemInfoMock.MAC_X64); // act Path linkDir = helper.findLinkDir(rootDir, tool); // assert diff --git a/cli/src/test/java/com/devonfw/tools/ide/os/WindowsHelperImplTest.java b/cli/src/test/java/com/devonfw/tools/ide/os/WindowsHelperImplTest.java index b9c8f95cde..423374d4b6 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/os/WindowsHelperImplTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/os/WindowsHelperImplTest.java @@ -7,7 +7,7 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.AbstractIdeTestContext; -import com.devonfw.tools.ide.context.IdeSlf4jContext; +import com.devonfw.tools.ide.context.IdeTestContextMock; /** * Tests for {@link WindowsHelperImpl}. @@ -20,7 +20,7 @@ class WindowsHelperImplTest extends AbstractIdeContextTest { @Test void testWindowsHelperParseRegString() { // arrange - AbstractIdeTestContext context = new IdeSlf4jContext(); + AbstractIdeTestContext context = IdeTestContextMock.get(); WindowsHelperImpl helper = new WindowsHelperImpl(context); List output = new ArrayList<>(); output.add(""); @@ -39,7 +39,7 @@ void testWindowsHelperParseRegString() { @Test void testWindowsHelperParseEmptyRegStringReturnsNull() { // arrange - AbstractIdeTestContext context = new IdeSlf4jContext(); + AbstractIdeTestContext context = IdeTestContextMock.get(); WindowsHelperImpl helper = new WindowsHelperImpl(context); List output = new ArrayList<>(); // act 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 8f6eb4f4d8..d8c76e8cc4 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 @@ -89,7 +89,7 @@ void testInvalidUsageSuccessError() { step.success("The Test-Step succeeded as expected"); throw new IllegalStateException("unexpected situation!"); } catch (IllegalStateException e) { - step.error(e); + step.error(e, e.toString()); } finally { step.close(); } diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/custom/CustomToolsMapperTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/custom/CustomToolsMapperTest.java index 4fbddc8ed8..cdc644432c 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/custom/CustomToolsMapperTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/custom/CustomToolsMapperTest.java @@ -9,7 +9,6 @@ import com.devonfw.tools.ide.context.AbstractIdeTestContext; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeSlf4jContext; import com.devonfw.tools.ide.context.IdeTestContext; import com.devonfw.tools.ide.os.OperatingSystem; import com.devonfw.tools.ide.os.SystemArchitecture; @@ -43,7 +42,7 @@ void testReadCustomToolsFromLegacyConfig() { IdeContext context = new IdeTestContext(); String legacyProperties = "(jboss-eap:7.1.4.GA:all:https://host.tld/projects/my-project firefox:70.0.1:all:)"; // act - CustomTools customTools = CustomToolsMapper.parseCustomToolsFromLegacyConfig(legacyProperties, context); + CustomTools customTools = CustomToolsMapper.parseCustomToolsFromLegacyConfig(legacyProperties); // assert assertThat(customTools.url()).isEqualTo("https://host.tld/projects/my-project"); assertThat(customTools.tools()).containsExactly(new CustomTool("jboss-eap", "7.1.4.GA", true, true, @@ -57,7 +56,7 @@ void testReadEmptyCustomToolsFromLegacyConfig() { IdeContext context = new IdeTestContext(); String legacyProperties = "()"; // act - CustomTools customTools = CustomToolsMapper.parseCustomToolsFromLegacyConfig(legacyProperties, context); + CustomTools customTools = CustomToolsMapper.parseCustomToolsFromLegacyConfig(legacyProperties); // assert assertThat(customTools).isNull(); } @@ -68,7 +67,7 @@ void testReadFaultyCustomToolsFromLegacyConfig() { IdeContext context = new IdeTestContext(); String legacyProperties = "(jboss-eap:7.1.4.GA:all)"; // act - CustomTools customTools = CustomToolsMapper.parseCustomToolsFromLegacyConfig(legacyProperties, context); + CustomTools customTools = CustomToolsMapper.parseCustomToolsFromLegacyConfig(legacyProperties); // assert assertThat(customTools).isNull(); } @@ -80,7 +79,7 @@ void testReadFaultyCustomToolsFromLegacyConfig() { void testProperConvertFromCustomToolsJsonToCustomToolMetaData() { // arrange - AbstractIdeTestContext context = new IdeSlf4jContext(Path.of("")); + AbstractIdeTestContext context = new IdeTestContext(); context.setSystemInfo(SystemInfoMock.LINUX_X64); String name = "jboss-eap"; String version = "7.4.5.GA"; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/dotnet/DotNetTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/dotnet/DotNetTest.java index 4ba8c644da..fbb783a889 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/dotnet/DotNetTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/dotnet/DotNetTest.java @@ -81,7 +81,6 @@ private void runExecutable(String operatingSystem) { SystemInfo systemInfo = SystemInfoMock.of(operatingSystem); this.context.setSystemInfo(systemInfo); - this.context.info("Running dotnet binary from: {}", this.commandlet.getToolBinPath()); this.commandlet.run(); } diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/ide/IdeToolDummyCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/ide/IdeToolDummyCommandletTest.java index 582e287919..d9dc40b157 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/ide/IdeToolDummyCommandletTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/ide/IdeToolDummyCommandletTest.java @@ -13,7 +13,7 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.AbstractIdeTestContext; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeSlf4jContext; +import com.devonfw.tools.ide.context.IdeTestContextMock; import com.devonfw.tools.ide.process.ProcessContext; import com.devonfw.tools.ide.process.ProcessErrorHandling; import com.devonfw.tools.ide.process.ProcessMode; @@ -37,7 +37,7 @@ class IdeToolDummyCommandletTest extends AbstractIdeContextTest { @Test void testDummyCommandlet(@TempDir Path tempDir) { - AbstractIdeTestContext context = new IdeSlf4jContext(); + AbstractIdeTestContext context = IdeTestContextMock.get(); context.setPluginsPath(tempDir); context.setIdeHome(tempDir); context.setSettingsPath(Path.of("src/test/resources/settings/dummy")); diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijTest.java index 1f537a2a9b..8943cdeea4 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijTest.java @@ -90,7 +90,7 @@ void testIntellijRun(String os) { SystemInfo systemInfo = SystemInfoMock.of(os); this.context.setSystemInfo(systemInfo); Intellij commandlet = new Intellij(this.context); - this.context.info("Starting testIntellijRun on {}", os); + System.out.println("Starting testIntellijRun on " + os); // act commandlet.run(); diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/pycharm/PycharmTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/pycharm/PycharmTest.java index 6ea76228b3..c6372984e4 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/pycharm/PycharmTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/pycharm/PycharmTest.java @@ -88,7 +88,7 @@ void testPycharmRun(String os) { SystemInfo systemInfo = SystemInfoMock.of(os); this.context.setSystemInfo(systemInfo); Pycharm commandlet = new Pycharm(this.context); - this.context.info("Starting testPycharmRun on {}", os); + System.out.println("Starting testPycharmRun on " + os); // act commandlet.run(); diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/repository/ToolRepositoryMock.java b/cli/src/test/java/com/devonfw/tools/ide/tool/repository/ToolRepositoryMock.java index abadfdbca0..06a53d7717 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/repository/ToolRepositoryMock.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/repository/ToolRepositoryMock.java @@ -13,6 +13,9 @@ import java.util.Set; import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.tool.ToolCommandlet; import com.devonfw.tools.ide.url.model.file.UrlDownloadFile; @@ -26,6 +29,8 @@ */ public class ToolRepositoryMock extends DefaultToolRepository { + private static final Logger LOG = LoggerFactory.getLogger(ToolRepositoryMock.class); + private static final String VERSION_DEFAULT = "default"; /** Variable to be used as base url for WireMock url replacement */ @@ -63,7 +68,7 @@ public Path download(String tool, String edition, VersionIdentifier version, Too String versionString = version.toString(); Path versionFolder = editionFolder.resolve(versionString); if (!Files.isDirectory(versionFolder)) { - this.context.debug("Could not find version {} so using 'default' for {}/{}", version, tool, edition); + LOG.debug("Could not find version {} so using 'default' for {}/{}", version, tool, edition); versionString = VERSION_DEFAULT; versionFolder = editionFolder.resolve(versionString); } @@ -82,7 +87,7 @@ public Path download(String tool, String edition, VersionIdentifier version, Too Path child = iterator.next(); if (Files.isRegularFile(child) && child.getFileName().startsWith("content.")) { contentArchive = child; - this.context.debug("Using compressed archive {} for mock download of {}/{}", child.getFileName(), tool, + LOG.debug("Using compressed archive {} for mock download of {}/{}", child.getFileName(), tool, edition); } else { break; diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/spring/SpringTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/spring/SpringTest.java index cadb6a38de..da24f0048a 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/spring/SpringTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/spring/SpringTest.java @@ -28,7 +28,6 @@ void testSpringInstall(WireMockRuntimeInfo wireMockRuntimeInfo) { // arrange IdeTestContext context = newContext(PROJECT_SPRING, wireMockRuntimeInfo); Spring commandlet = new Spring(context); - context.info("Starting testSpringInstall"); // act commandlet.install(); @@ -48,7 +47,6 @@ void testSpringRun(WireMockRuntimeInfo wireMockRuntimeInfo) { // arrange IdeTestContext context = newContext(PROJECT_SPRING, wireMockRuntimeInfo); Spring commandlet = new Spring(context); - context.info("Starting testSpringRun"); commandlet.arguments.addValue("foo"); // act diff --git a/cli/src/test/java/com/devonfw/tools/ide/url/model/AbstractUrlModelTest.java b/cli/src/test/java/com/devonfw/tools/ide/url/model/AbstractUrlModelTest.java index e6e1d91de8..8e7c180662 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/url/model/AbstractUrlModelTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/url/model/AbstractUrlModelTest.java @@ -6,7 +6,7 @@ import com.devonfw.tools.ide.context.AbstractIdeTestContext; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeSlf4jContext; +import com.devonfw.tools.ide.context.IdeTestContext; import com.devonfw.tools.ide.url.model.folder.UrlRepository; /** @@ -30,7 +30,7 @@ protected UrlRepository newRepo() { */ protected IdeContext newContext() { - AbstractIdeTestContext context = new IdeSlf4jContext(Path.of("")); + AbstractIdeTestContext context = new IdeTestContext(); context.setUrlsPath(URLS_PATH); return context; } From 52addda3eb37166753b7833f823dd710492e2eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Sun, 22 Feb 2026 19:18:44 +0100 Subject: [PATCH 33/51] #1713: added to CHANGELOG --- CHANGELOG.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index eac1f6acbc..68dbedcf99 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -6,6 +6,7 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE Release with new features and bugfixes: +* https://github.com/devonfw/IDEasy/issues/1713[#1713]: Advanced logging and writing logfiles The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/41?closed=1[milestone 2026.03.001]. From 043a5f7882aed375c2dca3883655d9d68f69615a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Sun, 22 Feb 2026 19:18:59 +0100 Subject: [PATCH 34/51] #1713: added to documentation --- documentation/variables.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/variables.adoc b/documentation/variables.adoc index 14a797fdd4..1f23ce9e13 100644 --- a/documentation/variables.adoc +++ b/documentation/variables.adoc @@ -40,4 +40,5 @@ See also link:https://github.com/devonfw/IDEasy/blob/main/cli/src/main/java/com/ |`HTTP_VERSIONS`|e.g. `HTTP_2, HTTP_1_1`| The optional list of HTTP versions to try in the given order (e.g. "HTTP_2, HTTP_1_1"). This can be used as a workaround for network/VPN related issues - see issue https://github.com/devonfw/IDEasy/issues/1393[#1393]. |`JASYPT_OPTS`|`algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator`|Options of jasypt. |`IDE_XML_MERGE_LEGACY_SUPPORT_ENABLED`|e.g. `false`|Support of legacy xml templates without XML merge namespace. +|`IDE_WRITE_LOGFILE`|`true`|Automatically write logfiles to `$IDE_ROOT/_ide/logs/YYYY/MM/dd/ideasy-HH-mm-ss.log`. |======================= From 7a4a631607d75ae2e1d2d6966a452b54d495a18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Sun, 22 Feb 2026 19:19:14 +0100 Subject: [PATCH 35/51] #404: fix tests on Linux --- .../ide/commandlet/InstallCommandletTest.java | 16 ++++++++-------- .../tools/ide/context/IdeTestContext.java | 7 ++----- .../ide/context/IdeTestContextAssertion.java | 2 +- .../tools/ide/log/IdeLogListenerCollector.java | 4 ++-- .../tools/ide/log/IdeTestLoggerAssertion.java | 12 +++++------- .../tools/ide/tool/LocalToolCommandletTest.java | 2 +- .../tools/ide/tool/intellij/IntellijTest.java | 2 +- .../tools/ide/tool/pycharm/PycharmTest.java | 2 +- .../tools/ide/tool/vscode/VscodeTest.java | 2 +- 9 files changed, 22 insertions(+), 27 deletions(-) diff --git a/cli/src/test/java/com/devonfw/tools/ide/commandlet/InstallCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/commandlet/InstallCommandletTest.java index daa12ea169..a453275307 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/commandlet/InstallCommandletTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/commandlet/InstallCommandletTest.java @@ -1,5 +1,7 @@ package com.devonfw.tools.ide.commandlet; +import static org.junit.jupiter.api.Assertions.assertThrows; + import java.util.List; import org.junit.jupiter.api.Test; @@ -13,8 +15,6 @@ import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; -import static org.junit.jupiter.api.Assertions.assertThrows; - /** * Test of {@link InstallCommandlet}. */ @@ -130,14 +130,14 @@ void testInstallCommandletWithSkipUpdates(WireMockRuntimeInfo wmRuntimeInfo) { install.version.setValueAsString("17*", context); // Record the log entry count before the action - int logCountBefore = context.getLogger().getEntries().size(); + int logCountBefore = context.getTestStartContext().getEntries().size(); // act - try to install with --skip-updates // Should skip the update to 17.0.10 since 17.0.6 matches the pattern install.run(); // assert - should NOT download 17.0.10, should stay on 17.0.6 - List newLogEntries = context.getLogger().getEntries().subList(logCountBefore, context.getLogger().getEntries().size()); + List newLogEntries = context.getTestStartContext().getEntries().subList(logCountBefore, context.getTestStartContext().getEntries().size()); boolean hasDownloadMessage = newLogEntries.stream().anyMatch(e -> e.message().contains("Trying to download")); assertThat(hasDownloadMessage).as("Should not download when --skip-updates is enabled and version matches pattern").isFalse(); assertThat(context.getSoftwarePath().resolve("java/.ide.software.version")).exists().hasContent(installedVersion); @@ -194,13 +194,13 @@ void testInstallCommandletWithSkipUpdatesInstallsWhenVersionMismatch(WireMockRun install.tool.setValueAsString("java", context); install.version.setValueAsString("21*", context); - int logCountBefore = context.getLogger().getEntries().size(); + int logCountBefore = context.getTestStartContext().getEntries().size(); // act - install with --skip-updates but with non-matching version install.run(); // assert - SHOULD download and install 21.x because installed 17.0.6 does NOT match pattern "21*" - List newLogEntries = context.getLogger().getEntries().subList(logCountBefore, context.getLogger().getEntries().size()); + List newLogEntries = context.getTestStartContext().getEntries().subList(logCountBefore, context.getTestStartContext().getEntries().size()); boolean hasDownloadMessage = newLogEntries.stream().anyMatch(e -> e.message().contains("Trying to download") && e.message().contains("21.")); assertThat(hasDownloadMessage).as("Should download when --skip-updates is enabled but version does not match").isTrue(); assertThat(context.getSoftwarePath().resolve("java/.ide.software.version")).exists().hasContent("21.0.8_9"); @@ -242,7 +242,7 @@ public void testInstallCommandletOfflineWithCachedDownload(WireMockRuntimeInfo w // Determine the correct file extension and OS name based on the current OS String fileExtension = context.getSystemInfo().isWindows() ? "zip" : "tgz"; String osName = context.getSystemInfo().getOs().toString().toLowerCase(); - assertThat(context).logAtDebug().hasMessage("Using cached download of java in version " + version + " from " + assertThat(context).logAtDebug().hasMessage("Using cached download of java in version " + version + " from " + context.getDownloadPath().resolve("default").resolve("java-" + version + "-" + osName + "-x64." + fileExtension) + " (offline mode)"); } @@ -299,7 +299,7 @@ public void testInstallCommandletOfflineUpdateWithoutCachedDownload(WireMockRunt // assert - should continue using the old version and log a warning assertThat(context.getSoftwarePath().resolve("java/.ide.software.version")).exists().hasContent(installedVersion); - assertThat(context).logAtWarning().hasMessage("Cannot download java in version " + targetVersion + assertThat(context).logAtWarning().hasMessage("Cannot download java in version " + targetVersion + " because we are offline. Continuing with already installed version " + installedVersion + "."); } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java index 995a7fc489..2aac04fd20 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java @@ -20,8 +20,6 @@ */ public class IdeTestContext extends AbstractIdeTestContext { - private final IdeTestStartContext logger; - private GitContext gitContext; /** @@ -58,7 +56,6 @@ public IdeTestContext(Path workingDirectory, IdeLogLevel logLevel, WireMockRunti private IdeTestContext(IdeTestStartContext startContext, Path workingDirectory, WireMockRuntimeInfo wireMockRuntimeInfo) { super(startContext, workingDirectory, wireMockRuntimeInfo); - this.logger = startContext; this.gitContext = new GitContextMock(); } @@ -92,9 +89,9 @@ public static IdeTestContext of() { /** * @return the {@link IdeTestStartContext}. */ - public IdeTestStartContext getLogger() { + public IdeTestStartContext getTestStartContext() { - return logger; + return (IdeTestStartContext) getStartContext(); } /** diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextAssertion.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextAssertion.java index 76a685eaaa..8a259bc311 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextAssertion.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextAssertion.java @@ -26,7 +26,7 @@ public IdeTestContextAssertion(IdeTestContext context) { */ public IdeTestLoggerAssertion log(IdeLogLevel level) { - return new IdeTestLoggerAssertion(context.getLogger().getEntries(), level); + return new IdeTestLoggerAssertion(context.getTestStartContext().getEntries(), level); } /** diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeLogListenerCollector.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeLogListenerCollector.java index 5950be0c78..6099578011 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/log/IdeLogListenerCollector.java +++ b/cli/src/test/java/com/devonfw/tools/ide/log/IdeLogListenerCollector.java @@ -1,7 +1,7 @@ package com.devonfw.tools.ide.log; -import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; /** * Implementation of {@link IdeLogListener} that collects all events as {@link IdeLogEntry}. @@ -15,7 +15,7 @@ public class IdeLogListenerCollector extends IdeLogListenerBuffer { */ public IdeLogListenerCollector() { super(false); - this.entries = new ArrayList<>(512); + this.entries = new CopyOnWriteArrayList<>(); } /** diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLoggerAssertion.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLoggerAssertion.java index e67bc6c5be..3676fb1759 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLoggerAssertion.java +++ b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLoggerAssertion.java @@ -21,7 +21,7 @@ public IdeTestLoggerAssertion(List entries, IdeLogLevel level) { } /** - * @param message the expected {@link com.devonfw.tools.ide.log.IdeSubLogger#log(String) log message}. + * @param message the expected {@link IdeLogEntry#message() log message}. * @return this assertion itself for fluent API calls. */ public IdeTestLoggerAssertion hasMessage(String message) { @@ -30,8 +30,7 @@ public IdeTestLoggerAssertion hasMessage(String message) { } /** - * @param message the {@link String} expected to be {@link String#contains(CharSequence) contained} in a - * {@link com.devonfw.tools.ide.log.IdeSubLogger#log(String) log message}. + * @param message the {@link String} expected to be {@link String#contains(CharSequence) contained} in a {@link IdeLogEntry}. * @return this assertion itself for fluent API calls. */ public IdeTestLoggerAssertion hasMessageContaining(String message) { @@ -40,7 +39,7 @@ public IdeTestLoggerAssertion hasMessageContaining(String message) { } /** - * @param message the {@link com.devonfw.tools.ide.log.IdeSubLogger#log(String) log message} that is not expected and should not have been logged. + * @param message the {@link IdeLogEntry#message() log message} that is not expected and should not have been logged. * @return this assertion itself for fluent API calls. */ public IdeTestLoggerAssertion hasNoMessage(String message) { @@ -49,8 +48,7 @@ public IdeTestLoggerAssertion hasNoMessage(String message) { } /** - * @param message the {@link String} expected not be {@link String#contains(CharSequence) contained} in any - * {@link com.devonfw.tools.ide.log.IdeSubLogger#log(String) log message}. + * @param message the {@link String} expected not be {@link String#contains(CharSequence) contained} in any {@link IdeLogEntry}. * @return this assertion itself for fluent API calls. */ public IdeTestLoggerAssertion hasNoMessageContaining(String message) { @@ -69,7 +67,7 @@ public IdeTestLoggerAssertion hasNoEntryWithException() { } /** - * @param messages the expected {@link com.devonfw.tools.ide.log.IdeSubLogger#log(String) log message}s in order. + * @param messages the expected {@link IdeLogEntry#message()} message}s in order. * @return this assertion itself for fluent API calls. */ public IdeTestLoggerAssertion hasEntries(String... messages) { diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/LocalToolCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/LocalToolCommandletTest.java index dec62d8e0e..c5f3f34df5 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/LocalToolCommandletTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/LocalToolCommandletTest.java @@ -131,7 +131,7 @@ void testRunToolWithDependencies() { private static void runIntellijAndCheckInstallationWithJavaDependency(IdeTestContext context) { // arrange - context.getLogger().getEntries().clear(); // clear logs from previous run(s) + context.getTestStartContext().getEntries().clear(); // clear logs from previous run(s) Intellij intellij = context.getCommandletManager().getCommandlet(Intellij.class); // act intellij.run(); diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijTest.java index 8943cdeea4..8047049eeb 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/intellij/IntellijTest.java @@ -121,7 +121,7 @@ void testCheckPluginInstallation() { // part 2 of test // arrange - context.getLogger().getEntries().clear(); + context.getTestStartContext().getEntries().clear(); // act commandlet.run(); // assert diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/pycharm/PycharmTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/pycharm/PycharmTest.java index c6372984e4..b82803d48c 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/pycharm/PycharmTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/pycharm/PycharmTest.java @@ -119,7 +119,7 @@ void testCheckPluginInstallation() { // part 2 of test // arrange - context.getLogger().getEntries().clear(); + context.getTestStartContext().getEntries().clear(); // act commandlet.run(); // assert diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/vscode/VscodeTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/vscode/VscodeTest.java index 434c4ffe8b..23c2007bc1 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/vscode/VscodeTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/vscode/VscodeTest.java @@ -61,7 +61,7 @@ void testCheckPluginInstallation() { // part 2 of test // arrange - context.getLogger().getEntries().clear(); + context.getTestStartContext().getEntries().clear(); // act commandlet.run(); // assert From e55a9190073d6a6b055cdbcb9191d071b54b023d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Sun, 22 Feb 2026 19:45:55 +0100 Subject: [PATCH 36/51] #404: workaround for JUL bug --- .../java/com/devonfw/tools/ide/context/AbstractIdeContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index f3b5172b73..ea0f1b22b2 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -1169,7 +1169,7 @@ protected final Properties createJavaUtilLoggingProperties(boolean console, bool } Properties properties = new Properties(); String intLevel = getLogLevel().getJulLevel().getName(); - String extLevel = "WARNING"; + String extLevel = "INFO"; // actually we want "WARNING" but there is a bug in JUL that the root level is applied to all loggers and "com.devonfw.tools.ide.level" then gets ignored. properties.setProperty(".level", extLevel); properties.setProperty("com.devonfw.tools.ide.level", intLevel); if (file) { From 060f7019f7a48407e30a52119266f5a23645e381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Sun, 22 Feb 2026 19:47:12 +0100 Subject: [PATCH 37/51] #404: fixed error --- gui/src/main/java/com/devonfw/ide/gui/MainController.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gui/src/main/java/com/devonfw/ide/gui/MainController.java b/gui/src/main/java/com/devonfw/ide/gui/MainController.java index 1bb6f0905b..0e64f0a47e 100644 --- a/gui/src/main/java/com/devonfw/ide/gui/MainController.java +++ b/gui/src/main/java/com/devonfw/ide/gui/MainController.java @@ -12,7 +12,6 @@ import com.devonfw.tools.ide.context.IdeStartContextImpl; import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.log.IdeLogListenerBuffer; -import com.devonfw.tools.ide.log.IdeSubLoggerOut; import com.devonfw.tools.ide.variable.IdeVariables; /** @@ -22,14 +21,19 @@ public class MainController { @FXML private ComboBox selectedProject; + @FXML private ComboBox selectedWorkspace; + @FXML private Button androidStudioOpen; + @FXML private Button eclipseOpen; + @FXML private Button intellijOpen; + @FXML private Button vsCodeOpen; @@ -130,7 +134,7 @@ private void openIDE(String inIde) { final IdeLogListenerBuffer buffer = new IdeLogListenerBuffer(); IdeLogLevel logLevel = IdeLogLevel.INFO; - IdeStartContextImpl startContext = new IdeStartContextImpl(logLevel, level -> new IdeSubLoggerOut(level, null, true, logLevel, buffer)); + IdeStartContextImpl startContext = new IdeStartContextImpl(logLevel, buffer); IdeGuiContext context = new IdeGuiContext(startContext, Path.of(this.directoryPath).resolve(this.projectValue).resolve(this.workspaceValue)); context.getCommandletManager().getCommandlet(inIde).run(); } From 8263a112b070160b8b29238c73de263371fc639d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Sun, 22 Feb 2026 20:34:22 +0100 Subject: [PATCH 38/51] #404: fixed error --- .../com/devonfw/tools/ide/context/IdeContextConsole.java | 9 +++++++++ .../devonfw/tools/IDEasy/dev/BuildSecurityJsonFiles.java | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContextConsole.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContextConsole.java index 10e386d1eb..81e949ea8f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeContextConsole.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeContextConsole.java @@ -7,6 +7,8 @@ import com.devonfw.tools.ide.io.IdeProgressBar; import com.devonfw.tools.ide.io.IdeProgressBarConsole; +import com.devonfw.tools.ide.log.IdeLogLevel; +import com.devonfw.tools.ide.log.IdeLogListenerNone; /** * Default implementation of {@link IdeContext} using the console. @@ -17,6 +19,13 @@ public class IdeContextConsole extends AbstractIdeContext { private final Scanner scanner; + /** + * The constructor. + */ + public IdeContextConsole() { + this(new IdeStartContextImpl(IdeLogLevel.INFO, IdeLogListenerNone.INSTANCE)); + } + /** * The constructor. * diff --git a/security/src/main/java/com/devonfw/tools/IDEasy/dev/BuildSecurityJsonFiles.java b/security/src/main/java/com/devonfw/tools/IDEasy/dev/BuildSecurityJsonFiles.java index b1e0ec6a49..33662b1eb4 100644 --- a/security/src/main/java/com/devonfw/tools/IDEasy/dev/BuildSecurityJsonFiles.java +++ b/security/src/main/java/com/devonfw/tools/IDEasy/dev/BuildSecurityJsonFiles.java @@ -16,7 +16,6 @@ import org.slf4j.LoggerFactory; import com.devonfw.tools.ide.context.IdeContextConsole; -import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.url.model.UrlMetadata; import com.devonfw.tools.ide.url.model.file.UrlSecurityFile; import com.devonfw.tools.ide.url.model.file.json.Cve; @@ -62,7 +61,7 @@ private BuildSecurityJsonFiles(Path urlsPath) { super(); UrlFinalReport report = new UrlFinalReport(); this.updateManager = new UpdateManager(urlsPath, report, Instant.now()); - IdeContextConsole context = new IdeContextConsole(IdeLogLevel.INFO, null, false); + IdeContextConsole context = new IdeContextConsole(); this.urlMetadata = new UrlMetadata(context, this.updateManager.getUrlRepository()); Settings settings = new Settings(); engine = new Engine(settings); From 98f01421f6aa880b5a4f45c2b7ed82e24f1f120f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Sun, 22 Feb 2026 21:00:38 +0100 Subject: [PATCH 39/51] #404: polishing (method names, JavaDoc, dont write logfile for version/edition list commandlets) --- .../tools/ide/commandlet/Commandlet.java | 8 ++++++-- .../ide/commandlet/ContextCommandlet.java | 2 +- .../ide/commandlet/EditionListCommandlet.java | 6 ++++++ .../tools/ide/commandlet/HelpCommandlet.java | 2 +- .../ide/commandlet/StatusCommandlet.java | 2 +- .../ide/commandlet/VersionListCommandlet.java | 6 ++++++ .../tools/ide/context/AbstractIdeContext.java | 19 +++++++++++-------- .../ide/context/AbstractIdeTestContext.java | 2 +- 8 files changed, 33 insertions(+), 14 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java index 01ea4ce046..2f1e395b92 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java @@ -213,7 +213,11 @@ public boolean isProcessableOutput() { return false; } - protected boolean isActivateJaveUtilLogging() { + /** + * @return {@code true} to write a logfile (unless disabled via {@link com.devonfw.tools.ide.variable.IdeVariables#IDE_WRITE_LOGFILE}), {@code false} + * otherwise. + */ + public boolean isWriteLogFile() { return !isProcessableOutput(); } @@ -223,7 +227,7 @@ protected boolean isActivateJaveUtilLogging() { public final void run() { if (this.context != null) { // for ContextCommandlet we do not have a context yet - ((AbstractIdeContext) this.context).configureJavaUtilLogging(isActivateJaveUtilLogging()); + ((AbstractIdeContext) this.context).configureJavaUtilLogging(isWriteLogFile()); } doRun(); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java index 905ab704d0..da9903c314 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ContextCommandlet.java @@ -74,7 +74,7 @@ public boolean isIdeHomeRequired() { } @Override - protected boolean isActivateJaveUtilLogging() { + public boolean isWriteLogFile() { return false; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionListCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionListCommandlet.java index c32ab97cdd..4385317186 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionListCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EditionListCommandlet.java @@ -32,6 +32,12 @@ public String getName() { return "list-editions"; } + @Override + public boolean isWriteLogFile() { + + return false; + } + @Override protected void doRun() { diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java index 16dab3f3bd..f78a916a7f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java @@ -54,7 +54,7 @@ public boolean isIdeRootRequired() { } @Override - protected boolean isActivateJaveUtilLogging() { + public boolean isWriteLogFile() { return false; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java index e5b8659fb1..35c4806f42 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java @@ -41,7 +41,7 @@ public String getName() { } @Override - protected boolean isActivateJaveUtilLogging() { + public boolean isWriteLogFile() { return false; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionListCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionListCommandlet.java index 3602d43445..abbb6fc7ec 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionListCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionListCommandlet.java @@ -32,6 +32,12 @@ public String getName() { return "list-versions"; } + @Override + public boolean isWriteLogFile() { + + return false; + } + @Override protected void doRun() { diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index ea0f1b22b2..850f4d69d7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -1129,6 +1129,11 @@ public int run(CliArguments arguments) { } } + /** + * Configures the logging system (JUL). + * + * @param logfile value of {@link Commandlet#isWriteLogFile()}. + */ public void configureJavaUtilLogging(boolean logfile) { if (this.julConfigured) { @@ -1144,7 +1149,7 @@ public void configureJavaUtilLogging(boolean logfile) { this.julConfigured = true; this.startContext.activateLogging(); } catch (IOException e) { - LOG.error("Failed to configure logging: " + e, e); + LOG.error("Failed to configure logging: {}", e.toString(), e); } } @@ -1157,15 +1162,15 @@ protected Properties createJavaUtilLoggingProperties(boolean logfile) { } } this.startContext.setWriteLogfile(logfile); - return createJavaUtilLoggingProperties(false, logfile); + return doCreateJavaUtilLoggingProperties(logfile); } - protected final Properties createJavaUtilLoggingProperties(boolean console, boolean file) { + protected final Properties doCreateJavaUtilLoggingProperties(boolean file) { Path idePath = getIdePath(); if (file && (idePath == null)) { file = false; - LOG.error("Cannot enable --logfile option since IDE_ROOT is undefined."); + LOG.error("Cannot enable log-file since IDE_ROOT is undefined."); } Properties properties = new Properties(); String intLevel = getLogLevel().getJulLevel().getName(); @@ -1174,10 +1179,6 @@ protected final Properties createJavaUtilLoggingProperties(boolean console, bool properties.setProperty("com.devonfw.tools.ide.level", intLevel); if (file) { properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler,java.util.logging.FileHandler"); - } else { - properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler"); - } - if (file) { properties.setProperty("java.util.logging.FileHandler.level", intLevel); properties.setProperty("java.util.logging.FileHandler.formatter", "java.util.logging.SimpleFormatter"); properties.setProperty("java.util.logging.FileHandler.encoding", "UTF-8"); @@ -1185,6 +1186,8 @@ protected final Properties createJavaUtilLoggingProperties(boolean console, bool Path logsPath = idePath.resolve(FOLDER_LOGS).resolve(DateTimeUtil.formatDate(now, true)); getFileAccess().mkdirs(logsPath); properties.setProperty("java.util.logging.FileHandler.pattern", logsPath.resolve("ideasy-" + DateTimeUtil.formatTime(now) + ".log").toString()); + } else { + properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler"); } properties.setProperty("com.devonfw.tools.ide.log.JulConsoleHandler.level", intLevel); properties.setProperty("java.util.logging.SimpleFormatter.format", "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL [%4$s] [%3$s] %5$s%6$s%n"); diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java index 4337995f08..9a038a8c7e 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java @@ -416,6 +416,6 @@ protected Path findBashInWindowsRegistry() { @Override protected Properties createJavaUtilLoggingProperties(boolean logfile) { - return createJavaUtilLoggingProperties(true, false); + return doCreateJavaUtilLoggingProperties(false); } } From caa9808972002ea94d80f08afd4c5a638856484c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Mon, 23 Feb 2026 10:32:22 +0100 Subject: [PATCH 40/51] #404: robustness fix --- .../tools/ide/context/AbstractIdeContext.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 850f4d69d7..59f199e870 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -1106,7 +1106,7 @@ public int run(CliArguments arguments) { return ProcessResult.SUCCESS; } } - this.startContext.activateLogging(); + activateLogging(); verifyIdeMinVersion(false); if (result != null) { LOG.error(result.getErrorMessage()); @@ -1119,7 +1119,7 @@ public int run(CliArguments arguments) { help.run(); return 1; } catch (Throwable t) { - this.startContext.activateLogging(); + activateLogging(); step.error(t, true); throw t; } finally { @@ -1129,6 +1129,17 @@ public int run(CliArguments arguments) { } } + /** + * Ensure the logging system is initialized. + */ + public void activateLogging() { + + if (!this.julConfigured) { + configureJavaUtilLogging(false); + } + this.startContext.activateLogging(); + } + /** * Configures the logging system (JUL). * From c39439f757cb1ddaa6b18638c230eb4415373e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Mon, 23 Feb 2026 11:10:14 +0100 Subject: [PATCH 41/51] #404: convenience methods for simpler usage --- .../devonfw/tools/ide/log/IdeLogLevel.java | 88 ++++++++++++++++++- .../tools/ide/log/JulConsoleHandler.java | 2 +- .../tools/ide/log/Slf4jLoggerAdapter.java | 12 +-- 3 files changed, 89 insertions(+), 13 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java index fee2ba376e..0dc7f7d344 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java @@ -1,8 +1,12 @@ package com.devonfw.tools.ide.log; +import org.slf4j.Logger; import org.slf4j.Marker; import org.slf4j.MarkerFactory; import org.slf4j.event.Level; +import org.slf4j.spi.LoggingEventBuilder; + +import com.devonfw.tools.ide.context.IdeStartContextImpl; /** * {@link Enum} with the available log-levels for IDEasy. @@ -106,7 +110,88 @@ public java.util.logging.Level getJulLevel() { */ public boolean isCustom() { - return (this == STEP) || (this == INTERACTION) || (this == SUCCESS) || (this == PROCESSABLE); + return (this.slf4jMarker != null); + } + + /** + * @param logger the SLF4J {@link Logger}. + * @param error the {@link Throwable} with the error to log. Must not be {@code null}. + */ + public void log(Logger logger, Throwable error) { + + log(logger, error, null, (Object[]) null); + } + + /** + * @param logger the SLF4J {@link Logger}. + * @param error the optional {@link Throwable} with the error to log or {@code null} for no error. + * @param message the message (template) to log. + */ + public void log(Logger logger, Throwable error, String message) { + + log(logger, error, message, (Object[]) null); + } + + /** + * @param logger the SLF4J {@link Logger}. + * @param message the message (template) to log. + */ + public void log(Logger logger, String message) { + + log(logger, null, message, (Object[]) null); + } + + /** + * @param logger the SLF4J {@link Logger}. + * @param message the message (template) to log. + * @param args the optional arguments to fill into the {@code message}. May be {@code null} or empty for no parameters. + */ + public void log(Logger logger, String message, Object... args) { + + log(logger, null, message, args); + } + + /** + * @param logger the SLF4J {@link Logger}. + * @param error the optional {@link Throwable} with the error to log or {@code null} for no error. + * @param message the message (template) to log. + * @param args the optional arguments to fill into the {@code message}. May be {@code null} or empty for no parameters. + */ + public void log(Logger logger, Throwable error, String message, Object... args) { + + LoggingEventBuilder builder = logger.atLevel(this.slf4jLevel).setCause(error); + if (this.slf4jMarker != null) { + builder = builder.addMarker(this.slf4jMarker); + } + if (Slf4jLoggerAdapter.isEmpty(args)) { + builder.log(message, args); + } else if (message == null) { + String msg = error.getMessage(); + if (msg == null) { + msg = error.toString(); + } + builder.log(msg); + } else { + builder.log(message); + } + } + + /** + * @return {@code true} if this {@link IdeLogLevel} is enabled (globally), {@code false} otherwise. + */ + public boolean isEnabled() { + + IdeLogLevel threshold = getLogLevel(); + return ordinal() >= threshold.ordinal(); + } + + static IdeLogLevel getLogLevel() { + IdeLogLevel threshold = IdeLogLevel.TRACE; + IdeStartContextImpl startContext = IdeStartContextImpl.get(); + if (startContext != null) { + threshold = startContext.getLogLevel(); + } + return threshold; } /** @@ -158,4 +243,5 @@ public static IdeLogLevel of(java.util.logging.Level level) { } throw new IllegalStateException("" + level); } + } diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java b/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java index df86e1be7d..11bdb46d38 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java @@ -28,7 +28,7 @@ public void publish(LogRecord record) { } } if (error != null) { - message = IdeLogExceptionDetails.of(ideLevel, Slf4jLoggerAdapter.getLogLevel()).format(message, error); + message = IdeLogExceptionDetails.of(ideLevel, IdeLogLevel.getLogLevel()).format(message, error); } out.append(message); if (startColor != null) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java index 0e9e7ee80c..bf4a9a0838 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java @@ -154,17 +154,7 @@ public void log(LoggingEvent event) { private boolean isLevelEnabled(Level level, Marker marker) { IdeLogLevel ideLevel = IdeLogLevel.of(level, marker); - IdeLogLevel threshold = getLogLevel(); - return ideLevel.ordinal() >= threshold.ordinal(); - } - - static IdeLogLevel getLogLevel() { - IdeLogLevel threshold = IdeLogLevel.TRACE; - IdeStartContextImpl startContext = IdeStartContextImpl.get(); - if (startContext != null) { - threshold = startContext.getLogLevel(); - } - return threshold; + return ideLevel.isEnabled(); } @Override From 0e2400b003a1833604437d6cab7f45e000e32e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Mon, 23 Feb 2026 11:10:50 +0100 Subject: [PATCH 42/51] #404: apply of simpler usage --- ...AbstractVersionOrEditionGetCommandlet.java | 23 +++++++++---------- .../ide/commandlet/CreateCommandlet.java | 2 +- .../ide/commandlet/EnvironmentCommandlet.java | 4 ++-- .../tools/ide/commandlet/HelpCommandlet.java | 13 ++--------- .../ide/commandlet/StatusCommandlet.java | 8 +++---- .../ide/commandlet/UpgradeCommandlet.java | 2 +- .../commandlet/UpgradeSettingsCommandlet.java | 4 ++-- .../ide/commandlet/VersionCommandlet.java | 2 +- .../tools/ide/context/AbstractIdeContext.java | 18 +++++++-------- .../devonfw/tools/ide/git/GitContextImpl.java | 2 +- .../tools/ide/log/IdeLogListenerBuffer.java | 14 +---------- .../tools/ide/migration/IdeMigrator.java | 2 +- .../tools/ide/network/NetworkStatusImpl.java | 7 +++--- .../tools/ide/security/ToolVersionChoice.java | 2 +- .../com/devonfw/tools/ide/step/StepImpl.java | 8 +++---- .../tools/ide/tool/GlobalToolCommandlet.java | 13 +++++------ .../tools/ide/tool/IdeasyCommandlet.java | 18 +++++++-------- .../tools/ide/tool/LocalToolCommandlet.java | 8 +++---- .../tools/ide/tool/ToolCommandlet.java | 4 ++-- .../tools/ide/tool/eclipse/Eclipse.java | 2 +- .../tool/ide/IdeaBasedIdeToolCommandlet.java | 2 +- .../com/devonfw/tools/ide/tool/node/Node.java | 2 +- .../repository/AbstractToolRepository.java | 4 ++-- .../devonfw/tools/ide/tool/vscode/Vscode.java | 2 +- .../ide/context/AbstractIdeTestContext.java | 2 +- 25 files changed, 72 insertions(+), 96 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java index b336228378..b387e884a7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractVersionOrEditionGetCommandlet.java @@ -4,7 +4,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.slf4j.Marker; import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.context.IdeContext; @@ -76,7 +75,7 @@ public boolean isProcessableOutput() { protected void doRun() { ToolCommandlet commandlet = this.tool.getValue(); - Marker marker = IdeLogLevel.PROCESSABLE.getSlf4jMarker(); + IdeLogLevel level = IdeLogLevel.PROCESSABLE; Object configuredValue = getConfiguredValue(commandlet); Object installedValue = getInstalledValue(commandlet); boolean getInstalledValue = this.installed.isTrue(); @@ -91,9 +90,9 @@ protected void doRun() { logToolInfo(commandlet, configuredValue, installedValue); } else { if (installedValue == null) { - LOG.info(marker, configuredValue.toString()); + level.log(LOG, configuredValue.toString()); } else { - LOG.info(marker, installedValue.toString()); + level.log(LOG, installedValue.toString()); } } } else { @@ -101,10 +100,10 @@ protected void doRun() { if (installedValue == null) { logToolInfo(commandlet, configuredValue, null); } else { - LOG.info(marker, installedValue.toString()); + level.log(LOG, installedValue.toString()); } } else { - LOG.info(marker, configuredValue.toString()); + level.log(LOG, configuredValue.toString()); } } } @@ -113,16 +112,16 @@ private void logToolInfo(ToolCommandlet commandlet, Object configuredValue, Obje String property = getPropertyToGet(); String toolName = commandlet.getName(); - Marker marker = IdeLogLevel.PROCESSABLE.getSlf4jMarker(); + IdeLogLevel level = IdeLogLevel.PROCESSABLE; if (installedValue == null) { - LOG.info(marker, "No installation of tool {} was found.", toolName); + level.log(LOG, "No installation of tool {} was found.", toolName); } else { - LOG.info(marker, "The installed {} for tool {} is {}", property, toolName, installedValue); + level.log(LOG, "The installed {} for tool {} is {}", property, toolName, installedValue); } - LOG.info(marker, "The configured {} for tool {} is {}", property, toolName, configuredValue); + level.log(LOG, "The configured {} for tool {} is {}", property, toolName, configuredValue); if (!Objects.equals(configuredValue, installedValue)) { - LOG.info(marker, "To install the configured {} call the following command:", property); - LOG.info(marker, "ide install {}", toolName); + level.log(LOG, "To install the configured {} call the following command:", property); + level.log(LOG, "ide install {}", toolName); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java index 0d07c2922b..58f8fb9999 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java @@ -71,7 +71,7 @@ protected void doRun() { super.doRun(); this.context.verifyIdeMinVersion(true); this.context.getFileAccess().writeFileContent(IdeVersion.getVersionString(), newProjectPath.resolve(IdeContext.FILE_SOFTWARE_VERSION)); - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully created new project '{}'.", newProjectName); + IdeLogLevel.SUCCESS.log(LOG, "Successfully created new project '{}'.", newProjectName); logWelcomeMessage(); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java index 96d71bcda6..7a1df72bee 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandlet.java @@ -104,7 +104,7 @@ private void printLines(Map variableMap, boolean winCmd) { LOG.debug("from {}:", line.getSource()); sourcePrinted = true; } - LOG.info(IdeLogLevel.PROCESSABLE.getSlf4jMarker(), format(line, winCmd)); + IdeLogLevel.PROCESSABLE.log(LOG, format(line, winCmd)); } } } @@ -112,7 +112,7 @@ private void printLines(Map variableMap, boolean winCmd) { List variables = new ArrayList<>(variableMap.values()); sortVariables(variables); for (VariableLine line : variables) { - LOG.info(IdeLogLevel.PROCESSABLE.getSlf4jMarker(), format(line, winCmd)); + IdeLogLevel.PROCESSABLE.log(LOG, format(line, winCmd)); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java index f78a916a7f..1a655f7444 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/HelpCommandlet.java @@ -6,8 +6,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.slf4j.Marker; -import org.slf4j.event.Level; import com.devonfw.tools.ide.context.AbstractIdeContext; import com.devonfw.tools.ide.context.IdeContext; @@ -64,7 +62,7 @@ protected void doRun() { this.context.printLogo(); NlsBundle bundle = NlsBundle.of(this.context); - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), bundle.get("version-banner"), IdeVersion.getVersionString()); + IdeLogLevel.SUCCESS.log(LOG, bundle.get("version-banner"), IdeVersion.getVersionString()); Commandlet cmd = this.commandlet.getValue(); if (cmd == null) { String usage = bundle.get("usage") + " ide [option]* [[commandlet] [arg]*]"; @@ -246,14 +244,7 @@ void print(IdeLogLevel level) { for (Arg arg : get()) { String message = format(arg); - Level slf4jLevel = level.getSlf4jLevel(); - Marker marker = level.getSlf4jMarker(); - if (marker == null) { - LOG.atLevel(slf4jLevel).log(message); - } else { - assert slf4jLevel == Level.INFO; - LOG.info(marker, message); - } + level.log(LOG, message); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java index 35c4806f42..9d050b3410 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/StatusCommandlet.java @@ -108,7 +108,7 @@ private void logSettingsGitStatus() { LOG.warn("Your settings are not up-to-date, please run 'ide update'."); } } else { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Your settings are up-to-date."); + IdeLogLevel.SUCCESS.log(LOG, "Your settings are up-to-date."); } String branch = gitContext.determineCurrentBranch(settingsPath); LOG.debug("Your settings branch is {}", branch); @@ -128,7 +128,7 @@ private void logMigrationStatus() { VersionIdentifier projectVersion = this.context.getProjectVersion(); VersionIdentifier targetVersion = migrator.getTargetVersion(); if (projectVersion.isLess(targetVersion)) { - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), + IdeLogLevel.INTERACTION.log(LOG, "Your project is on IDEasy version {} and needs an update to version {}!\nPlease run 'ide update' to migrate your project", projectVersion, targetVersion); } @@ -137,14 +137,14 @@ private void logMigrationStatus() { private void logGitBashLocationStatus() { Path bashPath = this.context.findBash(); if (bashPath != null) { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Found bash executable at: {}", bashPath); + IdeLogLevel.SUCCESS.log(LOG, "Found bash executable at: {}", bashPath); } else { LOG.error("No bash executable was found on your system!"); } GitContext gitContext = this.context.getGitContext(); Path gitPath = gitContext.findGit(); if (gitPath != null) { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Found git executable at: {}", gitPath); + IdeLogLevel.SUCCESS.log(LOG, "Found git executable at: {}", gitPath); } else { LOG.error("No git executable was found on your system!"); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java index 4c253d230e..d33d44afbf 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeCommandlet.java @@ -49,7 +49,7 @@ protected void doRun() { IdeasyCommandlet ideasy = new IdeasyCommandlet(this.context, this.mode.getValue()); ToolInstallation installation = ideasy.install(false); if (installation.newInstallation()) { - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "It is recommended to run 'ide update' on your IDEasy projects now."); + IdeLogLevel.INTERACTION.log(LOG, "It is recommended to run 'ide update' on your IDEasy projects now."); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java index aa4939278e..46914bb2ae 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java @@ -71,7 +71,7 @@ private void updateLegacyFolder(Path folder, String legacyName, String newName) try { if (!Files.exists(newFolder)) { fileAccess.move(legacyFolder, newFolder, StandardCopyOption.REPLACE_EXISTING); - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully renamed folder '{}' to '{}' in {}.", legacyName, newName, folder); + IdeLogLevel.SUCCESS.log(LOG, "Successfully renamed folder '{}' to '{}' in {}.", legacyName, newName, folder); } } catch (IllegalStateException e) { LOG.error("Error renaming folder {} to {} in {}", legacyName, newName, folder, e); @@ -233,7 +233,7 @@ private void updateRepositoryPropertiesFile(Path filePath) throws IOException { if (updated) { try { Files.write(filePath, lines, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully updated repository configuration file {}", filePath); + IdeLogLevel.SUCCESS.log(LOG, "Successfully updated repository configuration file {}", filePath); } catch (IOException e) { LOG.error("Failed to write updated repository configuration file {}", filePath); throw e; diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java index f8ba48dc24..da3ecb2ac7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/VersionCommandlet.java @@ -46,6 +46,6 @@ public boolean isProcessableOutput() { @Override protected void doRun() { - LOG.info(IdeLogLevel.PROCESSABLE.getSlf4jMarker(), IdeVersion.getVersionString()); + IdeLogLevel.PROCESSABLE.log(LOG, IdeVersion.getVersionString()); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 59f199e870..18dd1e63bb 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -895,12 +895,12 @@ public IdeLogListener getLogListener() { @Override public void logIdeHomeAndRootStatus() { if (this.ideRoot != null) { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "IDE_ROOT is set to {}", this.ideRoot); + IdeLogLevel.SUCCESS.log(LOG, "IDE_ROOT is set to {}", this.ideRoot); } if (this.ideHome == null) { LOG.warn(getMessageNotInsideIdeProject()); } else { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "IDE_HOME is set to {}", this.ideHome); + IdeLogLevel.SUCCESS.log(LOG, "IDE_HOME is set to {}", this.ideHome); } } @@ -958,7 +958,7 @@ public String askForInput(String message, String defaultValue) { while (true) { if (!message.isBlank()) { - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), message); + IdeLogLevel.INTERACTION.log(LOG, message); } if (isBatchMode()) { if (isForceMode()) { @@ -982,7 +982,7 @@ public String askForInput(String message, String defaultValue) { public O question(O[] options, String question, Object... args) { assert (options.length > 0); - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), question, args); + IdeLogLevel.INTERACTION.log(LOG, question, args); return displayOptionsAndGetAnswer(options); } @@ -996,24 +996,24 @@ private O displayOptionsAndGetAnswer(O[] options) { addMapping(mapping, key, option); String numericKey = Integer.toString(i); if (numericKey.equals(key)) { - LOG.trace("Options should not be numeric: " + key); + LOG.trace("Options should not be numeric: {}", key); } else { addMapping(mapping, numericKey, option); } - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "Option " + numericKey + ": " + title); + IdeLogLevel.INTERACTION.log(LOG, "Option {}: {}", numericKey, title); } O option = null; if (isBatchMode()) { if (isForceMode()) { option = options[0]; - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "" + option); + IdeLogLevel.INTERACTION.log(LOG, "" + option); } } else { while (option == null) { String answer = readLine(); option = mapping.get(answer); if (option == null) { - LOG.warn("Invalid answer: '" + answer + "' - please try again."); + LOG.warn("Invalid answer: '{}' - please try again.", answer); } } } @@ -1254,7 +1254,7 @@ settingsRepository, getSettingsCommitIdPath()))) { } else { msg = "Updates are available for the settings repository. If you want to apply the latest changes, call \"ide update\""; } - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), msg); + IdeLogLevel.INTERACTION.log(LOG, msg); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/git/GitContextImpl.java b/cli/src/main/java/com/devonfw/tools/ide/git/GitContextImpl.java index 00e9462882..5b15438e6e 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/git/GitContextImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/git/GitContextImpl.java @@ -125,7 +125,7 @@ private void handleErrors(Path targetRepository, ProcessResult result) { String message = "Failed to update git repository at " + targetRepository; if (this.context.isOfflineMode()) { LOG.warn(message); - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "Continuing as we are in offline mode - results may be outdated!"); + IdeLogLevel.INTERACTION.log(LOG, "Continuing as we are in offline mode - results may be outdated!"); } else { LOG.error(message); if (this.context.isOnline()) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java index 68f0944070..96cc0c2ab9 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java @@ -5,8 +5,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.slf4j.Marker; -import org.slf4j.spi.LoggingEventBuilder; /** * Implements {@link IdeLogListener} to buffer log events during bootstrapping and then flush them once the logger is properly configured. @@ -65,17 +63,7 @@ public void flushAndEndBuffering() { // write all cached log events to the logger again for processing for (IdeLogEntry entry : this.buffer) { IdeLogLevel level = entry.level(); - LoggingEventBuilder builder = LOG.atLevel(level.getSlf4jLevel()); - Marker marker = level.getSlf4jMarker(); - if (marker != null) { - builder = builder.addMarker(marker); - } - builder = builder.setCause(entry.error()); - if (entry.args() != null) { - builder.log(entry.rawMessage(), entry.args()); - } else { - builder.log(entry.rawMessage()); - } + level.log(LOG, entry.error(), entry.rawMessage(), entry.args()); } this.buffer.clear(); this.threshold = IdeLogLevel.TRACE; diff --git a/cli/src/main/java/com/devonfw/tools/ide/migration/IdeMigrator.java b/cli/src/main/java/com/devonfw/tools/ide/migration/IdeMigrator.java index 16cdeb46f5..a79d56afb4 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/migration/IdeMigrator.java +++ b/cli/src/main/java/com/devonfw/tools/ide/migration/IdeMigrator.java @@ -90,7 +90,7 @@ public void run(IdeContext context) { } } if (migrationCount > 0) { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully applied {} migration(s) to project {}", migrationCount, context.getProjectName()); + IdeLogLevel.SUCCESS.log(LOG, "Successfully applied {} migration(s) to project {}", migrationCount, context.getProjectName()); } else { LOG.debug("No migration to apply to project {}", context.getProjectName()); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/network/NetworkStatusImpl.java b/cli/src/main/java/com/devonfw/tools/ide/network/NetworkStatusImpl.java index 7fb1bb4a3d..4b7489def6 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/network/NetworkStatusImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/network/NetworkStatusImpl.java @@ -103,7 +103,7 @@ public void logStatusMessage() { } Throwable error = getError(); if (error == null) { - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "You are online."); + IdeLogLevel.INTERACTION.log(LOG, "You are online."); return; } String message = "You are offline because of the following error:"; @@ -116,10 +116,9 @@ public void logStatusMessage() { if (error instanceof SSLException) { LOG.warn( "You are having TLS issues. We guess you are forced to use a VPN tool breaking end-to-end encryption causing this effect. As a workaround you can create and configure a truststore as described here:"); - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), "https://github.com/devonfw/IDEasy/blob/main/documentation/proxy-support.adoc#tls-certificate-issues"); + IdeLogLevel.INTERACTION.log(LOG, "https://github.com/devonfw/IDEasy/blob/main/documentation/proxy-support.adoc#tls-certificate-issues"); } else { - LOG.info(IdeLogLevel.INTERACTION.getSlf4jMarker(), - "Please check potential proxy settings, ensure you are properly connected to the internet and retry this operation."); + IdeLogLevel.INTERACTION.log(LOG, "Please check potential proxy settings, ensure you are properly connected to the internet and retry this operation."); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/security/ToolVersionChoice.java b/cli/src/main/java/com/devonfw/tools/ide/security/ToolVersionChoice.java index fb95358857..262b17777b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/security/ToolVersionChoice.java +++ b/cli/src/main/java/com/devonfw/tools/ide/security/ToolVersionChoice.java @@ -63,7 +63,7 @@ public boolean logAndCheckIfEmpty() { String message = this.vulnerabilities.toString(this.toolEditionAndVersion); if (this.vulnerabilities.getIssues().isEmpty()) { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), message); + IdeLogLevel.SUCCESS.log(LOG, message); return true; } else { LOG.warn(message); 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 8e334444a3..5c7723b0b6 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 @@ -68,7 +68,7 @@ public StepImpl(AbstractIdeContext context, StepImpl parent, String name, boolea LOG.trace("Starting step {} with params {}...", name, Arrays.toString(params)); } if (!this.silent) { - LOG.info(IdeLogLevel.STEP.getSlf4jMarker(), "Start: {}", name); + IdeLogLevel.STEP.log(LOG, "Start: {}", name); } } @@ -160,9 +160,9 @@ private void end(Boolean newSuccess, Throwable error, boolean suppress, String m if (newSuccess.booleanValue()) { assert (error == null); if (message != null) { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), message, args); + IdeLogLevel.SUCCESS.log(LOG, message, args); } else if (!this.silent) { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully ended step '{}'.", this.name); + IdeLogLevel.SUCCESS.log(LOG, "Successfully ended step '{}'.", this.name); } LOG.debug("Step '{}' ended successfully.", this.name); } else { @@ -217,7 +217,7 @@ public void logSummary(boolean suppressSuccess) { logErrorSummary(0, summary); if (summary.getError() == 0) { if (!suppressSuccess) { - LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully completed {}", getNameWithParams()); + IdeLogLevel.SUCCESS.log(LOG, "Successfully completed {}", getNameWithParams()); } } else { LOG.error(summary.toString()); diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java index 4385b49acf..95c520a3b6 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java @@ -8,7 +8,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.slf4j.Marker; import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.common.Tag; @@ -80,12 +79,12 @@ protected boolean runWithPackageManager(boolean silent, List Date: Mon, 23 Feb 2026 11:53:47 +0100 Subject: [PATCH 43/51] #1303: bugfix for privacy mode --- .../com/devonfw/tools/ide/commandlet/CreateCommandlet.java | 2 +- cli/src/main/java/com/devonfw/tools/ide/util/PrivacyUtil.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java index 58f8fb9999..deb031459d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CreateCommandlet.java @@ -60,7 +60,7 @@ protected void doRun() { LOG.info("Creating new IDEasy project in {}", newProjectPath); if (!this.context.getFileAccess().isEmptyDir(newProjectPath)) { - this.context.askToContinue("Directory " + newProjectPath + " already exists. Do you want to continue?"); + this.context.askToContinue("Directory {} already exists. Do you want to continue?", newProjectPath); } else { this.context.getFileAccess().mkdirs(newProjectPath); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/util/PrivacyUtil.java b/cli/src/main/java/com/devonfw/tools/ide/util/PrivacyUtil.java index 1577ee6501..763b69222f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/util/PrivacyUtil.java +++ b/cli/src/main/java/com/devonfw/tools/ide/util/PrivacyUtil.java @@ -17,7 +17,7 @@ public final class PrivacyUtil { "tbz2", "zip", "compress", "compression", "global", "value", "code", "branch", "string", "long", "number", "numeric", "apache", "commons", "hibernate", "storage", "db", "spring", "springframework", "boot", "quarkus", "mnt", "usr", "user", "users", "windows", "etc", "var", "log", "lib", "drivers", "system", "system32", "appdata", "module", "info", "sha1", "md5", "sha256", "sha512", "pkcs", "p12", "cert", "file", "files", "bin", "bash", "program", - "mingw64"); + "mingw64", "dummy"); // construction forbidden private PrivacyUtil() { @@ -72,7 +72,7 @@ public static String removeSensitivePathInformation(String arg) { } index = indexOfSlash(arg, index); if (index < 0) { - result.append(arg, start, length); // append rest + appendSegment(arg, result, start, length); // append rest } } return result.toString(); From a08741ff58ce71441a7807021e1ce2064357eb4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Mon, 23 Feb 2026 11:54:15 +0100 Subject: [PATCH 44/51] #404: fixed stupid bug --- cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java index 0dc7f7d344..c76fb656f0 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java @@ -163,7 +163,7 @@ public void log(Logger logger, Throwable error, String message, Object... args) if (this.slf4jMarker != null) { builder = builder.addMarker(this.slf4jMarker); } - if (Slf4jLoggerAdapter.isEmpty(args)) { + if (!Slf4jLoggerAdapter.isEmpty(args)) { builder.log(message, args); } else if (message == null) { String msg = error.getMessage(); From 87fb9f488a74135607f1e9e5946899798ae418ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Mon, 23 Feb 2026 11:54:49 +0100 Subject: [PATCH 45/51] #1713: improve logfile naming --- .../tools/ide/commandlet/Commandlet.java | 2 +- .../tools/ide/context/AbstractIdeContext.java | 46 +++++++++++++------ .../ide/context/AbstractIdeTestContext.java | 4 +- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java index 2f1e395b92..3509e21a1c 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java @@ -227,7 +227,7 @@ public boolean isWriteLogFile() { public final void run() { if (this.context != null) { // for ContextCommandlet we do not have a context yet - ((AbstractIdeContext) this.context).configureJavaUtilLogging(isWriteLogFile()); + ((AbstractIdeContext) this.context).configureJavaUtilLogging(isWriteLogFile(), this); } doRun(); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 18dd1e63bb..474dd7ce99 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -1106,7 +1106,7 @@ public int run(CliArguments arguments) { return ProcessResult.SUCCESS; } } - activateLogging(); + activateLogging(cmd); verifyIdeMinVersion(false); if (result != null) { LOG.error(result.getErrorMessage()); @@ -1119,7 +1119,7 @@ public int run(CliArguments arguments) { help.run(); return 1; } catch (Throwable t) { - activateLogging(); + activateLogging(cmd); step.error(t, true); throw t; } finally { @@ -1132,10 +1132,10 @@ public int run(CliArguments arguments) { /** * Ensure the logging system is initialized. */ - public void activateLogging() { + private void activateLogging(Commandlet cmd) { if (!this.julConfigured) { - configureJavaUtilLogging(false); + configureJavaUtilLogging(false, cmd); } this.startContext.activateLogging(); } @@ -1144,13 +1144,14 @@ public void activateLogging() { * Configures the logging system (JUL). * * @param logfile value of {@link Commandlet#isWriteLogFile()}. + * @param cmd the {@link Commandlet} to be called. May be {@code null}. */ - public void configureJavaUtilLogging(boolean logfile) { + public void configureJavaUtilLogging(boolean logfile, Commandlet cmd) { if (this.julConfigured) { return; } - Properties properties = createJavaUtilLoggingProperties(logfile); + Properties properties = createJavaUtilLoggingProperties(logfile, cmd); try { ByteArrayOutputStream out = new ByteArrayOutputStream(512); properties.store(out, null); @@ -1164,7 +1165,7 @@ public void configureJavaUtilLogging(boolean logfile) { } } - protected Properties createJavaUtilLoggingProperties(boolean logfile) { + protected Properties createJavaUtilLoggingProperties(boolean logfile, Commandlet cmd) { if (logfile) { Boolean writeLogfile = IdeVariables.IDE_WRITE_LOGFILE.get(this); @@ -1173,10 +1174,10 @@ protected Properties createJavaUtilLoggingProperties(boolean logfile) { } } this.startContext.setWriteLogfile(logfile); - return doCreateJavaUtilLoggingProperties(logfile); + return doCreateJavaUtilLoggingProperties(logfile, cmd); } - protected final Properties doCreateJavaUtilLoggingProperties(boolean file) { + protected final Properties doCreateJavaUtilLoggingProperties(boolean file, Commandlet cmd) { Path idePath = getIdePath(); if (file && (idePath == null)) { @@ -1193,10 +1194,9 @@ protected final Properties doCreateJavaUtilLoggingProperties(boolean file) { properties.setProperty("java.util.logging.FileHandler.level", intLevel); properties.setProperty("java.util.logging.FileHandler.formatter", "java.util.logging.SimpleFormatter"); properties.setProperty("java.util.logging.FileHandler.encoding", "UTF-8"); - LocalDateTime now = LocalDateTime.now(); - Path logsPath = idePath.resolve(FOLDER_LOGS).resolve(DateTimeUtil.formatDate(now, true)); - getFileAccess().mkdirs(logsPath); - properties.setProperty("java.util.logging.FileHandler.pattern", logsPath.resolve("ideasy-" + DateTimeUtil.formatTime(now) + ".log").toString()); + Path logfile = createLogfilePath(idePath, cmd); + getFileAccess().mkdirs(logfile.getParent()); + properties.setProperty("java.util.logging.FileHandler.pattern", logfile.toString()); } else { properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler"); } @@ -1205,6 +1205,26 @@ protected final Properties doCreateJavaUtilLoggingProperties(boolean file) { return properties; } + private Path createLogfilePath(Path idePath, Commandlet cmd) { + LocalDateTime now = LocalDateTime.now(); + Path logsPath = idePath.resolve(FOLDER_LOGS).resolve(DateTimeUtil.formatDate(now, true)); + StringBuilder sb = new StringBuilder(32); + if (this.ideHome == null || ((cmd != null) && !cmd.isIdeHomeRequired())) { + sb.append("_ide-"); + } else { + sb.append(this.ideHome.getFileName().toString()); + sb.append('-'); + } + sb.append("ide-"); + if (cmd != null) { + sb.append(cmd.getName()); + sb.append('-'); + } + sb.append(DateTimeUtil.formatTime(now)); + sb.append(".log"); + return logsPath.resolve(sb.toString()); + } + @Override public void runWithoutLogging(Runnable lambda, IdeLogLevel threshold) { diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java index 5e918cba63..77ef26874f 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java @@ -414,8 +414,8 @@ protected Path findBashInWindowsRegistry() { } @Override - protected Properties createJavaUtilLoggingProperties(boolean logfile) { + protected Properties createJavaUtilLoggingProperties(boolean logfile, Commandlet cmd) { - return doCreateJavaUtilLoggingProperties(false); + return doCreateJavaUtilLoggingProperties(false, cmd); } } From e9424cfa46610c2527ca7d6561b4ad6a6cd0b947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Mon, 23 Feb 2026 12:18:25 +0100 Subject: [PATCH 46/51] #1303: bugfix for privacy mode --- .../devonfw/tools/ide/util/PrivacyUtil.java | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/util/PrivacyUtil.java b/cli/src/main/java/com/devonfw/tools/ide/util/PrivacyUtil.java index 763b69222f..c230d35814 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/util/PrivacyUtil.java +++ b/cli/src/main/java/com/devonfw/tools/ide/util/PrivacyUtil.java @@ -17,13 +17,24 @@ public final class PrivacyUtil { "tbz2", "zip", "compress", "compression", "global", "value", "code", "branch", "string", "long", "number", "numeric", "apache", "commons", "hibernate", "storage", "db", "spring", "springframework", "boot", "quarkus", "mnt", "usr", "user", "users", "windows", "etc", "var", "log", "lib", "drivers", "system", "system32", "appdata", "module", "info", "sha1", "md5", "sha256", "sha512", "pkcs", "p12", "cert", "file", "files", "bin", "bash", "program", - "mingw64", "dummy"); + "mingw64", "dummy", "hosts"); // construction forbidden private PrivacyUtil() { } + private static int indexOfSlash(String arg, int start) { + int index = arg.indexOf('/', start); + int index2 = arg.indexOf('\\', start); + if (index2 < 0) { + return index; + } else if ((index < 0) || (index2 < index)) { + return index2; + } + return index; + } + /** * @param arg the path or any {@link String} containing one or multiple paths. * @return a normalized form of the @@ -72,23 +83,24 @@ public static String removeSensitivePathInformation(String arg) { } index = indexOfSlash(arg, index); if (index < 0) { - appendSegment(arg, result, start, length); // append rest + // append rest + int end = start; + while (end < length) { + int cp = arg.codePointAt(end); + if ((cp == ' ') || (cp == '"') || (cp == '\'')) { + break; + } + end++; + } + appendSegment(arg, result, start, end); + if (end < length) { + result.append(arg, end, length); + } } } return result.toString(); } - private static int indexOfSlash(String arg, int start) { - int index = arg.indexOf('/', start); - int index2 = arg.indexOf('\\', start); - if (index2 < 0) { - return index; - } else if ((index < 0) || (index2 < index)) { - return index2; - } - return index; - } - private static void appendSegment(String arg, StringBuilder result, int start, int index) { String segment = arg.substring(start, index); From f1f7e1e611bf44ea1c42fa64ba51f696e7c1c807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Mon, 23 Feb 2026 12:19:04 +0100 Subject: [PATCH 47/51] #1713: improve configureJavaUtilLogging --- .../tools/ide/commandlet/Commandlet.java | 2 +- .../tools/ide/context/AbstractIdeContext.java | 42 ++++++++++--------- .../ide/context/AbstractIdeTestContext.java | 5 ++- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java index 3509e21a1c..76dd91ebe8 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java @@ -227,7 +227,7 @@ public boolean isWriteLogFile() { public final void run() { if (this.context != null) { // for ContextCommandlet we do not have a context yet - ((AbstractIdeContext) this.context).configureJavaUtilLogging(isWriteLogFile(), this); + ((AbstractIdeContext) this.context).configureJavaUtilLogging(this); } doRun(); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 474dd7ce99..8ee355105f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -168,6 +168,8 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt private boolean julConfigured; + private Path logfile; + /** * The constructor. * @@ -1121,6 +1123,9 @@ public int run(CliArguments arguments) { } catch (Throwable t) { activateLogging(cmd); step.error(t, true); + if (this.logfile != null) { + System.err.println("Logfile can be found at " + this.logfile); // do not use logger + } throw t; } finally { step.close(); @@ -1135,7 +1140,7 @@ public int run(CliArguments arguments) { private void activateLogging(Commandlet cmd) { if (!this.julConfigured) { - configureJavaUtilLogging(false, cmd); + configureJavaUtilLogging(cmd); } this.startContext.activateLogging(); } @@ -1143,15 +1148,16 @@ private void activateLogging(Commandlet cmd) { /** * Configures the logging system (JUL). * - * @param logfile value of {@link Commandlet#isWriteLogFile()}. * @param cmd the {@link Commandlet} to be called. May be {@code null}. */ - public void configureJavaUtilLogging(boolean logfile, Commandlet cmd) { + public void configureJavaUtilLogging(Commandlet cmd) { if (this.julConfigured) { return; } - Properties properties = createJavaUtilLoggingProperties(logfile, cmd); + boolean writeLogfile = isWriteLogfile(cmd); + this.startContext.setWriteLogfile(writeLogfile); + Properties properties = createJavaUtilLoggingProperties(writeLogfile, cmd); try { ByteArrayOutputStream out = new ByteArrayOutputStream(512); properties.store(out, null); @@ -1165,23 +1171,19 @@ public void configureJavaUtilLogging(boolean logfile, Commandlet cmd) { } } - protected Properties createJavaUtilLoggingProperties(boolean logfile, Commandlet cmd) { - - if (logfile) { - Boolean writeLogfile = IdeVariables.IDE_WRITE_LOGFILE.get(this); - if (Boolean.FALSE.equals(writeLogfile)) { - logfile = false; - } + protected boolean isWriteLogfile(Commandlet cmd) { + if (!cmd.isWriteLogFile()) { + return false; } - this.startContext.setWriteLogfile(logfile); - return doCreateJavaUtilLoggingProperties(logfile, cmd); + Boolean writeLogfile = IdeVariables.IDE_WRITE_LOGFILE.get(this); + return Boolean.TRUE.equals(writeLogfile); } - protected final Properties doCreateJavaUtilLoggingProperties(boolean file, Commandlet cmd) { + private Properties createJavaUtilLoggingProperties(boolean writeLogfile, Commandlet cmd) { Path idePath = getIdePath(); - if (file && (idePath == null)) { - file = false; + if (writeLogfile && (idePath == null)) { + writeLogfile = false; LOG.error("Cannot enable log-file since IDE_ROOT is undefined."); } Properties properties = new Properties(); @@ -1189,14 +1191,14 @@ protected final Properties doCreateJavaUtilLoggingProperties(boolean file, Comma String extLevel = "INFO"; // actually we want "WARNING" but there is a bug in JUL that the root level is applied to all loggers and "com.devonfw.tools.ide.level" then gets ignored. properties.setProperty(".level", extLevel); properties.setProperty("com.devonfw.tools.ide.level", intLevel); - if (file) { + if (writeLogfile) { properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler,java.util.logging.FileHandler"); properties.setProperty("java.util.logging.FileHandler.level", intLevel); properties.setProperty("java.util.logging.FileHandler.formatter", "java.util.logging.SimpleFormatter"); properties.setProperty("java.util.logging.FileHandler.encoding", "UTF-8"); - Path logfile = createLogfilePath(idePath, cmd); - getFileAccess().mkdirs(logfile.getParent()); - properties.setProperty("java.util.logging.FileHandler.pattern", logfile.toString()); + this.logfile = createLogfilePath(idePath, cmd); + getFileAccess().mkdirs(this.logfile.getParent()); + properties.setProperty("java.util.logging.FileHandler.pattern", this.logfile.toString()); } else { properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler"); } diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java index 77ef26874f..84022d2a05 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java @@ -414,8 +414,9 @@ protected Path findBashInWindowsRegistry() { } @Override - protected Properties createJavaUtilLoggingProperties(boolean logfile, Commandlet cmd) { + protected boolean isWriteLogfile(Commandlet cmd) { - return doCreateJavaUtilLoggingProperties(false, cmd); + return false; } + } From 7d88da9759bc8fae602829867f7f1f9b070094e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Mon, 23 Feb 2026 17:40:25 +0100 Subject: [PATCH 48/51] #1713: smart way to always write trace log --- .../tools/ide/context/AbstractIdeContext.java | 35 ++++++------- .../tools/ide/context/IdeStartContext.java | 10 +++- .../ide/context/IdeStartContextImpl.java | 51 ++++++++++++++----- .../devonfw/tools/ide/log/IdeLogLevel.java | 2 +- .../tools/ide/log/IdeLogListenerBuffer.java | 5 +- .../tools/ide/log/JulConsoleHandler.java | 12 ++++- .../devonfw/tools/ide/log/JulLogLevel.java | 16 +++--- .../tools/ide/log/Slf4jLoggerAdapter.java | 14 ++++- .../com/devonfw/tools/ide/tool/mvn/Mvn.java | 1 - 9 files changed, 101 insertions(+), 45 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index 8ee355105f..fbf2b3a877 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -883,9 +883,15 @@ protected ProcessContext createProcessContext() { } @Override - public IdeLogLevel getLogLevel() { + public IdeLogLevel getLogLevelConsole() { - return this.startContext.getLogLevel(); + return this.startContext.getLogLevelConsole(); + } + + @Override + public IdeLogLevel getLogLevelLogger() { + + return this.startContext.getLogLevelLogger(); } @Override @@ -1139,9 +1145,7 @@ public int run(CliArguments arguments) { */ private void activateLogging(Commandlet cmd) { - if (!this.julConfigured) { - configureJavaUtilLogging(cmd); - } + configureJavaUtilLogging(cmd); this.startContext.activateLogging(); } @@ -1187,13 +1191,12 @@ private Properties createJavaUtilLoggingProperties(boolean writeLogfile, Command LOG.error("Cannot enable log-file since IDE_ROOT is undefined."); } Properties properties = new Properties(); - String intLevel = getLogLevel().getJulLevel().getName(); - String extLevel = "INFO"; // actually we want "WARNING" but there is a bug in JUL that the root level is applied to all loggers and "com.devonfw.tools.ide.level" then gets ignored. - properties.setProperty(".level", extLevel); - properties.setProperty("com.devonfw.tools.ide.level", intLevel); + // prevent 3rd party (e.g. java.lang.ProcessBuilder) logging into our console via JUL + // see JulLogLevel for the trick we did to workaround JUL flaws + properties.setProperty(".level", "SEVERE"); if (writeLogfile) { + this.startContext.setLogLevelLogger(IdeLogLevel.TRACE); properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler,java.util.logging.FileHandler"); - properties.setProperty("java.util.logging.FileHandler.level", intLevel); properties.setProperty("java.util.logging.FileHandler.formatter", "java.util.logging.SimpleFormatter"); properties.setProperty("java.util.logging.FileHandler.encoding", "UTF-8"); this.logfile = createLogfilePath(idePath, cmd); @@ -1202,7 +1205,6 @@ private Properties createJavaUtilLoggingProperties(boolean writeLogfile, Command } else { properties.setProperty("handlers", "com.devonfw.tools.ide.log.JulConsoleHandler"); } - properties.setProperty("com.devonfw.tools.ide.log.JulConsoleHandler.level", intLevel); properties.setProperty("java.util.logging.SimpleFormatter.format", "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL [%4$s] [%3$s] %5$s%6$s%n"); return properties; } @@ -1259,7 +1261,7 @@ private ValidationResult applyAndRun(CliArguments arguments, Commandlet cmd) { if (cmd.isProcessableOutput()) { if (!LOG.isDebugEnabled()) { // unless --debug or --trace was supplied, processable output commandlets will disable all log-levels except INFO to prevent other logs interfere - previousLogLevel = this.startContext.setLogLevel(IdeLogLevel.PROCESSABLE); + previousLogLevel = this.startContext.setLogLevelConsole(IdeLogLevel.PROCESSABLE); } } else { if (cmd.isIdeHomeRequired()) { @@ -1286,9 +1288,8 @@ settingsRepository, getSettingsCommitIdPath()))) { } cmd.run(); } finally { - this.julConfigured = false; if (previousLogLevel != null) { - this.startContext.setLogLevel(previousLogLevel); + this.startContext.setLogLevelConsole(previousLogLevel); } } } else { @@ -1313,11 +1314,11 @@ private boolean ensureLicenseAgreement(Commandlet cmd) { // printing anything anymore in such case. return false; } - IdeLogLevel oldLogLevel = this.startContext.getLogLevel(); + IdeLogLevel oldLogLevel = this.startContext.getLogLevelConsole(); IdeLogLevel newLogLevel = oldLogLevel; if (oldLogLevel.ordinal() > IdeLogLevel.INFO.ordinal()) { newLogLevel = IdeLogLevel.INFO; - this.startContext.setLogLevel(newLogLevel); + this.startContext.setLogLevelConsole(newLogLevel); } StringBuilder sb = new StringBuilder(1180); sb.append(LOGO).append(""" @@ -1348,7 +1349,7 @@ This product (with its included 3rd party components) is open-source software an throw new RuntimeException("Failed to save license agreement!", e); } if (oldLogLevel != newLogLevel) { - this.startContext.setLogLevel(oldLogLevel); + this.startContext.setLogLevelConsole(oldLogLevel); } return true; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContext.java index 5d6d13f57b..b290133b1f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContext.java @@ -20,9 +20,15 @@ public interface IdeStartContext extends ReadOfflineMode { IdeLogListener getLogListener(); /** - * @return the minimum allowed {@link IdeLogLevel} (threshold). + * @return the minimum allowed {@link IdeLogLevel} (threshold) for console output (see --debug and --trace options). */ - IdeLogLevel getLogLevel(); + IdeLogLevel getLogLevelConsole(); + + /** + * @return the minimum allowed {@link IdeLogLevel} (threshold) for SLF4J and JUL logger (can be lower than {@link #getLogLevelConsole()} for finer details in + * logfile). + */ + IdeLogLevel getLogLevelLogger(); /** * @return {@code true} in case of quiet mode (reduced output), {@code false} otherwise. diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java index 048b040856..18d7d996de 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/IdeStartContextImpl.java @@ -16,7 +16,11 @@ public class IdeStartContextImpl implements IdeStartContext { protected final IdeLogListener logListener; - private IdeLogLevel logLevel; + protected final IdeLogListenerBuffer logListenerBuffer; + + private IdeLogLevel logLevelConsole; + + private IdeLogLevel logLevelLogger; private IdeLogArgFormatter argFormatter; @@ -45,16 +49,21 @@ public class IdeStartContextImpl implements IdeStartContext { private Locale locale; /** - * @param logLevel the minimum enabled {@link #getLogLevel() log level}. + * @param logLevelConsole the minimum enabled {@link #getLogLevelConsole() log level}. * @param logListener the {@link #getLogListener() logListener}. */ - public IdeStartContextImpl(IdeLogLevel logLevel, IdeLogListener logListener) { + public IdeStartContextImpl(IdeLogLevel logLevelConsole, IdeLogListener logListener) { super(); - this.logLevel = logLevel; + this.logLevelConsole = logLevelConsole; this.logListener = logListener; this.argFormatter = IdeLogArgFormatter.DEFAULT; IdeStartContextImpl.instance = this; + if (logListener instanceof IdeLogListenerBuffer buffer) { + this.logListenerBuffer = buffer; + } else { + this.logListenerBuffer = null; + } } @Override @@ -64,27 +73,45 @@ public IdeLogListener getLogListener() { } @Override - public IdeLogLevel getLogLevel() { + public IdeLogLevel getLogLevelConsole() { - return this.logLevel; + return this.logLevelConsole; } /** - * Sets the log level. - * - * @param logLevel {@link IdeLogLevel} + * @param logLevelConsole the new {@link IdeLogLevel} for the console. * @return the previous set logLevel {@link IdeLogLevel} */ - public IdeLogLevel setLogLevel(IdeLogLevel logLevel) { + public IdeLogLevel setLogLevelConsole(IdeLogLevel logLevelConsole) { - IdeLogLevel previousLogLevel = this.logLevel; + IdeLogLevel previousLogLevel = this.logLevelConsole; if ((previousLogLevel == null) || (previousLogLevel.ordinal() > IdeLogLevel.INFO.ordinal())) { previousLogLevel = IdeLogLevel.INFO; } - this.logLevel = logLevel; + this.logLevelConsole = logLevelConsole; return previousLogLevel; } + @Override + public IdeLogLevel getLogLevelLogger() { + + if (this.logLevelLogger == null) { + if ((this.logListenerBuffer != null) && (this.logListenerBuffer.isBuffering())) { + return IdeLogLevel.TRACE; + } + return this.logLevelConsole; + } + return this.logLevelLogger; + } + + /** + * @param logLevelLogger the new {@link #getLogLevelLogger() loglevel for the logger}. + */ + public void setLogLevelLogger(IdeLogLevel logLevelLogger) { + + this.logLevelLogger = logLevelLogger; + } + /** * @return the {@link IdeLogArgFormatter}. */ diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java index c76fb656f0..84a873eb9a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java @@ -189,7 +189,7 @@ static IdeLogLevel getLogLevel() { IdeLogLevel threshold = IdeLogLevel.TRACE; IdeStartContextImpl startContext = IdeStartContextImpl.get(); if (startContext != null) { - threshold = startContext.getLogLevel(); + threshold = startContext.getLogLevelLogger(); } return threshold; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java index 96cc0c2ab9..99ed845343 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeLogListenerBuffer.java @@ -49,7 +49,7 @@ public boolean onLog(IdeLogLevel level, String message, String rawMessage, Objec /** * @return {@code true} if this collector is currently buffering all logs, {@code false} otherwise (regular logging). */ - protected boolean isBuffering() { + public boolean isBuffering() { return this.buffering; } @@ -58,6 +58,9 @@ protected boolean isBuffering() { */ public void flushAndEndBuffering() { + if (!this.buffering) { + return; // buffering already ended + } // disable buffering further log events this.buffering = false; // write all cached log events to the logger again for processing diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java b/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java index 11bdb46d38..ff5817e5d5 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/JulConsoleHandler.java @@ -5,6 +5,8 @@ import java.util.logging.Level; import java.util.logging.LogRecord; +import com.devonfw.tools.ide.context.IdeStartContextImpl; + /** * Custom {@link Handler} for java.util.logging to log to console. */ @@ -14,6 +16,14 @@ public class JulConsoleHandler extends Handler { public void publish(LogRecord record) { Level julLevel = record.getLevel(); IdeLogLevel ideLevel = IdeLogLevel.of(julLevel); + IdeStartContextImpl startContext = IdeStartContextImpl.get(); + boolean colored = false; + if (startContext != null) { + colored = !startContext.isNoColorsMode(); + if (ideLevel.ordinal() < startContext.getLogLevelConsole().ordinal()) { + return; // console logging disabled for ideLevel + } + } PrintStream out = System.out; if (ideLevel == IdeLogLevel.ERROR) { out = System.err; @@ -21,7 +31,7 @@ public void publish(LogRecord record) { String message = record.getMessage(); Throwable error = record.getThrown(); String startColor = null; - if (Slf4jLoggerAdapter.isColored()) { + if (colored) { startColor = ideLevel.getStartColor(); if (startColor != null) { out.append(startColor); diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/JulLogLevel.java b/cli/src/main/java/com/devonfw/tools/ide/log/JulLogLevel.java index 85f9585d0a..31e02bc4f6 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/JulLogLevel.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/JulLogLevel.java @@ -8,28 +8,28 @@ public class JulLogLevel extends Level { /** @see IdeLogLevel#TRACE */ - public static final Level TRACE = new JulLogLevel("TRACE", 401); + public static final Level TRACE = new JulLogLevel("TRACE", 1010); /** @see IdeLogLevel#DEBUG */ - public static final Level DEBUG = new JulLogLevel("DEBUG", 501); + public static final Level DEBUG = new JulLogLevel("DEBUG", 1020); /** @see IdeLogLevel#INFO */ - public static final Level INFO = Level.INFO; + public static final Level INFO = new JulLogLevel("INFO", 1030); /** @see IdeLogLevel#STEP */ - public static final Level STEP = new JulLogLevel("STEP", 801); + public static final Level STEP = new JulLogLevel("STEP", 1040); /** @see IdeLogLevel#INTERACTION */ - public static final Level INTERACTION = new JulLogLevel("INTERACTION", 802); + public static final Level INTERACTION = new JulLogLevel("INTERACTION", 1050); /** @see IdeLogLevel#SUCCESS */ - public static final Level SUCCESS = new JulLogLevel("SUCCESS", 803); + public static final Level SUCCESS = new JulLogLevel("SUCCESS", 1060); /** @see IdeLogLevel#WARNING */ - public static final Level WARNING = Level.WARNING; + public static final Level WARNING = new JulLogLevel("WARNING", 1070); /** @see IdeLogLevel#WARNING */ - public static final Level ERROR = new JulLogLevel("ERROR", 1001); + public static final Level ERROR = new JulLogLevel("ERROR", 1080); /** @see IdeLogLevel#PROCESSABLE */ public static final Level PROCESSABLE = new JulLogLevel("PROCESSABLE", 2000); diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java index bf4a9a0838..2eae4806f2 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java @@ -149,12 +149,22 @@ public void log(LoggingEvent event) { assert markers.size() == 1; marker = markers.getFirst(); } - handleNormalizedLoggingCall(event.getLevel(), marker, event.getMessage(), event.getArgumentArray(), event.getThrowable()); + Level level = event.getLevel(); + IdeLogLevel ideLogLevel = IdeLogLevel.of(level, marker); + if (ideLogLevel.isEnabled()) { + handleNormalizedLoggingCall(level, marker, event.getMessage(), event.getArgumentArray(), event.getThrowable()); + } } private boolean isLevelEnabled(Level level, Marker marker) { IdeLogLevel ideLevel = IdeLogLevel.of(level, marker); - return ideLevel.isEnabled(); + if (!ideLevel.isEnabled()) { + return false; + } + if (!this.internal) { + return level.toInt() >= Level.INFO.toInt(); // 3rd party is limited to INFO logging to avoid potential log spam + } + return true; } @Override diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java b/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java index 3a9eb2ad4c..cf26227fa4 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java @@ -167,7 +167,6 @@ private void doCreateSettingsFile(Path settingsFile, Path settingsTemplateFile, private String getEncryptedPassword(String variable) { String input = this.context.askForInput("Please enter secret value for variable " + variable + ":"); - String encryptedPassword = retrievePassword("--encrypt-password", input); LOG.info("Encrypted as {}", encryptedPassword); From 5be0485149e6c4a365896f1d4bce31da72fafae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Mon, 23 Feb 2026 18:30:46 +0100 Subject: [PATCH 49/51] #1713: default to debug logging during tests, remove context mock --- .../tools/ide/context/AbstractIdeContext.java | 4 +- .../tools/ide/log/Slf4jLoggerAdapter.java | 2 +- .../ide/commandlet/HelpCommandletTest.java | 5 +-- ...mpletionCandidateCollectorDefaultTest.java | 8 ++-- .../ide/context/AbstractIdeContextTest.java | 5 +-- .../tools/ide/context/IdeTestContext.java | 2 +- .../tools/ide/context/IdeTestContextMock.java | 38 ---------------- ...nvironmentVariablesPropertiesFileTest.java | 5 +-- .../tools/ide/io/FileAccessImplTest.java | 45 +++++++++---------- .../devonfw/tools/ide/io/IniFileImplTest.java | 14 +++--- .../tools/ide/log/IdeTestStartContext.java | 13 ++++-- .../tools/ide/merge/xml/XmlMergerTest.java | 3 +- .../tools/ide/os/WindowsHelperImplTest.java | 6 +-- .../ide/property/BooleanPropertyTest.java | 4 +- .../ide/property/CommandletPropertyTest.java | 6 +-- .../tools/ide/property/EnumPropertyTest.java | 6 +-- .../ide/property/LocalePropertyTest.java | 6 +-- .../ide/property/NumberPropertyTest.java | 4 +- .../tools/ide/property/ToolPropertyTest.java | 6 +-- .../ide/property/VersionPropertyTest.java | 8 ++-- .../com/devonfw/tools/ide/step/StepTest.java | 11 ++--- .../tool/ide/IdeToolDummyCommandletTest.java | 4 +- .../tools/ide/tool/mvn/MvnRepositoryTest.java | 5 +-- .../tools/ide/variable/IdeVariablesTest.java | 9 ++-- 24 files changed, 91 insertions(+), 128 deletions(-) delete mode 100644 cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextMock.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index fbf2b3a877..171c8b288b 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -179,11 +179,13 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt public AbstractIdeContext(IdeStartContextImpl startContext, Path workingDirectory) { super(); - this.startContext = startContext; this.startContext.setArgFormatter(this); this.privacyMap = new HashMap<>(); this.systemInfo = SystemInfoImpl.INSTANCE; + if (isTest()) { + configureJavaUtilLogging(null); + } this.commandletManager = new CommandletManagerImpl(this); this.fileAccess = new FileAccessImpl(this); String userHomeProperty = getSystem().getProperty("user.home"); diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java index 2eae4806f2..47713db162 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/Slf4jLoggerAdapter.java @@ -162,7 +162,7 @@ private boolean isLevelEnabled(Level level, Marker marker) { return false; } if (!this.internal) { - return level.toInt() >= Level.INFO.toInt(); // 3rd party is limited to INFO logging to avoid potential log spam + return level.toInt() >= Level.WARN.toInt(); // 3rd party is limited to INFO logging to avoid potential log spam } return true; } diff --git a/cli/src/test/java/com/devonfw/tools/ide/commandlet/HelpCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/commandlet/HelpCommandletTest.java index 1057801485..e059ae73e3 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/commandlet/HelpCommandletTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/commandlet/HelpCommandletTest.java @@ -15,7 +15,6 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.context.IdeTestContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; import com.devonfw.tools.ide.nls.NlsBundle; import com.devonfw.tools.ide.property.KeywordProperty; import com.devonfw.tools.ide.property.Property; @@ -32,7 +31,7 @@ class HelpCommandletTest extends AbstractIdeContextTest { void testThatHomeIsNotRequired() { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); // act HelpCommandlet help = new HelpCommandlet(context); // assert @@ -110,7 +109,7 @@ void testRunWithCommandlet() { void testEnsureAllNlsPropertiesPresent(String locale) throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); NlsBundle bundleRoot = new NlsBundle(context, Locale.ROOT); NlsBundle bundle = new NlsBundle(context, Locale.forLanguageTag(locale)); SoftAssertions soft = new SoftAssertions(); diff --git a/cli/src/test/java/com/devonfw/tools/ide/completion/CompletionCandidateCollectorDefaultTest.java b/cli/src/test/java/com/devonfw/tools/ide/completion/CompletionCandidateCollectorDefaultTest.java index 3d295a41ff..b6e034de83 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/completion/CompletionCandidateCollectorDefaultTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/completion/CompletionCandidateCollectorDefaultTest.java @@ -6,7 +6,7 @@ import com.devonfw.tools.ide.commandlet.VersionCommandlet; import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; import com.devonfw.tools.ide.property.Property; import com.devonfw.tools.ide.property.VersionProperty; @@ -27,7 +27,7 @@ void testAddAllMatches() { String[] expectedCandidates = { "2.0", "2.1", "20", "200" }; VersionProperty versionProperty = new VersionProperty("", false, "version"); - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); CompletionCandidateCollector collector = new CompletionCandidateCollectorDefault(context); // act @@ -46,7 +46,7 @@ void testAddAllMatchesEmptyInput() { String input = ""; VersionProperty versionProperty = new VersionProperty("", false, "version"); - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); CompletionCandidateCollector collector = new CompletionCandidateCollectorDefault(context); // act @@ -66,7 +66,7 @@ void testClearCandidates() { String[] expectedCandidates = sortedCandidates; VersionProperty versionProperty = new VersionProperty("", false, "version"); - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); CompletionCandidateCollector collector = new CompletionCandidateCollectorDefault(context); // act diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java index 294a587b18..ad5d37022a 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java @@ -14,7 +14,6 @@ import org.assertj.core.api.Assertions; import com.devonfw.tools.ide.io.FileAccess; -import com.devonfw.tools.ide.io.FileAccessImpl; import com.devonfw.tools.ide.io.FileCopyMode; import com.devonfw.tools.ide.io.IdeProgressBarTestImpl; import com.devonfw.tools.ide.io.IdeProgressBarTestImpl.ProgressEvent; @@ -100,7 +99,7 @@ protected static IdeTestContext newContext(String testProject, String projectPat */ protected static IdeTestContext newContext(String testProject, String projectPath, boolean copyForMutation, WireMockRuntimeInfo wmRuntimeInfo) { - return newContext(testProject, projectPath, copyForMutation, wmRuntimeInfo, IdeLogLevel.TRACE); + return newContext(testProject, projectPath, copyForMutation, wmRuntimeInfo, IdeLogLevel.DEBUG); } /** @@ -119,7 +118,7 @@ protected static IdeTestContext newContext(String testProject, String projectPat Path ideRoot = TEST_PROJECTS.resolve(testProject); if (copyForMutation) { Path ideRootCopy = TEST_PROJECTS_COPY.resolve(testProject); - FileAccess fileAccess = new FileAccessImpl(IdeTestContextMock.get()); + FileAccess fileAccess = new IdeTestContext().getFileAccess(); fileAccess.delete(ideRootCopy); fileAccess.mkdirs(TEST_PROJECTS_COPY); fileAccess.copy(ideRoot, TEST_PROJECTS_COPY, FileCopyMode.COPY_TREE_OVERRIDE_TREE); diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java index 2aac04fd20..88b1934e1a 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java @@ -38,7 +38,7 @@ public IdeTestContext() { */ public IdeTestContext(Path workingDirectory, WireMockRuntimeInfo wireMockRuntimeInfo) { - this(workingDirectory, IdeLogLevel.TRACE, wireMockRuntimeInfo); + this(workingDirectory, IdeLogLevel.DEBUG, wireMockRuntimeInfo); } /** diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextMock.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextMock.java deleted file mode 100644 index 89a0f5e313..0000000000 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContextMock.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.devonfw.tools.ide.context; - -import java.nio.file.Path; - -import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeLogListenerNone; - -/** - * Mock instance of {@link com.devonfw.tools.ide.context.IdeContext}. - * - * @see #get() - */ -public class IdeTestContextMock extends AbstractIdeTestContext { - - private static final IdeTestContextMock INSTANCE = new IdeTestContextMock(); - - private static final Path PATH_MOCK = Path.of("/"); - - private IdeTestContextMock() { - - super(new IdeStartContextImpl(IdeLogLevel.TRACE, IdeLogListenerNone.INSTANCE), PATH_MOCK, null); - } - - @Override - protected boolean isMutable() { - - return false; - } - - /** - * @return the singleton mock instance of {@link com.devonfw.tools.ide.context.IdeContext}. Does NOT have {@link #getIdeHome() IDE_HOME}. - */ - public static IdeTestContextMock get() { - - return INSTANCE; - } - -} 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 25e58a7240..0ee2013957 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 @@ -11,7 +11,6 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeTestContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; import com.devonfw.tools.ide.log.IdeLogLevel; import com.devonfw.tools.ide.version.VersionIdentifier; @@ -80,7 +79,7 @@ void testSave(@TempDir Path tempDir) throws Exception { assertThat(lines).containsExactlyElementsOf(linesToWrite); EnvironmentVariablesPropertiesFile variables = new EnvironmentVariablesPropertiesFile(null, TYPE, - propertiesFilePath, IdeTestContextMock.get()); + propertiesFilePath, new IdeTestContext()); // act variables.set("var5", "5", true); @@ -125,7 +124,7 @@ void testSaveWithMissingParentFilePath(@TempDir Path tempDir) throws Exception { Path propertiesFilePath = tempDir.resolve("test.properties"); EnvironmentVariablesPropertiesFile variables = new EnvironmentVariablesPropertiesFile(null, TYPE, - propertiesFilePath, IdeTestContextMock.get()); + propertiesFilePath, new IdeTestContext()); // act variables.set("var1", "1.0", false); diff --git a/cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java b/cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java index 270818aa1a..7cd4750ad8 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java @@ -25,9 +25,7 @@ import org.junit.jupiter.api.io.TempDir; import com.devonfw.tools.ide.context.AbstractIdeContextTest; -import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.context.IdeTestContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; /** * Test of {@link FileAccessImpl}. @@ -43,7 +41,7 @@ void testSymlinkAbsolute(@TempDir Path tempDir) { // relative links are checked in testRelativeLinksWorkAfterMoving // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = new FileAccessImpl(context); Path dir = tempDir.resolve("parent"); createDirs(fileAccess, dir); @@ -65,7 +63,7 @@ void testSymlinkAbsolute(@TempDir Path tempDir) { void testSymlinkAbsolutePassingRelativeSource(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = new FileAccessImpl(context); Path dir = tempDir.resolve("parent"); createDirs(fileAccess, dir); @@ -89,7 +87,7 @@ void testSymlinkAbsolutePassingRelativeSource(@TempDir Path tempDir) { void testSymlinkAbsoluteAsFallback(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = new FileAccessImpl(context); Path dir = tempDir.resolve("parent"); createDirs(fileAccess, dir); @@ -112,7 +110,7 @@ void testSymlinkAbsoluteAsFallback(@TempDir Path tempDir) { void testSymlinkAbsoluteBreakAfterMoving(@TempDir Path tempDir) throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = new FileAccessImpl(context); Path dir = tempDir.resolve("parent"); createDirs(fileAccess, dir); @@ -138,7 +136,7 @@ void testSymlinkAbsoluteBreakAfterMoving(@TempDir Path tempDir) throws IOExcepti void testSymlinkRelativeWorkAfterMovingPassingRelativeSource(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = new FileAccessImpl(context); Path dir = tempDir.resolve("parent"); createDirs(fileAccess, dir); @@ -163,7 +161,7 @@ void testSymlinkRelativeWorkAfterMovingPassingRelativeSource(@TempDir Path tempD void testSymlinkRelativeWorkAfterMoving(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = new FileAccessImpl(context); Path dir = tempDir.resolve("parent"); createDirs(fileAccess, dir); @@ -189,7 +187,7 @@ void testSymlinkWindowsJunctionsCanNotPointToFiles(@TempDir Path tempDir) throws // arrange WindowsSymlinkTestHelper.assumeSymlinksSupported(); - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = context.getFileAccess(); Path file = tempDir.resolve("file"); Files.createFile(file); @@ -210,7 +208,7 @@ void testSymlinkWindowsJunctionsCanNotPointToFiles(@TempDir Path tempDir) throws void testSymlinkShortcutPaths(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = new FileAccessImpl(context); Path dir = tempDir.resolve("parent"); createDirs(fileAccess, dir); @@ -447,7 +445,7 @@ private void assertSymlinkRead(Path link, Path trueTarget) { void testUnzip(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); // act context.getFileAccess() @@ -467,7 +465,7 @@ void testUnzip(@TempDir Path tempDir) { void testUntarWithNoneCompressionWithFilePermissions(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); if (context.getSystemInfo().isWindows()) { return; } @@ -489,7 +487,7 @@ void testUntarWithNoneCompressionWithFilePermissions(@TempDir Path tempDir) { void testUntarWithGzCompressionWithFilePermissions(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); if (context.getSystemInfo().isWindows()) { return; } @@ -512,7 +510,8 @@ void testUntarWithGzCompressionWithFilePermissions(@TempDir Path tempDir) { void testUntarWithBzip2CompressionWithFilePermissions(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); + new IdeTestContext(); if (context.getSystemInfo().isWindows()) { return; } @@ -543,7 +542,7 @@ void testUntarWithGzipCompressionWithSymbolicLink(@TempDir Path tempDir) { // arrange WindowsSymlinkTestHelper.assumeSymlinksSupported(); - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); Path linkTarGz = Path.of("src/test/resources/com/devonfw/tools/ide/io/link.tar.gz"); FileAccess fileAccess = context.getFileAccess(); @@ -577,7 +576,7 @@ void testGeneratePermissionString() { @Test void testDisabledExtractMovesArchive(@TempDir Path tempDir) { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccessImpl fileAccess = new FileAccessImpl(context); Path downloadArchive = tempDir.resolve("downloaded.zip"); fileAccess.touch(downloadArchive); @@ -600,7 +599,7 @@ void testDisabledExtractMovesArchive(@TempDir Path tempDir) { @Test void testExtractTgzArchive(@TempDir Path tempDir) throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccessImpl fileAccess = new FileAccessImpl(context); Path downloadedTgz = tempDir.resolve("downloaded.tgz"); fileAccess.touch(downloadedTgz); @@ -642,7 +641,7 @@ void testExtractTgzArchive(@TempDir Path tempDir) throws IOException { */ @Test void testFindExistingFileInFolders(@TempDir Path tempDir) { - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccessImpl fileAccess = new FileAccessImpl(context); Path subfolder1 = tempDir.resolve("subfolder1"); fileAccess.mkdirs(subfolder1); @@ -728,7 +727,7 @@ void testDownloadSmallFileWithoutProgressBar(@TempDir Path tempDir) throws IOExc void testSymlinkOverwritesBrokenJunction(@TempDir Path tempDir) throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = new FileAccessImpl(context); Path sourceDir = tempDir.resolve("source"); Path targetLink = tempDir.resolve("junction"); @@ -768,7 +767,7 @@ void testSymlinkOverwritesBrokenJunction(@TempDir Path tempDir) throws IOExcepti void testIsJunctionHandlesBrokenLinks(@TempDir Path tempDir) throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); FileAccess fileAccess = new FileAccessImpl(context); if (!context.getSystemInfo().isWindows()) { @@ -818,7 +817,7 @@ void testIsJunctionHandlesBrokenLinks(@TempDir Path tempDir) throws IOException void testBinPath() { // arrange - FileAccess fileAccess = IdeTestContextMock.get().getFileAccess(); + FileAccess fileAccess = new IdeTestContext().getFileAccess(); Path projects = Path.of("src/test/resources/ide-projects"); Path rootPath = projects.resolve("basic/project/software/java"); Path binPath = rootPath.resolve("bin"); @@ -847,7 +846,7 @@ void testFindAncestor() { private void verifyFindAncestor(String path, String baseDir, int subfolderCount, String expectedResult) { - FileAccess fileAccess = IdeTestContextMock.get().getFileAccess(); + FileAccess fileAccess = new IdeTestContext().getFileAccess(); Path result = fileAccess.findAncestor(asPath(path), asPath(baseDir), subfolderCount); AbstractPathAssert assertion = assertThat(result).as("findAncestor(" + path + ", " + baseDir + ", " + subfolderCount); if (expectedResult == null) { @@ -868,7 +867,7 @@ private static Path asPath(String path) { void testIsNonEmptyFile(@TempDir Path tempDir) throws IOException { // arrange - FileAccess fileAccess = IdeTestContextMock.get().getFileAccess(); + FileAccess fileAccess = new IdeTestContext().getFileAccess(); // act + assert assertThat(fileAccess.isNonEmptyFile(tempDir)).isFalse(); diff --git a/cli/src/test/java/com/devonfw/tools/ide/io/IniFileImplTest.java b/cli/src/test/java/com/devonfw/tools/ide/io/IniFileImplTest.java index 231b3c789f..628c14a0fe 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/io/IniFileImplTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/io/IniFileImplTest.java @@ -10,7 +10,7 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; import com.devonfw.tools.ide.io.ini.IniFile; import com.devonfw.tools.ide.io.ini.IniFileImpl; import com.devonfw.tools.ide.io.ini.IniSection; @@ -64,7 +64,7 @@ private IniFile getIniFile(IdeContext context, String content) throws IOExceptio @Test void testGetSectionNames() throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); IniFile iniFileA = getIniFile(context, iniContentWithInitialProperties); IniFile iniFIleB = getIniFile(context, iniContent); @@ -88,7 +88,7 @@ void testGetSectionNames() throws IOException { @Test void testRemoveSection() throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); IniFile iniFileA = getIniFile(context, iniContentWithInitialProperties); IniFile iniFileB = getIniFile(context, iniContent); String[] expectedSections = { "filter \"lfs\"", "credential", "credential.details", "core" }; @@ -113,7 +113,7 @@ void testRemoveSection() throws IOException { @Test void testGetSection() throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); IniFile iniFileA = getIniFile(context, iniContentWithInitialProperties); IniFile iniFileB = getIniFile(context, iniContent); String sectionName = "credential"; @@ -143,7 +143,7 @@ void testGetSection() throws IOException { @Test void testGetOrCreateSection() throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); IniFile iniFileA = getIniFile(context, iniContentWithInitialProperties); IniFile iniFileB = getIniFile(context, iniContent); String sectionName = "credential"; @@ -186,7 +186,7 @@ void testGetOrCreateSection() throws IOException { @Test void testToString() throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); IniFile iniFileA = getIniFile(context, iniContentWithInitialProperties); IniFile iniFileB = getIniFile(context, iniContent); @@ -207,7 +207,7 @@ void testToString() throws IOException { @Test void testAddProperty() throws IOException { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); IniFile iniFileB = getIniFile(context, iniContent); String expectedContent = "variable = value\n" + iniContent; diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestStartContext.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestStartContext.java index bb419bd82f..4b174eb778 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestStartContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestStartContext.java @@ -11,14 +11,19 @@ public class IdeTestStartContext extends IdeStartContextImpl { private final IdeLogListenerCollector collector; - public IdeTestStartContext(IdeLogLevel logLevel) { + /** + * The constructor. + * + * @param logLevelConsole the {@link IdeLogLevel} acting as threshold for the console. + */ + public IdeTestStartContext(IdeLogLevel logLevelConsole) { - this(logLevel, new IdeLogListenerCollector()); + this(logLevelConsole, new IdeLogListenerCollector()); } - private IdeTestStartContext(IdeLogLevel minLogLevel, IdeLogListenerCollector logListener) { + private IdeTestStartContext(IdeLogLevel logLevelConsole, IdeLogListenerCollector logListener) { - super(minLogLevel, logListener); + super(logLevelConsole, logListener); this.collector = logListener; } diff --git a/cli/src/test/java/com/devonfw/tools/ide/merge/xml/XmlMergerTest.java b/cli/src/test/java/com/devonfw/tools/ide/merge/xml/XmlMergerTest.java index c0f1d52a51..e3be322fb1 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/merge/xml/XmlMergerTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/merge/xml/XmlMergerTest.java @@ -17,7 +17,6 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeTestContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; import com.devonfw.tools.ide.environment.EnvironmentVariables; import com.devonfw.tools.ide.environment.EnvironmentVariablesPropertiesMock; import com.devonfw.tools.ide.environment.EnvironmentVariablesType; @@ -51,7 +50,7 @@ void testMerger(Path folder, @TempDir Path tempDir) throws Exception { Path targetPath = tempDir.resolve(TARGET_XML); Path resultPath = folder.resolve(RESULT_XML); Files.copy(folder.resolve(TARGET_XML), targetPath, REPLACE_EXISTING); - IdeTestContextMock context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); EnvironmentVariablesPropertiesMock mockVariables = new EnvironmentVariablesPropertiesMock(null, EnvironmentVariablesType.SETTINGS, context); mockVariables.set("JAVA_HOME", "/projects/myproject", false); mockVariables.set("JAVA_VERSION", "21", false); diff --git a/cli/src/test/java/com/devonfw/tools/ide/os/WindowsHelperImplTest.java b/cli/src/test/java/com/devonfw/tools/ide/os/WindowsHelperImplTest.java index 423374d4b6..85935fb72a 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/os/WindowsHelperImplTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/os/WindowsHelperImplTest.java @@ -7,7 +7,7 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.AbstractIdeTestContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; /** * Tests for {@link WindowsHelperImpl}. @@ -20,7 +20,7 @@ class WindowsHelperImplTest extends AbstractIdeContextTest { @Test void testWindowsHelperParseRegString() { // arrange - AbstractIdeTestContext context = IdeTestContextMock.get(); + AbstractIdeTestContext context = new IdeTestContext(); WindowsHelperImpl helper = new WindowsHelperImpl(context); List output = new ArrayList<>(); output.add(""); @@ -39,7 +39,7 @@ void testWindowsHelperParseRegString() { @Test void testWindowsHelperParseEmptyRegStringReturnsNull() { // arrange - AbstractIdeTestContext context = IdeTestContextMock.get(); + AbstractIdeTestContext context = new IdeTestContext(); WindowsHelperImpl helper = new WindowsHelperImpl(context); List output = new ArrayList<>(); // act diff --git a/cli/src/test/java/com/devonfw/tools/ide/property/BooleanPropertyTest.java b/cli/src/test/java/com/devonfw/tools/ide/property/BooleanPropertyTest.java index 9935bb4706..432f921e8c 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/property/BooleanPropertyTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/property/BooleanPropertyTest.java @@ -6,7 +6,7 @@ import org.junit.jupiter.api.Test; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; /** * Test of {@link BooleanProperty}. @@ -15,7 +15,7 @@ class BooleanPropertyTest { @Test void testParse() { - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); BooleanProperty boolProp = new BooleanProperty("name", false, "alias"); assertThat(boolProp.parse("true", context)).isTrue(); diff --git a/cli/src/test/java/com/devonfw/tools/ide/property/CommandletPropertyTest.java b/cli/src/test/java/com/devonfw/tools/ide/property/CommandletPropertyTest.java index 9015efb1b2..ca3c841723 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/property/CommandletPropertyTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/property/CommandletPropertyTest.java @@ -10,7 +10,7 @@ import com.devonfw.tools.ide.completion.CompletionCandidateCollector; import com.devonfw.tools.ide.completion.CompletionCandidateCollectorDefault; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; import com.devonfw.tools.ide.tool.helm.Helm; import com.devonfw.tools.ide.tool.intellij.Intellij; @@ -23,7 +23,7 @@ class CommandletPropertyTest { void testCompleteValue() { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); String[] expectedCandidates = { "help", "helm" }; String input = "he"; CompletionCandidateCollector collector = new CompletionCandidateCollectorDefault(context); @@ -40,7 +40,7 @@ void testCompleteValue() { void testParse() { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); // act CommandletProperty cmdProp = new CommandletProperty("", false, ""); diff --git a/cli/src/test/java/com/devonfw/tools/ide/property/EnumPropertyTest.java b/cli/src/test/java/com/devonfw/tools/ide/property/EnumPropertyTest.java index 6f942a357c..769ff113bb 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/property/EnumPropertyTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/property/EnumPropertyTest.java @@ -10,7 +10,7 @@ import com.devonfw.tools.ide.completion.CompletionCandidateCollector; import com.devonfw.tools.ide.completion.CompletionCandidateCollectorDefault; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; /** * Test of {@link EnumProperty}. @@ -32,7 +32,7 @@ void testGetValueType() { @Test void testParse() { - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); EnumProperty enumProp = new EnumProperty<>("", false, "", TestEnum.class); assertThat(enumProp.parse("elementzero", context)).isEqualTo(TestEnum.ELEMENTZERO); @@ -42,7 +42,7 @@ void testParse() { @Test void testCompleteValue() { - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); String[] expectedCandidates = { "elementzero", "elementone", "elementtwo" }; String input = "ele"; CompletionCandidateCollector collector = new CompletionCandidateCollectorDefault(context); diff --git a/cli/src/test/java/com/devonfw/tools/ide/property/LocalePropertyTest.java b/cli/src/test/java/com/devonfw/tools/ide/property/LocalePropertyTest.java index 34588c0f85..8ccdac5f90 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/property/LocalePropertyTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/property/LocalePropertyTest.java @@ -10,7 +10,7 @@ import com.devonfw.tools.ide.completion.CompletionCandidateCollector; import com.devonfw.tools.ide.completion.CompletionCandidateCollectorDefault; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; /** * Test of {@link LocaleProperty}. @@ -22,7 +22,7 @@ class LocalePropertyTest extends Assertions { void testGermany() { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); Locale germany = Locale.GERMANY; // act LocaleProperty property = new LocaleProperty("--locale", true, null); @@ -39,7 +39,7 @@ void testGermany() { void testCompletion() { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); String[] expectedCandidates = { "de", "de-AT", "de-BE", "de-CH", "de-DE", "de-IT", "de-LI", "de-LU", "de-Latn-DE" }; String input = "de"; CompletionCandidateCollector collector = new CompletionCandidateCollectorDefault(context); diff --git a/cli/src/test/java/com/devonfw/tools/ide/property/NumberPropertyTest.java b/cli/src/test/java/com/devonfw/tools/ide/property/NumberPropertyTest.java index b8719743ca..6210b80580 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/property/NumberPropertyTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/property/NumberPropertyTest.java @@ -6,7 +6,7 @@ import org.junit.jupiter.api.Test; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; /** * Test of {@link NumberProperty}. @@ -16,7 +16,7 @@ class NumberPropertyTest { @Test void testParse() { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); // act NumberProperty numberProp = new NumberProperty("", false, ""); diff --git a/cli/src/test/java/com/devonfw/tools/ide/property/ToolPropertyTest.java b/cli/src/test/java/com/devonfw/tools/ide/property/ToolPropertyTest.java index 16a4f17240..11d028c48c 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/property/ToolPropertyTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/property/ToolPropertyTest.java @@ -10,7 +10,7 @@ import com.devonfw.tools.ide.completion.CompletionCandidateCollector; import com.devonfw.tools.ide.completion.CompletionCandidateCollectorDefault; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; import com.devonfw.tools.ide.tool.intellij.Intellij; import com.devonfw.tools.ide.tool.java.Java; @@ -21,7 +21,7 @@ class ToolPropertyTest { @Test void testCompleteValue() { - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); String[] expectedCandidates = { "az", "android-studio", "aws" }; String input = "a"; CompletionCandidateCollector collector = new CompletionCandidateCollectorDefault(context); @@ -34,7 +34,7 @@ void testCompleteValue() { @Test void testParse() { - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); ToolProperty toolProp = new ToolProperty("", false, ""); assertThat(toolProp.parse("intellij", context)).isInstanceOf(Intellij.class); diff --git a/cli/src/test/java/com/devonfw/tools/ide/property/VersionPropertyTest.java b/cli/src/test/java/com/devonfw/tools/ide/property/VersionPropertyTest.java index d17d5edab5..1105b1f441 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/property/VersionPropertyTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/property/VersionPropertyTest.java @@ -11,7 +11,7 @@ import com.devonfw.tools.ide.completion.CompletionCandidateCollector; import com.devonfw.tools.ide.completion.CompletionCandidateCollectorDefault; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; import com.devonfw.tools.ide.version.VersionIdentifier; /** @@ -21,7 +21,7 @@ class VersionPropertyTest { @Test void testParse() { - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); VersionProperty versionProp = new VersionProperty("", false, ""); assertThat(versionProp.parse("1", context)).isEqualTo(VersionIdentifier.of("1")); @@ -34,7 +34,7 @@ void testParse() { */ @Test void testCompleteValueUnfitCommandlet() { - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); CompletionCandidateCollector collector = new CompletionCandidateCollectorDefault(context); VersionProperty versionProp = new VersionProperty("", false, ""); @@ -49,7 +49,7 @@ void testCompleteValueUnfitCommandlet() { */ @Test void testCompleteValuePatternGiven() { - IdeContext context = IdeTestContextMock.get(); + IdeContext context = new IdeTestContext(); String anyVersion = "*"; String anyVersionAfter2 = "2.*"; CompletionCandidateCollector collector = new CompletionCandidateCollectorDefault(context); 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 d8c76e8cc4..0a5b87d12c 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 @@ -5,6 +5,7 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeTestContext; import com.devonfw.tools.ide.log.IdeLogEntry; +import com.devonfw.tools.ide.log.IdeLogLevel; /** * Test of {@link Step}. @@ -15,7 +16,7 @@ class StepTest extends AbstractIdeContextTest { void testValidUsageSuccess() { // arrage - IdeTestContext context = newContext(PROJECT_BASIC, "project", false); + IdeTestContext context = newContext(PROJECT_BASIC, "project", false, null, IdeLogLevel.TRACE); // act Step step = context.newStep("Test-Step"); try { @@ -36,7 +37,7 @@ void testValidUsageSuccess() { void testValidUsageSuccessSilent() { // arrage - IdeTestContext context = newContext(PROJECT_BASIC, "project", false); + IdeTestContext context = newContext(PROJECT_BASIC, "project", false, null, IdeLogLevel.TRACE); // act Step step = context.newStep(true, "Test-Step", "arg1", "arg2"); try { @@ -61,7 +62,7 @@ void testValidUsageSuccessSilent() { void testValidUsageError() { // arrage - IdeTestContext context = newContext(PROJECT_BASIC, "project", false); + IdeTestContext context = newContext(PROJECT_BASIC, "project", false, null, IdeLogLevel.TRACE); // act Step step = context.newStep("Test-Step"); try { @@ -82,7 +83,7 @@ void testValidUsageError() { void testInvalidUsageSuccessError() { // arrage - IdeTestContext context = newContext(PROJECT_BASIC, "project", false); + IdeTestContext context = newContext(PROJECT_BASIC, "project", false, null, IdeLogLevel.TRACE); // act Step step = context.newStep("Test-Step"); try { @@ -107,7 +108,7 @@ void testInvalidUsageSuccessError() { void testInvalidUsageErrorSuccess() { // arrage - IdeTestContext context = newContext(PROJECT_BASIC, "project", false); + IdeTestContext context = newContext(PROJECT_BASIC, "project", false, null, IdeLogLevel.TRACE); // act Step step = context.newStep("Test-Step"); try { diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/ide/IdeToolDummyCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/ide/IdeToolDummyCommandletTest.java index d9dc40b157..9478f37ffd 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/ide/IdeToolDummyCommandletTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/ide/IdeToolDummyCommandletTest.java @@ -13,7 +13,7 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.AbstractIdeTestContext; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; import com.devonfw.tools.ide.process.ProcessContext; import com.devonfw.tools.ide.process.ProcessErrorHandling; import com.devonfw.tools.ide.process.ProcessMode; @@ -37,7 +37,7 @@ class IdeToolDummyCommandletTest extends AbstractIdeContextTest { @Test void testDummyCommandlet(@TempDir Path tempDir) { - AbstractIdeTestContext context = IdeTestContextMock.get(); + AbstractIdeTestContext context = new IdeTestContext(); context.setPluginsPath(tempDir); context.setIdeHome(tempDir); context.setSettingsPath(Path.of("src/test/resources/settings/dummy")); diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/mvn/MvnRepositoryTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/mvn/MvnRepositoryTest.java index 4b980e39ce..142617013e 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/mvn/MvnRepositoryTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/mvn/MvnRepositoryTest.java @@ -13,7 +13,6 @@ import com.devonfw.tools.ide.context.AbstractIdeContextTest; import com.devonfw.tools.ide.context.IdeTestContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; import com.devonfw.tools.ide.os.OperatingSystem; import com.devonfw.tools.ide.os.SystemArchitecture; import com.devonfw.tools.ide.tool.ToolCommandlet; @@ -221,7 +220,7 @@ void testGetMetadataWithSnapshot() { void testResolveSnapshotVersion() { // arrange - IdeTestContextMock context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); MvnRepository mvnRepository = context.getMvnRepository(); Document metadata = parseXml(XML_SNAPSNOT_METADATA); @@ -237,7 +236,7 @@ void testResolveSnapshotVersion() { void testResolveVersion() { // arrange - IdeTestContextMock context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); MvnRepository mvnRepository = context.getMvnRepository(); Document metadata = parseXml(XML_RELEASE_METADATA); diff --git a/cli/src/test/java/com/devonfw/tools/ide/variable/IdeVariablesTest.java b/cli/src/test/java/com/devonfw/tools/ide/variable/IdeVariablesTest.java index 691553c0e8..b6617caa12 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/variable/IdeVariablesTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/variable/IdeVariablesTest.java @@ -6,8 +6,7 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; -import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.context.IdeTestContextMock; +import com.devonfw.tools.ide.context.IdeTestContext; /** * Test of {@link IdeVariables}. @@ -19,7 +18,7 @@ class IdeVariablesTest extends Assertions { void testIdeTools() { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); // act List ideTools = IdeVariables.IDE_TOOLS.get(context); // assert @@ -31,7 +30,7 @@ void testIdeTools() { void testHttpProtocols() { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); // act List httpVersionsEmpty = IdeVariables.HTTP_VERSIONS.get(context); List httpVersions2_11 = IdeVariables.HTTP_VERSIONS.fromString("HTTP_2, http_1_1", context); @@ -45,7 +44,7 @@ void testHttpProtocols() { void testIdeToolsWithCommasInBashArray() { // arrange - IdeContext context = IdeTestContextMock.get(); + IdeTestContext context = new IdeTestContext(); // act - using bash array syntax with commas (supported for convenience) List ideTools = IdeVariables.IDE_TOOLS.fromString("(java, maven, python, node)", context); // assert - should parse correctly with comma as separator From b4368b84d190e97bc791b391c5957d27d00b104a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Tue, 24 Feb 2026 10:48:39 +0100 Subject: [PATCH 50/51] #1713: fixed graalvm issue --- .../ide-cli/reflect-config.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cli/src/main/resources/META-INF/native-image/com.devonfw.tools.IDEasy/ide-cli/reflect-config.json b/cli/src/main/resources/META-INF/native-image/com.devonfw.tools.IDEasy/ide-cli/reflect-config.json index e9a098dbd0..5eb3b81a7d 100644 --- a/cli/src/main/resources/META-INF/native-image/com.devonfw.tools.IDEasy/ide-cli/reflect-config.json +++ b/cli/src/main/resources/META-INF/native-image/com.devonfw.tools.IDEasy/ide-cli/reflect-config.json @@ -44,5 +44,19 @@ "allPublicConstructors": true, "allDeclaredFields": true, "allDeclaredMethods": true + }, + { + "name": "com.devonfw.tools.ide.log.JulConsoleHandler", + "allDeclaredConstructors": false, + "allPublicConstructors": true, + "allDeclaredFields": false, + "allDeclaredMethods": false + }, + { + "name": "java.util.logging.FileHandler", + "allDeclaredConstructors": false, + "allPublicConstructors": true, + "allDeclaredFields": false, + "allDeclaredMethods": false } ] From 5655b6589f57c6e4b3c67e80f40fbd687c007788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Tue, 24 Feb 2026 10:48:58 +0100 Subject: [PATCH 51/51] #1713: updated doc to be in sync with code again --- documentation/variables.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/variables.adoc b/documentation/variables.adoc index 1f23ce9e13..fde4a03242 100644 --- a/documentation/variables.adoc +++ b/documentation/variables.adoc @@ -40,5 +40,5 @@ See also link:https://github.com/devonfw/IDEasy/blob/main/cli/src/main/java/com/ |`HTTP_VERSIONS`|e.g. `HTTP_2, HTTP_1_1`| The optional list of HTTP versions to try in the given order (e.g. "HTTP_2, HTTP_1_1"). This can be used as a workaround for network/VPN related issues - see issue https://github.com/devonfw/IDEasy/issues/1393[#1393]. |`JASYPT_OPTS`|`algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator`|Options of jasypt. |`IDE_XML_MERGE_LEGACY_SUPPORT_ENABLED`|e.g. `false`|Support of legacy xml templates without XML merge namespace. -|`IDE_WRITE_LOGFILE`|`true`|Automatically write logfiles to `$IDE_ROOT/_ide/logs/YYYY/MM/dd/ideasy-HH-mm-ss.log`. +|`IDE_WRITE_LOGFILE`|`true`|Automatically write logfiles to `$IDE_ROOT/_ide/logs/YYYY/MM/dd/«project»-ide-«command»-HH-mm-ss.log`. If you are not inside an IDEasy project or your command is not related to a project then `«project»` will be `_ide`. The logfile structure is designed in a way that allows you to quickly find and cleanup based on date but also based on details like the project and sub-command. |=======================