Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ jobs:
- name: Check formatting (Prettier)
run: make format-check

# uv provides `uvx`, which the Makefile uses to run a pinned Ruff.
- uses: astral-sh/setup-uv@v5

- name: Lint Python (Ruff)
run: make py-lint

- name: Check Python formatting (Ruff)
run: make py-format-check

# Type-check the frontend (svelte-check) — vite build strips types without
# checking them, so without this a type regression would slip through.
- name: Type-check frontend
Expand Down
19 changes: 17 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
.DEFAULT_GOAL := help

# Ruff is run via uvx so there's nothing to install or commit; pinned for
# reproducibility between local runs and CI.
RUFF := uvx ruff@0.14.5

help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-12s\033[0m %s\n", $$1, $$2}'

Expand All @@ -12,12 +16,23 @@ web-dev: ## Run the frontend dev server with HMR (reads web/public/mock-data.jso
web-check: ## Type-check the frontend (svelte-check); does not build
cd web && bun install --frozen-lockfile && bun run check

format: ## Format the whole repo with Prettier
format: py-format ## Format the whole repo (Prettier + Ruff)
@bun install --frozen-lockfile >/dev/null && bunx prettier --write .

format-check: ## Check formatting with Prettier (CI); does not write
@bun install --frozen-lockfile >/dev/null && bunx prettier --check .

py-lint: ## Lint the Python sources with Ruff
@$(RUFF) check .

py-format: ## Format the Python sources with Ruff
@$(RUFF) format .

py-format-check: ## Check Python formatting with Ruff (CI); does not write
@$(RUFF) format --check .

check: format-check py-lint py-format-check web-check ## Run all static checks (mirrors CI gates)

build: web-build ## Build the single-file artifact into dist/repo-intel
python3 build.py dist/repo-intel

Expand All @@ -37,4 +52,4 @@ gc: ## Repack git history (committed dist/repo-intel deltas down to ~nothing)
after=$$(git count-objects -vH | awk '/size-pack:/{print $$2 $$3}'); \
echo "pack: $$before -> $$after"

.PHONY: help web-build web-dev web-check format format-check build techdata dev install-hooks gc
.PHONY: help web-build web-dev web-check format format-check py-lint py-format py-format-check check build techdata dev install-hooks gc
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,17 @@ repo-intel facebook/react --clone # analyse via bare clone

## Development

| File | Purpose |
| ----------------- | ------------------------------------------------------------------------------------ |
| `repo-intel.py` | The script. Holds `TEMPLATE` + `TECHDATA` placeholders until bundled |
| `web/` | Frontend app (Svelte 5 + Vite + TypeScript). `bun run build` → `web/dist/index.html` |
| `web/src/lib/` | Dashboard engine: heatmap, timeline, charts, popovers, table (one module each) |
| `techdata.json` | Generated language + framework detection data (committed; embedded at build) |
| `gen_techdata.py` | Regenerates `techdata.json` from GitHub Linguist + a curated framework map |
| `build.py` | Substitutes the `TEMPLATE` / `TECHDATA` lines with their data as a `repr()` |
| `dist/repo-intel` | The built single-file artifact (committed; this is what curl/Action/Homebrew use) |
| File | Purpose |
| ------------------------- | -------------------------------------------------------------------------------------------------- |
| `repo-intel.py` | The script. Holds `TEMPLATE` + `TECHDATA` placeholders until bundled |
| `web/` | Frontend app (Svelte 5 + Vite + TypeScript). `bun run build` → `web/dist/index.html` |
| `web/src/App.svelte` | Root component — composes the dashboard from the `lib/components/` pieces |
| `web/src/lib/components/` | Dashboard UI as Svelte components — heatmap, table, charts, cards, popovers (one `.svelte` each) |
| `web/src/lib/` | Shared engine helpers: ECharts registration, the canvas timeline, popover state, theme, formatting |
| `techdata.json` | Generated language + framework detection data (committed; embedded at build) |
| `gen_techdata.py` | Regenerates `techdata.json` from GitHub Linguist + a curated framework map |
| `build.py` | Substitutes the `TEMPLATE` / `TECHDATA` lines with their data as a `repr()` |
| `dist/repo-intel` | The built single-file artifact (committed; this is what curl/Action/Homebrew use) |

The frontend is built with [Bun](https://bun.sh). It compiles to a single
self-contained `web/dist/index.html` (all JS + CSS inlined, Apache ECharts
Expand All @@ -238,6 +240,8 @@ make web-dev # frontend dev server with HMR (renders web/public/mock-dat
make build # rebuild the frontend bundle + dist/repo-intel
make techdata # regenerate techdata.json from Linguist (needs network)
make dev ARGS="3 facebook/react" # build frontend, then run from source live
make format # format the whole repo (Prettier + Ruff)
make check # run all static checks — Prettier + Ruff + svelte-check (mirrors CI)
```

`make web-dev` runs Vite's dev server with hot-reload against
Expand Down
10 changes: 5 additions & 5 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ def main():
("techdata.json", TECHDATA_PLACEHOLDER),
):
if script.count(placeholder) != 1:
sys.exit(f"error: expected exactly one {placeholder!r} line in repo-intel.py")
sys.exit(
f"error: expected exactly one {name} placeholder ({placeholder!r}) in repo-intel.py"
)

bundled = (
script
.replace(TEMPLATE_PLACEHOLDER, f"TEMPLATE = {template!r}")
.replace(TECHDATA_PLACEHOLDER, f"TECHDATA = {techdata!r}")
bundled = script.replace(TEMPLATE_PLACEHOLDER, f"TEMPLATE = {template!r}").replace(
TECHDATA_PLACEHOLDER, f"TECHDATA = {techdata!r}"
)
out_path.parent.mkdir(parents=True, exist_ok=True)
out_path.write_text(bundled, encoding="utf-8")
Expand Down
Loading
Loading