feat(compression): T07/R9 — gradle + dotnet RTK catalog filters (#5537)

Integrated into release/v3.8.42 (round 3). T07/R9 RTK gradle+dotnet filters
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-30 02:08:14 -03:00
committed by GitHub
parent 8946860885
commit a32cfb1597
5 changed files with 150 additions and 0 deletions

View File

@@ -27,6 +27,10 @@
- **compression (caveman):** add a **Chinese (zh / wenyan 文言) input-side rule pack** — the counterpart of the existing output-side `terse-cjk` style. New `rules/zh/{dedup,filler,ultra}.json` collapse repeated context ("如前所述" → "见上。"), drop pleasantries/hedging ("请帮我…/谢谢/我觉得"), strip sentence-final modal particles ("吗/呢/吧"), and abbreviate dense technical terms ("数据库"→"DB", "应用程序"→"app"). Chinese is now auto-detected: `detectCompressionLanguage` distinguishes zh from ja by Han-without-kana (kana is Japanese-exclusive, so a Han-heavy Japanese sentence still resolves to `ja`), and `zh` is listed in `listSupportedCompressionLanguages`. Patterns are ReDoS-safe (bounded literal alternations, no `\b` since CJK has no word boundaries). Regression guard: `tests/unit/caveman-packs-zh-wenyan.test.ts` (packs load + validate + shrink; zh/ja/non-CJK detection). gaps v3.8.42 — T05/C6.
### ✨ New Features
- **compression (RTK):** add **Gradle** and **.NET CLI (`dotnet`)** to the RTK tool-output filter catalog. Tool output for `gradle`/`gradlew` and `dotnet build|test|restore|publish` is now recognized (both by command and by output content) and compressed: Gradle daemon/welcome banners and no-op `> Task … UP-TO-DATE/SKIPPED/FROM-CACHE` lines are dropped while `BUILD SUCCESSFUL/FAILED`, "What went wrong", and stack traces are preserved; the .NET build banner, copyright, and `Determining projects to restore`/`Restored …` chatter are dropped while `Build succeeded/FAILED`, `error CS####`/`warning CS####`, and test summaries are preserved. New builtin filters `engines/rtk/filters/{gradle,dotnet}.json` (with inline tests run by the catalog gate) plus `gradle`/`dotnet` entries in the command detector. Regression guard: `tests/unit/rtk-gradle-dotnet-filters.test.ts`. gaps v3.8.42 — T07/R9.
---
## [3.8.41] — 2026-06-29

View File

@@ -27,6 +27,9 @@ type Detector = {
const COMMAND_PREFIXES = [
"git",
"make",
"gradle",
"gradlew",
"dotnet",
"terraform",
"tofu",
"opentofu",
@@ -114,6 +117,18 @@ const DETECTORS: Detector[] = [
commandPatterns: [/^make\b/i],
contentPatterns: [/^make\[\d+\]: (?:Entering|Leaving) directory/m, /make: \*\*\* /],
},
{
type: "gradle",
category: "build",
commandPatterns: [/^(?:gradle|gradlew|\.\/gradlew)\b/i],
contentPatterns: [/^> Task :/m, /^BUILD (?:SUCCESSFUL|FAILED)\b/m],
},
{
type: "dotnet",
category: "build",
commandPatterns: [/^dotnet\s+(?:build|test|run|restore|publish|pack|msbuild)\b/i, /^dotnet\b/i],
contentPatterns: [/^Build (?:succeeded|FAILED)\b/m, /\b(?:error|warning) CS\d+\b/m],
},
{
type: "terraform-plan",
category: "infra",

View File

@@ -0,0 +1,47 @@
{
"id": "dotnet",
"label": ".NET CLI",
"description": "Strip the .NET build banner and restore chatter; keep build/test status, warnings (CS####), and errors.",
"category": "build",
"priority": 78,
"match": {
"outputTypes": ["dotnet"],
"commands": ["^dotnet\\b"],
"patterns": ["^Build (?:succeeded|FAILED)\\b", "\\b(?:error|warning) CS\\d+\\b"]
},
"rules": {
"stripAnsi": true,
"dropPatterns": [
"^Microsoft \\(R\\)",
"^Copyright \\(C\\) Microsoft",
"Determining projects to restore",
"^\\s*Restored ",
"^\\s*$",
"^Time Elapsed "
],
"collapsePatterns": ["^\\s*Restored "],
"deduplicate": true,
"maxLines": 160,
"headLines": 40,
"tailLines": 60,
"onEmpty": "dotnet: ok"
},
"preserve": {
"errorPatterns": [
"Build FAILED",
"FAILED",
"\\berror CS\\d+\\b",
"\\bwarning CS\\d+\\b",
"Failed!"
],
"summaryPatterns": ["Build succeeded", "Passed!", "Total tests:"]
},
"tests": [
{
"name": "drops build banner + restore chatter, keeps status",
"command": "dotnet build",
"input": "Microsoft (R) Build Engine version 17.8\n Determining projects to restore...\nBuild succeeded.\n",
"expected": "Build succeeded."
}
]
}

View File

@@ -0,0 +1,47 @@
{
"id": "gradle",
"label": "Gradle",
"description": "Strip Gradle daemon/welcome chatter and no-op tasks; keep build status, failures, and warnings.",
"category": "build",
"priority": 78,
"match": {
"outputTypes": ["gradle"],
"commands": ["^(?:gradle|gradlew|\\./gradlew)\\b"],
"patterns": ["^> Task :", "^BUILD (?:SUCCESSFUL|FAILED)\\b"]
},
"rules": {
"stripAnsi": true,
"dropPatterns": [
"^Welcome to Gradle",
"^Starting a Gradle Daemon",
"^> Task :\\S+ (?:UP-TO-DATE|SKIPPED|NO-SOURCE|FROM-CACHE)$",
"^Download https?://",
"^\\s*$"
],
"collapsePatterns": ["^> Task :\\S+$"],
"deduplicate": true,
"maxLines": 160,
"headLines": 40,
"tailLines": 60,
"onEmpty": "gradle: ok"
},
"preserve": {
"errorPatterns": [
"BUILD FAILED",
"FAILED",
"What went wrong",
"Caused by:",
"error:",
"> Task :\\S+ FAILED"
],
"summaryPatterns": ["BUILD SUCCESSFUL", "actionable task"]
},
"tests": [
{
"name": "drops welcome + up-to-date tasks, keeps build status",
"command": "gradle build",
"input": "Welcome to Gradle 8.5!\n> Task :app:compileJava UP-TO-DATE\nBUILD SUCCESSFUL in 3s\n",
"expected": "BUILD SUCCESSFUL in 3s"
}
]
}

View File

@@ -0,0 +1,37 @@
import test from "node:test";
import assert from "node:assert/strict";
import { detectCommandType } from "../../open-sse/services/compression/engines/rtk/commandDetector.ts";
import { matchRtkFilter } from "../../open-sse/services/compression/engines/rtk/filterLoader.ts";
// T07 / R9 — gradle + dotnet RTK catalog filters (the catalog gap behind kubectl, etc.).
const GRADLE_OUTPUT =
"Welcome to Gradle 8.5!\n> Task :app:compileJava UP-TO-DATE\n> Task :app:test\nBUILD SUCCESSFUL in 12s\n";
const DOTNET_OUTPUT =
"Microsoft (R) Build Engine version 17.8\n Determining projects to restore...\n Restored /repo/App.csproj\nBuild succeeded.\n 0 Warning(s)\n";
test("detectCommandType recognizes gradle and dotnet by command", () => {
assert.equal(detectCommandType("", "gradle build").type, "gradle");
assert.equal(detectCommandType("", "./gradlew test").type, "gradle");
assert.equal(detectCommandType("", "dotnet build").type, "dotnet");
assert.equal(detectCommandType("", "dotnet test").type, "dotnet");
});
test("detectCommandType recognizes gradle/dotnet by output content alone", () => {
assert.equal(detectCommandType(GRADLE_OUTPUT).type, "gradle");
assert.equal(detectCommandType(DOTNET_OUTPUT).type, "dotnet");
});
test("matchRtkFilter selects the gradle / dotnet builtin filter", () => {
const cases: Array<[string, string, string]> = [
["gradle", GRADLE_OUTPUT, "gradle build"],
["gradle", GRADLE_OUTPUT, "./gradlew test"],
["dotnet", DOTNET_OUTPUT, "dotnet build"],
["dotnet", DOTNET_OUTPUT, "dotnet test"],
];
for (const [id, output, command] of cases) {
const filter = matchRtkFilter(output, command, { customFiltersEnabled: false });
assert.equal(filter?.id, id, `${command} should match the ${id} filter`);
assert.equal(filter?.category, "build");
}
});