Structured build output with per-phase metrics
- Dominant language
- Rust
- Stars
- 181
- Forks
- 11
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
The build pipeline currently provides minimal feedback. Only the JDK download has a progress bar; other phases run silently. When the build completes, users get no summary of what happened — how long each phase took, what was detected, how large the output is, or whether optimization opportunities exist.
## Inspiration
GraalVM's native-image provides rich [build output](https://www.graalvm.org/latest/reference-manual/native-image/overview/BuildOutput/) that shows per-phase metrics and counts:
```
GraalVM Native Image: Generating 'application' (executable)
========================================================
[1/8] Initializing... (3.2s @ 0.15GB)
Java version: 21+35, vendor version: GraalVM CE 21-dev
[2/8] Performing analysis... [*****] (5.1s @ 0.84GB)
3,216 reachable types, 4,708 fields, 17,492 methods
[3/8] Building universe... (1.2s @ 0.84GB)
[4/8] Parsing methods... [**] (1.5s @ 1.13GB)
[5/8] Inlining methods... [***] (0.8s @ 1.13GB)
[6/8] Compiling methods... [****] (8.7s @ 1.98GB)
[7/8] Layouting methods... [**] (1.3s @ 1.98GB)
[8/8] Creating image... [***] (3.1s @ 1.98GB)
--------------------------------------------------------
Top 10 origins of code area: Top 10 object types in image heap:
3.81MB java.base 827.16KB byte[] for strings
1.20MB app.jar 459.72KB java.lang.String
... ...
--------------------------------------------------------
7.3MB Code area 2.1MB Image heap
25.1s Total build time
```
Key aspects: phase timing, counts of processed items, memory usage, and a summary showing what contributed most to the output size.
## Expected Outcome
jbundle should produce structured, informative output for each build phase:
```
jbundle: Packaging './my-app' → './dist/app'
═══════════════════════════════════════════════════════════
[1/6] Detecting... (0.1s)
Build system: deps.edn (clojure -T:build uber)
[2/6] Building uberjar... (34.2s)
Output: target/app-standalone.jar (87.3 MB)
Namespaces: 142 AOT-compiled
[3/6] Downloading JDK 21... ████████████████████ (12.8s)
Source: Adoptium, linux-x64, 48.2 MB
Cache: ~/.jbundle/cache/jdk-21-linux-x64/
[4/6] Analyzing modules... (2.1s)
Detected: java.base, java.sql, java.naming (+4 more)
Method: jdeps static analysis
[5/6] Creating runtime (jlink)... (8.4s)
Modules: 7 of 71 available
Runtime size: 38.1 MB (compressed: zip-6)
[6/6] Packing binary... (1.8s)
Payload: runtime (38.1 MB) + app.jar (87.3 MB)
───────────────────────────────────────────────────────────
Output: ./dist/app
Final size: 94.2 MB
Breakdown: runtime 40% │ app 55% │ stub 5%
Total time: 59.4s
💡 Tip: --shrink could save ~12 MB (estimated)
═══════════════════════════════════════════════════════════
```
### Features
- **Per-phase timing**: shows where time is spent (useful for optimization)
- **Counts and sizes**: concrete numbers, not just "done"
- **Breakdown summary**: at a glance, understand the output composition
- **Actionable tips**: suggest flags that could improve the result
- **TTY-aware**: full formatting when interactive, plain text in CI (no ANSI codes when piped)
- **Machine-readable mode**: `--output-format json` for CI parsing and trend tracking
### JSON Output (for CI)
```json
{
"version": "0.1.0",
"phases": [
{"name": "detect", "duration_ms": 100, "build_system": "deps.edn"},
{"name": "build", "duration_ms": 34200, "jar_size_bytes": 91545600},
...
],
"output": {
"path": "./dist/app",
"size_bytes": 98784256,
"runtime_bytes": 39953612,
"app_bytes": 91545600
}
}
```
This enables CI pipelines to track binary size over time, alert on regressions, and generate dashboards — similar to how native-image users [monitor build metrics](https://www.graalvm.org/latest/reference-manual/native-image/overview/BuildOutput/) across releases.
Contributor guide
Research direction
The issue names no files, tests, or entry points. Start by mapping the existing build pipeline and JDK download progress implementation, then identify where phase results and CLI output are assembled. Done means agreeing on the phase metrics, summary, TTY behavior, and JSON schema before implementation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clojure, java, rust
- Domain
- build-system, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100