avelino / avelino/jbundle

Structured build output with per-phase metrics

Open
#18 1 comment 0 reactions 0 assignees View on GitHub
area/cli dx
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.