aboutsummaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile103
1 files changed, 97 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index 9dfc7d4..62e2b7e 100644
--- a/Makefile
+++ b/Makefile
@@ -4,11 +4,15 @@
DESTDIR ?=
PREFIX ?= $(HOME)/.local
BINDIR = $(DESTDIR)$(PREFIX)/bin
+SHAREDIR = $(DESTDIR)$(PREFIX)/share
+MANDIR = $(SHAREDIR)/man
+DOCDIR = $(SHAREDIR)/doc/krino
BIN = krino
VERSION != git describe --tags --always --dirty 2>/dev/null || echo dev
LDFLAGS = -s -w -X main.version=$(VERSION)
+CROSS_PLATFORMS = linux/amd64 linux/arm64 freebsd/amd64 openbsd/amd64
-.PHONY: all help build install uninstall test vet fmt ci install-hooks clean
+.PHONY: all help build install uninstall test vet fmt lint ci bench cross dist release deps install-hooks clean
all: build
@@ -17,16 +21,36 @@ help: ## show this help
awk 'BEGIN {FS = ":.*## "}; {printf " %-10s %s\n", $$1, $$2}'
@echo " version: $(VERSION) prefix: $(PREFIX)"
-build: ## build ./krino; Go fetches module dependencies itself
+build: ## build ./krino; Go fetches module dependencies itself; reports missing optional extractors
CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN) ./cmd/krino
+ @missing=""; \
+ for t in pdftotext antiword catdoc xls2csv catppt; do \
+ command -v "$$t" >/dev/null 2>&1 || missing="$$missing $$t"; \
+ done; \
+ if [ -n "$$missing" ]; then \
+ echo "optional extractors not found:$$missing (needed for some content rules; run 'make deps' or install by hand)"; \
+ else \
+ echo "all optional extractors found: pdftotext antiword catdoc xls2csv catppt"; \
+ fi
-install: build ## install to $(PREFIX)/bin
- mkdir -p $(BINDIR)
+install: build ## install binary, man pages and examples under $(PREFIX)
+ mkdir -p $(BINDIR) $(MANDIR)/man1 $(MANDIR)/man5 $(DOCDIR)/examples
rm -f $(BINDIR)/$(BIN)
install -m 755 $(BIN) $(BINDIR)/$(BIN)
+ install -m 644 man/krino.1 $(MANDIR)/man1/krino.1
+ install -m 644 man/krino.conf.5 $(MANDIR)/man5/krino.conf.5
+ install -m 644 examples/*.conf $(DOCDIR)/examples/
+ install -m 644 docs/sexp-primer.md $(DOCDIR)/sexp-primer.md
-uninstall: ## remove the installed binary
+uninstall: ## remove everything install placed, and nothing else
rm -f $(BINDIR)/$(BIN)
+ rm -f $(MANDIR)/man1/krino.1
+ rm -f $(MANDIR)/man5/krino.conf.5
+ rm -f $(DOCDIR)/sexp-primer.md
+ for f in examples/*.conf; do \
+ rm -f $(DOCDIR)/examples/$$(basename "$$f"); \
+ done
+ -rmdir $(DOCDIR)/examples $(DOCDIR) 2>/dev/null
test: ## run the tests
go test ./...
@@ -37,7 +61,10 @@ vet: ## go vet
fmt: ## gofmt the tree
gofmt -w .
-ci: ## the gate: gofmt, vet, tests, dependencies, no personal data staged
+lint: ## lint the man pages
+ scripts/man-lint
+
+ci: ## the gate: gofmt, vet, tests, dependencies, no personal data staged, man page lint
@test -z "$$(gofmt -l .)" || { echo "gofmt needed:"; gofmt -l .; exit 1; }
go vet ./...
GOOS=freebsd CGO_ENABLED=0 go vet ./...
@@ -46,8 +73,72 @@ ci: ## the gate: gofmt, vet, tests, dependencies, no personal data staged
@deps=$$(go list -deps ./... | grep -E '^[a-z0-9-]+\.[a-z]+/' | grep -vE '^golang\.org/x/(term|text|sys)(/|$$)' || true); \
test -z "$$deps" || { echo "unexpected dependencies:"; echo "$$deps"; exit 1; }
@scripts/leak-check
+ @scripts/man-lint
@echo "ci ok"
+bench: ## run the Go benchmarks on generated trees
+ go test -run '^$$' -bench . -benchmem ./...
+
+cross: ## cross-compile linux/amd64, linux/arm64, freebsd/amd64, openbsd/amd64 into dist/krino-$(VERSION)-<os>-<arch>/
+ @case '$(VERSION)' in \
+ ''|*[!A-Za-z0-9._+-]*) \
+ echo "refusing: VERSION must contain only letters, digits, and the characters . - _ +" >&2; \
+ exit 1 ;; \
+ esac
+ @for t in $(CROSS_PLATFORMS); do \
+ os=$${t%/*}; arch=$${t#*/}; \
+ dir=dist/krino-$(VERSION)-$$os-$$arch; \
+ case "$$dir" in \
+ dist/krino-*) rm -rf "$$dir" ;; \
+ *) echo "refusing to remove unexpected path: $$dir" >&2; exit 1 ;; \
+ esac; \
+ mkdir -p "$$dir"; \
+ echo "cross: $$os/$$arch -> $$dir/$(BIN)"; \
+ CGO_ENABLED=0 GOOS=$$os GOARCH=$$arch go build -trimpath -ldflags "$(LDFLAGS)" -o "$$dir/$(BIN)" ./cmd/krino || exit 1; \
+ for f in README.md LICENSE CHANGELOG.md man/krino.1 man/krino.conf.5 docs/sexp-primer.md; do \
+ test -f "$$f" && cp "$$f" "$$dir/$$(basename "$$f")"; \
+ done; \
+ test -d examples && cp -r examples "$$dir/examples"; \
+ done
+
+# dist: cross plus tarballs and SHA256SUMS, no tag. Undocumented plumbing so
+# `make release` is verifiable without tagging; deliberately absent from
+# `make help` (no `## ` comment).
+dist: cross
+ @command -v sha256sum >/dev/null 2>&1 && SUM=sha256sum || SUM="sha256 -r"; \
+ tarballs=""; \
+ cd dist && \
+ for t in $(CROSS_PLATFORMS); do \
+ os=$${t%/*}; arch=$${t#*/}; \
+ name=krino-$(VERSION)-$$os-$$arch; \
+ tar czf "$$name.tar.gz" "$$name" || exit 1; \
+ tarballs="$$tarballs $$name.tar.gz"; \
+ done && \
+ $$SUM $$tarballs > SHA256SUMS
+
+release: ## make cross + tarballs + SHA256SUMS in dist/, then tag v$(VERSION) (annotated; never pushes) - usage: make release VERSION=0.0.1
+ @case '$(VERSION)' in \
+ ''|*[!A-Za-z0-9._+-]*) \
+ echo "refusing: VERSION must contain only letters, digits, and the characters . - _ +" >&2; \
+ exit 1 ;; \
+ esac
+ @default_version=$$(git describe --tags --always --dirty 2>/dev/null || echo dev); \
+ test -n "$(VERSION)" && test "$(VERSION)" != "$$default_version" || \
+ { echo "refusing: pass an explicit VERSION, e.g. make release VERSION=0.0.1"; exit 1; }
+ @test -z "$$(git status --porcelain)" || \
+ { echo "refusing: working tree is not clean (git status --porcelain)"; exit 1; }
+ @git rev-parse -q --verify refs/tags/v$(VERSION) >/dev/null 2>&1 && \
+ { echo "refusing: tag v$(VERSION) already exists"; exit 1; } || true
+ @test -f README.md || \
+ { echo "refusing: README.md is missing"; exit 1; }
+ $(MAKE) ci
+ $(MAKE) dist VERSION=$(VERSION)
+ git tag -a "v$(VERSION)" -m "krino v$(VERSION)"
+ @echo "release v$(VERSION) built in dist/; tag v$(VERSION) created, not pushed"
+
+deps: ## install the optional content extractors; may ask for privileges
+ scripts/deps
+
install-hooks: ## install the pre-commit hook that runs the leak check
install -m 755 scripts/hooks/pre-commit "$$(git rev-parse --git-path hooks)/pre-commit"