diff --git a/src/core/toml_filter.rs b/src/core/toml_filter.rs index bd294f8af..0a2400b0d 100644 --- a/src/core/toml_filter.rs +++ b/src/core/toml_filter.rs @@ -1613,8 +1613,8 @@ match_command = "^make\\b" let filters = make_filters(BUILTIN_TOML); assert_eq!( filters.len(), - 58, - "Expected exactly 58 built-in filters, got {}. \ + 59, + "Expected exactly 59 built-in filters, got {}. \ Update this count when adding/removing filters in src/filters/.", filters.len() ); @@ -1671,11 +1671,11 @@ expected = "output line 1\noutput line 2" let combined = format!("{}\n\n{}", BUILTIN_TOML, new_filter); let filters = make_filters(&combined); - // All 58 existing filters still present + 1 new = 59 + // All 59 existing filters still present + 1 new = 60 assert_eq!( filters.len(), - 59, - "Expected 59 filters after concat (58 built-in + 1 new)" + 60, + "Expected 60 filters after concat (59 built-in + 1 new)" ); // New filter is discoverable diff --git a/src/discover/rules.rs b/src/discover/rules.rs index b315edd77..9eee138ce 100644 --- a/src/discover/rules.rs +++ b/src/discover/rules.rs @@ -486,9 +486,9 @@ pub const RULES: &[RtkRule] = &[ subcmd_status: &[], }, RtkRule { - pattern: r"^mvn\s+(compile|package|clean|install)\b", + pattern: r"^(\./)?mvnw?\s+(compile|package|clean|install|test)\b", rtk_cmd: "rtk mvn", - rewrite_prefixes: &["mvn"], + rewrite_prefixes: &["./mvnw", "mvnw", "mvn"], category: "Build", savings_pct: 70.0, subcmd_savings: &[], diff --git a/src/filters/mvn-build.toml b/src/filters/mvn-build.toml index 430a7f0cd..8750b3b1b 100644 --- a/src/filters/mvn-build.toml +++ b/src/filters/mvn-build.toml @@ -1,13 +1,18 @@ [filters.mvn-build] description = "Compact Maven build output" -match_command = "^mvn\\s+(compile|package|clean|install)\\b" +match_command = "^(\\.?\\/?)mvnw?\\s+(compile|package|clean|install)\\b" strip_ansi = true strip_lines_matching = [ "^\\[INFO\\] ---", "^\\[INFO\\] Building\\s", + "^\\[INFO\\] Scanning for projects", + "^\\[INFO\\] Compiling \\d+ source file", + "^\\[INFO\\] Recompiling the module", "^\\[INFO\\] Downloading\\s", "^\\[INFO\\] Downloaded\\s", "^\\[INFO\\]\\s*$", + "^\\[ERROR\\]\\s*$", + "^\\[ERROR\\] -> \\[Help", "^\\s*$", "^Downloading:", "^Downloaded:", @@ -42,3 +47,71 @@ input = """ [INFO] Finished at: 2024-01-15T10:30:00Z """ expected = "[INFO] BUILD SUCCESS\n[INFO] Total time: 4.123 s\n[INFO] Finished at: 2024-01-15T10:30:00Z" + +[[tests.mvn-build]] +name = "clean success strips all noise" +input = """ +[INFO] Scanning for projects... +[INFO] --- maven-compiler-plugin:3.13.0:compile (default-compile) --- +[INFO] Compiling 5 source files with javac [debug target 25] to target/classes +[INFO] BUILD SUCCESS +[INFO] Total time: 1.234 s +""" +expected = "[INFO] BUILD SUCCESS\n[INFO] Total time: 1.234 s" + +[[tests.mvn-build]] +name = "single compilation error preserves error details" +input = """ +[INFO] Scanning for projects... +[INFO] +[INFO] --- maven-compiler-plugin:3.13.0:compile (default-compile) --- +[INFO] Recompiling the module because of changed source code. +[INFO] Compiling 5 source files with javac [debug target 25] to target/classes +[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[42,15] cannot find symbol +[INFO] symbol: variable foo +[INFO] location: class com.example.MyService +[ERROR] COMPILATION FAILURE +[ERROR] +[ERROR] -> [Help 1] +""" +expected = "[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[42,15] cannot find symbol\n[INFO] symbol: variable foo\n[INFO] location: class com.example.MyService\n[ERROR] COMPILATION FAILURE" + +[[tests.mvn-build]] +name = "multiple compilation errors preserved" +input = """ +[INFO] Scanning for projects... +[INFO] --- maven-compiler-plugin:3.13.0:compile (default-compile) --- +[INFO] Compiling 10 source files with javac [debug target 25] to target/classes +[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[42,15] cannot find symbol +[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[55,10] incompatible types: String cannot be converted to int +[ERROR] /home/user/my-project/src/main/java/com/example/OtherClass.java:[10,20] method doStuff() is not defined +[ERROR] COMPILATION FAILURE +[ERROR] -> [Help 1] +""" +expected = "[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[42,15] cannot find symbol\n[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[55,10] incompatible types: String cannot be converted to int\n[ERROR] /home/user/my-project/src/main/java/com/example/OtherClass.java:[10,20] method doStuff() is not defined\n[ERROR] COMPILATION FAILURE" + +[[tests.mvn-build]] +name = "mixed errors and warnings preserved" +input = """ +[INFO] Scanning for projects... +[INFO] --- maven-compiler-plugin:3.13.0:compile (default-compile) --- +[INFO] Compiling 8 source files with javac [debug target 25] to target/classes +[WARNING] /home/user/my-project/src/main/java/com/example/OldService.java:[10,5] [deprecation] doStuff() in LegacyApi has been deprecated +[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[42,15] cannot find symbol +[WARNING] /home/user/my-project/src/main/java/com/example/OldService.java:[25,12] [unchecked] unchecked cast +[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[55,10] method not found +[ERROR] COMPILATION FAILURE +""" +expected = "[WARNING] /home/user/my-project/src/main/java/com/example/OldService.java:[10,5] [deprecation] doStuff() in LegacyApi has been deprecated\n[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[42,15] cannot find symbol\n[WARNING] /home/user/my-project/src/main/java/com/example/OldService.java:[25,12] [unchecked] unchecked cast\n[ERROR] /home/user/my-project/src/main/java/com/example/MyService.java:[55,10] method not found\n[ERROR] COMPILATION FAILURE" + +[[tests.mvn-build]] +name = "warnings-only build keeps warnings and success" +input = """ +[INFO] Scanning for projects... +[INFO] --- maven-compiler-plugin:3.13.0:compile (default-compile) --- +[INFO] Compiling 3 source files with javac [debug target 25] to target/classes +[WARNING] /home/user/my-project/src/main/java/com/example/OldService.java:[10,5] [deprecation] doStuff() in LegacyApi has been deprecated +[WARNING] /home/user/my-project/src/main/java/com/example/OldService.java:[25,12] [unchecked] unchecked cast +[INFO] BUILD SUCCESS +""" +expected = "[WARNING] /home/user/my-project/src/main/java/com/example/OldService.java:[10,5] [deprecation] doStuff() in LegacyApi has been deprecated\n[WARNING] /home/user/my-project/src/main/java/com/example/OldService.java:[25,12] [unchecked] unchecked cast\n[INFO] BUILD SUCCESS" diff --git a/src/filters/mvn-test.toml b/src/filters/mvn-test.toml new file mode 100644 index 000000000..a755c318f --- /dev/null +++ b/src/filters/mvn-test.toml @@ -0,0 +1,147 @@ +[filters.mvn-test] +description = "Compact Maven test output — failures only, strip surefire boilerplate" +match_command = "^(\\.?\\/?)mvnw?\\s+test\\b" +strip_ansi = true +# Stage 3: short-circuit on full success (no errors/failures anywhere) +match_output = [ + { pattern = "Tests run: (\\d+), Failures: 0, Errors: 0", message = "mvn test: ok (all tests passed)", unless = "<<< FAILURE|\\[ERROR\\]" }, +] +# Stage 2: blank out Maven surefire boilerplate and framework stack frames +replace = [ + { pattern = "^\\[ERROR\\]\\s*$", replacement = "" }, + { pattern = "^\\[ERROR\\] -> \\[Help.*", replacement = "" }, + { pattern = "^\\[ERROR\\] \\[Help \\d+\\].*", replacement = "" }, + { pattern = "^\\[ERROR\\] See .*/surefire-reports.*", replacement = "" }, + { pattern = "^\\[ERROR\\] See dump files.*", replacement = "" }, + { pattern = "^\\[ERROR\\] To see the full stack trace.*", replacement = "" }, + { pattern = "^\\[ERROR\\] Re-run Maven.*", replacement = "" }, + { pattern = "^\\[ERROR\\] For more information about.*", replacement = "" }, + # Strip framework stack frames (Maven, JUnit platform, Surefire, classworlds, JDK internals) + { pattern = "^\\[ERROR\\]\\s+at org\\.apache\\.maven\\..*", replacement = "" }, + { pattern = "^\\[ERROR\\]\\s+at org\\.junit\\.platform\\..*", replacement = "" }, + { pattern = "^\\[ERROR\\]\\s+at org\\.codehaus\\.plexus\\..*", replacement = "" }, + { pattern = "^\\[ERROR\\]\\s+at java\\.base/.*", replacement = "" }, + { pattern = "^\\[ERROR\\]\\s+\\.\\.\\. \\d+ more$", replacement = "" }, +] +keep_lines_matching = [ + "\\[ERROR\\]", + "BUILD (SUCCESS|FAILURE)", + "Tests run:", + "<<< FAILURE", + "<<< ERROR", + "^\\s+at\\s", + "Caused by:", + "^java\\.lang\\.\\w*Exception", + "^java\\.lang\\.\\w*Error", + "^org\\.junit\\..*Exception", + "^org\\.opentest4j\\.", + "expected:", + "but was:", + "Expected", + "Total time:", +] +tail_lines = 40 +max_lines = 40 +on_empty = "mvn test: ok (all tests passed)" + +[[tests.mvn-test]] +name = "all tests pass returns ok" +input = """ +[INFO] Scanning for projects... +[INFO] --- maven-compiler-plugin:3.13.0:compile (default-compile) --- +[INFO] Compiling 5 source files with javac [debug target 25] to target/classes +[INFO] --- maven-surefire-plugin:3.5.4:test (default-test) --- +[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider +[INFO] BUILD SUCCESS +[INFO] Total time: 3.456 s +""" +expected = "[INFO] BUILD SUCCESS\n[INFO] Total time: 3.456 s" + +[[tests.mvn-test]] +name = "954 tests pass returns short summary" +input = """ +[INFO] Scanning for projects... +[INFO] Building auth 1.3-SNAPSHOT +[INFO] --- maven-surefire-plugin:3.5.4:test (default-test) --- +[INFO] Tests run: 12, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.010 s -- in com.example.PermissionHelperTest +[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.073 s -- in com.example.SampleTest +[INFO] Tests run: 954, Failures: 0, Errors: 0, Skipped: 9 +[INFO] BUILD SUCCESS +[INFO] Total time: 01:46 min +""" +expected = "mvn test: ok (all tests passed)" + +[[tests.mvn-test]] +name = "test failure preserves error details and strips boilerplate" +input = """ +[INFO] Scanning for projects... +[INFO] --- maven-surefire-plugin:3.5.4:test (default-test) --- +[ERROR] Tests run: 27, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.073 s <<< FAILURE! -- in io.github.mavenmcp.parser.DependencyTreeParserTest +[ERROR] io.github.mavenmcp.parser.DependencyTreeParserTest.shouldMatchCaseInsensitively -- Time elapsed: 0.004 s <<< FAILURE! +java.lang.AssertionError: +Expected size: 1 but was: 3 +[INFO] +[INFO] BUILD FAILURE +[INFO] Total time: 0.611 s +[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.4:test (default-test) on project maven-mcp: There are test failures. +[ERROR] +[ERROR] See /home/mariusz/projects/maven-mcp/target/surefire-reports for the individual test results. +[ERROR] See dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream. +[ERROR] -> [Help 1] +[ERROR] +[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. +[ERROR] Re-run Maven using the -X switch to enable full debug logging. +[ERROR] +[ERROR] For more information about the errors and possible solutions, please read the following articles: +[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException +""" +expected = "[ERROR] Tests run: 27, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.073 s <<< FAILURE! -- in io.github.mavenmcp.parser.DependencyTreeParserTest\n[ERROR] io.github.mavenmcp.parser.DependencyTreeParserTest.shouldMatchCaseInsensitively -- Time elapsed: 0.004 s <<< FAILURE!\njava.lang.AssertionError:\nExpected size: 1 but was: 3\n[INFO] BUILD FAILURE\n[INFO] Total time: 0.611 s\n[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.4:test (default-test) on project maven-mcp: There are test failures." + +[[tests.mvn-test]] +name = "multiple test failures with assertion details" +input = """ +[ERROR] DependencyTreeParserTest.shouldParseDirectDependency:35 +expected: "org.slf4j" + but was: "com.google.guava" +[ERROR] DependencyTreeParserTest.shouldParseSimpleTree:22 +expected: "com.example" + but was: "org.slf4j" +[ERROR] Tests run: 17, Failures: 7, Errors: 0, Skipped: 0 +[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.4:test (default-test) on project maven-mcp: There are test failures. +[ERROR] +[ERROR] See /home/mariusz/projects/maven-mcp/target/surefire-reports for the individual test results. +[ERROR] -> [Help 1] +[ERROR] +[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. +[ERROR] Re-run Maven using the -X switch to enable full debug logging. +[ERROR] +[ERROR] For more information about the errors and possible solutions, please read the following articles: +[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException +""" +expected = "[ERROR] DependencyTreeParserTest.shouldParseDirectDependency:35\nexpected: \"org.slf4j\"\n but was: \"com.google.guava\"\n[ERROR] DependencyTreeParserTest.shouldParseSimpleTree:22\nexpected: \"com.example\"\n but was: \"org.slf4j\"\n[ERROR] Tests run: 17, Failures: 7, Errors: 0, Skipped: 0\n[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.4:test (default-test) on project maven-mcp: There are test failures." + +[[tests.mvn-test]] +name = "real project build failure strips noise" +input = """ +[INFO] Loaded 22505 auto-discovered prefixes for remote repository central +[INFO] Scanning for projects... +[WARNING] Could not transfer metadata from shibboleth-releases +[WARNING] 176 problems were encountered while building the effective model +[WARNING] 130 problems were encountered while building the effective model +[INFO] Building auth 1.3-SNAPSHOT +[INFO] --- jacoco:0.8.14:prepare-agent (prepare-agent) --- +[INFO] Testcontainers version: 2.0.4 +[INFO] Found Docker environment with local Unix socket +[INFO] npm warn deprecated domexception@2.0.1: Use your platform's native DOMException instead +[INFO] Parsing 'com.devskiller.auth.GlobalControllerExceptionHandler$VndErrors' +[INFO] BUILD FAILURE +[INFO] Total time: 37.404 s +[ERROR] Failed to execute goal cz.habarta.typescript-generator:typescript-generator-maven-plugin:3.2.1263:generate (Generate boost.d.ts) on project auth: Execution failed: Cannot read the array length because "array" is null -> [Help 1] +[ERROR] +[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch +[ERROR] Re-run Maven using the -X switch to enable verbose output +[ERROR] +[ERROR] For more information about the errors and possible solutions, please read the following articles: +[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException +""" +expected = "[INFO] BUILD FAILURE\n[INFO] Total time: 37.404 s\n[ERROR] Failed to execute goal cz.habarta.typescript-generator:typescript-generator-maven-plugin:3.2.1263:generate (Generate boost.d.ts) on project auth: Execution failed: Cannot read the array length because \"array\" is null -> [Help 1]" diff --git a/src/filters/spring-boot.toml b/src/filters/spring-boot.toml index 5ec03e58c..4c1b7d222 100644 --- a/src/filters/spring-boot.toml +++ b/src/filters/spring-boot.toml @@ -1,6 +1,6 @@ [filters.spring-boot] description = "Compact Spring Boot output — strip banner and verbose startup logs, keep key events" -match_command = "^(mvn\\s+spring-boot:run|java\\s+-jar.*\\.jar|gradle\\s+.*bootRun)" +match_command = "^((\\.?\\/?)mvnw?\\s+spring-boot:run|java\\s+-jar.*\\.jar|(gradle|gradlew|\\./)gradlew?\\s+.*bootRun)" strip_ansi = true keep_lines_matching = [ "Started\\s.*\\sin\\s",