Skip to content

Commit 5d56cf0

Browse files
authored
add -compactOutput (#1188)
1 parent da38a4e commit 5d56cf0

7 files changed

Lines changed: 162 additions & 40 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/CompilationProcess.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ private void runTests(ImTranslator translator, WurstCompilerJassImpl compiler, i
157157
PrintStream out = System.out;
158158
// tests
159159
gui.sendProgress("Running tests");
160-
System.out.println("Running tests");
161-
RunTests runTests = new RunTests(Optional.empty(), 0, 0, Optional.empty(), testTimeout, testFilter) {
160+
if (!runArgs.isCompactOutput()) {
161+
System.out.println("Running tests");
162+
}
163+
RunTests runTests = new RunTests(Optional.empty(), 0, 0, Optional.empty(), testTimeout, testFilter, runArgs.isCompactOutput()) {
162164
@Override
163165
protected void print(String message) {
164166
out.print(message);
@@ -176,6 +178,8 @@ protected void print(String message) {
176178
}
177179
}
178180

179-
System.out.println("Finished running tests");
181+
if (!runArgs.isCompactOutput()) {
182+
System.out.println("Finished running tests");
183+
}
180184
}
181185
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/Main.java

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
import java.nio.file.Path;
3232
import java.nio.file.Paths;
3333
import java.util.ArrayList;
34+
import java.util.LinkedHashMap;
3435
import java.util.List;
36+
import java.util.Map;
3537
import java.util.Optional;
3638

3739
import static de.peeeq.wurstio.languageserver.ProjectConfigBuilder.FILE_NAME;
@@ -99,7 +101,7 @@ public static void main(String[] args) {
99101
// use the error reporting with GUI
100102
ErrorReporting.instance = new ErrorReportingIO();
101103
} else {
102-
gui = new WurstGuiCliImpl();
104+
gui = new WurstGuiCliImpl(runArgs.isCompactOutput());
103105
}
104106

105107
if (runArgs.showLastErrors()) {
@@ -183,23 +185,50 @@ public static void main(String[] args) {
183185
if (gui != null) {
184186
gui.sendFinished();
185187
if (!runArgs.isGui()) {
186-
if (gui.getErrorCount() > 0) {
187-
// print error messages
188-
for (CompileError err : gui.getErrorList()) {
188+
if (runArgs.isCompactOutput()) {
189+
printCompactMessages(gui);
190+
} else {
191+
if (gui.getErrorCount() > 0) {
192+
// print error messages
193+
for (CompileError err : gui.getErrorList()) {
194+
System.out.println(err);
195+
}
196+
// signal that there was an error when compiling
197+
System.exit(1);
198+
}
199+
// print warnings:
200+
for (CompileError err : gui.getWarningList()) {
189201
System.out.println(err);
190202
}
191-
// signal that there was an error when compiling
192-
System.exit(1);
193203
}
194-
// print warnings:
195-
for (CompileError err : gui.getWarningList()) {
196-
System.out.println(err);
204+
if (gui.getErrorCount() > 0) {
205+
System.exit(1);
197206
}
198207
}
199208
}
200209
}
201210
}
202211

212+
private static void printCompactMessages(WurstGui gui) {
213+
if (gui.getErrorCount() > 0) {
214+
System.out.println("Errors: " + gui.getErrorCount());
215+
for (CompileError err : gui.getErrorList()) {
216+
System.out.println(err.toCompactString());
217+
}
218+
}
219+
if (!gui.getWarningList().isEmpty()) {
220+
Map<String, Integer> warningsByFile = new LinkedHashMap<>();
221+
for (CompileError err : gui.getWarningList()) {
222+
String file = new File(err.getSource().getFile()).getName();
223+
warningsByFile.put(file, warningsByFile.getOrDefault(file, 0) + 1);
224+
}
225+
System.out.println("Warnings: " + gui.getWarningList().size());
226+
for (Map.Entry<String, Integer> entry : warningsByFile.entrySet()) {
227+
System.out.println("Warning " + entry.getKey() + ": " + entry.getValue());
228+
}
229+
}
230+
}
231+
203232
private static void logStartup(String[] args) {
204233
// VM Arguments
205234
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/RunTests.java

Lines changed: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public class RunTests extends UserRequest<Object> {
4747
private final Optional<String> testName;
4848
private final int timeoutSeconds;
4949
private final Optional<String> testFilter;
50+
private final boolean compactOutput;
5051

5152
private final List<ImFunction> successTests = Lists.newArrayList();
5253
private final List<TestFailure> failTests = Lists.newArrayList();
@@ -98,12 +99,17 @@ public RunTests(Optional<String> filename, int line, int column, Optional<String
9899
}
99100

100101
public RunTests(Optional<String> filename, int line, int column, Optional<String> testName, int timeoutSeconds, Optional<String> testFilter) {
102+
this(filename, line, column, testName, timeoutSeconds, testFilter, false);
103+
}
104+
105+
public RunTests(Optional<String> filename, int line, int column, Optional<String> testName, int timeoutSeconds, Optional<String> testFilter, boolean compactOutput) {
101106
this.filename = filename.map(WFile::create);
102107
this.line = line;
103108
this.column = column;
104109
this.testName = testName;
105110
this.timeoutSeconds = timeoutSeconds;
106111
this.testFilter = testFilter;
112+
this.compactOutput = compactOutput;
107113
}
108114

109115

@@ -175,7 +181,7 @@ public TestResult runTests(ImTranslator translator, ImProg imProg, Optional<Func
175181

176182
if (gui.getErrorCount() > 0) {
177183
for (CompileError compileError : gui.getErrorList()) {
178-
println(compileError.toString());
184+
println(compactOutput ? compileError.toCompactString() : compileError.toString());
179185
}
180186
println("There were some problem while running compiletime expressions and functions.");
181187
return new TestResult(0, 1);
@@ -196,7 +202,7 @@ public TestResult runTests(ImTranslator translator, ImProg imProg, Optional<Func
196202
}
197203
if (matched.isEmpty()) {
198204
println("No tests match filter '" + testFilter.get() + "'.");
199-
} else {
205+
} else if (!compactOutput) {
200206
println("Filter '" + testFilter.get() + "' matched " + matched.size() + " test(s):");
201207
for (String name : matched) {
202208
println(" " + name);
@@ -228,7 +234,9 @@ public TestResult runTests(ImTranslator translator, ImProg imProg, Optional<Func
228234
WPos source = f.attrTrace().attrSource();
229235
String file = new File(source.getFile()).toPath().normalize().toString();
230236
String message = "Running " + file + ":" + source.getLine() + " - " + f.getName() + "..";
231-
println(message);
237+
if (!compactOutput) {
238+
println(message);
239+
}
232240
WLogger.info(message);
233241

234242
try {
@@ -253,59 +261,95 @@ public TestResult runTests(ImTranslator translator, ImProg imProg, Optional<Func
253261

254262
if (gui.getErrorCount() > 0) {
255263
StringBuilder sb = new StringBuilder();
264+
int appendedErrors = 0;
256265
for (CompileError error : gui.getErrorList()) {
257-
sb.append(error).append("\n");
258-
println(error.getMessage());
266+
if (compactOutput) {
267+
if (appendedErrors >= 3) {
268+
continue;
269+
}
270+
if (sb.length() > 0) {
271+
sb.append("; ");
272+
}
273+
sb.append(error.toCompactString());
274+
appendedErrors++;
275+
} else {
276+
sb.append(error).append("\n");
277+
}
278+
if (!compactOutput) {
279+
println(error.getMessage());
280+
}
281+
}
282+
if (compactOutput && gui.getErrorCount() > appendedErrors) {
283+
sb.append("; +").append(gui.getErrorCount() - appendedErrors).append(" more");
259284
}
260285
gui.clearErrors();
261286
TestFailure failure = new TestFailure(f, interpreter.getStackFrames(), sb.toString());
262287
failTests.add(failure);
263288
} else {
264289
successTests.add(f);
265-
println("\tOK!");
290+
if (!compactOutput) {
291+
println("\tOK!");
292+
}
266293
}
267294
} catch (TestSuccessException e) {
268295
successTests.add(f);
269-
println("\tOK!");
296+
if (!compactOutput) {
297+
println("\tOK!");
298+
}
270299
} catch (TestFailException e) {
271300
TestFailure failure = new TestFailure(f, interpreter.getStackFrames(), e.getMessage());
272301
failTests.add(failure);
273-
println("\tFAILED assertion:");
274-
println("\t" + failure.getMessageWithStackFrame());
302+
if (!compactOutput) {
303+
println("\tFAILED assertion:");
304+
println("\t" + failure.getMessageWithStackFrame());
305+
}
275306
} catch (TestTimeOutException e) {
276307
failTests.add(new TestFailure(f, interpreter.getStackFrames(), e.getMessage()));
277-
println("\tFAILED - TIMEOUT (This test did not complete in " + timeoutSeconds + " seconds, it might contain an endless loop)");
278-
println(interpreter.getStackFrames().toString());
308+
if (!compactOutput) {
309+
println("\tFAILED - TIMEOUT (This test did not complete in " + timeoutSeconds + " seconds, it might contain an endless loop)");
310+
println(interpreter.getStackFrames().toString());
311+
}
279312
} catch (InterpreterException e) {
280313
TestFailure failure = new TestFailure(f, interpreter.getStackFrames(), e.getMessage());
281314
failTests.add(failure);
282-
println("\t" + failure.getMessageWithStackFrame());
315+
if (!compactOutput) {
316+
println("\t" + failure.getMessageWithStackFrame());
317+
}
283318
} catch (Throwable e) {
284319
failTests.add(new TestFailure(f, interpreter.getStackFrames(), e.toString()));
285-
println("\tFAILED with exception: " + e.getClass() + " " + e.getLocalizedMessage());
286-
println(interpreter.getStackFrames().toString());
287-
println("Here are some compiler internals, that might help Wurst developers to debug this issue:");
288-
StringWriter sw = new StringWriter();
289-
PrintWriter pw = new PrintWriter(sw);
290-
e.printStackTrace(pw);
291-
String sStackTrace = sw.toString();
292-
println("\t" + e.getLocalizedMessage());
293-
println("\t" + sStackTrace);
320+
if (!compactOutput) {
321+
println("\tFAILED with exception: " + e.getClass() + " " + e.getLocalizedMessage());
322+
println(interpreter.getStackFrames().toString());
323+
println("Here are some compiler internals, that might help Wurst developers to debug this issue:");
324+
StringWriter sw = new StringWriter();
325+
PrintWriter pw = new PrintWriter(sw);
326+
e.printStackTrace(pw);
327+
String sStackTrace = sw.toString();
328+
println("\t" + e.getLocalizedMessage());
329+
println("\t" + sStackTrace);
330+
}
294331
}
295332
}
296333
}
297334
} // Scheduler is automatically shut down here
298335

299-
println("Tests succeeded: " + successTests.size() + "/" + (successTests.size() + failTests.size()));
300-
if (failTests.size() == 0) {
301-
println(">> All tests have passed successfully!");
336+
if (compactOutput) {
337+
println("Tests: " + successTests.size() + "/" + (successTests.size() + failTests.size()) + " passed");
338+
for (TestFailure failure : failTests) {
339+
println("FAILED " + qualifiedTestName(failure.getFunction()));
340+
}
302341
} else {
303-
println(">> " + failTests.size() + " Tests have failed!");
342+
println("Tests succeeded: " + successTests.size() + "/" + (successTests.size() + failTests.size()));
343+
if (failTests.size() == 0) {
344+
println(">> All tests have passed successfully!");
345+
} else {
346+
println(">> " + failTests.size() + " Tests have failed!");
347+
}
304348
}
305349
if (gui.getErrorCount() > 0) {
306350
println("There were some errors reported while running the tests.");
307351
for (CompileError error : gui.getErrorList()) {
308-
println(error.toString());
352+
println(compactOutput ? error.toCompactString() : error.toString());
309353
}
310354
}
311355

@@ -319,21 +363,28 @@ private void redirectInterpreterOutput(ProgramState globalState) {
319363

320364
@Override
321365
public void write(int b) throws IOException {
322-
if (b > 0) {
366+
if (!compactOutput && b > 0) {
323367
println("" + (char) b);
324368
}
325369
}
326370

327371
@Override
328372
public void write(byte[] b, int off, int len) throws IOException {
329-
println(new String(b, off, len));
373+
if (!compactOutput) {
374+
println(new String(b, off, len));
375+
}
330376
}
331377

332378

333379
};
334380
globalState.setOutStream(new PrintStream(os));
335381
}
336382

383+
private String qualifiedTestName(ImFunction f) {
384+
String packageName = f.attrTrace().attrNearestPackage().tryGetNameDef().getName();
385+
return packageName + "." + f.getName();
386+
}
387+
337388
protected void println(String message) {
338389
print(message);
339390
print(System.lineSeparator());

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/RunArgs.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public class RunArgs {
4949
private final RunOption optionShowVersion;
5050
private final RunOption optionPrettyPrint;
5151
private final RunOption optionMeasureTimes;
52+
private final RunOption optionCompactOutput;
5253
private final RunOption optionHotStartmap;
5354
private final RunOption optionHotReload;
5455
private final RunOption optionTestTimeout;
@@ -104,6 +105,7 @@ public RunArgs(String... args) {
104105
+ "some programming errors like null-pointer-dereferences or accessing of destroyed objects can no longer be detected. "
105106
+ "It is strongly recommended to not use this option, but it can give some performance benefits.");
106107
optionMeasureTimes = addOption("measure", "Measure how long each step of the translation process takes.");
108+
optionCompactOutput = addOption("compactOutput", "Print compact CLI output for automated agents.");
107109
// tools
108110
optionAbout = addOption("-about", "Show the 'about' window.");
109111
optionFixInstall = addOption("-fixInstallation", "Checks your wc3 installation and applies compatibility fixes");
@@ -357,6 +359,10 @@ public boolean isMeasureTimes() {
357359
return optionMeasureTimes.isSet;
358360
}
359361

362+
public boolean isCompactOutput() {
363+
return optionCompactOutput.isSet;
364+
}
365+
360366
public boolean isHotStartmap() {
361367
return optionHotStartmap.isSet;
362368
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/CompileError.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ public String toString() {
7272
message;
7373
}
7474

75+
public String toCompactString() {
76+
File file = new File(source.getFile());
77+
return errorType + " " + file.getName() + ":" + source.getLine() + ": " + message.replace('\r', ' ').replace('\n', ' ');
78+
}
79+
7580
public ErrorType getErrorType() {
7681
return errorType;
7782
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/gui/WurstGuiCliImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
*/
88
public class WurstGuiCliImpl extends WurstGui {
99

10+
private final boolean compactOutput;
11+
12+
public WurstGuiCliImpl() {
13+
this(false);
14+
}
15+
16+
public WurstGuiCliImpl(boolean compactOutput) {
17+
this.compactOutput = compactOutput;
18+
}
1019

1120
@Override
1221
public void sendError(CompileError err) {
@@ -19,6 +28,9 @@ public void sendProgress(String msg) {
1928

2029
@Override
2130
public void sendFinished() {
31+
if (compactOutput) {
32+
return;
33+
}
2234
System.out.println("compilation finished (errors: " + getErrorCount() + ", warnings: " + getWarningList().size() + ")");
2335
}
2436

de.peeeq.wurstscript/src/test/java/tests/wurstscript/utils/UtilsTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
import de.peeeq.wurstscript.utils.TopsortCycleException;
55
import de.peeeq.wurstscript.utils.Utils;
6+
import de.peeeq.wurstscript.RunArgs;
7+
import de.peeeq.wurstscript.attributes.CompileError;
8+
import de.peeeq.wurstscript.parser.WPos;
69
import org.testng.Assert;
710
import org.testng.annotations.Test;
811

@@ -12,6 +15,18 @@
1215

1316
public class UtilsTest {
1417

18+
@Test
19+
public void compactOutputFlag() {
20+
Assert.assertTrue(new RunArgs("-compactOutput").isCompactOutput());
21+
}
22+
23+
@Test
24+
public void compactCompileErrorIsSingleLine() {
25+
CompileError error = new CompileError((WPos) null, "first line\nsecond line");
26+
Assert.assertFalse(error.toCompactString().contains("\n"));
27+
Assert.assertTrue(error.toCompactString().contains("first line second line"));
28+
}
29+
1530
@Test
1631
public void array() {
1732
int[] ar1 = {1, 2, 3};

0 commit comments

Comments
 (0)