From 049872ddff60e91a34b08bdd889e1a055cfc3627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Balv=C3=ADn?= Date: Wed, 16 Sep 2026 22:53:01 +0200 Subject: [PATCH] build: restore the canonical justfile recipe set Assisted-by: GLM 5.3 Flash --- justfile | 122 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 40 deletions(-) diff --git a/justfile b/justfile index aa45bbc..da635ff 100644 --- a/justfile +++ b/justfile @@ -1,59 +1,101 @@ -# Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) -# SPDX-License-Identifier: BSD-3-Clause +# gasm-devkit: developer tooling for Go's Plan 9 assembler (GAsm). -# gasm-devkit — developer tooling for Go's Plan 9 assembler (GAsm). +binary := "gasm" +package := "./cmd/gasm" -version := "0.33.0" +# What the test and bench recipes sweep. The whole suite runs, so the +# packages that need hardware and the CLI glue stay under the gates. +packages := "./..." + +# The coverage floor is computed over these product packages only, so the +# hardware-bound (debug) and the CLI glue (cmd/gasm) do not dilute the +# number. Keep this equal to the Coverage gate in .gitea/workflows/test.yml. +coverpkg := "./arch/...,./asm/...,./ast/...,./disasm/...,./format/...,./lexer/...,./lint/...,./lsp/...,./parser/...,./token/...,./verify/..." + +bindir := env_var_or_default("BINDIR", env_var("HOME") / ".local" / "bin") default: @just --list -# Download module dependencies. -install: - go mod download - -# Vet + gofmt check — zero errors, zero warnings. +# Compile. Zero errors, zero warnings. build: - go vet ./... - @test -z "$(gofmt -l .)" || { echo "gofmt diff:"; gofmt -l .; exit 1; } + CGO_ENABLED=0 go build -ldflags "-s -w" -o bin/{{binary}} {{package}} -# Full test suite + race detector + 80 % coverage gate. -# The coverage gate matches CI: it excludes packages that need hardware or -# are CLI glue (debug, cmd/gasm), so the number is identical locally and in CI. +# The test gate: the suite, no cache, the coverage floor. test: - go test -race -count=1 ./... - go test -count=1 -coverprofile=coverage.out \ - sourcedock.dev/petrbalvin/gasm-devkit/arch \ - sourcedock.dev/petrbalvin/gasm-devkit/asm \ - sourcedock.dev/petrbalvin/gasm-devkit/ast \ - sourcedock.dev/petrbalvin/gasm-devkit/format \ - sourcedock.dev/petrbalvin/gasm-devkit/lexer \ - sourcedock.dev/petrbalvin/gasm-devkit/lint \ - sourcedock.dev/petrbalvin/gasm-devkit/lsp \ - sourcedock.dev/petrbalvin/gasm-devkit/parser \ - sourcedock.dev/petrbalvin/gasm-devkit/token \ - sourcedock.dev/petrbalvin/gasm-devkit/verify - go tool cover -func=coverage.out | awk '/^total:/{gsub("%","",$3);if($3+0<80){print "coverage "$3"% < 80%";exit 1}print "coverage "$3"%"}' + #!/usr/bin/env perl + my $coverpkg = q({{coverpkg}}); + system(q{go}, q{test}, q{-count=1}, q{-timeout}, q{30m}, + q{-coverprofile}, q{coverage.out}, q{-coverpkg}, $coverpkg, + qw({{packages}})) == 0 + or die qq{the test suite failed\n}; + open(my $c, q{-|}, q{go}, q{tool}, q{cover}, q{-func=coverage.out}) or die qq{cover: $!}; + my $total; + while (my $l = <$c>) { $total = $1 if $l =~ m{^total:\s+\S+\s+([0-9.]+)%} } + close($c); + die qq{no total line in coverage.out\n} unless defined $total; + printf qq{Total coverage: %s%%\n}, $total; + exit($total < 80 ? 1 : 0); -# Format all Go sources. +# The same suite under the race detector. The expensive one. +race: + go test -race -count=1 -timeout 30m {{packages}} + +# Fast scoped run for iterating. This is the one that runs after every edit. +unit pkgs=packages run=".*": + go test {{pkgs}} -run '{{run}}' + +# Time-boxed fuzz of one target in one package. The package is required; never a gate. +fuzz target pkg fuzztime="60s": + go test -run '^$' -fuzz '{{target}}' -fuzztime={{fuzztime}} {{pkg}} + +# Benchmarks. On an idle machine only. +bench pkgs=packages: + go test -run '^$' -bench=. -benchmem -count=5 {{pkgs}} + +# Format in place. fmt: gofmt -w . -# Run the gasm CLI (pass args after --, e.g. `just run -- lint file.s`). +# Zero diff. Prints nothing when everything is formatted. +fmt-check: + #!/usr/bin/env perl + open(my $g, q{-|}, q{gofmt}, q{-l}, q{.}) or die qq{gofmt: $!}; + my @bad = <$g>; + close($g); + print @bad; + exit(@bad ? 1 : 0); + +# Both static gates: go vet and go fix -diff. +vet: + go vet ./... + go fix -diff ./... + +# The definition of done, in one command. Once per task, never per edit. +gates: build fmt-check vet test race + +# Build artefacts only, not the installed binary. +clean: + rm -rf bin/ coverage.out + +# Build, then copy the binary into bindir. +install: build + install -d "{{bindir}}" + install -m 755 bin/{{binary}} "{{bindir}}/{{binary}}" + +# Remove the installed binary. +uninstall: + rm -f "{{bindir}}/{{binary}}" + +# Run the program. The flag is there because `go run` does not stamp the build otherwise. run *ARGS: - go run -ldflags "-X main.version={{version}}" ./cmd/gasm {{ARGS}} + go run -buildvcs=true {{package}} {{ARGS}} -# Install the gasm binary into ~/.local/bin (stamped with the release version). -install-bin: - mkdir -p "$HOME/.local/bin" - GOBIN="$HOME/.local/bin" go install -ldflags "-X main.version={{version}}" ./cmd/gasm +# Run with watch or hot reload, where the project has one. +dev: + go run -buildvcs=true {{package}} -# Regenerate the architecture instruction tables from the Go toolchain source. +# Regenerate the architecture instruction tables from the Go toolchain source. Not a gate. gen: go run _gen/gen.go gofmt -w arch/ - -# Remove build artefacts and the installed binaries. -uninstall: - rm -f coverage.out gasm "$HOME/.local/bin/gasm" "$HOME/go/bin/gasm" - find . -name '*.test' -delete