cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / Makefile
Makefile 8.6K
1# 012 builds as pure Go. Only the e2e tests need cgo and libghostty-vt,2# which is built from source with Zig into .deps/.34GHOSTTY_COMMIT := 27e8b3fa85d9cf8c7cd5ae2ced348bcb0a4fba9c5DEPS := $(CURDIR)/.deps6GHOSTTY_SRC := $(DEPS)/ghostty-src7GHOSTTY_OUT := $(DEPS)/ghostty8GHOSTTY_STAMP := $(GHOSTTY_OUT)/.built-$(GHOSTTY_COMMIT)910.PHONY: check quick lint build run test fuzz e2e screens oracle demos libghostty clean stress stress-data stress-report obs-up obs-down obs-status stress-load stress-e2e speed speed-update dist site site-release site-publish site-serve site-deps1112build:13 CGO_ENABLED=0 go build -o bin/012 ./cmd/0121415run: build16 ./bin/0121718# Release archives: 012 cross-compiled (pure Go, -trimpath, stamped with19# VERSION) for macOS, Linux and Windows on amd64 and arm64 into dist/,20# with SHA256SUMS. Nothing is uploaded; see docs/contributing/releasing.md.21dist:22 VERSION=$(VERSION) scripts/dist.sh2324# Unit tests, all but the timed ones, which run alone in make speed.25test:26 STRESS_DIR=$(DEPS)/stress go test -skip '^($(TIMED_UI)|$(TIMED_NBVIEW))$$' ./...2728# Everything that must pass before a push: lint, unit tests, the excelize29# oracle and the end-to-end tests in libghostty at once, then the speed30# gate and timed tests alone (scripts/check.sh). make quick checks only31# what changed, for iterating.32check: $(GHOSTTY_STAMP)33 @scripts/check.sh3435quick:36 @PKGS="$(PKGS)" TIMED='^($(TIMED_UI)|$(TIMED_NBVIEW))$$' scripts/quick.sh3738# gofmt, vet (with the stress benchmarks), staticcheck, shape limits and39# the docs checks, at once.40lint:41 scripts/lint.sh4243# Tests that time frames against fixed bounds: make test skips them and44# make speed runs them alone, as the speed gate.45TIMED_UI := TestSpeed|TestSharedEditWithinAFrame|TestStreamGridAtFrameSpeed46TIMED_NBVIEW := TestScrollsAtFrameSpeed4748# The speed gate: frames and recalculation on mid-sized sheets against49# internal/ui/testdata/speed.json, in about two seconds, and the tests50# that time frames, alone so that no other tests share the CPU.51# speed-update rewrites the baseline. See52# docs/contributing/limits.md#the-speed-gate.53speed:54 go test ./internal/ui -run '^($(TIMED_UI))$$' -count=1 -speed55 go test ./internal/ui/nbview -run '^($(TIMED_NBVIEW))$$' -count=15657speed-update:58 go test ./internal/ui -run '^TestSpeed$$' -count=1 -speed-update -v5960fuzz:61 go test ./internal/sheet -run '^$$' -fuzz FuzzParse -fuzztime 60s62 go test ./internal/sheet -run '^$$' -fuzz FuzzRead -fuzztime 60s63 go test ./internal/sheet -run '^$$' -fuzz FuzzRandomEdits -fuzztime 60s64 go test ./internal/fileio -run '^$$' -fuzz FuzzReadDelimited -fuzztime 60s65 go test ./internal/fileio -run '^$$' -fuzz FuzzReadWK1 -fuzztime 60s66 go test ./internal/fileio -run '^$$' -fuzz 'FuzzReadXLSX$$' -fuzztime 60s67 go test ./internal/fileio -run '^$$' -fuzz FuzzReadXLSXParts -fuzztime 60s68 go test ./internal/nuon -run '^$$' -fuzz FuzzParse -fuzztime 60s69 go test ./internal/fileio -run '^$$' -fuzz FuzzReadNUON -fuzztime 60s7071e2e: $(GHOSTTY_STAMP)72 cd e2e && PKG_CONFIG_PATH=$(GHOSTTY_OUT)/share/pkgconfig go test -count=1 ./...7374# Rewrite golden screens and build e2e/testdata/screens/gallery.html for75# visual review. Review the diff and the gallery before committing.76screens: $(GHOSTTY_STAMP)77 cd e2e && PKG_CONFIG_PATH=$(GHOSTTY_OUT)/share/pkgconfig go test -count=1 -run 'TestScreens|TestStills' ./... -update7879# Stress: fetch real datasets into .deps/stress, run the benchmarks built80# with -tags stress, print a summary and record the run in81# .deps/stress/results/runs.jsonl. BENCH, BENCHTIME and PKGS narrow it;82# see docs/contributing/limits.md. Plain `go test ./...` never runs these.83stress:84 scripts/stress/run.sh8586stress-data:87 scripts/stress-data.sh8889# Compare the latest run with the previous one, a baseline and the last90# tagged release's run (DuckDB); exits 1 on a regression against the91# release past THRESHOLD (0.10) plus the benchmark's noise.92stress-report:93 scripts/stress/report.sh9495# The observability stack (deploy/observability): an OpenTelemetry96# Collector, ClickHouse and Grafana in Docker. See docs/contributing/observability.md.97obs-up:98 scripts/obs.sh up99100obs-down:101 scripts/obs.sh down102103obs-status:104 scripts/obs.sh status105106# End-to-end key latency on a big sheet through libghostty, with the107# telemetry log on (O12_E2E_LOG keeps it).108stress-e2e: $(GHOSTTY_STAMP)109 cd e2e && STRESS=1 PKG_CONFIG_PATH=$(GHOSTTY_OUT)/share/pkgconfig go test -count=1 -run TestStressKeyLatency -v ./...110111# Load the recorded stress runs into the stack's ClickHouse.112stress-load:113 scripts/stress/clickhouse-load.sh114115# Differential tests: formulas and number formats against excelize's116# calculation engine. A separate module, so the binary never depends on it.117oracle:118 cd oracle && go test -count=1 ./...119120# Demo GIFs from the VHS tapes in demos/ into demos/out/ (gitignored),121# PNG stills of key moments in demos/out/stills/, and smaller GIFs for122# the README in demos/out/media/ (12 fps, a 64-color palette, the last123# frame held). Needs vhs 0.12+ (go install124# github.com/charmbracelet/vhs@latest), ttyd and ffmpeg. The JEV demo125# talks to demos/fakejev, started here, never the real service.126# VHS's ttyd has sixel on, so charts are recorded as the sixel images127# 012 draws. DEMOS=jev renders just one. Each tape runs128# 012 with its theme set to the tape's Set Theme (setup.tape's unless it129# sets one), and in JetBrains Mono, served to VHS's browser in ttyd's130# page from e2e/testdata/fonts, so it needn't be installed131# (docs/contributing/site.md#font-and-colors).132DEMOS ?= $(basename $(notdir $(wildcard demos/*.tape)))133FAKEJEV_ADDR := 127.0.0.1:8799134135demos: build136 @for t in vhs ttyd ffmpeg; do command -v $$t >/dev/null || { echo "demos need $$t (vhs: go install github.com/charmbracelet/vhs@latest; ttyd, ffmpeg: brew install ttyd ffmpeg)"; exit 1; }; done137 CGO_ENABLED=0 go build -o bin/fakejev ./demos/fakejev138 mkdir -p demos/out/stills139 bin/fakejev -addr $(FAKEJEV_ADDR) & pid=$$!; trap "kill $$pid" EXIT; \140 export DEMOS_TTYD="$$(command -v ttyd)" PATH="$(CURDIR)/demos/lib:$$PATH" DEMOS_PAGE="$(CURDIR)/demos/out/ttyd.html"; \141 demos/lib/font-page "$$DEMOS_PAGE" e2e/testdata/fonts || exit 1; \142 export XDG_CONFIG_HOME="$$(mktemp -d)" O12_JEV_CREDENTIAL_STORE=false O12_LOCALE=en-US; \143 cd demos && for d in $(DEMOS); do theme="$$(grep -h '^Set Theme' lib/setup.tape $$d.tape | tail -1 | cut -d'"' -f2)"; \144 echo "vhs $$d.tape ($$theme)"; O12_THEME="$$theme" vhs -q $$d.tape || exit 1; done145 mkdir -p demos/out/media146 for d in $(DEMOS); do ffmpeg -v error -y -i demos/out/$$d.gif -filter_complex \147 "fps=12,tpad=stop_mode=clone:stop_duration=2,split[a][b];[a]palettegen=max_colors=64:stats_mode=diff[p];[b][p]paletteuse=dither=none:diff_mode=rectangle" \148 demos/out/media/$$d.gif || exit 1; done149 @ls -l demos/out/media150151# The docs site (website/): Docusaurus over docs/, built into152# website/build. Needs Node 20.11+ and npm; nothing else in the build or153# make check does. The build fails on a broken link or anchor. SITE_URL154# sets the address canonical links and the sitemap use155# (https://012.dev.site unless set). Node's warning that localStorage has156# no backing file is about the build's own process, which never stores157# anything. See docs/contributing/site.md.158SITE_NODE := NODE_OPTIONS=--disable-warning=ExperimentalWarning159160site: site-deps161 cd website && $(SITE_NODE) npm run build162163# The site as published: the build above plus a release's archives and164# SHA256SUMS under /releases/<version>/ and /releases/latest/, and165# install.sh and install.ps1 at the root. VERSION is the newest version166# tag unless set; the archives are dist/'s when it holds that version,167# else built from the tag. See docs/contributing/releasing.md.168site-release: site169 VERSION=$(VERSION) scripts/site-release.sh170171# The site with the release, deployed to https://012.dev.site: Cloudflare172# Workers static assets, configured in website/wrangler.jsonc, with the173# wrangler website/package.json pins. Needs Node 22+ and wrangler logged174# in (npx wrangler login). See docs/contributing/site.md.175site-publish: site-release176 cd website && npx --no-install wrangler deploy177178site-serve: site-deps179 cd website && $(SITE_NODE) npm run start180181site-deps:182 @command -v npm >/dev/null || { echo "the site needs Node 20.11+ and npm"; exit 1; }183 cd website && npm ci184185libghostty: $(GHOSTTY_STAMP)186187# The commit matches the one pinned by go.mitchellh.com/libghostty.188$(GHOSTTY_STAMP):189 rm -rf $(GHOSTTY_SRC)190 git init -q $(GHOSTTY_SRC)191 git -C $(GHOSTTY_SRC) fetch -q --depth 1 https://github.com/ghostty-org/ghostty.git $(GHOSTTY_COMMIT)192 git -C $(GHOSTTY_SRC) checkout -q FETCH_HEAD193 cd $(GHOSTTY_SRC) && zig build -Demit-lib-vt -Demit-xcframework=false -Doptimize=ReleaseFast --prefix $(GHOSTTY_OUT)194 touch $@195196clean:197 rm -rf bin $(DEPS)