Skip to content

Commit b731286

Browse files
authored
#531: prevent logging for processable commandlets #511: consolidate test context (#541)
1 parent 78cf4b6 commit b731286

21 files changed

+348
-366
lines changed

cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
import java.util.List;
1313
import java.util.Locale;
1414
import java.util.Map;
15-
import java.util.Objects;
16-
import java.util.function.Function;
1715

1816
import com.devonfw.tools.ide.cli.CliAbortException;
1917
import com.devonfw.tools.ide.cli.CliArgument;
@@ -34,8 +32,9 @@
3432
import com.devonfw.tools.ide.io.FileAccess;
3533
import com.devonfw.tools.ide.io.FileAccessImpl;
3634
import com.devonfw.tools.ide.log.IdeLogLevel;
35+
import com.devonfw.tools.ide.log.IdeLogger;
36+
import com.devonfw.tools.ide.log.IdeLoggerImpl;
3737
import com.devonfw.tools.ide.log.IdeSubLogger;
38-
import com.devonfw.tools.ide.log.IdeSubLoggerNone;
3938
import com.devonfw.tools.ide.merge.DirectoryMerger;
4039
import com.devonfw.tools.ide.network.ProxyContext;
4140
import com.devonfw.tools.ide.os.SystemInfo;
@@ -60,7 +59,7 @@ public abstract class AbstractIdeContext implements IdeContext {
6059

6160
private static final String IDE_URLS_GIT = "https://github.com/devonfw/ide-urls.git";
6261

63-
private final Map<IdeLogLevel, IdeSubLogger> loggers;
62+
private final IdeLoggerImpl logger;
6463

6564
private Path ideHome;
6665

@@ -116,8 +115,6 @@ public abstract class AbstractIdeContext implements IdeContext {
116115

117116
private DirectoryMerger workspaceMerger;
118117

119-
private final Function<IdeLogLevel, IdeSubLogger> loggerFactory;
120-
121118
private boolean offlineMode;
122119

123120
private boolean forceMode;
@@ -137,18 +134,15 @@ public abstract class AbstractIdeContext implements IdeContext {
137134
/**
138135
* The constructor.
139136
*
140-
* @param minLogLevel the minimum {@link IdeLogLevel} to enable. Should be {@link IdeLogLevel#INFO} by default.
141-
* @param factory the {@link Function} to create {@link IdeSubLogger} per {@link IdeLogLevel}.
137+
* @param logger the {@link IdeLogger}.
142138
* @param userDir the optional {@link Path} to current working directory.
143139
* @param toolRepository @param toolRepository the {@link ToolRepository} of the context. If it is set to {@code null} {@link DefaultToolRepository} will
144140
* be used.
145141
*/
146-
public AbstractIdeContext(IdeLogLevel minLogLevel, Function<IdeLogLevel, IdeSubLogger> factory, Path userDir, ToolRepository toolRepository) {
142+
public AbstractIdeContext(IdeLoggerImpl logger, Path userDir, ToolRepository toolRepository) {
147143

148144
super();
149-
this.loggerFactory = factory;
150-
this.loggers = new HashMap<>();
151-
setLogLevel(minLogLevel);
145+
this.logger = logger;
152146
this.systemInfo = SystemInfoImpl.INSTANCE;
153147
this.commandletManager = new CommandletManagerImpl(this);
154148
this.fileAccess = new FileAccessImpl(this);
@@ -309,14 +303,6 @@ public String getMessageIdeHome() {
309303
*/
310304
public boolean isTest() {
311305

312-
return isMock();
313-
}
314-
315-
/**
316-
* @return {@code true} if this is a mock context for JUnits, {@code false} otherwise.
317-
*/
318-
public boolean isMock() {
319-
320306
return false;
321307
}
322308

@@ -708,9 +694,7 @@ protected ProcessContext createProcessContext() {
708694
@Override
709695
public IdeSubLogger level(IdeLogLevel level) {
710696

711-
IdeSubLogger logger = this.loggers.get(level);
712-
Objects.requireNonNull(logger);
713-
return logger;
697+
return this.logger.level(level);
714698
}
715699

716700
@Override
@@ -793,24 +777,6 @@ private static <O> void addMapping(Map<String, O> mapping, String key, O option)
793777
}
794778
}
795779

796-
/**
797-
* Sets the log level.
798-
*
799-
* @param logLevel {@link IdeLogLevel}
800-
*/
801-
public void setLogLevel(IdeLogLevel logLevel) {
802-
803-
for (IdeLogLevel level : IdeLogLevel.values()) {
804-
IdeSubLogger logger;
805-
if (level.ordinal() < logLevel.ordinal()) {
806-
logger = new IdeSubLoggerNone(level);
807-
} else {
808-
logger = this.loggerFactory.apply(level);
809-
}
810-
this.loggers.put(level, logger);
811-
}
812-
}
813-
814780
@Override
815781
public Step getCurrentStep() {
816782

@@ -918,7 +884,13 @@ private boolean applyAndRun(CliArguments arguments, Commandlet cmd) {
918884
} else if (cmd.isIdeRootRequired() && (this.ideRoot == null)) {
919885
throw new CliException(getMessageIdeRootNotFound(), ProcessResult.NO_IDE_ROOT);
920886
}
921-
if (!cmd.isProcessableOutput()) {
887+
if (cmd.isProcessableOutput()) {
888+
for (IdeLogLevel level : IdeLogLevel.values()) {
889+
if (level != IdeLogLevel.INFO) {
890+
this.logger.setLogLevel(level, false);
891+
}
892+
}
893+
} else {
922894
if (cmd.isIdeHomeRequired()) {
923895
debug(getMessageIdeHomeFound());
924896
}

cli/src/main/java/com/devonfw/tools/ide/context/IdeContextConsole.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.devonfw.tools.ide.io.IdeProgressBar;
66
import com.devonfw.tools.ide.io.IdeProgressBarConsole;
77
import com.devonfw.tools.ide.log.IdeLogLevel;
8+
import com.devonfw.tools.ide.log.IdeLoggerImpl;
89
import com.devonfw.tools.ide.log.IdeSubLoggerOut;
910

1011
import me.tongfei.progressbar.ProgressBarBuilder;
@@ -26,7 +27,7 @@ public class IdeContextConsole extends AbstractIdeContext {
2627
*/
2728
public IdeContextConsole(IdeLogLevel minLogLevel, Appendable out, boolean colored) {
2829

29-
super(minLogLevel, level -> new IdeSubLoggerOut(level, out, colored, minLogLevel), null, null);
30+
super(new IdeLoggerImpl(minLogLevel, level -> new IdeSubLoggerOut(level, out, colored, minLogLevel)), null, null);
3031
if (System.console() == null) {
3132
debug("System console not available - using System.in as fallback");
3233
this.scanner = new Scanner(System.in);
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.devonfw.tools.ide.log;
2+
3+
import java.util.Objects;
4+
import java.util.function.Function;
5+
6+
/**
7+
* Implementation of {@link IdeLogger}.
8+
*/
9+
public class IdeLoggerImpl implements IdeLogger {
10+
11+
private final Function<IdeLogLevel, IdeSubLogger> loggerFactory;
12+
13+
private final IdeSubLogger[] loggers;
14+
15+
/**
16+
* @param minLogLevel the minimum enabled {@link IdeLogLevel}.
17+
* @param factory the factory to create active {@link IdeSubLogger} instances.
18+
*/
19+
public IdeLoggerImpl(IdeLogLevel minLogLevel, Function<IdeLogLevel, IdeSubLogger> factory) {
20+
21+
super();
22+
this.loggerFactory = factory;
23+
this.loggers = new IdeSubLogger[IdeLogLevel.values().length];
24+
setLogLevel(minLogLevel);
25+
}
26+
27+
@Override
28+
public IdeSubLogger level(IdeLogLevel level) {
29+
30+
IdeSubLogger logger = this.loggers[level.ordinal()];
31+
Objects.requireNonNull(logger);
32+
return logger;
33+
}
34+
35+
/**
36+
* Sets the log level.
37+
*
38+
* @param logLevel {@link IdeLogLevel}
39+
*/
40+
public void setLogLevel(IdeLogLevel logLevel) {
41+
42+
for (IdeLogLevel level : IdeLogLevel.values()) {
43+
boolean enabled = level.ordinal() >= logLevel.ordinal();
44+
setLogLevel(level, enabled);
45+
}
46+
}
47+
48+
/**
49+
* @param logLevel the {@link IdeLogLevel} to modify.
50+
* @param enabled - {@code true} to enable, {@code false} to disable.
51+
*/
52+
public void setLogLevel(IdeLogLevel logLevel, boolean enabled) {
53+
54+
IdeSubLogger logger;
55+
if (enabled) {
56+
logger = this.loggerFactory.apply(logLevel);
57+
} else {
58+
logger = IdeSubLoggerNone.of(logLevel);
59+
}
60+
this.loggers[logLevel.ordinal()] = logger;
61+
}
62+
63+
}

cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerNone.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,22 @@
55
*/
66
public final class IdeSubLoggerNone extends AbstractIdeSubLogger {
77

8+
private static final IdeSubLoggerNone[] LOGGERS;
9+
10+
static {
11+
IdeLogLevel[] levels = IdeLogLevel.values();
12+
LOGGERS = new IdeSubLoggerNone[levels.length];
13+
for (int i = 0; i < levels.length; i++) {
14+
LOGGERS[i] = new IdeSubLoggerNone(levels[i]);
15+
}
16+
}
17+
818
/**
919
* The constructor.
1020
*
1121
* @param level the {@link #getLevel() log-level}.
1222
*/
13-
public IdeSubLoggerNone(IdeLogLevel level) {
23+
private IdeSubLoggerNone(IdeLogLevel level) {
1424

1525
super(level);
1626
}
@@ -27,4 +37,13 @@ public boolean isEnabled() {
2737
return false;
2838
}
2939

40+
/**
41+
* @param level the {@link IdeLogLevel}.
42+
* @return the {@link IdeSubLoggerNone} instance.
43+
*/
44+
public static IdeSubLoggerNone of(IdeLogLevel level) {
45+
46+
return LOGGERS[level.ordinal()];
47+
}
48+
3049
}

cli/src/test/java/com/devonfw/tools/ide/completion/IdeCompleterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,6 @@ private IdeCompleter newCompleter() {
128128

129129
private IdeTestContext newTestContext() {
130130

131-
return new IdeTestContext(Path.of(""), "");
131+
return new IdeTestContext(Path.of(""));
132132
}
133133
}

cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ public abstract class AbstractIdeContextTest extends Assertions {
3434
private static final int CHUNK_SIZE = 1024;
3535

3636
/**
37-
* @param testProject the (folder)name of the project test case, in this folder a 'project' folder represents the test project in {@link #TEST_PROJECTS}. E.g.
38-
* "basic".
37+
* @param testProject the (folder)name of the project test case, in this folder a 'project' folder represents the test project in {@link #TEST_PROJECTS}.
38+
* E.g. "basic".
3939
* @return the {@link IdeTestContext} pointing to that project.
4040
*/
4141
protected IdeTestContext newContext(String testProject) {
@@ -44,8 +44,8 @@ protected IdeTestContext newContext(String testProject) {
4444
}
4545

4646
/**
47-
* @param testProject the (folder)name of the project test case, in this folder a 'project' folder represents the test project in {@link #TEST_PROJECTS}. E.g.
48-
* "basic".
47+
* @param testProject the (folder)name of the project test case, in this folder a 'project' folder represents the test project in {@link #TEST_PROJECTS}.
48+
* E.g. "basic".
4949
* @param projectPath the relative path inside the test project where to create the context.
5050
* @return the {@link IdeTestContext} pointing to that project.
5151
*/
@@ -55,11 +55,11 @@ protected static IdeTestContext newContext(String testProject, String projectPat
5555
}
5656

5757
/**
58-
* @param testProject the (folder)name of the project test case, in this folder a 'project' folder represents the test project in {@link #TEST_PROJECTS}. E.g.
59-
* "basic".
58+
* @param testProject the (folder)name of the project test case, in this folder a 'project' folder represents the test project in {@link #TEST_PROJECTS}.
59+
* E.g. "basic".
6060
* @param projectPath the relative path inside the test project where to create the context.
61-
* @param copyForMutation - {@code true} to create a copy of the project that can be modified by the test, {@code false} otherwise (only to save resources if
62-
* you are 100% sure that your test never modifies anything in that project.)
61+
* @param copyForMutation - {@code true} to create a copy of the project that can be modified by the test, {@code false} otherwise (only to save resources
62+
* if you are 100% sure that your test never modifies anything in that project.)
6363
* @return the {@link IdeTestContext} pointing to that project.
6464
*/
6565
protected static IdeTestContext newContext(String testProject, String projectPath, boolean copyForMutation) {
@@ -68,11 +68,11 @@ protected static IdeTestContext newContext(String testProject, String projectPat
6868
}
6969

7070
/**
71-
* @param testProject the (folder)name of the project test case, in this folder a 'project' folder represents the test project in {@link #TEST_PROJECTS}. E.g.
72-
* "basic".
71+
* @param testProject the (folder)name of the project test case, in this folder a 'project' folder represents the test project in {@link #TEST_PROJECTS}.
72+
* E.g. "basic".
7373
* @param projectPath the relative path inside the test project where to create the context.
74-
* @param copyForMutation - {@code true} to create a copy of the project that can be modified by the test, {@code false} otherwise (only to save resources if
75-
* you are 100% sure that your test never modifies anything in that project.)
74+
* @param copyForMutation - {@code true} to create a copy of the project that can be modified by the test, {@code false} otherwise (only to save resources
75+
* if you are 100% sure that your test never modifies anything in that project.)
7676
* @param logLevel the {@link IdeLogLevel} used as threshold for logging.
7777
* @return the {@link IdeTestContext} pointing to that project.
7878
*/
@@ -112,24 +112,6 @@ protected static IdeTestContext newContext(Path projectPath) {
112112
return new IdeTestContext(projectPath);
113113
}
114114

115-
/**
116-
* @param projectPath the relative path inside the test project where to create the context.
117-
* @param errors list of error messages.
118-
* @param outs list of out messages.
119-
* @param exitCode the exit code.
120-
* @param isOnline boolean if it should be run in online mode.
121-
* @return the {@link GitContextTestContext} pointing to that project.
122-
*/
123-
protected static GitContextTestContext newGitContext(Path projectPath, List<String> errors, List<String> outs, int exitCode, boolean isOnline) {
124-
125-
GitContextTestContext context;
126-
context = new GitContextTestContext(isOnline, projectPath);
127-
context.setErrors(errors);
128-
context.setOuts(outs);
129-
context.setExitCode(exitCode);
130-
return context;
131-
}
132-
133115
protected static IdeTestContextAssertion assertThat(IdeTestContext context) {
134116

135117
return new IdeTestContextAssertion(context);

0 commit comments

Comments
 (0)