diff --git a/cli/src/main/java/com/devonfw/tools/ide/process/LogEvent.java b/cli/src/main/java/com/devonfw/tools/ide/process/LogEvent.java new file mode 100644 index 000000000..055f81c68 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/process/LogEvent.java @@ -0,0 +1,11 @@ +package com.devonfw.tools.ide.process; + +/** + * Represent a log event. + * + * @param error A boolean flag that indicates whether the log event represents and error or standard output + * @param message A string containing the log message + */ +public record LogEvent(boolean error, String message) { + +} 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 24cec551a..ed6a7c90f 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 @@ -167,14 +167,15 @@ public ProcessResult run(ProcessMode processMode) { this.processBuilder.command(args); + List logs = new ArrayList<>(); List out = null; List err = null; Process process = this.processBuilder.start(); if (processMode == ProcessMode.DEFAULT_CAPTURE) { - CompletableFuture> outFut = readInputStream(process.getInputStream()); - CompletableFuture> errFut = readInputStream(process.getErrorStream()); + CompletableFuture> outFut = readInputStream(process.getInputStream(), false, logs); + CompletableFuture> errFut = readInputStream(process.getErrorStream(), true, logs); out = outFut.get(); err = errFut.get(); } @@ -187,10 +188,9 @@ public ProcessResult run(ProcessMode processMode) { exitCode = process.waitFor(); } - ProcessResult result = new ProcessResultImpl(exitCode, out, err); + ProcessResult result = new ProcessResultImpl(exitCode, out, err, logs); performLogging(result, exitCode, interpreter); - return result; } catch (CliProcessException | IllegalStateException e) { @@ -214,11 +214,19 @@ public ProcessResult run(ProcessMode processMode) { * @param is {@link InputStream}. * @return {@link CompletableFuture}. */ - private static CompletableFuture> readInputStream(InputStream is) { + private static CompletableFuture> readInputStream(InputStream is, boolean errorStream, List logs) { return CompletableFuture.supplyAsync(() -> { try (InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr)) { + + String line; + while ((line = br.readLine()) != null) { + synchronized (logs) { + LogEvent logEvent = new LogEvent(errorStream, line); + logs.add(logEvent); + } + } return br.lines().toList(); } catch (Throwable e) { throw new RuntimeException("There was a problem while executing the program", e); 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 c4786d54b..980ce6ae2 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 @@ -18,19 +18,23 @@ public class ProcessResultImpl implements ProcessResult { private final List err; + private final List logEvents; + /** * The constructor. * * @param exitCode the {@link #getExitCode() exit code}. * @param out the {@link #getOut() out}. * @param err the {@link #getErr() err}. + * @param logEvents the {@link #getLogEvents()} () logEvents}. */ - public ProcessResultImpl(int exitCode, List out, List err) { + public ProcessResultImpl(int exitCode, List out, List err, List logEvents) { super(); this.exitCode = exitCode; this.out = Objects.requireNonNullElse(out, Collections.emptyList()); this.err = Objects.requireNonNullElse(err, Collections.emptyList()); + this.logEvents = Objects.requireNonNullElse(logEvents, Collections.emptyList()); } @Override @@ -51,6 +55,11 @@ public List getErr() { return this.err; } + public List getLogEvents() { + + return this.logEvents; + } + @Override public void log(IdeLogLevel level, IdeContext context) { log(level, context, level);