diff --git a/.github/docs-pipeline-contract.md b/.github/docs-pipeline-contract.md new file mode 100644 index 000000000..f812912cd --- /dev/null +++ b/.github/docs-pipeline-contract.md @@ -0,0 +1,57 @@ +# RTK Documentation — Interface Contract + +This directory contains user-facing documentation for the RTK website. +It feeds `rtk-ai/rtk-website` via the `prepare-docs.mjs` pipeline. + +**Scope**: `docs/guide/` is website content only. Technical and contributor documentation +lives in the codebase (distributed, co-located pattern): +- `ARCHITECTURE.md` — System design, ADRs, filtering strategies +- `CONTRIBUTING.md` — Design philosophy, PR process, TOML vs Rust +- `SECURITY.md` — Vulnerability policy +- `src/*/README.md` — Per-module implementation docs +- `hooks/README.md` — Hook system and agent integrations + +## Structure + +``` +docs/ + README.md <- This file (interface contract — do not remove) + guide/ -> User-facing documentation (website "Guide" tab) + index.md + getting-started/ + installation.md + quick-start.md + supported-agents.md + what-rtk-covers.md + analytics/ + gain.md + configuration.md + troubleshooting.md +``` + +## Frontmatter (required on every .md) + +Every markdown file under `docs/guide/` must include: + +```yaml +--- +title: string # Page title (used in sidebar + search) +description: string # One-line summary for search results and SEO +sidebar: + order: number # Position within the sidebar group (1 = first) +--- +``` + +The `prepare-docs.mjs` pipeline validates this at build time and fails fast +if frontmatter is missing or malformed. + +## Conventions + +- **Filenames**: kebab-case, `.md` only +- **Subdirectories**: become sidebar groups in Starlight +- **Internal links**: relative (`./foo.md`, `../configuration.md`) +- **Diagrams**: Mermaid in fenced code blocks +- **Code samples**: always specify the language (`rust`, `toml`, `bash`) +- **Language**: English only +- **No `rtk ` syntax**: users never type `rtk` — hooks rewrite commands transparently. + Only `rtk gain`, `rtk init`, `rtk verify`, and `rtk proxy` appear as user-typed commands. diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f6bf6e54..8772465b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,7 +43,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **security:** default to ask when no permission rule matches ([#886](https://github.com/rtk-ai/rtk/issues/886)) ([158c745](https://github.com/rtk-ai/rtk/commit/158c74527f6591d372e40a78cd604d73a20649a9)) * **security:** default to ask when no permission rule matches ([#886](https://github.com/rtk-ai/rtk/issues/886)) ([41a6c6b](https://github.com/rtk-ai/rtk/commit/41a6c6bf6da78a4754794fdc6a1469df2e327920)) * **tracking:** use std::env::temp_dir() for compatibility (instead of unix tmp) ([e918661](https://github.com/rtk-ai/rtk/commit/e918661440d7b50321f0535032f52c5e87aaf3cb)) - ## [Unreleased] ### Features diff --git a/Cargo.toml b/Cargo.toml index 69beeaa53..a766e9228 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,6 @@ priority = "optional" assets = [ ["target/release/rtk", "usr/bin/", "755"], ] - # cargo-generate-rpm configuration [package.metadata.generate-rpm] assets = [ diff --git a/README.md b/README.md index 24a93f364..78116b252 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@

WebsiteInstall • - Troubleshooting • - Architecture • + Troubleshooting • + ArchitectureDiscord

@@ -313,153 +313,32 @@ RTK supports 10 AI coding tools. Each integration transparently rewrites shell c | Tool | Install | Method | |------|---------|--------| | **Claude Code** | `rtk init -g` | PreToolUse hook (bash) | -| **GitHub Copilot (VS Code)** | `rtk init -g --copilot` | PreToolUse hook (`rtk hook copilot`) — transparent rewrite | +| **GitHub Copilot (VS Code)** | `rtk init -g --copilot` | PreToolUse hook — transparent rewrite | | **GitHub Copilot CLI** | `rtk init -g --copilot` | PreToolUse deny-with-suggestion (CLI limitation) | | **Cursor** | `rtk init -g --agent cursor` | preToolUse hook (hooks.json) | -| **Gemini CLI** | `rtk init -g --gemini` | BeforeTool hook (`rtk hook gemini`) | +| **Gemini CLI** | `rtk init -g --gemini` | BeforeTool hook | | **Codex** | `rtk init -g --codex` | AGENTS.md + RTK.md instructions | | **Windsurf** | `rtk init --agent windsurf` | .windsurfrules (project-scoped) | | **Cline / Roo Code** | `rtk init --agent cline` | .clinerules (project-scoped) | | **OpenCode** | `rtk init -g --opencode` | Plugin TS (tool.execute.before) | | **OpenClaw** | `openclaw plugins install ./openclaw` | Plugin TS (before_tool_call) | -| **Mistral Vibe** | Planned (#800) | Blocked on upstream BeforeToolCallback | +| **Mistral Vibe** | Planned ([#800](https://github.com/rtk-ai/rtk/issues/800)) | Blocked on upstream | -### Claude Code (default) - -```bash -rtk init -g # Install hook + RTK.md -rtk init -g --auto-patch # Non-interactive (CI/CD) -rtk init --show # Verify installation -rtk init -g --uninstall # Remove -``` - -### GitHub Copilot (VS Code + CLI) - -```bash -rtk init -g --copilot # Install hook + instructions -``` - -Creates `.github/hooks/rtk-rewrite.json` (PreToolUse hook) and `.github/copilot-instructions.md` (prompt-level awareness). - -The hook (`rtk hook copilot`) auto-detects the format: -- **VS Code Copilot Chat**: transparent rewrite via `updatedInput` (same as Claude Code) -- **Copilot CLI**: deny-with-suggestion (CLI does not support `updatedInput` yet — see [copilot-cli#2013](https://github.com/github/copilot-cli/issues/2013)) - -### Cursor - -```bash -rtk init -g --agent cursor -``` - -Creates `~/.cursor/hooks/rtk-rewrite.sh` + patches `~/.cursor/hooks.json` with preToolUse matcher. Works with both Cursor editor and `cursor-agent` CLI. - -### Gemini CLI - -```bash -rtk init -g --gemini -rtk init -g --gemini --uninstall -``` - -Creates `~/.gemini/hooks/rtk-hook-gemini.sh` + patches `~/.gemini/settings.json` with BeforeTool hook. - -### Codex (OpenAI) - -```bash -rtk init -g --codex -``` - -Creates `~/.codex/RTK.md` + `~/.codex/AGENTS.md` with `@RTK.md` reference. Codex reads these as global instructions. - -### Windsurf - -```bash -rtk init --agent windsurf -``` - -Creates `.windsurfrules` in the current project. Cascade reads rules and prefixes commands with `rtk`. - -### Cline / Roo Code - -```bash -rtk init --agent cline -``` - -Creates `.clinerules` in the current project. Cline reads rules and prefixes commands with `rtk`. - -### OpenCode - -```bash -rtk init -g --opencode -``` - -Creates `~/.config/opencode/plugins/rtk.ts`. Uses `tool.execute.before` hook. - -### OpenClaw - -```bash -openclaw plugins install ./openclaw -``` - -Plugin in `openclaw/` directory. Uses `before_tool_call` hook, delegates to `rtk rewrite`. - -### Mistral Vibe (planned) - -Blocked on upstream BeforeToolCallback support ([mistral-vibe#531](https://github.com/mistralai/mistral-vibe/issues/531), [PR #533](https://github.com/mistralai/mistral-vibe/pull/533)). Tracked in [#800](https://github.com/rtk-ai/rtk/issues/800). - -### Commands Rewritten - -| Raw Command | Rewritten To | -|-------------|-------------| -| `git status/diff/log/add/commit/push/pull` | `rtk git ...` | -| `gh pr/issue/run` | `rtk gh ...` | -| `cargo test/build/clippy` | `rtk cargo ...` | -| `cat/head/tail ` | `rtk read ` | -| `rg/grep ` | `rtk grep ` | -| `ls` | `rtk ls` | -| `vitest/jest` | `rtk vitest run` | -| `tsc` | `rtk tsc` | -| `eslint/biome` | `rtk lint` | -| `prettier` | `rtk prettier` | -| `playwright` | `rtk playwright` | -| `prisma` | `rtk prisma` | -| `ruff check/format` | `rtk ruff ...` | -| `pytest` | `rtk pytest` | -| `pip list/install` | `rtk pip ...` | -| `go test/build/vet` | `rtk go ...` | -| `golangci-lint` | `rtk golangci-lint` | -| `rake test` / `rails test` | `rtk rake test` | -| `rspec` / `bundle exec rspec` | `rtk rspec` | -| `rubocop` / `bundle exec rubocop` | `rtk rubocop` | -| `bundle install/update` | `rtk bundle ...` | -| `aws sts/ec2/lambda/...` | `rtk aws ...` | -| `docker ps/images/logs` | `rtk docker ...` | -| `kubectl get/logs` | `rtk kubectl ...` | -| `curl` | `rtk curl` | -| `pnpm list/outdated` | `rtk pnpm ...` | - -Commands already using `rtk`, heredocs (`<<`), and unrecognized commands pass through unchanged. +For per-agent setup details, override controls, and graceful degradation, see the [Supported Agents guide](https://www.rtk-ai.app/guide/getting-started/supported-agents). ## Configuration -### Config File - `~/.config/rtk/config.toml` (macOS: `~/Library/Application Support/rtk/config.toml`): ```toml -[tracking] -database_path = "/path/to/custom.db" # default: ~/.local/share/rtk/history.db - [hooks] exclude_commands = ["curl", "playwright"] # skip rewrite for these [tee] enabled = true # save raw output on failure (default: true) mode = "failures" # "failures", "always", or "never" -max_files = 20 # rotation limit ``` -### Tee: Full Output Recovery - When a command fails, RTK saves the full unfiltered output so the LLM can read it without re-executing: ``` @@ -467,6 +346,8 @@ FAILED: 2/15 tests [full output: ~/.local/share/rtk/tee/1707753600_cargo_test.log] ``` +For the full config reference (all sections, env vars, per-project filters), see the [Configuration guide](https://www.rtk-ai.app/guide/getting-started/configuration). + ### Uninstall ```bash @@ -477,11 +358,11 @@ brew uninstall rtk # If installed via Homebrew ## Documentation -- **[TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md)** - Fix common issues -- **[INSTALL.md](INSTALL.md)** - Detailed installation guide -- **[ARCHITECTURE.md](docs/contributing/ARCHITECTURE.md)** - Technical architecture -- **[SECURITY.md](SECURITY.md)** - Security policy and PR review process -- **[AUDIT_GUIDE.md](docs/AUDIT_GUIDE.md)** - Token savings analytics guide +- **[rtk-ai.app/guide](https://www.rtk-ai.app/guide)** — full user guide (installation, supported agents, what gets optimized, analytics, configuration, troubleshooting) +- **[INSTALL.md](INSTALL.md)** — detailed installation reference +- **[ARCHITECTURE.md](ARCHITECTURE.md)** — system design and technical decisions +- **[CONTRIBUTING.md](CONTRIBUTING.md)** — contribution guide +- **[SECURITY.md](SECURITY.md)** — security policy ## Privacy & Telemetry @@ -505,6 +386,26 @@ export RTK_TELEMETRY_DISABLED=1 enabled = false ``` +## Star History + + + + + + Star History Chart + + + +## StarMapper + + + + + + StarMapper + + + ## Contributing Contributions welcome! Please open an issue or PR on [GitHub](https://github.com/rtk-ai/rtk). diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md deleted file mode 100644 index cf52f026d..000000000 --- a/docs/TROUBLESHOOTING.md +++ /dev/null @@ -1,337 +0,0 @@ -# RTK Troubleshooting Guide - -## Problem: "rtk gain" command not found - -### Symptom -```bash -$ rtk --version -rtk 1.0.0 # (or similar) - -$ rtk gain -rtk: 'gain' is not a rtk command. See 'rtk --help'. -``` - -### Root Cause -You installed the **wrong rtk package**. You have **Rust Type Kit** (reachingforthejack/rtk) instead of **Rust Token Killer** (rtk-ai/rtk). - -### Solution - -**1. Uninstall the wrong package:** -```bash -cargo uninstall rtk -``` - -**2. Install the correct one (Token Killer):** - -#### Quick Install (Linux/macOS) -```bash -curl -fsSL https://github.com/rtk-ai/rtk/blob/master/install.sh | sh -``` - -#### Alternative: Manual Installation -```bash -cargo install --git https://github.com/rtk-ai/rtk -``` - -**3. Verify installation:** -```bash -rtk --version -rtk gain # MUST show token savings stats, not error -``` - -If `rtk gain` now works, installation is correct. - ---- - -## Problem: Confusion Between Two "rtk" Projects - -### The Two Projects - -| Project | Repository | Purpose | Key Command | -|---------|-----------|---------|-------------| -| **Rust Token Killer** ✅ | rtk-ai/rtk | LLM token optimizer for Claude Code | `rtk gain` | -| **Rust Type Kit** ❌ | reachingforthejack/rtk | Rust codebase query and type generator | `rtk query` | - -### How to Identify Which One You Have - -```bash -# Check if "gain" command exists -rtk gain - -# Token Killer → Shows token savings stats -# Type Kit → Error: "gain is not a rtk command" -``` - ---- - -## Problem: cargo install rtk installs wrong package - -### Why This Happens -If **Rust Type Kit** is published to crates.io under the name `rtk`, running `cargo install rtk` will install the wrong package. - -### Solution -**NEVER use** `cargo install rtk` without verifying. - -**Always use explicit repository URLs:** - -```bash -# CORRECT - Token Killer -cargo install --git https://github.com/rtk-ai/rtk - -# OR install from fork -git clone https://github.com/rtk-ai/rtk.git -cd rtk && git checkout feat/all-features -cargo install --path . --force -``` - -**After any installation, ALWAYS verify:** -```bash -rtk gain # Must work if you want Token Killer -``` - ---- - -## Problem: RTK not working in Claude Code - -### Symptom -Claude Code doesn't seem to be using rtk, outputs are verbose. - -### Checklist - -**1. Verify rtk is installed and correct:** -```bash -rtk --version -rtk gain # Must show stats -``` - -**2. Initialize rtk for Claude Code:** -```bash -# Global (all projects) -rtk init --global - -# Per-project -cd /your/project -rtk init -``` - -**3. Verify CLAUDE.md file exists:** -```bash -# Check global -cat ~/.claude/CLAUDE.md | grep rtk - -# Check project -cat ./CLAUDE.md | grep rtk -``` - -**4. Install auto-rewrite hook (recommended for automatic RTK usage):** - -**Option A: Automatic (recommended)** -```bash -rtk init -g -# → Installs hook + RTK.md automatically -# → Follow printed instructions to add hook to ~/.claude/settings.json -# → Restart Claude Code - -# Verify installation -rtk init --show # Should show "✅ Hook: executable, with guards" -``` - -**Option B: Manual (fallback)** -```bash -# Copy hook to Claude Code hooks directory -mkdir -p ~/.claude/hooks -cp .claude/hooks/rtk-rewrite.sh ~/.claude/hooks/ -chmod +x ~/.claude/hooks/rtk-rewrite.sh -``` - -Then add to `~/.claude/settings.json` (replace `~` with full path): -```json -{ - "hooks": { - "PreToolUse": [ - { - "matcher": "Bash", - "hooks": [ - { - "type": "command", - "command": "/Users/yourname/.claude/hooks/rtk-rewrite.sh" - } - ] - } - ] - } -} -``` - -**Note**: Use absolute path in `settings.json`, not `~/.claude/...` - ---- - -## Problem: RTK not working in OpenCode - -### Symptom -OpenCode runs commands without rtk, outputs are verbose. - -### Checklist - -**1. Verify rtk is installed and correct:** -```bash -rtk --version -rtk gain # Must show stats -``` - -**2. Install the OpenCode plugin (global only):** -```bash -rtk init -g --opencode -``` - -**3. Verify plugin file exists:** -```bash -ls -la ~/.config/opencode/plugins/rtk.ts -``` - -**4. Restart OpenCode** -OpenCode must be restarted to load the plugin. - -**5. Verify status:** -```bash -rtk init --show # Should show "OpenCode: plugin installed" -``` - ---- - -## Problem: RTK commands fail on Windows ("program not found" or "No such file") - -### Symptom -``` -rtk vitest --run -# Error: program not found -# Or: The system cannot find the file specified - -rtk lint . -# Error: No such file or directory -``` - -### Root Cause -On Windows, Node.js tools (vitest, eslint, tsc, etc.) are installed as `.CMD` or `.BAT` wrapper scripts, not as native `.exe` binaries. Rust's `std::process::Command::new("vitest")` does not honor the Windows `PATHEXT` environment variable, so it cannot find `vitest.CMD` even when it's on PATH. - -### Solution -Update to rtk v0.23.1+ which resolves this via the `which` crate for proper PATH+PATHEXT resolution. All 16+ command modules now use `resolved_command()` instead of `Command::new()`. - -```bash -cargo install --git https://github.com/rtk-ai/rtk -rtk --version # Should be 0.23.1+ -``` - -### Affected Commands -All commands that spawn external tools: `rtk vitest`, `rtk lint`, `rtk tsc`, `rtk pnpm`, `rtk playwright`, `rtk prisma`, `rtk next`, `rtk prettier`, `rtk ruff`, `rtk pytest`, `rtk pip`, `rtk mypy`, `rtk golangci-lint`, and others. - ---- - -## Problem: "command not found: rtk" after installation - -### Symptom -```bash -$ cargo install --path . --force - Compiling rtk v0.7.1 - Finished release [optimized] target(s) - Installing ~/.cargo/bin/rtk - -$ rtk --version -zsh: command not found: rtk -``` - -### Root Cause -`~/.cargo/bin` is not in your PATH. - -### Solution - -**1. Check if cargo bin is in PATH:** -```bash -echo $PATH | grep -o '[^:]*\.cargo[^:]*' -``` - -**2. If not found, add to PATH:** - -For **bash** (`~/.bashrc`): -```bash -export PATH="$HOME/.cargo/bin:$PATH" -``` - -For **zsh** (`~/.zshrc`): -```bash -export PATH="$HOME/.cargo/bin:$PATH" -``` - -For **fish** (`~/.config/fish/config.fish`): -```fish -set -gx PATH $HOME/.cargo/bin $PATH -``` - -**3. Reload shell config:** -```bash -source ~/.bashrc # or ~/.zshrc or restart terminal -``` - -**4. Verify:** -```bash -which rtk -rtk --version -rtk gain -``` - ---- - -## Problem: Compilation errors during installation - -### Symptom -```bash -$ cargo install --path . -error: failed to compile rtk v0.7.1 -``` - -### Solutions - -**1. Update Rust toolchain:** -```bash -rustup update stable -rustup default stable -``` - -**2. Clean and rebuild:** -```bash -cargo clean -cargo build --release -cargo install --path . --force -``` - -**3. Check Rust version (minimum required):** -```bash -rustc --version # Should be 1.70+ for most features -``` - -**4. If still fails, report issue:** -- GitHub: https://github.com/rtk-ai/rtk/issues - ---- - -## Need More Help? - -**Report issues:** -- Fork-specific: https://github.com/rtk-ai/rtk/issues -- Upstream: https://github.com/rtk-ai/rtk/issues - -**Run the diagnostic script:** -```bash -# From the rtk repository root -bash scripts/check-installation.sh -``` - -This script will check: -- ✅ RTK installed and in PATH -- ✅ Correct version (Token Killer, not Type Kit) -- ✅ Available features (pnpm, vitest, next, etc.) -- ✅ Claude Code integration (CLAUDE.md files) -- ✅ Auto-rewrite hook status - -The script provides specific fix commands for any issues found. diff --git a/docs/guide/analytics/discover.md b/docs/guide/analytics/discover.md new file mode 100644 index 000000000..77d21cc65 --- /dev/null +++ b/docs/guide/analytics/discover.md @@ -0,0 +1,58 @@ +--- +title: Discover and Session +description: Find missed savings opportunities with rtk discover, and track RTK adoption with rtk session +sidebar: + order: 2 +--- + +# Discover and Session + +## rtk discover — find missed savings + +`rtk discover` analyzes your Claude Code command history to identify commands that ran without RTK filtering and calculates how many tokens you lost. + +```bash +rtk discover # analyze current project history +rtk discover --all # all projects +rtk discover --all --since 7 # last 7 days, all projects +``` + +**Example output:** + +``` +Missed savings analysis (last 7 days) +──────────────────────────────────── +Command Count Est. lost +cargo test 12 ~48,000 tokens +git log 8 ~12,000 tokens +pnpm list 3 ~6,000 tokens +──────────────────────────────────── +Total missed: 23 ~66,000 tokens + +Run `rtk init --global` to capture these automatically. +``` + +If commands appear in the missed list after installing RTK, it usually means the hook isn't active for that agent. See [Troubleshooting](../troubleshooting.md) — "Agent not using RTK". + +## rtk session — adoption tracking + +`rtk session` shows RTK adoption across recent Claude Code sessions: how many shell commands ran through RTK vs. raw. + +```bash +rtk session +``` + +**Example output:** + +``` +Recent sessions (last 10) +───────────────────────────────────────────────────── +Session Total RTK Coverage +2026-04-06 14:32 (45 cmds) 45 43 95.6% +2026-04-05 09:14 (38 cmds) 38 38 100.0% +2026-04-04 16:50 (52 cmds) 52 49 94.2% +───────────────────────────────────────────────────── +Average coverage: 96.6% +``` + +Low coverage on a session usually means RTK was disabled (`RTK_DISABLED=1`) or the hook wasn't active for a specific subagent. diff --git a/docs/guide/analytics/gain.md b/docs/guide/analytics/gain.md new file mode 100644 index 000000000..db2249d4b --- /dev/null +++ b/docs/guide/analytics/gain.md @@ -0,0 +1,196 @@ +--- +title: Token Savings Analytics +description: Measure and analyze your RTK token savings with rtk gain +sidebar: + order: 1 +--- + +# Token Savings Analytics + +`rtk gain` shows how many tokens RTK has saved across all your commands, with daily, weekly, and monthly breakdowns. + +## Quick reference + +```bash +# Default summary +rtk gain + +# Temporal breakdowns +rtk gain --daily # all days since tracking started +rtk gain --weekly # aggregated by week +rtk gain --monthly # aggregated by month +rtk gain --all # all breakdowns at once + +# Classic flags +rtk gain --graph # ASCII graph, last 30 days +rtk gain --history # last 10 commands +rtk gain --quota -t pro # quota analysis (pro/5x/20x tiers) + +# Export +rtk gain --all --format json > savings.json +rtk gain --all --format csv > savings.csv +``` + +## Daily breakdown + +```bash +rtk gain --daily +``` + +``` +📅 Daily Breakdown (3 days) +════════════════════════════════════════════════════════════════ +Date Cmds Input Output Saved Save% +──────────────────────────────────────────────────────────────── +2026-01-28 89 380.9K 26.7K 355.8K 93.4% +2026-01-29 102 894.5K 32.4K 863.7K 96.6% +2026-01-30 5 749 55 694 92.7% +──────────────────────────────────────────────────────────────── +TOTAL 196 1.3M 59.2K 1.2M 95.6% +``` + +- **Cmds**: RTK commands executed +- **Input**: Estimated tokens from raw command output +- **Output**: Actual tokens after filtering +- **Saved**: Input - Output (tokens that never reached the LLM) +- **Save%**: Saved / Input × 100 + +## Weekly and monthly breakdowns + +```bash +rtk gain --weekly +rtk gain --monthly +``` + +Same columns as daily, aggregated by Sunday-Saturday week or calendar month. + +## Export formats + +| Format | Flag | Use case | +|--------|------|----------| +| `text` | default | Terminal display | +| `json` | `--format json` | Programmatic analysis, dashboards | +| `csv` | `--format csv` | Excel, Python/R, Google Sheets | + +**JSON structure:** +```json +{ + "summary": { + "total_commands": 196, + "total_input": 1276098, + "total_output": 59244, + "total_saved": 1220217, + "avg_savings_pct": 95.62 + }, + "daily": [...], + "weekly": [...], + "monthly": [...] +} +``` + +## Typical savings by command + +| Command | Typical savings | Mechanism | +|---------|----------------|-----------| +| `git status` | 77-93% | Compact stat format | +| `eslint` | 84% | Group by rule | +| `vitest run` | 94-99% | Show failures only | +| `find` | 75% | Tree format | +| `pnpm list` | 70-90% | Compact dependencies | +| `grep` | 70% | Truncate + group | + +## How token estimation works + +RTK estimates tokens using `text.len() / 4` (4 characters per token average). This is accurate to ±10% compared to actual LLM tokenization — sufficient for trend analysis. + +``` +Input Tokens = estimate_tokens(raw_command_output) +Output Tokens = estimate_tokens(rtk_filtered_output) +Saved Tokens = Input - Output +Savings % = (Saved / Input) × 100 +``` + +## Database + +Savings data is stored locally in SQLite: + +- **Location**: `~/.local/share/rtk/history.db` (Linux / macOS) +- **Retention**: 90 days (automatic cleanup) +- **Scope**: Global across all projects and Claude sessions + +```bash +# Inspect raw data +sqlite3 ~/.local/share/rtk/history.db \ + "SELECT timestamp, rtk_cmd, saved_tokens FROM commands + ORDER BY timestamp DESC LIMIT 10" + +# Backup +cp ~/.local/share/rtk/history.db ~/backups/rtk-history-$(date +%Y%m%d).db + +# Reset +rm ~/.local/share/rtk/history.db # recreated on next command +``` + +## Analysis workflows + +```bash +# Weekly progress: generate a CSV report every Monday +rtk gain --weekly --format csv > reports/week-$(date +%Y-%W).csv + +# Monthly budget review +rtk gain --monthly --format json | jq '.monthly[] | + {month, saved_tokens, quota_pct: (.saved_tokens / 6000000 * 100)}' + +# Cron: daily JSON snapshot for a dashboard +0 0 * * * rtk gain --all --format json > /var/www/dashboard/rtk-stats.json +``` + +**Python/pandas:** +```python +import pandas as pd +import subprocess + +result = subprocess.run(['rtk', 'gain', '--all', '--format', 'csv'], + capture_output=True, text=True) +lines = result.stdout.split('\n') +daily_start = lines.index('# Daily Data') + 2 +daily_end = lines.index('', daily_start) +daily_df = pd.read_csv(pd.StringIO('\n'.join(lines[daily_start:daily_end]))) +daily_df['date'] = pd.to_datetime(daily_df['date']) +daily_df.plot(x='date', y='savings_pct', kind='line') +``` + +**GitHub Actions (weekly stats):** +```yaml +on: + schedule: + - cron: '0 0 * * 1' +jobs: + stats: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: cargo install rtk + - run: rtk gain --weekly --format json > stats/week-$(date +%Y-%W).json + - run: git add stats/ && git commit -m "Weekly rtk stats" && git push +``` + +## Troubleshooting + +**No data showing:** +```bash +ls -lh ~/.local/share/rtk/history.db +sqlite3 ~/.local/share/rtk/history.db "SELECT COUNT(*) FROM commands" +git status # run any tracked command to generate data +``` + +**Incorrect statistics:** Token estimation is a heuristic. For precise counts, use `tiktoken`: +```bash +pip install tiktoken +git status > output.txt +python -c " +import tiktoken +enc = tiktoken.get_encoding('cl100k_base') +print(len(enc.encode(open('output.txt').read())), 'actual tokens') +" +``` diff --git a/docs/guide/getting-started/configuration.md b/docs/guide/getting-started/configuration.md new file mode 100644 index 000000000..f2b1d5a2e --- /dev/null +++ b/docs/guide/getting-started/configuration.md @@ -0,0 +1,115 @@ +--- +title: Configuration +description: Customize RTK behavior via config.toml, environment variables, and per-project filters +sidebar: + order: 4 +--- + +# Configuration + +## Config file location + +| Platform | Path | +|----------|------| +| Linux | `~/.config/rtk/config.toml` | +| macOS | `~/Library/Application Support/rtk/config.toml` | + +```bash +rtk config # show current configuration +rtk config --create # create config file with defaults +``` + +## Full config structure + +```toml +[tracking] +enabled = true # enable/disable token tracking +history_days = 90 # retention in days (auto-cleanup) +database_path = "/custom/path/tracking.db" # optional override + +[display] +colors = true # colored output +emoji = true # use emojis in output +max_width = 120 # maximum output width + +[filters] +ignore_dirs = [".git", "node_modules", "target", "__pycache__", ".venv", "vendor"] +ignore_files = ["*.lock", "*.min.js", "*.min.css"] + +[tee] +enabled = true # save raw output on failure +mode = "failures" # "failures" (default), "always", "never" +max_files = 20 # rotation: keep last N files +# directory = "/custom/tee/path" # optional override + +[telemetry] +enabled = true # anonymous daily ping (opt-out below) + +[hooks] +exclude_commands = [] # commands to never auto-rewrite +``` + +## Environment variables + +| Variable | Description | +|----------|-------------| +| `RTK_DISABLED=1` | Disable RTK for a single command (`RTK_DISABLED=1 git status`) | +| `RTK_TEE_DIR` | Override the tee directory | +| `RTK_TELEMETRY_DISABLED=1` | Disable telemetry | +| `RTK_HOOK_AUDIT=1` | Enable hook audit logging | +| `SKIP_ENV_VALIDATION=1` | Skip env validation (useful with Next.js) | + +## Tee system + +When a command fails, RTK saves the full raw output to a local file and prints the path: + +``` +FAILED: 2/15 tests +[full output: ~/.local/share/rtk/tee/1707753600_cargo_test.log] +``` + +Your AI assistant can then read the file if it needs more detail, without re-running the command. + +| Setting | Default | Description | +|---------|---------|-------------| +| `tee.enabled` | `true` | Enable/disable | +| `tee.mode` | `"failures"` | `"failures"`, `"always"`, `"never"` | +| `tee.max_files` | `20` | Rotation: keep last N files | +| Min size | 500 bytes | Outputs shorter than this are not saved | +| Max file size | 1 MB | Truncated above this | + +## Excluding commands from auto-rewrite + +Prevent specific commands from being rewritten by the hook: + +```toml +[hooks] +exclude_commands = ["git rebase", "git cherry-pick", "docker exec"] +``` + +Or for a single invocation: + +```bash +RTK_DISABLED=1 git rebase main +``` + +## Telemetry + +RTK sends one anonymous ping per day (23h interval). No personal data, no file paths, no command content. + +Data sent: device hash, version, OS, architecture, command count/24h, top commands, savings %. + +To opt out: + +```bash +# Via environment variable +export RTK_TELEMETRY_DISABLED=1 + +# Via config.toml +[telemetry] +enabled = false +``` + +## Per-project filters + +Create `.rtk/filters.toml` in your project root to add custom filters or override built-ins. See [`src/filters/README.md`](https://github.com/rtk-ai/rtk/blob/master/src/filters/README.md) for the full TOML DSL reference. diff --git a/docs/guide/getting-started/installation.md b/docs/guide/getting-started/installation.md new file mode 100644 index 000000000..3f3eac286 --- /dev/null +++ b/docs/guide/getting-started/installation.md @@ -0,0 +1,81 @@ +--- +title: Installation +description: Install RTK via curl, Homebrew, Cargo, or from source, and verify the correct version +sidebar: + order: 1 +--- + +# Installation + +## Name collision warning + +Two unrelated projects share the name `rtk`. Make sure you install the right one: + +- **Rust Token Killer** (`rtk-ai/rtk`) — this project, a token-saving CLI proxy +- **Rust Type Kit** (`reachingforthejack/rtk`) — a different tool for generating Rust types + +The easiest way to verify you have the correct one: run `rtk gain`. It should display token savings stats. If it returns "command not found", you either have the wrong package or RTK is not installed. + +## Check before installing + +```bash +rtk --version # should print: rtk x.y.z +rtk gain # should show token savings stats +``` + +If both commands work, RTK is already installed. Skip to [Project initialization](#project-initialization). + +## Quick install (Linux and macOS) + +```bash +curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/master/install.sh | sh +``` + +## Homebrew (macOS and Linux) + +```bash +brew install rtk-ai/tap/rtk +``` + +## Cargo + +```bash +cargo install rtk +``` + +## Verify installation + +```bash +rtk --version # rtk x.y.z +rtk gain # token savings dashboard +``` + +If `rtk gain` fails but `rtk --version` succeeds, you installed Rust Type Kit by mistake. Uninstall it first: + +```bash +cargo uninstall rtk +``` + +Then reinstall using one of the methods above. + +## Project initialization + +Run once per project to enable the Claude Code hook: + +```bash +rtk init +``` + +For a global install that patches `settings.json` automatically: + +```bash +rtk init --global +``` + +## Uninstall + +```bash +rtk init -g --uninstall # remove hook, RTK.md, and settings.json entry +cargo uninstall rtk # remove binary (if installed via Cargo) +brew uninstall rtk # remove binary (if installed via Homebrew) +``` diff --git a/docs/guide/getting-started/quick-start.md b/docs/guide/getting-started/quick-start.md new file mode 100644 index 000000000..af661ebff --- /dev/null +++ b/docs/guide/getting-started/quick-start.md @@ -0,0 +1,70 @@ +--- +title: Quick Start +description: Get RTK running in 5 minutes and see your first token savings +sidebar: + order: 2 +--- + +# Quick Start + +This guide walks you through your first RTK commands after installation. + +## Prerequisites + +RTK is installed and verified: + +```bash +rtk --version # rtk x.y.z +rtk gain # shows token savings dashboard +``` + +If not, see [Installation](./installation.md). + +## Step 1: Initialize for your AI assistant + +```bash +# For Claude Code (global — applies to all projects) +rtk init --global + +# For a single project only +cd /your/project && rtk init +``` + +This installs the hook that automatically rewrites commands. Restart your AI assistant after this step. + +## Step 2: Use your tools normally + +Once the hook is installed, nothing changes in how you work. Your AI assistant runs commands as usual — the hook intercepts them transparently and rewrites them before execution. + +For example, when Claude Code runs `cargo test`, the hook rewrites it to `rtk cargo test` before it executes. The LLM receives filtered output with only the failures — not 500 lines of passing tests. You never see or type `rtk`. + +Supported ecosystems: Git, Cargo/Rust, JavaScript (vitest, tsc, eslint, pnpm, Next.js, Prisma), Python, Go, Ruby, .NET, Docker/Kubernetes, GitHub CLI, and more. See [What RTK Optimizes](../what-rtk-covers.md) for the full list. + +## Step 3: Check your savings + +After a few commands, see how much was saved: + +```bash +rtk gain +``` + +``` +Total commands : 12 +Input tokens : 45,230 +Output tokens : 4,890 +Saved : 40,340 (89.2%) +``` + +## Step 4: Unsupported commands + +Commands RTK doesn't recognize run through passthrough — output is unchanged, usage is tracked: + +```bash +rtk proxy make install +``` + +## Next steps + +- [What RTK Optimizes](../what-rtk-covers.md) — all supported commands and savings by ecosystem +- [Supported agents](./supported-agents.md) — Claude Code, Cursor, Copilot, and more +- [Configuration](./configuration.md) — customize RTK behavior diff --git a/docs/guide/getting-started/supported-agents.md b/docs/guide/getting-started/supported-agents.md new file mode 100644 index 000000000..dc45bf970 --- /dev/null +++ b/docs/guide/getting-started/supported-agents.md @@ -0,0 +1,147 @@ +--- +title: Supported Agents +description: How to integrate RTK with Claude Code, Cursor, Copilot, Cline, Windsurf, Codex, and OpenCode +sidebar: + order: 3 +--- + +# Supported Agents + +RTK supports 10 AI coding agents across 3 integration tiers. Mistral Vibe support is planned. + +## How it works + +Each agent integration intercepts CLI commands before execution and rewrites them to their RTK equivalent. The agent runs `rtk cargo test` instead of `cargo test`, sees filtered output, and uses up to 90% fewer tokens — without any change to your workflow. + +All rewrite logic lives in the RTK binary (`rtk rewrite`). Agent hooks are thin delegates that parse the agent-specific JSON format and call `rtk rewrite` for the actual decision. + +``` +Agent runs "cargo test" + -> Hook intercepts (PreToolUse / plugin event) + -> Calls rtk rewrite "cargo test" + -> Returns "rtk cargo test" + -> Agent executes filtered command + -> LLM sees 90% fewer tokens +``` + +## Supported agents + +| Agent | Integration tier | Can rewrite transparently? | +|-------|-----------------|---------------------------| +| Claude Code | Shell hook (`PreToolUse`) | Yes | +| VS Code Copilot Chat | Shell hook (`PreToolUse`) | Yes | +| GitHub Copilot CLI | Shell hook (deny-with-suggestion) | No (agent retries) | +| Cursor | Shell hook (`preToolUse`) | Yes | +| Gemini CLI | Rust binary (`BeforeTool`) | Yes | +| OpenCode | TypeScript plugin (`tool.execute.before`) | Yes | +| OpenClaw | TypeScript plugin (`before_tool_call`) | Yes | +| Cline / Roo Code | Rules file (prompt-level) | N/A | +| Windsurf | Rules file (prompt-level) | N/A | +| Codex CLI | AGENTS.md instructions | N/A | +| Mistral Vibe | Planned ([#800](https://github.com/rtk-ai/rtk/issues/800)) | Pending upstream | + +## Installation by agent + +### Claude Code + +```bash +rtk init --global # installs hook + patches settings.json +``` + +Restart Claude Code. Verify: + +```bash +rtk init --show # shows hook status +``` + +### Cursor + +```bash +rtk init --global --cursor +``` + +Restart Cursor. The hook uses `preToolUse` with Cursor's `updated_input` format. + +### VS Code Copilot Chat + +```bash +rtk init --global --copilot +``` + +### Gemini CLI + +```bash +rtk init --global --gemini +``` + +### OpenCode + +```bash +rtk init --global --opencode +``` + +Creates `~/.config/opencode/plugins/rtk.ts`. Uses the `tool.execute.before` hook. + +### OpenClaw + +```bash +openclaw plugins install ./openclaw +``` + +Plugin in the `openclaw/` directory. Uses the `before_tool_call` hook, delegates to `rtk rewrite`. + +### Cline / Roo Code + +```bash +rtk init --cline # creates .clinerules in current project +``` + +Cline reads `.clinerules` as custom instructions. RTK adds guidance telling Cline to prefer `rtk ` over raw commands. + +### Windsurf + +```bash +rtk init --windsurf # creates .windsurfrules in current project +``` + +### Codex CLI + +```bash +rtk init --codex # creates AGENTS.md or patches existing one +``` + +### Mistral Vibe (planned) + +Support is blocked on upstream `BeforeToolCallback` ([mistral-vibe#531](https://github.com/mistralai/mistral-vibe/issues/531)). Tracked in [#800](https://github.com/rtk-ai/rtk/issues/800). + +## Integration tiers explained + +| Tier | Mechanism | How rewrites work | +|------|-----------|------------------| +| **Full hook** | Shell script or Rust binary, intercepts via agent API | Transparent — agent never sees the raw command | +| **Plugin** | TypeScript/JS in agent's plugin system | Transparent — in-place mutation | +| **Rules file** | Prompt-level instructions | Guidance only — agent is told to prefer `rtk ` | + +Rules file integrations (Cline, Windsurf, Codex) rely on the model following instructions. Full hook integrations (Claude Code, Cursor, Gemini) are guaranteed — the command is rewritten before the agent sees it. + +## Graceful degradation + +Hooks never block command execution. If RTK is missing, the hook exits cleanly and the raw command runs unchanged: + +- RTK binary not found: warning to stderr, exit 0 +- Invalid JSON input: pass through unchanged +- RTK version too old: warning to stderr, exit 0 +- Filter logic error: fallback to raw command output + +## Override: disable RTK for one command + +```bash +RTK_DISABLED=1 git status # runs raw git status, no rewrite +``` + +Or exclude commands permanently in `~/.config/rtk/config.toml`: + +```toml +[hooks] +exclude_commands = ["git rebase", "git cherry-pick"] +``` diff --git a/docs/guide/index.md b/docs/guide/index.md new file mode 100644 index 000000000..2b9a09b47 --- /dev/null +++ b/docs/guide/index.md @@ -0,0 +1,55 @@ +--- +title: RTK Documentation +description: RTK (Rust Token Killer) — reduce LLM token consumption by 60-90% on common dev commands, with zero workflow changes +sidebar: + order: 1 +--- + +# RTK — Rust Token Killer + +RTK is a CLI proxy that sits between your AI assistant and your development tools. It filters command output before it reaches the LLM, keeping only what matters and discarding boilerplate, progress bars, and noise. + +**Result:** 60-90% fewer tokens consumed per command, without changing how you work. You run `git status` as usual — RTK's hook intercepts it, filters the output, and the LLM sees a compact 3-line summary instead of 40 lines. + +## How it works + +``` +Your AI assistant runs: git status + ↓ + Hook intercepts (PreToolUse) + ↓ + rtk git status (transparent rewrite) + ↓ + Raw output: 40 lines → Filtered: 3 lines + ~800 tokens → ~60 tokens (92% saved) + ↓ + LLM sees the compact output +``` + +Zero config changes to your workflow. The hook handles everything automatically. + +## What RTK optimizes + +60+ commands across 9 ecosystems — Git, Cargo/Rust, JavaScript, Python, Go, Ruby, .NET, Docker/Kubernetes, and more. See [What RTK Optimizes](./what-rtk-covers.md) for the full list with savings percentages. + +## Get started + +1. **[Installation](./getting-started/installation.md)** — Install RTK and verify you have the right package +2. **[Quick Start](./getting-started/quick-start.md)** — Connect to your AI assistant in 5 minutes +3. **[Supported Agents](./getting-started/supported-agents.md)** — Claude Code, Cursor, Copilot, Gemini, and 7 more + +## Measure your savings + +```bash +rtk gain # total savings across all sessions +rtk gain --daily # day-by-day breakdown +rtk gain --weekly # weekly aggregation +``` + +See [Analytics](./analytics/gain.md) for export formats and analysis workflows. + +## Further reading + +- [Configuration](./getting-started/configuration.md) — config.toml, global flags, env vars, tee recovery +- [Troubleshooting](./troubleshooting.md) — common issues and fixes +- [ARCHITECTURE.md](https://github.com/rtk-ai/rtk/blob/master/ARCHITECTURE.md) — system design for contributors diff --git a/docs/guide/troubleshooting.md b/docs/guide/troubleshooting.md new file mode 100644 index 000000000..5efcabd9b --- /dev/null +++ b/docs/guide/troubleshooting.md @@ -0,0 +1,156 @@ +--- +title: Troubleshooting +description: Common RTK issues and how to fix them +sidebar: + order: 8 +--- + +# Troubleshooting + +## `rtk gain` says "not a rtk command" + +**Symptom:** +```bash +$ rtk gain +rtk: 'gain' is not a rtk command. See 'rtk --help'. +``` + +**Cause:** You installed **Rust Type Kit** (`reachingforthejack/rtk`) instead of **Rust Token Killer** (`rtk-ai/rtk`). They share the same binary name. + +**Fix:** +```bash +cargo uninstall rtk +curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/master/install.sh | sh +rtk gain # should now show token savings stats +``` + +## How to tell which rtk you have + +| If `rtk gain`... | You have | +|------------------|----------| +| Shows token savings dashboard | Rust Token Killer ✅ | +| Returns "not a rtk command" | Rust Type Kit ❌ | + +## AI assistant not using RTK + +**Symptom:** Claude Code (or another agent) runs `cargo test` instead of `rtk cargo test`. + +**Checklist:** + +1. Verify RTK is installed: + ```bash + rtk --version + rtk gain + ``` + +2. Initialize the hook: + ```bash + rtk init --global # Claude Code + rtk init --global --cursor # Cursor + rtk init --global --opencode # OpenCode + ``` + +3. Restart your AI assistant. + +4. Verify hook status: + ```bash + rtk init --show + ``` + +5. Check `settings.json` has the hook registered (Claude Code): + ```bash + cat ~/.claude/settings.json | grep rtk + ``` + +## RTK not found after `cargo install` + +**Symptom:** +```bash +$ rtk --version +zsh: command not found: rtk +``` + +**Cause:** `~/.cargo/bin` is not in your PATH. + +**Fix:** + +For bash (`~/.bashrc`) or zsh (`~/.zshrc`): +```bash +export PATH="$HOME/.cargo/bin:$PATH" +``` + +For fish (`~/.config/fish/config.fish`): +```fish +set -gx PATH $HOME/.cargo/bin $PATH +``` + +Then reload: +```bash +source ~/.zshrc # or ~/.bashrc +rtk --version +``` + +## RTK not working on Windows + +**Symptom:** +``` +rtk vitest --run +Error: program not found +``` + +**Cause:** On Windows, Node.js tools are installed as `.CMD`/`.BAT` wrappers. Older RTK versions couldn't find them. + +**Fix:** Update to RTK v0.23.1+: +```bash +cargo install --git https://github.com/rtk-ai/rtk +rtk --version # should be 0.23.1+ +``` + +## Compilation error during installation + +```bash +rustup update stable +rustup default stable +cargo clean +cargo build --release +cargo install --path . --force +``` + +Minimum required Rust version: 1.70+. + +## OpenCode not using RTK + +```bash +rtk init --global --opencode +# restart OpenCode +rtk init --show # should show "OpenCode: plugin installed" +``` + +## `cargo install rtk` installs the wrong package + +If Rust Type Kit is published to crates.io under the name `rtk`, `cargo install rtk` may install the wrong one. + +Always use the explicit URL: + +```bash +cargo install --git https://github.com/rtk-ai/rtk +``` + +## Run the diagnostic script + +From the RTK repository root: + +```bash +bash scripts/check-installation.sh +``` + +Checks: +- RTK installed and in PATH +- Correct version (Token Killer, not Type Kit) +- Available features +- Claude Code integration +- Hook status + +## Still stuck? + +Open an issue: https://github.com/rtk-ai/rtk/issues diff --git a/docs/guide/what-rtk-covers.md b/docs/guide/what-rtk-covers.md new file mode 100644 index 000000000..426e91a97 --- /dev/null +++ b/docs/guide/what-rtk-covers.md @@ -0,0 +1,153 @@ +--- +title: What RTK Optimizes +description: Commands and ecosystems automatically optimized by RTK with typical token savings +sidebar: + order: 2 +--- + +# What RTK Optimizes + +Once RTK is installed with a hook, these commands are automatically intercepted and filtered. You run them normally — the hook rewrites them transparently before execution. + +60+ commands across 9 ecosystems. Typical savings: 60-99%. + +## Git + +| Command | Savings | What changes | +|---------|---------|--------------| +| `git status` | 75-93% | Compact stat format, grouped by state | +| `git log` | 80-92% | Hash + author + subject only | +| `git diff` | 70% | Context reduced, headers stripped | +| `git show` | 70% | Same as diff | +| `git stash list` | 75% | Compact one-line per entry | + +## GitHub CLI + +| Command | Savings | What changes | +|---------|---------|--------------| +| `gh pr view` | 87% | Removes ASCII art and verbose metadata | +| `gh pr checks` | 79% | Status + name only, failures highlighted | +| `gh run list` | 82% | Compact workflow run summary | +| `gh issue view` | 80% | Body only, no decoration | + +## Graphite (Stacked PRs) + +| Command | Savings | What changes | +|---------|---------|--------------| +| `gt log` | 75% | Stack summary only | +| `gt status` | 70% | Current branch context | + +## Cargo / Rust + +| Command | Savings | What changes | +|---------|---------|--------------| +| `cargo test` | 90% | Failures only, passed tests suppressed | +| `cargo nextest` | 90% | Same as test | +| `cargo build` | 80% | Errors and warnings only | +| `cargo check` | 80% | Errors and warnings only | +| `cargo clippy` | 80% | Lint warnings grouped by file | + +## JavaScript / TypeScript + +| Command | Savings | What changes | +|---------|---------|--------------| +| `vitest run` | 94-99% | Failures only | +| `tsc` | 75% | Type errors grouped by file | +| `eslint` | 84% | Violations grouped by rule | +| `pnpm list` | 70-90% | Compact dependency tree | +| `pnpm outdated` | 70% | Package + current + latest only | +| `next build` | 80% | Route summary + errors only | +| `prisma migrate` | 75% | Migration status only | +| `playwright test` | 90% | Failures + trace links only | + +## Python + +| Command | Savings | What changes | +|---------|---------|--------------| +| `pytest` | 80-90% | Failures only | +| `ruff check` | 75% | Violations grouped by file | +| `mypy` | 75% | Type errors grouped by file | +| `pip install` | 70% | Installed packages only, progress stripped | + +## Go + +| Command | Savings | What changes | +|---------|---------|--------------| +| `go test` | 80-90% | Failures only | +| `golangci-lint run` | 75% | Violations grouped by file | +| `go build` | 75% | Errors only | + +## Ruby + +| Command | Savings | What changes | +|---------|---------|--------------| +| `rspec` | 80-90% | Failures only | +| `rubocop` | 75% | Offenses grouped by file | +| `rake` | 70% | Task output, build errors highlighted | + +## .NET + +| Command | Savings | What changes | +|---------|---------|--------------| +| `dotnet build` | 80% | Errors and warnings only | +| `dotnet test` | 85-90% | Failures only | +| `dotnet format` | 75% | Changed files only | + +## Docker / Kubernetes + +| Command | Savings | What changes | +|---------|---------|--------------| +| `docker ps` | 65% | Essential columns (name, image, status, port) | +| `docker images` | 60% | Name + tag + size only | +| `docker logs` | 70% | Deduplicated, last N lines | +| `docker compose up` | 75% | Service status, errors highlighted | +| `kubectl get pods` | 65% | Name + status + restarts only | +| `kubectl logs` | 70% | Deduplicated entries | + +## Files and Search + +| Command | Savings | What changes | +|---------|---------|--------------| +| `ls` | 80% | Tree format with file counts | +| `find` | 75% | Tree format | +| `grep` | 70% | Truncated lines, grouped by file | +| `diff` | 65% | Context reduced | +| `wc` | 60% | Compact counts | +| `cat` / `head` / `tail ` | 60-80% | Smart file reading via `rtk read` | +| `rtk smart ` | 85% | 2-line heuristic code summary (signatures only) | + +## Cloud and Data + +| Command | Savings | What changes | +|---------|---------|--------------| +| `aws` | 70% | JSON condensed, relevant fields only | +| `psql` | 65% | Query results without decoration | +| `curl` | 60% | Response body only, headers stripped | + +## Global flags + +These flags apply to all RTK commands and can push savings even higher: + +| Flag | Description | +|------|-------------| +| `-u` / `--ultra-compact` | ASCII icons, inline format — extra token reduction on top of normal filtering | +| `-v` / `--verbose` | Show filtering details on stderr (`-v`, `-vv`, `-vvv` for increasing detail) | + +```bash +# Ultra-compact: even smaller output +git log # → already filtered by RTK +git log -u # → ultra-compact variant (if using rtk directly) + +# Debug: see what RTK is doing +RTK_DISABLED=0 git status -vvv +``` + +## Commands that are not rewritten + +If a command isn't in the list above, RTK runs it through passthrough — the output reaches the LLM unchanged. You can explicitly track unsupported commands: + +```bash +rtk proxy make install # runs make install, tracks usage, no filtering +``` + +To check which commands were missed opportunities: `rtk discover`. diff --git a/src/cmds/java/mod.rs b/src/cmds/java/mod.rs new file mode 100644 index 000000000..4685e68f0 --- /dev/null +++ b/src/cmds/java/mod.rs @@ -0,0 +1 @@ +automod::dir!(pub "src/cmds/java"); diff --git a/src/cmds/java/mvn_cmd.rs b/src/cmds/java/mvn_cmd.rs new file mode 100644 index 000000000..c569c6d1c --- /dev/null +++ b/src/cmds/java/mvn_cmd.rs @@ -0,0 +1,978 @@ +//! Filters Maven (`mvn`) command output — test results, build errors. +//! +//! State machine parser for `mvn test` output with states: +//! Preamble -> Testing -> Summary -> Done. +//! Strips thousands of noise lines to compact failure reports (99%+ savings). + +use crate::core::runner; +use crate::core::tracking; +use crate::core::utils::{exit_code_from_status, resolved_command, strip_ansi}; +use anyhow::{Context, Result}; +use lazy_static::lazy_static; +use regex::Regex; +use std::ffi::OsString; +use std::path::Path; + +lazy_static! { + static ref TESTS_RUN_RE: Regex = + Regex::new(r"Tests run:\s*(\d+),\s*Failures:\s*(\d+),\s*Errors:\s*(\d+),\s*Skipped:\s*(\d+)") + .unwrap(); + static ref FAILURE_HEADER_RE: Regex = + Regex::new(r"^\[ERROR\]\s+(\S+\.\S+)\s+--\s+Time elapsed:.*<<<\s+(FAILURE|ERROR)!") + .unwrap(); + static ref TOTAL_TIME_RE: Regex = + Regex::new(r"Total time:\s+(.+)") + .unwrap(); + static ref VERSION_MANAGED_RE: Regex = + Regex::new(r"\s*\(version managed from [^)]+\)") + .unwrap(); +} + +/// Auto-detect mvnw wrapper; fall back to system `mvn`. +fn mvn_command() -> std::process::Command { + if Path::new("mvnw").exists() { + resolved_command("./mvnw") + } else { + resolved_command("mvn") + } +} + +/// Run `mvn test` with state-machine filtered output. +pub fn run_test(args: &[String], verbose: u8) -> Result { + let mut cmd = mvn_command(); + cmd.arg("test"); + + for arg in args { + cmd.arg(arg); + } + + if verbose > 0 { + eprintln!("Running: mvn test {}", args.join(" ")); + } + + runner::run_filtered( + cmd, + "mvn test", + &args.join(" "), + filter_mvn_test, + runner::RunOptions::with_tee("mvn_test"), + ) +} + +/// Run `mvn build` (defaults to `package` goal) with line-filtered output. +pub fn run_build(args: &[String], verbose: u8) -> Result { + let mut cmd = mvn_command(); + + // Default to 'package' if no goal specified + if args.is_empty() { + cmd.arg("package"); + } else { + for arg in args { + cmd.arg(arg); + } + } + + if verbose > 0 { + let display = if args.is_empty() { + "package".to_string() + } else { + args.join(" ") + }; + eprintln!("Running: mvn {}", display); + } + + runner::run_filtered( + cmd, + "mvn build", + &args.join(" "), + filter_mvn_build, + runner::RunOptions::with_tee("mvn_build"), + ) +} + +/// Run `mvn dependency:tree` with filtered output — strips duplicates and boilerplate. +pub fn run_dep_tree(args: &[String], verbose: u8) -> Result { + let mut cmd = mvn_command(); + cmd.arg("dependency:tree"); + + for arg in args { + cmd.arg(arg); + } + + if verbose > 0 { + eprintln!("Running: mvn dependency:tree {}", args.join(" ")); + } + + runner::run_filtered( + cmd, + "mvn dependency:tree", + &args.join(" "), + filter_mvn_dep_tree, + runner::RunOptions::with_tee("mvn_dep_tree"), + ) +} + +/// Goals that produce filterable build output (short-lived, captured). +const BUILD_GOALS: &[&str] = &["compile", "package", "clean", "install", "verify"]; + +/// Handles mvn subcommands not matched by dedicated Clap variants. +/// Build-like goals go through `filter_mvn_build`; everything else +/// streams directly via `status()` (safe for long-running goals). +pub fn run_other(args: &[OsString], verbose: u8) -> Result { + if args.is_empty() { + anyhow::bail!("mvn: no subcommand specified"); + } + + let subcommand = args[0].to_string_lossy(); + + if verbose > 0 { + eprintln!("Running: mvn {} ...", subcommand); + } + + // Route build-like goals through the build filter + if BUILD_GOALS.contains(&subcommand.as_ref()) { + let string_args: Vec = args.iter().map(|a| a.to_string_lossy().into_owned()).collect(); + return run_build(&string_args, verbose); + } + + // Everything else: passthrough with streaming (safe for spring-boot:run etc.) + let timer = tracking::TimedExecution::start(); + + let mut cmd = mvn_command(); + for arg in args { + cmd.arg(arg); + } + + let status = cmd + .status() + .with_context(|| format!("Failed to run mvn {}", subcommand))?; + + let args_str = tracking::args_display(args); + timer.track_passthrough( + &format!("mvn {}", args_str), + &format!("rtk mvn {} (passthrough)", args_str), + ); + + Ok(exit_code_from_status(&status, "mvn")) +} + +// --------------------------------------------------------------------------- +// State machine parser for mvn test output +// --------------------------------------------------------------------------- + +const MAX_DETAIL_LINES: usize = 3; +const MAX_FAILURES_SHOWN: usize = 10; +const MAX_LINE_LENGTH: usize = 200; + +#[derive(Debug, PartialEq)] +enum TestParseState { + Preamble, + Testing, + Summary, + Done, +} + +#[derive(Default)] +struct TestCounts { + run: u32, + failures: u32, + errors: u32, + skipped: u32, +} + +enum BuildResult { + Success, + Failure, +} + +struct FailureEntry { + name: String, + details: Vec, +} + +/// Filter `mvn test` output using a state machine parser. +/// +/// States: Preamble -> Testing -> Summary -> Done +/// - Preamble: skip everything before "T E S T S" marker +/// - Testing: collect failure details from [ERROR] headers and assertion lines +/// - Summary: parse final "Tests run:" line, BUILD SUCCESS/FAILURE, Total time +/// - Done: stop at Help boilerplate +fn filter_mvn_test(output: &str) -> String { + let clean = strip_ansi(output); + let mut state = TestParseState::Preamble; + + let mut failures: Vec = Vec::new(); + let mut current_failure: Option = None; + + let mut counts = TestCounts::default(); + let mut build_result: Option = None; + let mut total_time: Option = None; + let mut found_tests_section = false; + + for line in clean.lines() { + let trimmed = line.trim(); + let stripped = strip_maven_prefix(trimmed); + + // Global transition: T E S T S marker resets to Testing from any state + // (multi-module builds emit this marker per module) + if stripped.contains("T E S T S") { + found_tests_section = true; + state = TestParseState::Testing; + continue; + } + + match state { + TestParseState::Preamble => {} + TestParseState::Testing => { + if stripped == "Results:" { + if let Some(f) = current_failure.take() { + failures.push(f); + } + state = TestParseState::Summary; + continue; + } + + if let Some(caps) = FAILURE_HEADER_RE.captures(trimmed) { + if let Some(f) = current_failure.take() { + failures.push(f); + } + let test_name = caps.get(1).map_or("", |m| m.as_str()).to_string(); + current_failure = Some(FailureEntry { + name: test_name, + details: Vec::new(), + }); + continue; + } + + if let Some(ref mut f) = current_failure { + if f.details.len() >= MAX_DETAIL_LINES { + continue; + } + if is_framework_frame(stripped) + || is_maven_boilerplate(trimmed) + || stripped.is_empty() + || (trimmed.starts_with("[ERROR]") && stripped.contains("<<<")) + { + continue; + } + f.details.push(stripped.to_string()); + } + } + TestParseState::Summary => { + if is_maven_boilerplate(trimmed) || stripped.starts_with("Failures:") { + continue; + } + + if let Some(caps) = TESTS_RUN_RE.captures(stripped) { + counts.run = caps.get(1).map_or(0, |m| m.as_str().parse().unwrap_or(0)); + counts.failures = + caps.get(2).map_or(0, |m| m.as_str().parse().unwrap_or(0)); + counts.errors = + caps.get(3).map_or(0, |m| m.as_str().parse().unwrap_or(0)); + counts.skipped = + caps.get(4).map_or(0, |m| m.as_str().parse().unwrap_or(0)); + } + + if stripped.contains("BUILD SUCCESS") { + build_result = Some(BuildResult::Success); + } else if stripped.contains("BUILD FAILURE") { + build_result = Some(BuildResult::Failure); + } + + if let Some(caps) = TOTAL_TIME_RE.captures(stripped) { + total_time = Some(caps.get(1).map_or("", |m| m.as_str()).trim().to_string()); + state = TestParseState::Done; + } + } + TestParseState::Done => break, + } + } + + if !found_tests_section { + return "mvn test: no tests run".to_string(); + } + + let time_str = total_time.as_deref().unwrap_or("?"); + let has_failures = counts.failures > 0 || counts.errors > 0; + + if !has_failures { + let passed = counts.run.saturating_sub(counts.skipped); + let mut summary = format!("mvn test: {} passed", passed); + if counts.skipped > 0 { + summary.push_str(&format!(", {} skipped", counts.skipped)); + } + summary.push_str(&format!(" ({})", time_str)); + return summary; + } + + let failed_count = counts.failures + counts.errors; + let mut result = format!("mvn test: {} run, {} failed", counts.run, failed_count); + if counts.skipped > 0 { + result.push_str(&format!(", {} skipped", counts.skipped)); + } + result.push_str(&format!(" ({})\n", time_str)); + + if let Some(ref br) = build_result { + let label = match br { + BuildResult::Success => "SUCCESS", + BuildResult::Failure => "FAILURE", + }; + result.push_str(&format!("BUILD {}\n", label)); + } + + if !failures.is_empty() { + result.push_str("\nFailures:\n"); + } + for (i, failure) in failures.iter().take(MAX_FAILURES_SHOWN).enumerate() { + result.push_str(&format!("{}. {}\n", i + 1, failure.name)); + for detail in &failure.details { + if detail.len() > MAX_LINE_LENGTH { + result.push_str(&format!(" {}...\n", &detail[..MAX_LINE_LENGTH])); + } else { + result.push_str(&format!(" {}\n", detail)); + } + } + } + if failures.len() > MAX_FAILURES_SHOWN { + result.push_str(&format!( + "\n... +{} more failures\n", + failures.len() - MAX_FAILURES_SHOWN + )); + } + + result.trim().to_string() +} + +/// Strip [INFO], [ERROR], [WARNING] prefixes from Maven output lines. +fn strip_maven_prefix(line: &str) -> &str { + let trimmed = line.trim(); + for tag in &["[INFO]", "[ERROR]", "[WARNING]"] { + if let Some(rest) = trimmed.strip_prefix(tag) { + return rest.trim_start(); + } + } + trimmed +} + +/// Returns true for Java framework stack frames that should be stripped. +/// Expects pre-trimmed input (callers pass `stripped` or `trimmed`). +fn is_framework_frame(line: &str) -> bool { + let check = line.strip_prefix("at ").unwrap_or(line); + + const FRAMEWORK_PREFIXES: &[&str] = &[ + "org.apache.maven.", + "org.junit.platform.", + "org.junit.jupiter.", + "org.codehaus.plexus.", + "java.base/", + "sun.reflect.", + "jdk.internal.", + ]; + + for prefix in FRAMEWORK_PREFIXES { + if check.starts_with(prefix) { + return true; + } + } + + // "... N more" truncation markers + line.starts_with("...") && line.contains("more") +} + +/// Returns true for Maven boilerplate lines that should be stripped. +/// Expects pre-trimmed input from callers. +fn is_maven_boilerplate(line: &str) -> bool { + // Empty [ERROR] or [INFO] lines + if line == "[ERROR]" || line == "[INFO]" || line == "[WARNING]" { + return true; + } + + let stripped = strip_maven_prefix(line); + + // Separator lines (dashes) + if stripped.starts_with("---") && stripped.chars().all(|c| c == '-' || c.is_whitespace()) { + return true; + } + + const BOILERPLATE_PATTERNS: &[&str] = &[ + "-> [Help", + "http://cwiki.apache.org", + "https://cwiki.apache.org", + "surefire-reports", + "Re-run Maven", + "re-run Maven", + "full stack trace", + "enable verbose output", + "See dump files", + "Failed to execute goal", + "There are test failures", + ]; + + for pattern in BOILERPLATE_PATTERNS { + if stripped.contains(pattern) { + return true; + } + } + + false +} + +// --------------------------------------------------------------------------- +// Line filter for mvn build output +// --------------------------------------------------------------------------- + +/// Filter `mvn build`/`mvn package` output — strip [INFO] noise, keep errors and summary. +fn filter_mvn_build(output: &str) -> String { + let clean = strip_ansi(output); + let mut result_lines: Vec = Vec::new(); + + for line in clean.lines() { + let trimmed = line.trim(); + if should_keep_build_line(trimmed) { + result_lines.push(trimmed.to_string()); + } + } + + if result_lines.is_empty() { + return "mvn: ok".to_string(); + } + + result_lines.join("\n") +} + +const INFO_NOISE_PATTERNS: &[&str] = &[ + "---", + "Building ", + "Downloading ", + "Downloaded ", + "Scanning ", + "Compiling ", + "Recompiling ", + "Nothing to compile", + "Using auto detected", + "Loaded ", + "Creating container", + "Container ", + "Image ", + "Testcontainers", + "Docker ", + "Ryuk ", + "Checking the system", + "Connected to docker", + "Running ", + "Tests run:", + "Results:", + "T E S T S", + "Finished at:", + "from pom.xml", +]; + +/// Returns true if a build output line should be kept. +fn should_keep_build_line(line: &str) -> bool { + let trimmed = line.trim(); + + if trimmed.is_empty() { + return false; + } + + let stripped = strip_maven_prefix(trimmed); + + // Keep error lines + if trimmed.starts_with("[ERROR]") { + return !is_maven_boilerplate(trimmed); + } + + // Keep BUILD SUCCESS/FAILURE + if stripped.contains("BUILD SUCCESS") || stripped.contains("BUILD FAILURE") { + return true; + } + + // Keep Total time + if TOTAL_TIME_RE.is_match(stripped) { + return true; + } + + // Strip [INFO] noise + if trimmed.starts_with("[INFO]") { + if stripped.is_empty() { + return false; + } + + if stripped.starts_with("---") && stripped.chars().all(|c| c == '-' || c.is_whitespace()) { + return false; + } + + for pattern in INFO_NOISE_PATTERNS { + if stripped.contains(pattern) { + return false; + } + } + + if stripped.contains("deprecated") || stripped.contains("WARNING") { + return false; + } + + return true; + } + + // Strip [WARNING] lines for build filter + if trimmed.starts_with("[WARNING]") { + return false; + } + + // Keep anything else (compilation errors without prefix, etc.) + true +} + +// --------------------------------------------------------------------------- +// Line filter for mvn dependency:tree output +// --------------------------------------------------------------------------- + +/// Filter `mvn dependency:tree` — strip Maven boilerplate, omitted duplicates, +/// and "version managed" annotations. Keep tree structure and conflicts. +fn filter_mvn_dep_tree(output: &str) -> String { + let clean = strip_ansi(output); + let mut result_lines: Vec = Vec::new(); + + for line in clean.lines() { + let trimmed = line.trim(); + + // Skip empty lines and Maven boilerplate + if trimmed.is_empty() || is_maven_boilerplate(trimmed) { + continue; + } + + let stripped = strip_maven_prefix(trimmed); + + // Skip non-tree Maven lines (Scanning, Building, separators, etc.) + if trimmed.starts_with("[WARNING]") { + continue; + } + if trimmed.starts_with("[INFO]") { + if stripped.is_empty() { + continue; + } + // Skip separator lines + if stripped.starts_with("---") + && stripped.chars().all(|c| c == '-' || c.is_whitespace()) + { + continue; + } + // Skip preamble noise + if stripped.starts_with("Scanning ") + || stripped.starts_with("Building ") + || stripped.starts_with("Loaded ") + || stripped.contains("from pom.xml") + || stripped.contains("BUILD SUCCESS") + || stripped.contains("BUILD FAILURE") + || TOTAL_TIME_RE.is_match(stripped) + || stripped.starts_with("Finished at:") + { + continue; + } + } + + // Skip lines with "omitted for duplicate" + if stripped.contains("omitted for duplicate") { + continue; + } + + // Clean "version managed" annotations from kept lines + let cleaned = VERSION_MANAGED_RE.replace_all(stripped, "").to_string(); + + result_lines.push(cleaned); + } + + if result_lines.is_empty() { + return "mvn dependency:tree: no output".to_string(); + } + + result_lines.join("\n") +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::core::utils::count_tokens; + + #[test] + fn test_filter_pass_output() { + let input = include_str!("../../../tests/fixtures/mvn_test_pass_mavenmcp.txt"); + let output = filter_mvn_test(input); + assert!( + output.contains("mvn test:"), + "should contain summary prefix" + ); + assert!(output.contains("183 passed"), "should show 183 passed"); + assert!(output.contains("4.748 s"), "should contain total time"); + assert!( + !output.contains("[INFO]"), + "should not contain raw [INFO] prefix" + ); + } + + #[test] + fn test_filter_fail_output() { + let input = include_str!("../../../tests/fixtures/mvn_test_fail_auth.txt"); + let output = filter_mvn_test(input); + assert!( + output.contains("5 run, 2 failed"), + "should show run/failed counts, got: {}", + output + ); + assert!(output.contains("23.819 s"), "should contain total time"); + assert!( + output.contains("EmailParserTest.should_extract_domain_from_email"), + "should list first failure" + ); + assert!( + output.contains("ScoreTypeTest.shouldMapToRole"), + "should list second failure" + ); + assert!( + output.contains("broken.example.com"), + "should include assertion details" + ); + assert!( + !output.contains("surefire-reports"), + "should strip boilerplate" + ); + assert!( + !output.contains("cwiki.apache.org"), + "should strip help links" + ); + } + + #[test] + fn test_pass_savings() { + let input = include_str!("../../../tests/fixtures/mvn_test_pass_mavenmcp.txt"); + let output = filter_mvn_test(input); + + let input_tokens = count_tokens(input); + let output_tokens = count_tokens(&output); + + let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0); + + assert!( + savings >= 90.0, + "mvn test pass: expected >=90% savings, got {:.1}% ({} -> {} tokens)", + savings, + input_tokens, + output_tokens, + ); + } + + #[test] + fn test_fail_savings() { + let input = include_str!("../../../tests/fixtures/mvn_test_fail_auth.txt"); + let output = filter_mvn_test(input); + + let input_tokens = count_tokens(input); + let output_tokens = count_tokens(&output); + + let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0); + + assert!( + savings >= 60.0, + "mvn test fail: expected >=60% savings, got {:.1}% ({} -> {} tokens)", + savings, + input_tokens, + output_tokens, + ); + } + + #[test] + fn test_filter_large_suite() { + let input = include_str!("../../../tests/fixtures/mvn_test_large_suite.txt"); + let output = filter_mvn_test(input); + assert!( + output.contains("3262 run, 23 failed"), + "should show run/failed counts, got: {}", + output + ); + assert!( + output.contains("+13 more failures"), + "should cap at 10 and show remaining" + ); + assert!( + output.contains("SearchReadModelTest"), + "should list assertion failures" + ); + assert!( + output.contains("PatchableFieldTest"), + "should list compilation errors" + ); + } + + #[test] + fn test_large_suite_savings() { + let input = include_str!("../../../tests/fixtures/mvn_test_large_suite.txt"); + let output = filter_mvn_test(input); + + let input_tokens = count_tokens(input); + let output_tokens = count_tokens(&output); + let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0); + + assert!( + savings >= 60.0, + "mvn test large suite: expected >=60% savings, got {:.1}% ({} -> {} tokens)", + savings, + input_tokens, + output_tokens, + ); + } + + #[test] + fn test_empty_input() { + let output = filter_mvn_test(""); + assert_eq!(output, "mvn test: no tests run"); + } + + #[test] + fn test_filter_many_failures_output() { + let input = include_str!("../../../tests/fixtures/mvn_test_many_failures.txt"); + let output = filter_mvn_test(input); + assert!( + output.contains("28 run, 28 failed"), + "should show total run/failed counts, got: {}", + output + ); + assert!( + output.contains("+4 more failures"), + "should cap at 10 and show remaining count" + ); + } + + #[test] + fn test_many_failures_savings() { + let input = include_str!("../../../tests/fixtures/mvn_test_many_failures.txt"); + let output = filter_mvn_test(input); + + let input_tokens = count_tokens(input); + let output_tokens = count_tokens(&output); + let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0); + + assert!( + savings >= 60.0, + "mvn test many failures: expected >=60% savings, got {:.1}% ({} -> {} tokens)", + savings, + input_tokens, + output_tokens, + ); + } + + #[test] + fn test_filter_multimodule_output() { + let input = include_str!("../../../tests/fixtures/mvn_test_multimodule.txt"); + let output = filter_mvn_test(input); + assert!( + output.contains("860 run, 4 failed"), + "should show total run/failed across modules, got: {}", + output + ); + assert!( + output.contains("GitDiffReaderTest.shouldBuildDiff"), + "should list failure from services module" + ); + assert!( + output.contains("ServiceUnavailableException"), + "should include error details" + ); + assert!( + output.contains("01:31 min"), + "should contain total time" + ); + } + + #[test] + fn test_multimodule_savings() { + let input = include_str!("../../../tests/fixtures/mvn_test_multimodule.txt"); + let output = filter_mvn_test(input); + + let input_tokens = count_tokens(input); + let output_tokens = count_tokens(&output); + let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0); + + assert!( + savings >= 60.0, + "mvn test multimodule: expected >=60% savings, got {:.1}% ({} -> {} tokens)", + savings, + input_tokens, + output_tokens, + ); + } + + #[test] + fn test_filter_pass_large_ansi() { + let input = include_str!("../../../tests/fixtures/mvn_test_pass_large_ansi.txt"); + let output = filter_mvn_test(input); + assert!( + output.contains("950 passed"), + "should show 950 passed (959-9 skipped), got: {}", + output + ); + assert!( + output.contains("9 skipped"), + "should show 9 skipped" + ); + assert!( + output.contains("01:32 min"), + "should contain total time" + ); + assert!( + !output.contains("PortUnreachableException"), + "should strip app log noise" + ); + assert!( + !output.contains("[stdout]"), + "should strip [stdout] lines" + ); + assert!( + !output.contains("liquibase"), + "should strip liquibase stderr" + ); + } + + #[test] + fn test_pass_large_ansi_savings() { + let input = include_str!("../../../tests/fixtures/mvn_test_pass_large_ansi.txt"); + let output = filter_mvn_test(input); + + let input_tokens = count_tokens(input); + let output_tokens = count_tokens(&output); + let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0); + + assert!( + savings >= 95.0, + "mvn test large ANSI pass: expected >=95% savings, got {:.1}% ({} -> {} tokens)", + savings, + input_tokens, + output_tokens, + ); + } + + #[test] + fn test_no_test_section() { + let input = "[INFO] Building my-project 1.0\n[INFO] BUILD SUCCESS\n"; + let output = filter_mvn_test(input); + assert_eq!(output, "mvn test: no tests run"); + } + + // --- dependency:tree tests --- + + #[test] + fn test_dep_tree_simple() { + let input = include_str!("../../../tests/fixtures/mvn_dep_tree_simple.txt"); + let output = filter_mvn_dep_tree(input); + assert!( + output.contains("com.example:my-app:jar:1.0.0"), + "should contain root artifact, got: {}", + output + ); + assert!( + output.contains("slf4j-api"), + "should contain direct dep" + ); + assert!( + output.contains("guava"), + "should contain guava" + ); + assert!( + !output.contains("[INFO]"), + "should strip [INFO] prefix" + ); + assert!( + !output.contains("BUILD SUCCESS"), + "should strip boilerplate" + ); + assert!( + !output.contains("Scanning"), + "should strip preamble" + ); + } + + #[test] + fn test_dep_tree_conflicts() { + let input = include_str!("../../../tests/fixtures/mvn_dep_tree_conflicts.txt"); + let output = filter_mvn_dep_tree(input); + assert!( + output.contains("omitted for conflict with 2.18.3"), + "should keep conflict info, got: {}", + output + ); + assert!( + !output.contains("BUILD SUCCESS"), + "should strip boilerplate" + ); + } + + #[test] + fn test_dep_tree_beacon_strips_duplicates() { + let input = include_str!("../../../tests/fixtures/mvn_dep_tree_beacon.txt"); + let output = filter_mvn_dep_tree(input); + assert!( + !output.contains("omitted for duplicate"), + "should strip all 'omitted for duplicate' lines" + ); + assert!( + output.contains("com.skillpanel:beacon"), + "should contain root artifact" + ); + assert!( + output.contains("spring-boot-starter-web"), + "should contain direct deps" + ); + } + + #[test] + fn test_dep_tree_beacon_cleans_version_managed() { + let input = include_str!("../../../tests/fixtures/mvn_dep_tree_beacon.txt"); + let output = filter_mvn_dep_tree(input); + assert!( + !output.contains("version managed from"), + "should strip 'version managed' annotations" + ); + } + + #[test] + fn test_dep_tree_beacon_savings() { + let input = include_str!("../../../tests/fixtures/mvn_dep_tree_beacon.txt"); + let output = filter_mvn_dep_tree(input); + + let input_tokens = count_tokens(input); + let output_tokens = count_tokens(&output); + let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0); + + assert!( + savings >= 60.0, + "mvn dep tree beacon: expected >=60% savings, got {:.1}% ({} -> {} tokens)", + savings, + input_tokens, + output_tokens, + ); + } + + #[test] + fn test_dep_tree_simple_savings() { + let input = include_str!("../../../tests/fixtures/mvn_dep_tree_simple.txt"); + let output = filter_mvn_dep_tree(input); + + let input_tokens = count_tokens(input); + let output_tokens = count_tokens(&output); + let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0); + + assert!( + savings >= 30.0, + "mvn dep tree simple: expected >=30% savings, got {:.1}% ({} -> {} tokens)", + savings, + input_tokens, + output_tokens, + ); + } + + #[test] + fn test_dep_tree_empty() { + let output = filter_mvn_dep_tree(""); + assert_eq!(output, "mvn dependency:tree: no output"); + } +} diff --git a/src/cmds/mod.rs b/src/cmds/mod.rs index 1eca0b84c..0f25bd8de 100644 --- a/src/cmds/mod.rs +++ b/src/cmds/mod.rs @@ -4,6 +4,7 @@ pub mod cloud; pub mod dotnet; pub mod git; pub mod go; +pub mod java; pub mod js; pub mod python; pub mod ruby; diff --git a/src/cmds/system/ls.rs b/src/cmds/system/ls.rs index a69c271fe..ac40ae328 100644 --- a/src/cmds/system/ls.rs +++ b/src/cmds/system/ls.rs @@ -4,8 +4,20 @@ use super::constants::NOISE_DIRS; use crate::core::runner::{self, RunOptions}; use crate::core::utils::resolved_command; use anyhow::Result; +use lazy_static::lazy_static; +use regex::Regex; use std::io::IsTerminal; +lazy_static! { + /// Matches the date+time portion in `ls -la` output, which serves as a + /// stable anchor regardless of owner/group column width. + /// E.g.: " Mar 31 16:18 " or " Dec 25 2024 " + static ref LS_DATE_RE: Regex = Regex::new( + r"\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{1,2}\s+(?:\d{4}|\d{2}:\d{2})\s+" + ) + .unwrap(); +} + pub fn run(args: &[String], verbose: u8) -> Result { let show_all = args .iter() @@ -101,6 +113,40 @@ fn human_size(bytes: u64) -> String { } } +/// Parse a single `ls -la` line, returning `(file_type_char, size, name)`. +/// +/// Uses the date field as a stable anchor — the date format in `ls -la` is +/// always three tokens (`Mon DD HH:MM` or `Mon DD YYYY`), so we locate it +/// with a regex, then extract size (rightmost number before the date) and +/// filename (everything after the date). This handles owner/group names that +/// contain spaces, which break the old fixed-column approach. +fn parse_ls_line(line: &str) -> Option<(char, u64, String)> { + let date_match = LS_DATE_RE.find(line)?; + let name = line[date_match.end()..].to_string(); + + let before_date = &line[..date_match.start()]; + let before_parts: Vec<&str> = before_date.split_whitespace().collect(); + if before_parts.len() < 4 { + return None; + } + + let perms = before_parts[0]; + let file_type = perms.chars().next()?; + + // Size is the rightmost parseable number before the date. + // nlinks is also numeric but appears earlier; scanning from the end + // guarantees we hit the size field first. + let mut size: u64 = 0; + for part in before_parts.iter().rev() { + if let Ok(s) = part.parse::() { + size = s; + break; + } + } + + Some((file_type, size, name)) +} + /// Parse ls -la output into compact format: /// name/ (dirs) /// name size (files) @@ -113,18 +159,13 @@ fn compact_ls(raw: &str, show_all: bool) -> (String, String) { let mut by_ext: HashMap = HashMap::new(); for line in raw.lines() { - // Skip total, empty, . and .. if line.starts_with("total ") || line.is_empty() { continue; } - let parts: Vec<&str> = line.split_whitespace().collect(); - if parts.len() < 9 { + let Some((file_type, size, name)) = parse_ls_line(line) else { continue; - } - - // Filename is everything from column 9 onward (handles spaces) - let name = parts[8..].join(" "); + }; // Skip . and .. if name == "." || name == ".." { @@ -136,12 +177,9 @@ fn compact_ls(raw: &str, show_all: bool) -> (String, String) { continue; } - let is_dir = parts[0].starts_with('d'); - - if is_dir { + if file_type == 'd' { dirs.push(name); - } else if parts[0].starts_with('-') || parts[0].starts_with('l') { - let size: u64 = parts[4].parse().unwrap_or(0); + } else if file_type == '-' || file_type == 'l' { let ext = if let Some(pos) = name.rfind('.') { name[pos..].to_string() } else { @@ -325,4 +363,109 @@ mod tests { line_count ); } + + // Regression test for #948: owner/group with spaces breaks fixed-column parsing + #[test] + fn test_compact_multiline_group() { + let input = "total 8\n\ + -rw-r--r-- 1 fjeanne utilisa. du domaine 0 Mar 31 16:18 empty.txt\n\ + -rw-r--r-- 1 fjeanne utilisa. du domaine 1234 Mar 31 16:18 data.json\n"; + let (entries, _summary) = compact_ls(input, false); + assert!( + entries.contains("empty.txt"), + "should contain 'empty.txt', got: {entries}" + ); + assert!( + entries.contains("data.json"), + "should contain 'data.json', got: {entries}" + ); + assert!( + !entries.contains("16:18"), + "time should not leak into filename, got: {entries}" + ); + assert!( + entries.contains("0B"), + "empty.txt should show 0B, got: {entries}" + ); + assert!( + entries.contains("1.2K"), + "data.json should show 1.2K (1234 bytes), got: {entries}" + ); + } + + #[test] + fn test_compact_year_format_date() { + // Some systems show year instead of time for old files + let input = "total 8\n\ + -rw-r--r-- 1 user staff 5678 Dec 25 2024 archive.tar\n"; + let (entries, _summary) = compact_ls(input, false); + assert!( + entries.contains("archive.tar"), + "should contain filename, got: {entries}" + ); + assert!( + entries.contains("5.5K"), + "should show 5.5K, got: {entries}" + ); + } + + #[test] + fn test_parse_ls_line_basic() { + let (ft, size, name) = parse_ls_line( + "-rw-r--r-- 1 user staff 1234 Jan 1 12:00 file.txt", + ) + .unwrap(); + assert_eq!(ft, '-'); + assert_eq!(size, 1234); + assert_eq!(name, "file.txt"); + } + + #[test] + fn test_parse_ls_line_multiline_group() { + let (ft, size, name) = parse_ls_line( + "-rw-r--r-- 1 fjeanne utilisa. du domaine 0 Mar 31 16:18 empty.txt", + ) + .unwrap(); + assert_eq!(ft, '-'); + assert_eq!(size, 0); + assert_eq!(name, "empty.txt"); + } + + #[test] + fn test_parse_ls_line_dir_with_space_in_group() { + let (ft, size, name) = parse_ls_line( + "drwxr-xr-x 2 fjeanne utilisa. du domaine 64 Mar 31 16:18 my dir", + ) + .unwrap(); + assert_eq!(ft, 'd'); + assert_eq!(size, 64); + assert_eq!(name, "my dir"); + } + + #[test] + fn test_parse_ls_line_symlink() { + let (ft, size, name) = parse_ls_line( + "lrwxr-xr-x 1 user staff 10 Jan 1 12:00 link -> target", + ) + .unwrap(); + assert_eq!(ft, 'l'); + assert_eq!(size, 10); + assert_eq!(name, "link -> target"); + } + + #[test] + fn test_parse_ls_line_returns_none_for_total() { + assert!(parse_ls_line("total 48").is_none()); + } + + #[test] + fn test_parse_ls_line_year_format() { + let (ft, size, name) = parse_ls_line( + "-rw-r--r-- 1 user staff 5678 Dec 25 2024 old.tar.gz", + ) + .unwrap(); + assert_eq!(ft, '-'); + assert_eq!(size, 5678); + assert_eq!(name, "old.tar.gz"); + } } diff --git a/src/core/toml_filter.rs b/src/core/toml_filter.rs index bd294f8af..5c96b0165 100644 --- a/src/core/toml_filter.rs +++ b/src/core/toml_filter.rs @@ -1574,7 +1574,6 @@ match_command = "^make\\b" "markdownlint", "mix-compile", "mix-format", - "mvn-build", "ping", "pio-run", "poetry-install", @@ -1613,8 +1612,8 @@ match_command = "^make\\b" let filters = make_filters(BUILTIN_TOML); assert_eq!( filters.len(), - 58, - "Expected exactly 58 built-in filters, got {}. \ + 57, + "Expected exactly 57 built-in filters, got {}. \ Update this count when adding/removing filters in src/filters/.", filters.len() ); @@ -1671,11 +1670,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 57 existing filters still present + 1 new = 58 assert_eq!( filters.len(), - 59, - "Expected 59 filters after concat (58 built-in + 1 new)" + 58, + "Expected 58 filters after concat (57 built-in + 1 new)" ); // New filter is discoverable diff --git a/src/discover/rules.rs b/src/discover/rules.rs index b315edd77..def475eb2 100644 --- a/src/discover/rules.rs +++ b/src/discover/rules.rs @@ -486,11 +486,11 @@ pub const RULES: &[RtkRule] = &[ subcmd_status: &[], }, RtkRule { - pattern: r"^mvn\s+(compile|package|clean|install)\b", + pattern: r"^(\.\/?)?mvnw?\s+(test|compile|package|clean|install|dependency:tree)\b", rtk_cmd: "rtk mvn", - rewrite_prefixes: &["mvn"], + rewrite_prefixes: &["mvn", "mvnw", "./mvnw"], category: "Build", - savings_pct: 70.0, + savings_pct: 90.0, subcmd_savings: &[], subcmd_status: &[], }, diff --git a/src/filters/README.md b/src/filters/README.md index fbd4c4cb0..702f5034f 100644 --- a/src/filters/README.md +++ b/src/filters/README.md @@ -64,3 +64,58 @@ expected = "expected filtered output" Use the command name as the filename: `terraform-plan.toml`, `docker-inspect.toml`, `mix-compile.toml`. For commands with subcommands, prefer `-.toml` over grouping multiple filters in one file. + +## Build and runtime pipeline + +How a `.toml` file goes from contributor → binary → filtered output. + +```mermaid +flowchart TD + A[["src/filters/my-tool.toml\n(new file)"]] --> B + + subgraph BUILD ["cargo build"] + B["build.rs\n1. ls src/filters/*.toml\n2. sort alphabetically\n3. concat → BUILTIN_TOML"] --> C + C{"TOML valid?\nDuplicate names?"} -->|"fail"| D[["Build fails\nerror points to bad file"]] + C -->|"ok"| E[["OUT_DIR/builtin_filters.toml\n(generated)"]] + E --> F["rustc embeds via include_str!"] + F --> G[["rtk binary\nBUILTIN_TOML embedded"]] + end + + subgraph TESTS ["cargo test"] + H["test_builtin_filter_count\nassert_eq!(filters.len(), N)"] -->|"wrong count"| I[["FAIL"]] + J["test_builtin_all_filters_present\nassert!(names.contains('my-tool'))"] -->|"name missing"| K[["FAIL"]] + L["test_builtin_all_filters_have_inline_tests\nassert!(tested.contains(name))"] -->|"no tests"| M[["FAIL"]] + end + + subgraph RUNTIME ["rtk my-tool args"] + R["TomlFilterRegistry::load()\n1. .rtk/filters.toml\n2. ~/.config/rtk/filters.toml\n3. BUILTIN_TOML\n4. passthrough"] --> S + S{"match_command\nmatches?"} -->|"no match"| T[["exec raw (passthrough)"]] + S -->|"match"| U["exec command\ncapture stdout"] + U --> V["8-stage pipeline\nstrip_ansi → replace → match_output\n→ strip/keep_lines → truncate\n→ tail_lines → max_lines → on_empty"] + V --> W[["print filtered output + exit code"]] + end + + G --> H & J & L & R +``` + +## Filter lookup priority + +```mermaid +flowchart LR + CMD["rtk my-tool args"] --> P1 + P1{"1. .rtk/filters.toml\n(project-local)"} + P1 -->|"match"| WIN["apply filter"] + P1 -->|"no match"| P2 + P2{"2. ~/.config/rtk/filters.toml\n(user-global)"} + P2 -->|"match"| WIN + P2 -->|"no match"| P3 + P3{"3. BUILTIN_TOML\n(binary)"} + P3 -->|"match"| WIN + P3 -->|"no match"| P4[["exec raw (passthrough)"]] +``` + +First match wins. A project filter with the same name as a built-in shadows the built-in and triggers a warning: + +``` +[rtk] warning: filter 'make' is shadowing a built-in filter +``` diff --git a/src/filters/mvn-build.toml b/src/filters/mvn-build.toml deleted file mode 100644 index 430a7f0cd..000000000 --- a/src/filters/mvn-build.toml +++ /dev/null @@ -1,44 +0,0 @@ -[filters.mvn-build] -description = "Compact Maven build output" -match_command = "^mvn\\s+(compile|package|clean|install)\\b" -strip_ansi = true -strip_lines_matching = [ - "^\\[INFO\\] ---", - "^\\[INFO\\] Building\\s", - "^\\[INFO\\] Downloading\\s", - "^\\[INFO\\] Downloaded\\s", - "^\\[INFO\\]\\s*$", - "^\\s*$", - "^Downloading:", - "^Downloaded:", - "^Progress", -] -max_lines = 50 -on_empty = "mvn: ok" - -[[tests.mvn-build]] -name = "strips INFO noise, preserves errors and summary" -input = """ -[INFO] --- -[INFO] Building myapp 1.0-SNAPSHOT -[INFO] Downloading org.apache.maven.plugins:maven-compiler-plugin:3.11.0 -[INFO] Downloaded org.apache.maven.plugins:maven-compiler-plugin:3.11.0 -[INFO] -[ERROR] /src/main/java/Main.java:[10,5] cannot find symbol - symbol: method foo() -[INFO] BUILD FAILURE -[INFO] Total time: 2.543 s -""" -expected = "[ERROR] /src/main/java/Main.java:[10,5] cannot find symbol\n symbol: method foo()\n[INFO] BUILD FAILURE\n[INFO] Total time: 2.543 s" - -[[tests.mvn-build]] -name = "successful build keeps BUILD SUCCESS line" -input = """ -[INFO] --- -[INFO] Building myapp 1.0-SNAPSHOT -[INFO] -[INFO] BUILD SUCCESS -[INFO] Total time: 4.123 s -[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" diff --git a/src/main.rs b/src/main.rs index 1954ed8ea..06f2e9f3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use cmds::cloud::{aws_cmd, container, curl_cmd, psql_cmd, wget_cmd}; use cmds::dotnet::{binlog, dotnet_cmd, dotnet_format_report, dotnet_trx}; use cmds::git::{diff_cmd, gh_cmd, git, gt_cmd}; use cmds::go::{go_cmd, golangci_cmd}; +use cmds::java::mvn_cmd; use cmds::js::{ lint_cmd, next_cmd, npm_cmd, playwright_cmd, pnpm_cmd, prettier_cmd, prisma_cmd, tsc_cmd, vitest_cmd, @@ -642,6 +643,12 @@ enum Commands { command: GoCommands, }, + /// Maven commands with compact output + Mvn { + #[command(subcommand)] + command: MvnCommands, + }, + /// Graphite (gt) stacked PR commands with compact output Gt { #[command(subcommand)] @@ -1033,6 +1040,29 @@ enum GoCommands { Other(Vec), } +#[derive(Subcommand)] +enum MvnCommands { + /// Run tests with compact output (state machine parser, 99%+ token reduction) + Test { + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + /// Build with compact output (strip noise, keep errors and summary) + Build { + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + /// Dependency tree with compact output (strip duplicates and boilerplate) + #[command(name = "dependency:tree")] + DepTree { + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + args: Vec, + }, + /// Passthrough: runs any unsupported mvn subcommand directly + #[command(external_subcommand)] + Other(Vec), +} + /// RTK-only subcommands that should never fall back to raw execution. /// If Clap fails to parse these, show the Clap error directly. const RTK_META_COMMANDS: &[&str] = &[ @@ -1917,6 +1947,13 @@ fn run_cli() -> Result { GoCommands::Other(args) => go_cmd::run_other(&args, cli.verbose)?, }, + Commands::Mvn { command } => match command { + MvnCommands::Test { args } => mvn_cmd::run_test(&args, cli.verbose)?, + MvnCommands::Build { args } => mvn_cmd::run_build(&args, cli.verbose)?, + MvnCommands::DepTree { args } => mvn_cmd::run_dep_tree(&args, cli.verbose)?, + MvnCommands::Other(args) => mvn_cmd::run_other(&args, cli.verbose)?, + }, + Commands::Gt { command } => match command { GtCommands::Log { args } => gt_cmd::run_log(&args, cli.verbose)?, GtCommands::Submit { args } => gt_cmd::run_submit(&args, cli.verbose)?, @@ -2202,6 +2239,7 @@ fn is_operational_command(cmd: &Commands) -> bool { | Commands::Rspec { .. } | Commands::Pip { .. } | Commands::Go { .. } + | Commands::Mvn { .. } | Commands::GolangciLint { .. } | Commands::Gt { .. } ) diff --git a/tests/fixtures/mvn_dep_tree_beacon.txt b/tests/fixtures/mvn_dep_tree_beacon.txt new file mode 100644 index 000000000..6d3f6d58b --- /dev/null +++ b/tests/fixtures/mvn_dep_tree_beacon.txt @@ -0,0 +1,652 @@ +[INFO] Scanning for projects... +[INFO] +[INFO] -----------------------< com.skillpanel:beacon >------------------------ +[INFO] Building beacon 1.0-SNAPSHOT +[INFO] from pom.xml +[INFO] --------------------------------[ jar ]--------------------------------- +[INFO] +[INFO] --- dependency:3.9.0:tree (default-cli) @ beacon --- +[INFO] com.skillpanel:beacon:jar:1.0-SNAPSHOT +[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:4.0.3:compile +[INFO] | +- org.springframework.boot:spring-boot-starter-jackson:jar:4.0.3:compile (version managed from 4.0.3; scope not updated to compile) +[INFO] | | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- org.springframework.boot:spring-boot-jackson:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- (tools.jackson.core:jackson-databind:jar:3.0.4:compile - version managed from 3.0.4; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:4.0.3:compile (version managed from 4.0.3; scope not updated to compile) +[INFO] | | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | +- (org.springframework.boot:spring-boot-tomcat:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework.boot:spring-boot-web-server:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | +- (jakarta.annotation:jakarta.annotation-api:jar:3.0.0:compile - version managed from 3.0.0; omitted for duplicate) +[INFO] | | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:11.0.18:compile (version managed from 11.0.18) +[INFO] | | | +- (org.apache.tomcat.embed:tomcat-embed-el:jar:11.0.18:compile - version managed from 11.0.18; omitted for duplicate) +[INFO] | | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:11.0.18:compile (version managed from 11.0.18) +[INFO] | | | \- (org.apache.tomcat.embed:tomcat-embed-core:jar:11.0.18:compile - version managed from 11.0.18; omitted for duplicate) +[INFO] | | \- org.springframework.boot:spring-boot-tomcat:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-web-server:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- (org.apache.tomcat.embed:tomcat-embed-core:jar:11.0.18:compile - version managed from 11.0.18; omitted for duplicate) +[INFO] | | \- (jakarta.annotation:jakarta.annotation-api:jar:3.0.0:runtime - version managed from 3.0.0; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-http-converter:jar:4.0.3:compile (version managed from 4.0.3; scope not updated to compile) +[INFO] | | +- org.springframework.boot:spring-boot:jar:4.0.3:compile (version managed from 4.0.3; scope not updated to compile) +[INFO] | | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | \- (org.springframework:spring-context:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | \- org.springframework:spring-web:jar:7.0.5:compile (version managed from 7.0.5; scope not updated to compile) +[INFO] | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | \- (io.micrometer:micrometer-observation:jar:1.16.3:compile - version managed from 1.16.3; omitted for duplicate) +[INFO] | \- org.springframework.boot:spring-boot-webmvc:jar:4.0.3:compile (version managed from 4.0.3; scope not updated to compile) +[INFO] | +- org.springframework.boot:spring-boot-servlet:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- (org.springframework:spring-web:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | +- (org.springframework:spring-web:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | +- org.springframework:spring-webmvc:jar:7.0.5:compile (version managed from 7.0.5) +[INFO] | | +- (org.springframework:spring-aop:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-context:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-expression:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | \- (org.springframework:spring-web:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | \- (org.springframework.boot:spring-boot-http-converter:jar:4.0.3:runtime - version managed from 4.0.3; omitted for duplicate) +[INFO] +- org.springframework.boot:spring-boot-starter-webflux:jar:4.0.3:compile +[INFO] | +- org.springframework.boot:spring-boot-starter:jar:4.0.3:compile (version managed from 4.0.3; scope not updated to compile) +[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.5.32:compile (version managed from 1.5.32) +[INFO] | | | | +- ch.qos.logback:logback-core:jar:1.5.32:compile (version managed from 1.5.32) +[INFO] | | | | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 2.0.17; omitted for duplicate) +[INFO] | | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.25.3:compile (version managed from 2.25.3) +[INFO] | | | | +- org.apache.logging.log4j:log4j-api:jar:2.25.3:compile (version managed from 2.25.3) +[INFO] | | | | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 2.0.17; omitted for duplicate) +[INFO] | | | \- org.slf4j:jul-to-slf4j:jar:2.0.17:compile (version managed from 2.0.17) +[INFO] | | | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 2.0.17; omitted for duplicate) +[INFO] | | +- (org.springframework.boot:spring-boot-autoconfigure:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- jakarta.annotation:jakarta.annotation-api:jar:3.0.0:compile (version managed from 3.0.0; scope not updated to compile) +[INFO] | | \- (org.yaml:snakeyaml:jar:2.5:compile - version managed from 2.5; omitted for duplicate) +[INFO] | +- (org.springframework.boot:spring-boot-starter-jackson:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-starter-reactor-netty:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- org.springframework.boot:spring-boot-reactor:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | \- (io.projectreactor:reactor-core:jar:3.8.3:compile - version managed from 3.8.3; omitted for duplicate) +[INFO] | | \- org.springframework.boot:spring-boot-reactor-netty:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-web-server:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- io.projectreactor.netty:reactor-netty-http:jar:1.3.3:compile (version managed from 1.3.3) +[INFO] | | | +- io.netty:netty-codec-http:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-codec-compression:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | \- (io.netty:netty-handler:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- io.netty:netty-codec-http2:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-handler:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | \- (io.netty:netty-codec-http:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- io.netty:netty-codec-http3:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-codec-http:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-codec-compression:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-handler:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport-native-unix-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-resolver:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- io.netty:netty-codec-classes-quic:jar:4.2.10.Final:compile (version managed from 4.2.10.Final; scope not updated to compile) +[INFO] | | | | +- io.netty:netty-codec-native-quic:jar:linux-x86_64:4.2.10.Final:runtime (version managed from 4.2.10.Final; scope managed from runtime) +[INFO] | | | | | \- (io.netty:netty-codec-classes-quic:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- io.netty:netty-codec-native-quic:jar:linux-aarch_64:4.2.10.Final:runtime (version managed from 4.2.10.Final; scope managed from runtime) +[INFO] | | | | | \- (io.netty:netty-codec-classes-quic:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- io.netty:netty-codec-native-quic:jar:osx-x86_64:4.2.10.Final:runtime (version managed from 4.2.10.Final; scope managed from runtime) +[INFO] | | | | | \- (io.netty:netty-codec-classes-quic:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- io.netty:netty-codec-native-quic:jar:osx-aarch_64:4.2.10.Final:runtime (version managed from 4.2.10.Final; scope managed from runtime) +[INFO] | | | | | \- (io.netty:netty-codec-classes-quic:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | \- io.netty:netty-codec-native-quic:jar:windows-x86_64:4.2.10.Final:runtime (version managed from 4.2.10.Final; scope managed from runtime) +[INFO] | | | | \- (io.netty:netty-codec-classes-quic:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- (io.netty:netty-resolver-dns:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64:4.2.10.Final:runtime (version managed from 4.2.10.Final; scope managed from compile) +[INFO] | | | | \- io.netty:netty-resolver-dns-classes-macos:jar:4.2.10.Final:runtime (version managed from 4.2.10.Final) +[INFO] | | | | +- (io.netty:netty-common:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-resolver-dns:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | \- (io.netty:netty-transport-native-unix-common:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.2.10.Final:runtime (version managed from 4.2.10.Final; scope managed from compile) +[INFO] | | | | +- (io.netty:netty-common:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport-native-unix-common:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | \- io.netty:netty-transport-classes-epoll:jar:4.2.10.Final:runtime (version managed from 4.2.10.Final) +[INFO] | | | | +- (io.netty:netty-common:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | \- (io.netty:netty-transport-native-unix-common:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- io.projectreactor.netty:reactor-netty-core:jar:1.3.3:compile (version managed from 1.3.3) +[INFO] | | | | +- (io.netty:netty-handler:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- io.netty:netty-handler-proxy:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | +- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | +- io.netty:netty-codec-socks:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | | \- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | +- (io.netty:netty-codec-http:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | \- (io.netty:netty-handler:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-resolver-dns:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64:4.2.10.Final:runtime - version managed from 4.2.10.Final; scope managed from compile; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.2.10.Final:runtime - version managed from 4.2.10.Final; scope managed from compile; omitted for duplicate) +[INFO] | | | | +- (io.projectreactor:reactor-core:jar:3.8.3:compile - version managed from 3.8.3; omitted for duplicate) +[INFO] | | | | \- (org.jspecify:jspecify:jar:1.0.0:compile - version managed from 1.0.0; omitted for duplicate) +[INFO] | | | +- (io.projectreactor:reactor-core:jar:3.8.3:compile - version managed from 3.8.3; omitted for duplicate) +[INFO] | | | \- (org.jspecify:jspecify:jar:1.0.0:compile - version managed from 1.0.0; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-web:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | \- (org.springframework.boot:spring-boot-netty:jar:4.0.3:runtime - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- org.springframework.boot:spring-boot-webflux:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-http-codec:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- (org.springframework:spring-web:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | +- org.springframework:spring-webflux:jar:7.0.5:compile (version managed from 7.0.5) +[INFO] | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-web:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | \- (io.projectreactor:reactor-core:jar:3.8.3:compile - version managed from 3.8.3; omitted for duplicate) +[INFO] | \- org.springframework.boot:spring-boot-web-server:jar:4.0.3:compile (version managed from 4.0.3; scope not updated to compile) +[INFO] | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- (org.springframework:spring-web:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:4.0.3:compile +[INFO] | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-starter-jdbc:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework.boot:spring-boot-jdbc:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- com.zaxxer:HikariCP:jar:7.0.2:compile (version managed from 7.0.2) +[INFO] | | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 2.0.17; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-data-jpa:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- org.springframework.boot:spring-boot-data-commons:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | +- org.springframework.boot:spring-boot-persistence:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | | \- (org.springframework:spring-tx:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | \- org.springframework.data:spring-data-commons:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 2.0.17; omitted for duplicate) +[INFO] | | +- org.springframework.boot:spring-boot-hibernate:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | +- org.springframework.boot:spring-boot-jpa:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | | +- (org.springframework.boot:spring-boot-jdbc:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | | +- (org.springframework.boot:spring-boot-transaction:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | | +- jakarta.persistence:jakarta.persistence-api:jar:3.2.0:compile (version managed from 3.2.0) +[INFO] | | | | \- (org.springframework:spring-orm:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | +- org.hibernate.orm:hibernate-core:jar:7.2.4.Final:compile (version managed from 7.2.4.Final) +[INFO] | | | | +- (jakarta.persistence:jakarta.persistence-api:jar:3.2.0:compile - version managed from 3.2.0; omitted for duplicate) +[INFO] | | | | +- jakarta.transaction:jakarta.transaction-api:jar:2.0.1:compile (version managed from 2.0.1) +[INFO] | | | | +- (org.jboss.logging:jboss-logging:jar:3.6.2.Final:runtime - version managed from 3.6.1.Final; omitted for duplicate) +[INFO] | | | | +- org.hibernate.models:hibernate-models:jar:1.0.1:runtime +[INFO] | | | | | \- (org.jboss.logging:jboss-logging:jar:3.6.2.Final:runtime - version managed from 3.5.0.Final; omitted for duplicate) +[INFO] | | | | +- (com.fasterxml:classmate:jar:1.7.3:runtime - version managed from 1.7.1; omitted for duplicate) +[INFO] | | | | +- (net.bytebuddy:byte-buddy:jar:1.17.8:runtime - version managed from 1.17.8; omitted for duplicate) +[INFO] | | | | +- (jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.4:runtime - version managed from 4.0.4; omitted for duplicate) +[INFO] | | | | +- org.glassfish.jaxb:jaxb-runtime:jar:4.0.6:runtime (version managed from 4.0.6) +[INFO] | | | | | \- org.glassfish.jaxb:jaxb-core:jar:4.0.6:runtime (version managed from 4.0.6) +[INFO] | | | | | +- (jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.4:runtime - version managed from 4.0.4; omitted for duplicate) +[INFO] | | | | | +- (jakarta.activation:jakarta.activation-api:jar:2.1.4:runtime - version managed from 2.1.4; omitted for duplicate) +[INFO] | | | | | +- org.eclipse.angus:angus-activation:jar:2.0.3:runtime +[INFO] | | | | | | \- (jakarta.activation:jakarta.activation-api:jar:2.1.4:runtime - version managed from 2.1.4; omitted for duplicate) +[INFO] | | | | | +- org.glassfish.jaxb:txw2:jar:4.0.6:runtime (version managed from 4.0.6) +[INFO] | | | | | \- com.sun.istack:istack-commons-runtime:jar:4.1.2:runtime +[INFO] | | | | +- jakarta.inject:jakarta.inject-api:jar:2.0.1:runtime (version managed from 2.0.1) +[INFO] | | | | \- (org.antlr:antlr4-runtime:jar:4.13.2:runtime - omitted for duplicate) +[INFO] | | | \- org.springframework:spring-orm:jar:7.0.5:compile (version managed from 7.0.5) +[INFO] | | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-jdbc:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | \- (org.springframework:spring-tx:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | +- org.springframework.data:spring-data-jpa:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | +- (org.springframework.data:spring-data-commons:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-orm:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-context:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-aop:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-tx:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | +- org.antlr:antlr4-runtime:jar:4.13.2:compile +[INFO] | | | +- (jakarta.annotation:jakarta.annotation-api:jar:3.0.0:compile - version managed from 2.0.0; omitted for duplicate) +[INFO] | | | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 2.0.17; omitted for duplicate) +[INFO] | | \- org.springframework:spring-aspects:jar:7.0.5:compile (version managed from 7.0.5) +[INFO] | | \- org.aspectj:aspectjweaver:jar:1.9.25.1:compile (version managed from 1.9.25) +[INFO] | \- org.springframework.boot:spring-boot-jdbc:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-sql:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | \- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-transaction:jar:4.0.3:compile (version managed from 4.0.3; scope not updated to compile) +[INFO] | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework.boot:spring-boot-persistence:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- (org.springframework:spring-tx:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | \- org.springframework:spring-jdbc:jar:7.0.5:compile (version managed from 7.0.5) +[INFO] | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | \- (org.springframework:spring-tx:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] +- org.springframework.boot:spring-boot-starter-data-redis:jar:4.0.3:compile +[INFO] | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- org.springframework.boot:spring-boot-data-redis:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- (org.springframework.boot:spring-boot-data-commons:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- (org.springframework.boot:spring-boot-transaction:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- io.lettuce:lettuce-core:jar:6.8.2.RELEASE:compile (version managed from 6.8.2.RELEASE) +[INFO] | | +- redis.clients.authentication:redis-authx-core:jar:0.1.1-beta2:compile +[INFO] | | | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 1.7.36; omitted for duplicate) +[INFO] | | +- io.netty:netty-common:jar:4.2.10.Final:compile (version managed from 4.1.125.Final) +[INFO] | | +- io.netty:netty-handler:jar:4.2.10.Final:compile (version managed from 4.1.125.Final) +[INFO] | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- io.netty:netty-resolver:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | \- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- io.netty:netty-buffer:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | \- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- io.netty:netty-transport-native-unix-common:jar:4.2.10.Final:compile (version managed from 4.2.10.Final; scope not updated to compile) +[INFO] | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | \- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | \- io.netty:netty-codec-base:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | \- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | +- io.netty:netty-transport:jar:4.2.10.Final:compile (version managed from 4.1.125.Final) +[INFO] | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | \- (io.netty:netty-resolver:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | +- (io.projectreactor:reactor-core:jar:3.8.3:compile - version managed from 3.6.6; omitted for duplicate) +[INFO] | | \- io.netty:netty-resolver-dns:jar:4.2.10.Final:compile (version managed from 4.1.125.Final; scope not updated to compile) +[INFO] | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | +- (io.netty:netty-resolver:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | +- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | +- io.netty:netty-codec-dns:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | \- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | \- (io.netty:netty-handler:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | +- org.springframework.data:spring-data-redis:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- org.springframework.data:spring-data-keyvalue:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | +- (org.springframework.data:spring-data-commons:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-context:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-tx:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 2.0.17; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-tx:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | +- org.springframework:spring-oxm:jar:7.0.5:compile (version managed from 7.0.3) +[INFO] | | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | \- (jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.4:runtime - version managed from 3.0.1; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-aop:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | +- org.springframework:spring-context-support:jar:7.0.5:compile (version managed from 7.0.3) +[INFO] | | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-context:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | \- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 2.0.17; omitted for duplicate) +[INFO] | \- org.springframework.boot:spring-boot-netty:jar:4.0.3:runtime (version managed from 4.0.3) +[INFO] | +- (org.springframework.boot:spring-boot:jar:4.0.3:runtime - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- (io.netty:netty-common:jar:4.2.10.Final:runtime - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] +- org.springframework.boot:spring-boot-starter-validation:jar:4.0.3:compile +[INFO] | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- org.springframework.boot:spring-boot-validation:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.apache.tomcat.embed:tomcat-embed-el:jar:11.0.18:compile (version managed from 11.0.18) +[INFO] | \- org.hibernate.validator:hibernate-validator:jar:9.0.1.Final:compile (version managed from 9.0.1.Final) +[INFO] | +- jakarta.validation:jakarta.validation-api:jar:3.1.1:compile (version managed from 3.1.1) +[INFO] | +- org.jboss.logging:jboss-logging:jar:3.6.2.Final:compile (version managed from 3.6.1.Final; scope not updated to compile) +[INFO] | \- com.fasterxml:classmate:jar:1.7.3:compile (version managed from 1.7.0; scope not updated to compile) +[INFO] +- org.springframework.boot:spring-boot-starter-actuator:jar:4.0.3:compile +[INFO] | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- org.springframework.boot:spring-boot-micrometer-metrics:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- org.springframework.boot:spring-boot-micrometer-observation:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | | \- (io.micrometer:micrometer-observation:jar:1.16.3:compile - version managed from 1.16.3; omitted for duplicate) +[INFO] | | \- (io.micrometer:micrometer-core:jar:1.16.3:compile - version managed from 1.16.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-actuator-autoconfigure:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-autoconfigure:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- org.springframework.boot:spring-boot-actuator:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | \- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-health:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | \- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- io.micrometer:micrometer-observation:jar:1.16.3:compile (version managed from 1.16.3) +[INFO] | | +- (org.jspecify:jspecify:jar:1.0.0:compile - version managed from 1.0.0; omitted for duplicate) +[INFO] | | \- io.micrometer:micrometer-commons:jar:1.16.3:compile (version managed from 1.16.3) +[INFO] | | \- (org.jspecify:jspecify:jar:1.0.0:compile - version managed from 1.0.0; omitted for duplicate) +[INFO] | \- io.micrometer:micrometer-jakarta9:jar:1.16.3:compile (version managed from 1.16.3) +[INFO] | +- (org.jspecify:jspecify:jar:1.0.0:compile - version managed from 1.0.0; omitted for duplicate) +[INFO] | +- io.micrometer:micrometer-core:jar:1.16.3:compile (version managed from 1.16.3) +[INFO] | | +- (org.jspecify:jspecify:jar:1.0.0:compile - version managed from 1.0.0; omitted for duplicate) +[INFO] | | +- (io.micrometer:micrometer-commons:jar:1.16.3:compile - version managed from 1.16.3; omitted for duplicate) +[INFO] | | +- (io.micrometer:micrometer-observation:jar:1.16.3:compile - version managed from 1.16.3; omitted for duplicate) +[INFO] | | +- org.hdrhistogram:HdrHistogram:jar:2.2.2:runtime +[INFO] | | \- org.latencyutils:LatencyUtils:jar:2.0.3:runtime +[INFO] | +- (io.micrometer:micrometer-commons:jar:1.16.3:compile - version managed from 1.16.3; omitted for duplicate) +[INFO] | \- (io.micrometer:micrometer-observation:jar:1.16.3:compile - version managed from 1.16.3; omitted for duplicate) +[INFO] +- org.springframework.boot:spring-boot-starter-security:jar:4.0.3:compile +[INFO] | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-security:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- org.springframework.security:spring-security-config:jar:7.0.3:compile (version managed from 7.0.3) +[INFO] | | | +- (org.springframework.security:spring-security-core:jar:7.0.3:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-aop:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-context:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | | \- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | \- (org.springframework.security:spring-security-web:jar:7.0.3:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | \- org.springframework:spring-aop:jar:7.0.5:compile (version managed from 7.0.5) +[INFO] | +- org.springframework:spring-beans:jar:7.0.5:compile (version managed from 7.0.5) +[INFO] | | \- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | \- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] +- com.devskiller:toolkit:jar:1.3-38:compile +[INFO] | +- org.slf4j:slf4j-api:jar:2.0.17:compile (version managed from 2.0.7) +[INFO] | +- (com.nimbusds:nimbus-jose-jwt:jar:10.5:compile - omitted for conflict with 9.37) +[INFO] | +- org.bouncycastle:bcprov-jdk18on:jar:1.82:compile +[INFO] | +- org.bouncycastle:bcpkix-jdk18on:jar:1.82:compile +[INFO] | | \- org.bouncycastle:bcutil-jdk18on:jar:1.82:compile +[INFO] | | \- (org.bouncycastle:bcprov-jdk18on:jar:1.82:compile - omitted for duplicate) +[INFO] | +- com.courier:courier-java:jar:3.3.0:compile +[INFO] | | +- (com.squareup.okhttp3:okhttp:jar:4.12.0:compile - omitted for conflict with 5.0.0-alpha.14) +[INFO] | | +- (com.fasterxml.jackson.core:jackson-databind:jar:2.20.2:compile - version managed from 2.13.0; omitted for duplicate) +[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.20.2:compile (version managed from 2.12.3) +[INFO] | | | +- (com.fasterxml.jackson.core:jackson-core:jar:2.20.2:compile - version managed from 2.20.2; omitted for duplicate) +[INFO] | | | \- (com.fasterxml.jackson.core:jackson-databind:jar:2.20.2:compile - version managed from 2.20.2; omitted for duplicate) +[INFO] | | \- (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.20.2:compile - version managed from 2.12.3; omitted for duplicate) +[INFO] | +- (com.devskiller.friendly-id:friendly-id:jar:1.1.0:compile - omitted for conflict with 2.0.0-SNAPSHOT) +[INFO] | +- org.apache.commons:commons-lang3:jar:3.19.0:compile (version managed from 3.13.0; scope not updated to compile) +[INFO] | +- jakarta.servlet:jakarta.servlet-api:jar:6.1.0:compile (version managed from 6.0.0) +[INFO] | +- com.github.ulisesbocchio:jasypt-spring-boot-starter:jar:3.0.5:compile +[INFO] | | \- com.github.ulisesbocchio:jasypt-spring-boot:jar:3.0.5:compile +[INFO] | | \- org.jasypt:jasypt:jar:1.9.3:compile +[INFO] | +- io.github.resilience4j:resilience4j-retry:jar:2.0.2:compile +[INFO] | | +- io.github.resilience4j:resilience4j-core:jar:2.0.2:compile +[INFO] | | | \- (org.slf4j:slf4j-api:jar:2.0.17:runtime - version managed from 1.7.30; omitted for duplicate) +[INFO] | | \- (org.slf4j:slf4j-api:jar:2.0.17:runtime - version managed from 1.7.30; omitted for duplicate) +[INFO] | \- io.vavr:vavr:jar:0.10.4:compile +[INFO] | \- io.vavr:vavr-match:jar:0.10.4:compile +[INFO] +- com.devskiller.friendly-id:friendly-id:jar:2.0.0-SNAPSHOT:compile (scope not updated to compile) +[INFO] | \- org.jspecify:jspecify:jar:1.0.0:compile (version managed from 1.0.0; scope not updated to compile) +[INFO] +- com.devskiller.friendly-id:friendly-id-jackson2-datatype:jar:2.0.0-SNAPSHOT:compile +[INFO] | +- (com.devskiller.friendly-id:friendly-id:jar:2.0.0-SNAPSHOT:compile - omitted for duplicate) +[INFO] | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.20:compile (version managed from 2.18.2) +[INFO] | +- com.fasterxml.jackson.core:jackson-core:jar:2.20.2:compile (version managed from 2.18.2) +[INFO] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.20.2:compile (version managed from 2.18.2) +[INFO] | | +- (com.fasterxml.jackson.core:jackson-annotations:jar:2.20:compile - version managed from 2.20; omitted for duplicate) +[INFO] | | \- (com.fasterxml.jackson.core:jackson-core:jar:2.20.2:compile - version managed from 2.20.2; omitted for duplicate) +[INFO] | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.20.2:compile (version managed from 2.18.2) +[INFO] | +- (com.fasterxml.jackson.core:jackson-core:jar:2.20.2:compile - version managed from 2.20.2; omitted for duplicate) +[INFO] | \- (com.fasterxml.jackson.core:jackson-databind:jar:2.20.2:compile - version managed from 2.20.2; omitted for duplicate) +[INFO] +- com.devskiller.friendly-id:friendly-id-jackson-datatype:jar:2.0.0-SNAPSHOT:compile +[INFO] | +- (com.devskiller.friendly-id:friendly-id:jar:2.0.0-SNAPSHOT:compile - omitted for duplicate) +[INFO] | +- (com.fasterxml.jackson.core:jackson-annotations:jar:2.20:compile - version managed from 2.20; omitted for duplicate) +[INFO] | +- tools.jackson.core:jackson-core:jar:3.0.4:compile (version managed from 3.0.3) +[INFO] | \- tools.jackson.core:jackson-databind:jar:3.0.4:compile (version managed from 3.0.3) +[INFO] | +- (com.fasterxml.jackson.core:jackson-annotations:jar:2.20:compile - version managed from 2.20; omitted for duplicate) +[INFO] | \- (tools.jackson.core:jackson-core:jar:3.0.4:compile - version managed from 3.0.4; omitted for duplicate) +[INFO] +- org.springframework.boot:spring-boot-starter-amqp:jar:4.0.3:compile +[INFO] | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- org.springframework.boot:spring-boot-amqp:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | +- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework:spring-messaging:jar:7.0.5:compile (version managed from 7.0.5) +[INFO] | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | \- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | +- (org.springframework.amqp:spring-rabbit:jar:4.0.2:compile - version managed from 4.0.2; omitted for duplicate) +[INFO] | \- (org.springframework.boot:spring-boot-transaction:jar:4.0.3:runtime - version managed from 4.0.3; omitted for duplicate) +[INFO] +- nl.big-o:liqp:jar:0.9.2.3:compile +[INFO] | +- (com.fasterxml.jackson.core:jackson-annotations:jar:2.20:compile - version managed from 2.13.2; omitted for duplicate) +[INFO] | +- (com.fasterxml.jackson.core:jackson-core:jar:2.20.2:compile - version managed from 2.13.2; omitted for duplicate) +[INFO] | +- (com.fasterxml.jackson.core:jackson-databind:jar:2.20.2:compile - version managed from 2.13.4.2; omitted for duplicate) +[INFO] | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.20.2:compile (version managed from 2.13.2) +[INFO] | | +- (com.fasterxml.jackson.core:jackson-annotations:jar:2.20:compile - version managed from 2.20; omitted for duplicate) +[INFO] | | +- (com.fasterxml.jackson.core:jackson-core:jar:2.20.2:compile - version managed from 2.20.2; omitted for duplicate) +[INFO] | | \- (com.fasterxml.jackson.core:jackson-databind:jar:2.20.2:compile - version managed from 2.20.2; omitted for duplicate) +[INFO] | \- ua.co.k:strftime4j:jar:1.0.6:compile +[INFO] +- com.ibm.icu:icu4j:jar:78.2:compile +[INFO] +- com.mailjet:mailjet-client:jar:6.0.1:compile +[INFO] | +- com.squareup.okhttp3:okhttp:jar:5.0.0-alpha.14:compile +[INFO] | | +- com.squareup.okio:okio-jvm:jar:3.9.0:compile +[INFO] | | | \- (org.jetbrains.kotlin:kotlin-stdlib:jar:2.2.21:compile - version managed from 1.9.21; omitted for duplicate) +[INFO] | | \- org.jetbrains.kotlin:kotlin-stdlib:jar:2.2.21:compile (version managed from 1.9.23) +[INFO] | | \- org.jetbrains:annotations:jar:13.0:compile (scope not updated to compile) +[INFO] | +- org.json:json:jar:20231013:compile +[INFO] | \- com.google.code.gson:gson:jar:2.13.2:compile (version managed from 2.9.0) +[INFO] | \- com.google.errorprone:error_prone_annotations:jar:2.41.0:compile +[INFO] +- com.slack.api:slack-api-client:jar:1.47.0:compile +[INFO] | +- com.slack.api:slack-api-model:jar:1.47.0:compile +[INFO] | | \- (com.google.code.gson:gson:jar:2.13.2:compile - version managed from 2.12.1; omitted for duplicate) +[INFO] | +- (com.squareup.okhttp3:okhttp:jar:4.12.0:compile - omitted for conflict with 5.0.0-alpha.14) +[INFO] | +- (com.google.code.gson:gson:jar:2.13.2:compile - version managed from 2.12.1; omitted for duplicate) +[INFO] | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 1.7.36; omitted for duplicate) +[INFO] +- com.nimbusds:nimbus-jose-jwt:jar:9.37:compile (scope not updated to compile) +[INFO] | \- com.github.stephenc.jcip:jcip-annotations:jar:1.0-1:compile +[INFO] +- org.jsoup:jsoup:jar:1.22.1:compile +[INFO] +- commons-validator:commons-validator:jar:1.10.1:compile +[INFO] | +- commons-beanutils:commons-beanutils:jar:1.11.0:compile +[INFO] | | +- (commons-logging:commons-logging:jar:1.3.5:compile - version managed from 1.3.5; omitted for duplicate) +[INFO] | | \- (commons-collections:commons-collections:jar:3.2.2:compile - omitted for duplicate) +[INFO] | +- commons-digester:commons-digester:jar:2.1:compile +[INFO] | +- commons-logging:commons-logging:jar:1.3.5:compile (version managed from 1.3.5) +[INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile +[INFO] +- org.postgresql:postgresql:jar:42.7.10:runtime +[INFO] | \- org.checkerframework:checker-qual:jar:3.52.0:runtime +[INFO] +- org.liquibase:liquibase-core:jar:5.0.1:compile +[INFO] | +- com.opencsv:opencsv:jar:5.12.0:compile +[INFO] | | +- (org.apache.commons:commons-lang3:jar:3.19.0:compile - version managed from 3.18.0; omitted for duplicate) +[INFO] | | +- (org.apache.commons:commons-text:jar:1.13.1:compile - omitted for conflict with 1.14.0) +[INFO] | | \- (org.apache.commons:commons-collections4:jar:4.5.0:compile - omitted for duplicate) +[INFO] | +- org.yaml:snakeyaml:jar:2.5:compile (version managed from 2.5) +[INFO] | +- javax.xml.bind:jaxb-api:jar:2.3.1:compile +[INFO] | +- org.apache.commons:commons-collections4:jar:4.5.0:compile +[INFO] | +- org.apache.commons:commons-text:jar:1.14.0:compile +[INFO] | | \- (org.apache.commons:commons-lang3:jar:3.19.0:compile - version managed from 3.18.0; omitted for duplicate) +[INFO] | +- (org.apache.commons:commons-lang3:jar:3.19.0:compile - version managed from 3.19.0; omitted for duplicate) +[INFO] | \- commons-io:commons-io:jar:2.20.0:compile (scope not updated to compile) +[INFO] +- org.springframework.boot:spring-boot-starter-jooq:jar:4.0.3:compile +[INFO] | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- (org.springframework.boot:spring-boot-starter-jdbc:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-jooq:jar:4.0.3:compile (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-jdbc:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- (org.springframework.boot:spring-boot-transaction:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- (org.springframework.boot:spring-boot-jdbc:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] +- org.jooq.pro:jooq:jar:3.20.8:compile +[INFO] | \- io.r2dbc:r2dbc-spi:jar:1.0.0.RELEASE:compile (version managed from 1.0.0.RELEASE) +[INFO] | \- org.reactivestreams:reactive-streams:jar:1.0.4:compile (version managed from 1.0.3) +[INFO] +- org.projectlombok:lombok:jar:1.18.42:compile +[INFO] +- net.logstash.logback:logstash-logback-encoder:jar:8.0:compile +[INFO] | \- (com.fasterxml.jackson.core:jackson-databind:jar:2.20.2:compile - version managed from 2.17.2; omitted for duplicate) +[INFO] +- com.datadoghq:dd-trace-api:jar:1.60.1:compile +[INFO] | \- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 1.7.30; omitted for duplicate) +[INFO] +- org.springframework.boot:spring-boot-starter-test:jar:4.0.3:test +[INFO] | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-test:jar:4.0.3:test (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- (org.springframework:spring-test:jar:7.0.5:test - version managed from 7.0.5; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-test-autoconfigure:jar:4.0.3:test (version managed from 4.0.3) +[INFO] | | \- (org.springframework.boot:spring-boot-test:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- com.jayway.jsonpath:json-path:jar:2.10.0:test (version managed from 2.10.0) +[INFO] | | +- (net.minidev:json-smart:jar:2.6.0:test - version managed from 2.6.0; omitted for duplicate) +[INFO] | | \- (org.slf4j:slf4j-api:jar:2.0.17:test - version managed from 2.0.17; omitted for duplicate) +[INFO] | +- jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.4:runtime (version managed from 4.0.4; scope not updated to runtime) +[INFO] | | \- jakarta.activation:jakarta.activation-api:jar:2.1.4:runtime (version managed from 2.1.4) +[INFO] | +- net.minidev:json-smart:jar:2.6.0:test (version managed from 2.6.0) +[INFO] | | \- net.minidev:accessors-smart:jar:2.6.0:test +[INFO] | | \- org.ow2.asm:asm:jar:9.7.1:test +[INFO] | +- org.assertj:assertj-core:jar:3.27.7:test (version managed from 3.27.7) +[INFO] | | \- net.bytebuddy:byte-buddy:jar:1.17.8:runtime (version managed from 1.18.3; scope not updated to runtime) +[INFO] | +- (org.awaitility:awaitility:jar:4.3.0:test - version managed from 4.3.0; omitted for duplicate) +[INFO] | +- org.hamcrest:hamcrest:jar:3.0:test (version managed from 3.0) +[INFO] | +- org.junit.jupiter:junit-jupiter:jar:6.0.3:test (version managed from 6.0.3) +[INFO] | | +- org.junit.jupiter:junit-jupiter-api:jar:6.0.3:test (version managed from 6.0.3) +[INFO] | | | +- org.opentest4j:opentest4j:jar:1.3.0:test +[INFO] | | | +- org.junit.platform:junit-platform-commons:jar:6.0.3:test (version managed from 6.0.3) +[INFO] | | | | +- (org.apiguardian:apiguardian-api:jar:1.1.2:test - omitted for duplicate) +[INFO] | | | | \- (org.jspecify:jspecify:jar:1.0.0:test - version managed from 1.0.0; omitted for duplicate) +[INFO] | | | +- org.apiguardian:apiguardian-api:jar:1.1.2:test +[INFO] | | | \- (org.jspecify:jspecify:jar:1.0.0:test - version managed from 1.0.0; omitted for duplicate) +[INFO] | | +- org.junit.jupiter:junit-jupiter-params:jar:6.0.3:test (version managed from 6.0.3) +[INFO] | | | +- (org.junit.jupiter:junit-jupiter-api:jar:6.0.3:test - version managed from 6.0.3; omitted for duplicate) +[INFO] | | | +- (org.apiguardian:apiguardian-api:jar:1.1.2:test - omitted for duplicate) +[INFO] | | | \- (org.jspecify:jspecify:jar:1.0.0:test - version managed from 1.0.0; omitted for duplicate) +[INFO] | | \- org.junit.jupiter:junit-jupiter-engine:jar:6.0.3:test (version managed from 6.0.3) +[INFO] | | +- org.junit.platform:junit-platform-engine:jar:6.0.3:test (version managed from 6.0.3) +[INFO] | | | +- (org.opentest4j:opentest4j:jar:1.3.0:test - omitted for duplicate) +[INFO] | | | +- (org.junit.platform:junit-platform-commons:jar:6.0.3:test - version managed from 6.0.3; omitted for duplicate) +[INFO] | | | +- (org.apiguardian:apiguardian-api:jar:1.1.2:test - omitted for duplicate) +[INFO] | | | \- (org.jspecify:jspecify:jar:1.0.0:test - version managed from 1.0.0; omitted for duplicate) +[INFO] | | +- (org.junit.jupiter:junit-jupiter-api:jar:6.0.3:test - version managed from 6.0.3; omitted for duplicate) +[INFO] | | +- (org.apiguardian:apiguardian-api:jar:1.1.2:test - omitted for duplicate) +[INFO] | | \- (org.jspecify:jspecify:jar:1.0.0:test - version managed from 1.0.0; omitted for duplicate) +[INFO] | +- org.mockito:mockito-core:jar:5.20.0:test (version managed from 5.20.0) +[INFO] | | +- (net.bytebuddy:byte-buddy:jar:1.17.8:test - version managed from 1.17.7; omitted for duplicate) +[INFO] | | +- net.bytebuddy:byte-buddy-agent:jar:1.17.8:test (version managed from 1.17.7) +[INFO] | | \- org.objenesis:objenesis:jar:3.3:test +[INFO] | +- org.mockito:mockito-junit-jupiter:jar:5.20.0:test (version managed from 5.20.0) +[INFO] | | +- (org.mockito:mockito-core:jar:5.20.0:test - version managed from 5.20.0; omitted for duplicate) +[INFO] | | \- (org.junit.jupiter:junit-jupiter-api:jar:6.0.3:test - version managed from 5.13.4; omitted for duplicate) +[INFO] | +- org.skyscreamer:jsonassert:jar:1.5.3:test (version managed from 1.5.3) +[INFO] | | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test +[INFO] | +- org.springframework:spring-core:jar:7.0.5:compile (version managed from 7.0.5; scope not updated to compile) +[INFO] | | +- (commons-logging:commons-logging:jar:1.3.5:compile - version managed from 1.3.5; omitted for duplicate) +[INFO] | | \- (org.jspecify:jspecify:jar:1.0.0:compile - version managed from 1.0.0; omitted for duplicate) +[INFO] | +- org.springframework:spring-test:jar:7.0.5:test (version managed from 7.0.5) +[INFO] | | \- (org.springframework:spring-core:jar:7.0.5:test - version managed from 7.0.5; omitted for duplicate) +[INFO] | \- org.xmlunit:xmlunit-core:jar:2.10.4:test (version managed from 2.10.4) +[INFO] | \- (jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.4:test - version managed from 2.3.3; omitted for duplicate) +[INFO] +- org.springframework.boot:spring-boot-starter-webmvc-test:jar:4.0.3:test +[INFO] | +- org.springframework.boot:spring-boot-starter-jackson-test:jar:4.0.3:test (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-starter-jackson:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- (org.springframework.boot:spring-boot-starter-test:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- (org.springframework.boot:spring-boot-starter-test:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-starter-webmvc:jar:4.0.3:test (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-starter:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework.boot:spring-boot-starter-jackson:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework.boot:spring-boot-starter-tomcat:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework.boot:spring-boot-http-converter:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- (org.springframework.boot:spring-boot-webmvc:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- org.springframework.boot:spring-boot-webmvc-test:jar:4.0.3:test (version managed from 4.0.3) +[INFO] | | +- (org.springframework.boot:spring-boot-test-autoconfigure:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework.boot:spring-boot-webmvc:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework.boot:spring-boot-http-converter:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | | \- (org.springframework.boot:spring-boot-web-server:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- org.springframework.boot:spring-boot-resttestclient:jar:4.0.3:test (version managed from 4.0.3) +[INFO] | +- (org.springframework.boot:spring-boot-test:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | +- (org.springframework.boot:spring-boot-http-converter:jar:4.0.3:test - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- (org.springframework:spring-web:jar:7.0.5:test - version managed from 7.0.5; omitted for duplicate) +[INFO] +- org.springframework.security:spring-security-test:jar:7.0.3:test +[INFO] | +- org.springframework.security:spring-security-core:jar:7.0.3:compile (version managed from 7.0.3; scope not updated to compile) +[INFO] | | +- org.springframework.security:spring-security-crypto:jar:7.0.3:compile (version managed from 7.0.3) +[INFO] | | +- (org.springframework:spring-aop:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | +- org.springframework:spring-context:jar:7.0.5:compile (version managed from 7.0.4) +[INFO] | | | +- (org.springframework:spring-aop:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | +- (org.springframework:spring-expression:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | \- (io.micrometer:micrometer-observation:jar:1.16.3:compile - version managed from 1.16.3; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | +- org.springframework:spring-expression:jar:7.0.5:compile (version managed from 7.0.4) +[INFO] | | | \- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | \- (io.micrometer:micrometer-observation:jar:1.16.3:compile - version managed from 1.16.3; omitted for duplicate) +[INFO] | +- org.springframework.security:spring-security-web:jar:7.0.3:compile (version managed from 7.0.3; scope not updated to compile) +[INFO] | | +- (org.springframework.security:spring-security-core:jar:7.0.3:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-aop:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-context:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-expression:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | | \- (org.springframework:spring-web:jar:7.0.5:compile - version managed from 7.0.4; omitted for duplicate) +[INFO] | +- (org.springframework:spring-core:jar:7.0.5:test - version managed from 7.0.4; omitted for duplicate) +[INFO] | \- (org.springframework:spring-test:jar:7.0.5:test - version managed from 7.0.4; omitted for duplicate) +[INFO] +- org.springframework.boot:spring-boot-testcontainers:jar:4.0.3:test +[INFO] | +- org.springframework.boot:spring-boot-autoconfigure:jar:4.0.3:compile (version managed from 4.0.3; scope not updated to compile) +[INFO] | | \- (org.springframework.boot:spring-boot:jar:4.0.3:compile - version managed from 4.0.3; omitted for duplicate) +[INFO] | \- org.testcontainers:testcontainers:jar:2.0.3:test (version managed from 2.0.3) +[INFO] | +- (org.slf4j:slf4j-api:jar:2.0.17:test - version managed from 1.7.36; omitted for duplicate) +[INFO] | +- org.apache.commons:commons-compress:jar:1.28.0:test +[INFO] | | +- commons-codec:commons-codec:jar:1.19.0:test (version managed from 1.19.0) +[INFO] | | +- (commons-io:commons-io:jar:2.20.0:test - omitted for duplicate) +[INFO] | | \- (org.apache.commons:commons-lang3:jar:3.19.0:test - version managed from 3.18.0; omitted for duplicate) +[INFO] | +- org.rnorth.duct-tape:duct-tape:jar:1.0.8:test +[INFO] | | \- (org.jetbrains:annotations:jar:17.0.0:test - omitted for conflict with 13.0) +[INFO] | +- com.github.docker-java:docker-java-api:jar:3.7.0:test +[INFO] | | +- (com.fasterxml.jackson.core:jackson-annotations:jar:2.20:test - version managed from 2.20; omitted for duplicate) +[INFO] | | \- (org.slf4j:slf4j-api:jar:2.0.17:test - version managed from 1.7.30; omitted for duplicate) +[INFO] | \- com.github.docker-java:docker-java-transport-zerodep:jar:3.7.0:test +[INFO] | +- com.github.docker-java:docker-java-transport:jar:3.7.0:test +[INFO] | +- (org.slf4j:slf4j-api:jar:2.0.17:test - version managed from 1.7.36; omitted for duplicate) +[INFO] | \- net.java.dev.jna:jna:jar:5.18.1:test +[INFO] +- org.springframework.amqp:spring-rabbit-test:jar:4.0.2:test +[INFO] | +- org.springframework.amqp:spring-rabbit:jar:4.0.2:compile (version managed from 4.0.2; scope not updated to compile) +[INFO] | | +- org.springframework.amqp:spring-amqp:jar:4.0.2:compile (version managed from 4.0.2) +[INFO] | | | \- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | +- com.rabbitmq:amqp-client:jar:5.27.1:compile (version managed from 5.27.1; scope not updated to compile) +[INFO] | | | +- (org.slf4j:slf4j-api:jar:2.0.17:compile - version managed from 1.7.36; omitted for duplicate) +[INFO] | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.7.Final; omitted for duplicate) +[INFO] | | | +- io.netty:netty-codec:jar:4.2.10.Final:compile (version managed from 4.2.7.Final) +[INFO] | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- io.netty:netty-codec-compression:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | \- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- io.netty:netty-codec-protobuf:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | | \- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | \- io.netty:netty-codec-marshalling:jar:4.2.10.Final:compile (version managed from 4.2.10.Final) +[INFO] | | | | +- (io.netty:netty-common:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-buffer:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | +- (io.netty:netty-transport:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | | \- (io.netty:netty-codec-base:jar:4.2.10.Final:compile - version managed from 4.2.10.Final; omitted for duplicate) +[INFO] | | | \- (io.netty:netty-handler:jar:4.2.10.Final:compile - version managed from 4.2.7.Final; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-context:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-messaging:jar:7.0.5:compile - version managed from 7.0.3; omitted for duplicate) +[INFO] | | +- org.springframework:spring-tx:jar:7.0.5:compile (version managed from 7.0.3) +[INFO] | | | +- (org.springframework:spring-beans:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | | \- (org.springframework:spring-core:jar:7.0.5:compile - version managed from 7.0.5; omitted for duplicate) +[INFO] | | \- (io.micrometer:micrometer-observation:jar:1.16.3:compile - version managed from 1.16.2; omitted for duplicate) +[INFO] | +- org.springframework.amqp:spring-rabbit-junit:jar:4.0.2:test (version managed from 4.0.2) +[INFO] | | +- (org.springframework:spring-core:jar:7.0.5:test - version managed from 7.0.3; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-test:jar:7.0.5:test - version managed from 7.0.3; omitted for duplicate) +[INFO] | | +- (com.rabbitmq:amqp-client:jar:5.27.1:test - version managed from 5.27.1; omitted for duplicate) +[INFO] | | +- (org.springframework:spring-web:jar:7.0.5:test - version managed from 7.0.3; omitted for duplicate) +[INFO] | | +- (org.junit.jupiter:junit-jupiter-api:jar:6.0.3:test - version managed from 6.0.2; omitted for duplicate) +[INFO] | | \- (org.assertj:assertj-core:jar:3.27.7:test - version managed from 3.27.6; omitted for duplicate) +[INFO] | +- org.hamcrest:hamcrest-library:jar:3.0:test (version managed from 3.0) +[INFO] | | \- (org.hamcrest:hamcrest-core:jar:3.0:test - version managed from 3.0; omitted for duplicate) +[INFO] | +- org.hamcrest:hamcrest-core:jar:3.0:test (version managed from 3.0) +[INFO] | | \- (org.hamcrest:hamcrest:jar:3.0:test - version managed from 3.0; omitted for duplicate) +[INFO] | \- (org.mockito:mockito-core:jar:5.20.0:test - version managed from 5.20.0; omitted for duplicate) +[INFO] +- io.projectreactor:reactor-test:jar:3.8.3:test +[INFO] | +- io.projectreactor:reactor-core:jar:3.8.3:compile (version managed from 3.8.3; scope not updated to compile) +[INFO] | | +- (org.reactivestreams:reactive-streams:jar:1.0.4:compile - version managed from 1.0.4; omitted for duplicate) +[INFO] | | \- (org.jspecify:jspecify:jar:1.0.0:compile - version managed from 1.0.0; omitted for duplicate) +[INFO] | \- (org.jspecify:jspecify:jar:1.0.0:test - version managed from 1.0.0; omitted for duplicate) +[INFO] +- org.awaitility:awaitility:jar:4.3.0:test (scope not updated to test) +[INFO] | \- (org.hamcrest:hamcrest:jar:3.0:test - version managed from 2.1; omitted for duplicate) +[INFO] +- org.testcontainers:testcontainers-junit-jupiter:jar:2.0.3:test +[INFO] | \- (org.testcontainers:testcontainers:jar:2.0.3:test - version managed from 2.0.3; omitted for duplicate) +[INFO] +- org.testcontainers:testcontainers-postgresql:jar:2.0.3:test +[INFO] | \- org.testcontainers:testcontainers-jdbc:jar:2.0.3:test (version managed from 2.0.3) +[INFO] | \- org.testcontainers:testcontainers-database-commons:jar:2.0.3:test (version managed from 2.0.3) +[INFO] | \- (org.testcontainers:testcontainers:jar:2.0.3:test - version managed from 2.0.3; omitted for duplicate) +[INFO] \- org.testcontainers:testcontainers-rabbitmq:jar:2.0.3:test +[INFO] \- (org.testcontainers:testcontainers:jar:2.0.3:test - version managed from 2.0.3; omitted for duplicate) +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 0.561 s +[INFO] Finished at: 2026-03-09T20:37:27+01:00 +[INFO] ------------------------------------------------------------------------ diff --git a/tests/fixtures/mvn_dep_tree_conflicts.txt b/tests/fixtures/mvn_dep_tree_conflicts.txt new file mode 100644 index 000000000..72e8bd9ac --- /dev/null +++ b/tests/fixtures/mvn_dep_tree_conflicts.txt @@ -0,0 +1,16 @@ +[INFO] Scanning for projects... +[INFO] +[INFO] --- dependency:3.7.0:tree (default-cli) @ my-app --- +[INFO] com.example:my-app:jar:1.0.0 +[INFO] +- com.example:lib-a:jar:1.0.0:compile +[INFO] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.18.3:compile +[INFO] | | +- com.fasterxml.jackson.core:jackson-core:jar:2.18.3:compile +[INFO] | | \- com.fasterxml.jackson.core:jackson-annotations:jar:2.18.3:compile +[INFO] | \- org.slf4j:slf4j-api:jar:2.0.9:compile +[INFO] +- com.example:lib-b:jar:2.0.0:compile +[INFO] | +- (com.fasterxml.jackson.core:jackson-databind:jar:2.17.0:compile - omitted for conflict with 2.18.3) +[INFO] | \- (org.slf4j:slf4j-api:jar:2.0.7:compile - omitted for conflict with 2.0.9) +[INFO] \- com.example:lib-c:jar:3.0.0:compile +[INFO] \- (com.fasterxml.jackson.core:jackson-databind:jar:2.19.0:compile - omitted for conflict with 2.18.3) +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS diff --git a/tests/fixtures/mvn_dep_tree_simple.txt b/tests/fixtures/mvn_dep_tree_simple.txt new file mode 100644 index 000000000..92a436d85 --- /dev/null +++ b/tests/fixtures/mvn_dep_tree_simple.txt @@ -0,0 +1,22 @@ +[INFO] Scanning for projects... +[INFO] +[INFO] ------------------< com.example:my-app >------------------- +[INFO] Building my-app 1.0.0 +[INFO] from pom.xml +[INFO] --------------------------------[ jar ]--------------------------------- +[INFO] +[INFO] --- dependency:3.7.0:tree (default-cli) @ my-app --- +[INFO] com.example:my-app:jar:1.0.0 +[INFO] +- org.slf4j:slf4j-api:jar:2.0.17:compile +[INFO] +- com.google.guava:guava:jar:33.0.0-jre:compile +[INFO] | +- com.google.guava:failureaccess:jar:1.0.2:compile +[INFO] | \- com.google.guava:listenablefuture:jar:9999.0-empty-to-avoid-conflict-with-guava:compile +[INFO] +- com.fasterxml.jackson.core:jackson-databind:jar:2.19.2:compile +[INFO] | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.19.2:compile +[INFO] | \- com.fasterxml.jackson.core:jackson-core:jar:2.19.2:compile +[INFO] \- org.junit.jupiter:junit-jupiter:jar:5.11.4:test +[INFO] +- org.junit.jupiter:junit-jupiter-api:jar:5.11.4:test +[INFO] \- org.junit.jupiter:junit-jupiter-engine:jar:5.11.4:test +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ diff --git a/tests/fixtures/mvn_test_fail_auth.txt b/tests/fixtures/mvn_test_fail_auth.txt new file mode 100644 index 000000000..018dad29e --- /dev/null +++ b/tests/fixtures/mvn_test_fail_auth.txt @@ -0,0 +1,95 @@ +[INFO] Scanning for projects... +[WARNING] Could not transfer metadata from/to central: Checksum validation failed +[WARNING] +[WARNING] 1 problem was encountered while building the effective model for 'com.example:webapp:jar:1.0-SNAPSHOT' +[WARNING] +[WARNING] Total model problems reported: 1 +[WARNING] +[INFO] +[INFO] -------------------------------------------------< com.example:webapp >-------------------------------------------------- +[INFO] Building webapp 1.0-SNAPSHOT +[INFO] from pom.xml +[INFO] ---------------------------------------------------------[ jar ]---------------------------------------------------------- +[WARNING] 176 problems were encountered while building the effective model for 'com.example:dep:jar:3.2.0' during n/a +[WARNING] 130 problems were encountered while building the effective model for 'org.redisson:redisson-spring-boot-starter:jar:4.0.0' +[WARNING] 76 problems were encountered while building the effective model for 'com.playtika.testcontainers:embedded-redis:jar:3.1.11' +[INFO] +[INFO] --- clean:3.5.0:clean (default-clean) @ webapp --- +[INFO] Deleting /home/user/project/target +[INFO] +[INFO] --- jacoco:0.8.14:prepare-agent (prepare-agent) @ webapp --- +[INFO] argLine set to -javaagent:/home/user/.m2/repository/org/jacoco/org.jacoco.agent/0.8.14/org.jacoco.agent-0.8.14-runtime.jar +[INFO] +[INFO] --- testcontainers-jooq-codegen:0.0.4:generate (generate-jooq-sources) @ webapp --- +[WARNING] Could not transfer metadata from/to flyway-repo: Connection refused +[INFO] Image pull policy will be performed by: DefaultPullPolicy() +[WARNING] [stderr] Apr 08, 2026 5:45:45 PM liquibase.changelog +[WARNING] [stderr] INFO: Reading resource: db/changelog/2025/db.changelog-main.yaml +[WARNING] [stderr] INFO: Reading resource: db/changelog/2025/db.changelog-001.yaml +[WARNING] [stderr] INFO: Reading resource: db/changelog/2025/db.changelog-002.yaml +[INFO] +[INFO] --- maven-compiler-plugin:3.14.0:compile (default-compile) @ webapp --- +[INFO] Compiling 42 source files with javac [debug target 25] to target/classes +[INFO] +[INFO] --- maven-compiler-plugin:3.14.0:testCompile (default-testCompile) @ webapp --- +[INFO] Compiling 18 source files with javac [debug target 25] to target/test-classes +[WARNING] /home/user/project/src/test/java/com/example/TestFactory.java:[44,27] deprecated +[WARNING] /home/user/project/src/test/java/com/example/TestFactory.java:[48,45] deprecated +[WARNING] /home/user/project/src/test/java/com/example/SpecificationsTest.java:[60,44] deprecated +[INFO] /home/user/project/src/test/java/com/example/ProcessorTest.java: uses unchecked or unsafe operations. +[INFO] +[INFO] --- surefire:3.5.5:test (default-test) @ webapp --- +[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider +[WARNING] The system property java.util.logging.config.file is configured twice! +[INFO] +[INFO] ------------------------------------------------------- +[INFO] T E S T S +[INFO] ------------------------------------------------------- +[INFO] Running com.example.score.ScoreTypeTest +[INFO] Running com.example.company.EmailParserTest +[ERROR] Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.050 s <<< FAILURE! -- in com.example.company.EmailParserTest +[ERROR] Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.058 s <<< FAILURE! -- in com.example.score.ScoreTypeTest +[ERROR] com.example.company.EmailParserTest.should_extract_domain_from_email -- Time elapsed: 0.009 s <<< FAILURE! +org.opentest4j.AssertionFailedError: + +expected: "broken.example.com" + but was: "user.example.com" + at com.example.company.EmailParserTest.should_extract_domain_from_email(EmailParserTest.java:14) + +[ERROR] com.example.score.ScoreTypeTest.shouldMapToRole -- Time elapsed: 0.008 s <<< FAILURE! +org.opentest4j.AssertionFailedError: + +expected: "app:BROKEN" + but was: "app:all" + at com.example.score.ScoreTypeTest.shouldMapToRole(ScoreTypeTest.java:24) + +[INFO] +[INFO] Results: +[INFO] +[ERROR] Failures: +[ERROR] EmailParserTest.should_extract_domain_from_email:14 +expected: "broken.example.com" + but was: "user.example.com" +[ERROR] ScoreTypeTest.shouldMapToRole:24 +expected: "app:BROKEN" + but was: "app:all" +[INFO] +[ERROR] Tests run: 5, Failures: 2, Errors: 0, Skipped: 0 +[INFO] +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[INFO] BUILD FAILURE +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[INFO] Total time: 23.819 s +[INFO] Finished at: 2026-04-08T17:45:57+02:00 +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.5:test (default-test) on project webapp: There are test failures. +[ERROR] +[ERROR] See /home/user/project/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 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/MojoFailureException diff --git a/tests/fixtures/mvn_test_large_suite.txt b/tests/fixtures/mvn_test_large_suite.txt new file mode 100644 index 000000000..5ab6abb71 --- /dev/null +++ b/tests/fixtures/mvn_test_large_suite.txt @@ -0,0 +1,204 @@ +[INFO] Scanning for projects... +[WARNING] Could not transfer metadata from/to central: Checksum validation failed +[INFO] +[INFO] -----------------------< com.example:platform >------------------------ +[INFO] Building platform 2.0-SNAPSHOT +[INFO] from pom.xml +[INFO] --------------------------------[ jar ]--------------------------------- +[WARNING] 42 problems were encountered while building the effective model +[INFO] +[INFO] --- maven-compiler-plugin:3.14.0:compile (default-compile) @ platform --- +[INFO] Compiling 120 source files with javac +[INFO] +[INFO] --- maven-compiler-plugin:3.14.0:testCompile (default-testCompile) @ platform --- +[INFO] Compiling 85 source files with javac +[WARNING] /home/user/project/src/test/java/com/example/DeprecatedTest.java:[10,5] deprecated +[WARNING] /home/user/project/src/test/java/com/example/OtherTest.java:[20,8] deprecated +[INFO] +[INFO] --- surefire:3.5.4:test (default-test) @ platform --- +[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider +[INFO] +[INFO] ------------------------------------------------------- +[INFO] T E S T S +[INFO] ------------------------------------------------------- +[INFO] Running com.example.registry.SearchModelTest +[INFO] Tests run: 50, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.123 s -- in com.example.registry.SearchModelTest +[INFO] Running com.example.registry.IndexServiceTest +[INFO] Tests run: 30, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.456 s -- in com.example.registry.IndexServiceTest +[INFO] Running com.example.organization.OrgServiceTest +[INFO] Tests run: 25, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.234 s -- in com.example.organization.OrgServiceTest +[INFO] Running com.example.organization.PatchableFieldTest +[ERROR] Tests run: 6, Failures: 0, Errors: 6, Skipped: 0, Time elapsed: 0.010 s <<< FAILURE! -- in com.example.organization.PatchableFieldTest +[ERROR] com.example.organization.PatchableFieldTest.fromStrings_returns_empty -- Time elapsed: 0 s <<< ERROR! +java.lang.Error: +Unresolved compilation problem: + log cannot be resolved + + at com.example.organization.PatchableFieldTest.fromStrings_returns_empty(PatchableFieldTest.java:12) + +[ERROR] com.example.organization.PatchableFieldTest.fromStrings_converts_names -- Time elapsed: 0 s <<< ERROR! +java.lang.Error: +Unresolved compilation problem: + log cannot be resolved + + at com.example.organization.PatchableFieldTest.fromStrings_converts_names(PatchableFieldTest.java:20) + +[ERROR] com.example.organization.PatchableFieldTest.shouldUpdate_false_when_empty -- Time elapsed: 0 s <<< ERROR! +java.lang.ClassCastException: class com.example.organization.PatchableField not an enum + at com.example.organization.PatchableFieldTest.shouldUpdate_false_when_empty(PatchableFieldTest.java:36) + +[ERROR] com.example.organization.PatchableFieldTest.shouldUpdate_true_when_null -- Time elapsed: 0 s <<< ERROR! +java.lang.Error: +Unresolved compilation problem: + + at com.example.organization.PatchableField.shouldUpdate(PatchableField.java:29) + +[ERROR] com.example.organization.PatchableFieldTest.shouldUpdateAny_true -- Time elapsed: 0 s <<< ERROR! +java.lang.NullPointerException: Cannot invoke "java.lang.Enum.getDeclaringClass()" because "e1" is null + at com.example.organization.PatchableFieldTest.shouldUpdateAny_true(PatchableFieldTest.java:49) + +[ERROR] com.example.organization.PatchableFieldTest.fromStrings_ignores_unknown -- Time elapsed: 0 s <<< ERROR! +java.lang.Error: +Unresolved compilation problem: + log cannot be resolved + + at com.example.organization.PatchableFieldTest.fromStrings_ignores_unknown(PatchableFieldTest.java:55) + +[INFO] Running com.example.search.SearchReadModelTest +[ERROR] Tests run: 3, Failures: 3, Errors: 0, Skipped: 0, Time elapsed: 4.567 s <<< FAILURE! -- in com.example.search.SearchReadModelTest +[ERROR] com.example.search.SearchReadModelTest.should_get_person_ratings -- Time elapsed: 1.234 s <<< FAILURE! +java.lang.AssertionError: +Expecting actual: + [("Group1", {SELF=50, SUPERVISOR=35}, 40, null, 3), + ("Group2", {SELF=80}, 80, null, 1)] +to have size: + <1> +but had size: + <2> + + at com.example.search.SearchReadModelTest.should_get_person_ratings(SearchReadModelTest.java:85) + +[ERROR] com.example.search.SearchReadModelTest.should_get_company_ratings -- Time elapsed: 0.987 s <<< FAILURE! +org.assertj.core.error.AssertJMultipleFailuresError: +[List check single element] (1 failure) +-- failure 1 -- +expected: 42 + but was: 38 + + at com.example.search.SearchReadModelTest.should_get_company_ratings(SearchReadModelTest.java:120) + +[ERROR] com.example.search.SearchReadModelTest.should_not_include_unknown_skills -- Time elapsed: 0.456 s <<< FAILURE! +org.assertj.core.error.AssertJMultipleFailuresError: +[List check single element] (1 failure) +-- failure 1 -- +expected size: 0 but was: 1 + + at com.example.search.SearchReadModelTest.should_not_include_unknown_skills(SearchReadModelTest.java:150) + +[INFO] Running com.example.payment.PaymentServiceTest +[INFO] Tests run: 100, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 8.901 s -- in com.example.payment.PaymentServiceTest +[INFO] Running com.example.report.ReportGeneratorTest +[INFO] Tests run: 45, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.210 s -- in com.example.report.ReportGeneratorTest +[INFO] Running com.example.integration.ApiIntegrationTest +[ERROR] Tests run: 14, Failures: 0, Errors: 14, Skipped: 0, Time elapsed: 0.015 s <<< FAILURE! -- in com.example.integration.ApiIntegrationTest +[ERROR] com.example.integration.ApiIntegrationTest.shouldCreateUser -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldDeleteUser -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldUpdateUser -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldListUsers -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldGetUser -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldSearchUsers -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldPaginateUsers -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldFilterUsers -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldSortUsers -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldExportUsers -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldImportUsers -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldValidateInput -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldHandleConcurrency -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.integration.ApiIntegrationTest.shouldRetryOnFailure -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[INFO] +[INFO] Results: +[INFO] +[ERROR] Failures: +[ERROR] SearchReadModelTest.should_get_person_ratings:85 expected size: 1 but was: 2 +[ERROR] SearchReadModelTest.should_get_company_ratings:120 expected: 42 but was: 38 +[ERROR] SearchReadModelTest.should_not_include_unknown_skills:150 expected size: 0 but was: 1 +[ERROR] Errors: +[ERROR] PatchableFieldTest.fromStrings_returns_empty >> Error Unresolved compilation problem: log cannot be resolved +[ERROR] PatchableFieldTest.fromStrings_converts_names >> Error Unresolved compilation problem: log cannot be resolved +[ERROR] PatchableFieldTest.shouldUpdate_false_when_empty >> ClassCast not an enum +[ERROR] PatchableFieldTest.shouldUpdate_true_when_null >> Error Unresolved compilation problem +[ERROR] PatchableFieldTest.shouldUpdateAny_true >> NullPointer Cannot invoke "java.lang.Enum.getDeclaringClass()" +[ERROR] PatchableFieldTest.fromStrings_ignores_unknown >> Error Unresolved compilation problem: log cannot be resolved +[ERROR] ApiIntegrationTest.shouldCreateUser >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldDeleteUser >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldUpdateUser >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldListUsers >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldGetUser >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldSearchUsers >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldPaginateUsers >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldFilterUsers >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldSortUsers >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldExportUsers >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldImportUsers >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldValidateInput >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldHandleConcurrency >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ApiIntegrationTest.shouldRetryOnFailure >> IllegalState ApplicationContext failure threshold (1) exceeded +[INFO] +[ERROR] Tests run: 3262, Failures: 3, Errors: 20, Skipped: 4 +[INFO] +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[INFO] BUILD FAILURE +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[INFO] Total time: 03:25 min +[INFO] Finished at: 2026-04-08T21:07:54+02:00 +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.4:test (default-test) on project platform: There are test failures. +[ERROR] +[ERROR] See /home/user/project/target/surefire-reports for the individual test results. +[ERROR] -> [Help 1] +[ERROR] +[ERROR] Re-run Maven using the '-X' switch to enable full debug logging. +[ERROR] +[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException diff --git a/tests/fixtures/mvn_test_many_failures.txt b/tests/fixtures/mvn_test_many_failures.txt new file mode 100644 index 000000000..a3466fff9 --- /dev/null +++ b/tests/fixtures/mvn_test_many_failures.txt @@ -0,0 +1,115 @@ +[INFO] Scanning for projects... +[WARNING] The requested profile "unit-tests" could not be activated because it does not exist. +[INFO] +[INFO] -----------------------< com.example:myapp >------------------------ +[INFO] Building myapp 0.0.1-SNAPSHOT +[INFO] from pom.xml +[INFO] --------------------------------[ jar ]--------------------------------- +[INFO] +[INFO] --- resources:3.3.1:resources (default-resources) @ myapp --- +[INFO] Copying 2 resources from src/main/resources to target/classes +[INFO] +[INFO] --- surefire:3.5.5:test (default-test) @ myapp --- +[INFO] +[INFO] ------------------------------------------------------- +[INFO] T E S T S +[INFO] ------------------------------------------------------- +[INFO] Running com.example.controller.ItemControllerTest +[ERROR] Tests run: 4, Failures: 0, Errors: 4, Skipped: 0, Time elapsed: 8.737 s <<< FAILURE! -- in com.example.controller.ItemControllerTest +[ERROR] com.example.controller.ItemControllerTest.shouldReturn404ForNonExistent -- Time elapsed: 0.003 s <<< ERROR! +java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@7b05dab testClass = com.example.controller.ItemControllerTest, locations = [], classes = [com.example.MyApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"]] + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.lambda$loadContext$0(DefaultCacheAwareContextLoaderDelegate.java:195) + at org.springframework.test.context.cache.DefaultContextCache.put(DefaultContextCache.java:214) + at java.base/java.lang.reflect.Method.invoke(Method.java:565) + +[ERROR] com.example.controller.ItemControllerTest.shouldCreate -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.ItemControllerTest.shouldUpdate -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.ItemControllerTest.shouldDelete -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[INFO] Running com.example.controller.OrderControllerTest +[ERROR] Tests run: 7, Failures: 0, Errors: 7, Skipped: 0, Time elapsed: 0.012 s <<< FAILURE! -- in com.example.controller.OrderControllerTest +[ERROR] com.example.controller.OrderControllerTest.shouldReturn404 -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.OrderControllerTest.shouldUpdate -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.OrderControllerTest.shouldCreate -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.OrderControllerTest.shouldDelete -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.OrderControllerTest.shouldList -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.OrderControllerTest.shouldRejectDuplicate -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.OrderControllerTest.shouldGetById -- Time elapsed: 0.001 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[INFO] Running com.example.controller.LeaseControllerTest +[ERROR] Tests run: 14, Failures: 0, Errors: 14, Skipped: 0, Time elapsed: 0.019 s <<< FAILURE! -- in com.example.controller.LeaseControllerTest +[ERROR] com.example.controller.LeaseControllerTest.shouldReturn400 -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.LeaseControllerTest.shouldList -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[ERROR] com.example.controller.LeaseControllerTest.shouldGetById -- Time elapsed: 0 s <<< ERROR! +java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded + at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:157) + +[INFO] +[INFO] Results: +[INFO] +[ERROR] Errors: +[ERROR] ItemControllerTest.shouldReturn404ForNonExistent >> IllegalState Failed to load ApplicationContext +[ERROR] ItemControllerTest.shouldCreate >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ItemControllerTest.shouldUpdate >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] ItemControllerTest.shouldDelete >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] OrderControllerTest.shouldReturn404 >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] OrderControllerTest.shouldUpdate >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] OrderControllerTest.shouldCreate >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] OrderControllerTest.shouldDelete >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] OrderControllerTest.shouldList >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] OrderControllerTest.shouldRejectDuplicate >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] OrderControllerTest.shouldGetById >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] LeaseControllerTest.shouldReturn400 >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] LeaseControllerTest.shouldList >> IllegalState ApplicationContext failure threshold (1) exceeded +[ERROR] LeaseControllerTest.shouldGetById >> IllegalState ApplicationContext failure threshold (1) exceeded +[INFO] +[ERROR] Tests run: 28, Failures: 0, Errors: 28, Skipped: 0 +[INFO] +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD FAILURE +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 22.379 s +[INFO] Finished at: 2026-04-08T20:58:01+02:00 +[INFO] ------------------------------------------------------------------------ +[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.5.5:test (default-test) on project myapp: There are test failures. +[ERROR] +[ERROR] See /home/user/project/target/surefire-reports for the individual test results. +[ERROR] -> [Help 1] +[ERROR] +[ERROR] Re-run Maven using the '-X' switch to enable full debug logging. +[ERROR] +[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException diff --git a/tests/fixtures/mvn_test_multimodule.txt b/tests/fixtures/mvn_test_multimodule.txt new file mode 100644 index 000000000..ab3ea3404 --- /dev/null +++ b/tests/fixtures/mvn_test_multimodule.txt @@ -0,0 +1,118 @@ +[INFO] Scanning for projects... +[INFO] Building parent 1.0-SNAPSHOT +[INFO] --------------------------------[ pom ]--------------------------------- +[INFO] +[INFO] --- maven-surefire-plugin:3.1.2:test (default-test) @ common --- +[INFO] +[INFO] ------------------------------------------------------- +[INFO] T E S T S +[INFO] ------------------------------------------------------- +[INFO] Running com.example.common.PathUtilsTest +[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.056 s -- in com.example.common.PathUtilsTest +[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0 +[INFO] +[INFO] Results: +[INFO] +[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0 +[INFO] +[INFO] --- maven-surefire-plugin:3.1.2:test (default-test) @ data --- +[INFO] +[INFO] ------------------------------------------------------- +[INFO] T E S T S +[INFO] ------------------------------------------------------- +[INFO] Running com.example.data.RepositoryTest +[INFO] Tests run: 34, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.036 s -- in com.example.data.RepositoryTest +[INFO] Running com.example.data.ModelTest +[INFO] Tests run: 25, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.370 s -- in com.example.data.ModelTest +[INFO] Tests run: 194, Failures: 0, Errors: 0, Skipped: 0 +[INFO] +[INFO] Results: +[INFO] +[INFO] Tests run: 194, Failures: 0, Errors: 0, Skipped: 0 +[INFO] +[INFO] --- maven-surefire-plugin:3.1.2:test (default-test) @ ml --- +[INFO] +[INFO] ------------------------------------------------------- +[INFO] T E S T S +[INFO] ------------------------------------------------------- +[INFO] Running com.example.ml.BenchmarkTest +[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.632 s -- in com.example.ml.BenchmarkTest +[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0 +[INFO] +[INFO] Results: +[INFO] +[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0 +[INFO] +[INFO] --- maven-surefire-plugin:3.1.2:test (default-test) @ services --- +[INFO] +[INFO] ------------------------------------------------------- +[INFO] T E S T S +[INFO] ------------------------------------------------------- +[INFO] Running com.example.services.FileHasherTest +[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 s -- in com.example.services.FileHasherTest +[INFO] Running com.example.services.GitDiffReaderTest +[ERROR] Tests run: 4, Failures: 0, Errors: 4, Skipped: 0, Time elapsed: 3.167 s <<< FAILURE! -- in com.example.services.GitDiffReaderTest +[ERROR] com.example.services.GitDiffReaderTest.shouldBuildDiffWithFiltering -- Time elapsed: 3.109 s <<< ERROR! +org.eclipse.jgit.api.errors.ServiceUnavailableException: Signing service is not available + at org.eclipse.jgit.api.CommitCommand.sign(CommitCommand.java:328) + at org.eclipse.jgit.api.CommitCommand.call(CommitCommand.java:283) + at com.example.services.GitDiffReaderTest.shouldBuildDiffWithFiltering(GitDiffReaderTest.java:116) + at java.base/java.lang.reflect.Method.invoke(Method.java:565) + +[ERROR] com.example.services.GitDiffReaderTest.shouldReturnEmptyDiff -- Time elapsed: 0.013 s <<< ERROR! +org.eclipse.jgit.api.errors.ServiceUnavailableException: Signing service is not available + at org.eclipse.jgit.api.CommitCommand.sign(CommitCommand.java:328) + at org.eclipse.jgit.api.CommitCommand.call(CommitCommand.java:283) + at com.example.services.GitDiffReaderTest.shouldReturnEmptyDiff(GitDiffReaderTest.java:67) + at java.base/java.lang.reflect.Method.invoke(Method.java:565) + +[ERROR] com.example.services.GitDiffReaderTest.shouldBuildDiff -- Time elapsed: 0.012 s <<< ERROR! +org.eclipse.jgit.api.errors.ServiceUnavailableException: Signing service is not available + at org.eclipse.jgit.api.CommitCommand.sign(CommitCommand.java:328) + at com.example.services.GitDiffReaderTest.shouldBuildDiff(GitDiffReaderTest.java:35) + +[ERROR] com.example.services.GitDiffReaderTest.shouldBuildDiffForDevops -- Time elapsed: 0.011 s <<< ERROR! +org.eclipse.jgit.api.errors.ServiceUnavailableException: Signing service is not available + at org.eclipse.jgit.api.CommitCommand.sign(CommitCommand.java:328) + at com.example.services.GitDiffReaderTest.shouldBuildDiffForDevops(GitDiffReaderTest.java:88) + +[INFO] Running com.example.services.IoHelperTest +[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 s -- in com.example.services.IoHelperTest +[INFO] Tests run: 651, Failures: 0, Errors: 4, Skipped: 4 +[INFO] +[INFO] Results: +[INFO] +[ERROR] Errors: +[ERROR] GitDiffReaderTest.shouldBuildDiff:35 >> ServiceUnavailable Signing service is not available +[ERROR] GitDiffReaderTest.shouldBuildDiffForDevops:88 >> ServiceUnavailable Signing service is not available +[ERROR] GitDiffReaderTest.shouldBuildDiffWithFiltering:116 >> ServiceUnavailable Signing service is not available +[ERROR] GitDiffReaderTest.shouldReturnEmptyDiff:67 >> ServiceUnavailable Signing service is not available +[INFO] +[ERROR] Tests run: 860, Failures: 0, Errors: 4, Skipped: 4 +[INFO] +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[INFO] Reactor Summary for parent 1.0-SNAPSHOT: +[INFO] +[INFO] parent ............................................................................................... SUCCESS [ 0.189 s] +[INFO] common ............................................................................................... SUCCESS [ 0.959 s] +[INFO] data ................................................................................................. SUCCESS [ 28.127 s] +[INFO] ml ................................................................................................... SUCCESS [ 2.214 s] +[INFO] services ............................................................................................. FAILURE [ 58.575 s] +[INFO] integrations ......................................................................................... SKIPPED +[INFO] webapp ............................................................................................... SKIPPED +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[INFO] BUILD FAILURE +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[INFO] Total time: 01:31 min +[INFO] Finished at: 2026-04-08T20:45:10+02:00 +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.1.2:test (default-test) on project services: There are test failures. +[ERROR] +[ERROR] See /home/user/project/services/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 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/MojoFailureException diff --git a/tests/fixtures/mvn_test_pass_large_ansi.txt b/tests/fixtures/mvn_test_pass_large_ansi.txt new file mode 100644 index 000000000..93e3ac76e --- /dev/null +++ b/tests/fixtures/mvn_test_pass_large_ansi.txt @@ -0,0 +1,53 @@ +[INFO] Loaded 22505 auto-discovered prefixes for remote repository central (prefixes-central.txt) +[INFO] Scanning for projects... +[WARNING] Could not transfer metadata /.meta/prefixes.txt from/to shibboleth-releases-5d99c0486312ae43e4bc39d107c6522d62203c00 (https://build.shibboleth.net/nexus/content/repositories/releases/): Checksum validation failed, no checksums available +[INFO] -------------------------------------------------< com.example:auth >-------------------------------------------------- +[INFO] Building auth 1.3-SNAPSHOT +[INFO] from pom.xml +[INFO] ---------------------------------------------------------[ jar ]---------------------------------------------------------- +[INFO] Loaded 22505 auto-discovered prefixes for remote repository central (prefixes-central.txt) +[INFO] Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor') +[INFO] Found Docker environment with local Unix socket (unix:///var/run/docker.sock) +[INFO] Docker host IP address is localhost +[INFO] Creating container for image: testcontainers/ryuk:0.14.0 +[INFO] Container testcontainers/ryuk:0.14.0 started in PT0.44146219S +[INFO] ✔︎ Docker server version should be at least 1.6.0 +[INFO] Container postgres:17 started in PT5.716666928S +[WARNING] [stderr] Apr 08, 2026 9:25:10 PM liquibase.database +[WARNING] [stderr] Apr 08, 2026 9:25:10 PM liquibase.changelog +[WARNING] [stderr] INFO: Reading resource: db/changelog/2024/db.changelog.2024-1719408042.sql +[WARNING] [stderr] Apr 08, 2026 9:25:10 PM liquibase.changelog +[INFO] ------------------------------------------------------- +[INFO] T E S T S +[INFO] ------------------------------------------------------- +[INFO] Running com.example.webapp.user.PermissionCompareTest +[INFO] Running com.example.webapp.user.ModifyTeamTest +[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 s -- in com.example.webapp.user.PermissionCompareTest +[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.065 s -- in com.example.webapp.user.PermissionGrouperTest +[INFO] Running com.example.webapp.user.PermissionProcessorTest +[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.004 s -- in com.example.webapp.user.PermissionProcessorTest +[INFO] Running com.example.webapp.user.ProductHelperTest +[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.003 s -- in com.example.webapp.user.ProductHelperTest +[INFO] Running com.example.webapp.user.RelayStateUtilTest +[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.015 s -- in com.example.webapp.user.RelayStateUtilTest +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1719408042.sql::dev2:1719408042-1::dev2 +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1719478245.yaml::1719478245-1::dev1 +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1719571809.yaml::1719571809-1::dev1 +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1721123826.yaml::1721123826-1::dev1 +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1726125249.yaml::1726125249-1::dev1 +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1726133977.yaml::1726133977-1::dev2 +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1726647573.yaml::1726647573-1::dev1 +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1727864000.sql::1727864000-1::dev3 +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1727939482.yaml::1727939482-1::dev1 +[INFO] [stdout] Running Changeset: db/changelog/2024/db.changelog.2024-1728049660.yaml::1728049660-1::dev1 +[INFO] Tests run: 61, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 18.44 s -- in com.example.webapp.scim.ScimUserControllerIntegrationTest +[INFO] Results: +[INFO] +[INFO] Tests run: 959, Failures: 0, Errors: 0, Skipped: 9 +[INFO] +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[INFO] BUILD SUCCESS +[INFO] -------------------------------------------------------------------------------------------------------------------------- +[INFO] Total time: 01:32 min +[INFO] Finished at: 2026-04-08T21:26:30+02:00 +[INFO] -------------------------------------------------------------------------------------------------------------------------- diff --git a/tests/fixtures/mvn_test_pass_mavenmcp.txt b/tests/fixtures/mvn_test_pass_mavenmcp.txt new file mode 100644 index 000000000..beb535770 --- /dev/null +++ b/tests/fixtures/mvn_test_pass_mavenmcp.txt @@ -0,0 +1,35 @@ +[INFO] Scanning for projects... +[INFO] +[INFO] -------------------< com.example:my-app >-------------------- +[INFO] Building my-app 1.0-SNAPSHOT +[INFO] from pom.xml +[INFO] --------------------------------[ jar ]--------------------------------- +[INFO] +[INFO] --- maven-compiler-plugin:3.13.0:compile (default-compile) --- +[INFO] Nothing to compile - all classes are up to date. +[INFO] +[INFO] --- maven-surefire-plugin:3.5.4:test (default-test) --- +[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider +[INFO] +[INFO] ------------------------------------------------------- +[INFO] T E S T S +[INFO] ------------------------------------------------------- +[INFO] Running com.example.config.AppConfigTest +[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.047 s -- in com.example.config.AppConfigTest +[INFO] Running com.example.service.UserServiceTest +[INFO] Tests run: 12, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 s -- in com.example.service.UserServiceTest +[INFO] Running com.example.controller.ApiControllerTest +[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.325 s -- in com.example.controller.ApiControllerTest +[INFO] Running com.example.repository.ItemRepositoryTest +[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.060 s -- in com.example.repository.ItemRepositoryTest +[INFO] +[INFO] Results: +[INFO] +[INFO] Tests run: 183, Failures: 0, Errors: 0, Skipped: 0 +[INFO] +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 4.748 s +[INFO] Finished at: 2026-04-08T18:26:55+02:00 +[INFO] ------------------------------------------------------------------------