cat / 012
clone

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

cat/module-path
012 / scripts / lint.sh
lint.sh 3.8K executable
1#!/bin/sh2# Checked by make lint, all at once, each check's findings printed whole3# once it ends:4# - gofmt, and go vet with -tags stress (every file plain vet sees, and5# the stress benchmarks; nothing builds only without the tag)6# - staticcheck, with staticcheck.conf, in every module7# - no function with cognitive complexity over 25 (gocognit)8# - no Go file over 500 lines, no tracked file over 2 MB or compiled9# - no docs or comments narrating history (scripts/doclint)10# - links, anchors, the docs index, media and tapes in step (scripts/doccheck)11# The tools run with go run at pinned versions, so they never enter go.mod;12# go run and staticcheck cache their work, so a second run is quick.13#14# With directories as arguments (make quick), the Go checks look only at15# those packages; the tracked-file and docs checks always cover the repo.16set -eu17cd "$(dirname "$0")/.."1819GOCOGNIT=github.com/uudashr/gocognit/cmd/gocognit@v1.2.120STATICCHECK=honnef.co/go/tools/cmd/staticcheck@2026.2.221MAX_COGNIT=2522MAX_LINES=50023: "${PKG_CONFIG_PATH:=$(pwd)/.deps/ghostty/share/pkgconfig}"24export PKG_CONFIG_PATH2526whole=true27if [ $# -gt 0 ]; then28 dirs=$* whole=false29else30 dirs=$(find cmd internal demos e2e oracle -name '*.go' -exec dirname {} \; | sort -u)31fi3233# pkgs MOD prints the packages to check in module MOD as paths relative34# to it: ./... for the whole module, else those of the directories given.35pkgs() {36 if $whole; then37 echo ./...38 return39 fi40 for d in $dirs; do41 case $1 in42 .) case $d in oracle | oracle/* | e2e | e2e/*) continue ;; esac; echo "./$d" ;;43 *) case $d in "$1") echo . ;; "$1"/*) echo "./${d#"$1"/}" ;; esac ;;44 esac45 done46}4748gofmt_check() {49 bad=$(gofmt -l $dirs)50 if [ -n "$bad" ]; then51 echo "$bad"52 echo "gofmt: files above need formatting"53 return 154 fi55}5657vet() {58 set -- $(pkgs .)59 [ $# -eq 0 ] || go vet -tags stress "$@"60}6162# Warnings are fixed, or turned off in staticcheck.conf with a reason;63# none are left standing.64staticcheck() {65 mod=$166 set -- $(pkgs "$mod")67 [ $# -gt 0 ] || return 068 if ! (cd "$mod" && go run $STATICCHECK "$@"); then69 echo "staticcheck: findings in $mod"70 return 171 fi72}7374# Tracked files stay small and textual: no compiled binaries, nothing over75# 2 MB (docs/media GIFs have their own 1 MB limit in doccheck).76tracked() {77 big=$(git ls-files -z | xargs -0 wc -c 2>/dev/null | awk '$1 > 2097152 && $2 != "total" { sub(/^ *[0-9]+ /, ""); print }')78 bins=$(git ls-files | grep -E '\.(test|exe|o|a|so|dylib)$|^bin/|(^|/)(zz_|tmp_?|scratch|dbg_)[^/]*$' || true)79 if [ -n "$big" ]; then80 echo "tracked files over 2 MB:"81 echo "$big"82 fi83 if [ -n "$bins" ]; then84 echo "compiled or scratch files tracked by git:"85 echo "$bins"86 fi87 [ -z "$big$bins" ]88}8990shape() {91 over=$(go run $GOCOGNIT -over $MAX_COGNIT $dirs || true)92 long=$(find $dirs -maxdepth 1 -name '*.go' -exec wc -l {} + | awk -v max=$MAX_LINES '$2 != "total" && $1 > max')93 if [ -n "$over" ]; then94 echo "cognitive complexity over $MAX_COGNIT:"95 echo "$over" | sort -rn96 fi97 if [ -n "$long" ]; then98 echo "files over $MAX_LINES lines:"99 echo "$long" | sort -rn100 fi101 [ -z "$over$long" ]102}103104# Docs and comments describe the code as it is, not how it got here105# (doclint); links and anchors resolve, the index lists every doc, and106# every tape records something a doc shows (doccheck).107doclint() { go run ./scripts/doclint; }108doccheck() { go run ./scripts/doccheck; }109110out=$(mktemp -d)111trap 'rm -rf "$out"' EXIT112names=""113run() {114 name=$1115 shift116 ("$@") >"$out/$name" 2>&1 &117 eval "pid_$name=$!"118 names="$names $name"119}120121run gofmt gofmt_check122run vet vet123run staticcheck staticcheck .124run staticcheck_oracle staticcheck oracle125run staticcheck_e2e staticcheck e2e126run tracked tracked127run shape shape128run doclint doclint129run doccheck doccheck130131fail=0132for name in $names; do133 eval "pid=\$pid_$name"134 wait "$pid" || fail=1135 cat "$out/$name"136done137exit $fail