Bundle a static pdftotext into the binary

The PDF parsers shell out to pdftotext, so every machine running money needed
poppler-utils installed. scripts/build-bundled.sh now builds a deployable
binary that carries its own: pdftotext is compiled in a container from a
checksum-pinned poppler release as a fully static musl executable, then
embedded with `go build -tags bundled`. The result is one file that runs on
any Linux of that architecture with nothing installed alongside it.

It is still the real pdftotext, run as a subprocess. Linking poppler through
cgo would have cost the pure-Go build, and its C++ text API is not guaranteed
to space columns the way pdftotext -layout does, which is what the parsers
were tuned on. Only what text extraction needs is compiled in -- no
fontconfig, cairo or image codecs -- and its output is byte-identical to a
full distro build on the same PDF.

At runtime the embedded copy is written to the user cache directory, not
/tmp, which servers often mount noexec. It is named by content hash, so a
newer build never runs an older copy, and verified before reuse, so a write cut
short by a killed process is replaced rather than trusted. `money config` says
which pdftotext is in use.

The tag is opt-in: plain go build and go test never need the 5 MB executable,
which is gitignored rather than committed. Building with the tag for anything
but linux/amd64 or linux/arm64 fails with a message saying so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 18:02:46 +02:00
co-authored by Claude Opus 5.5
parent 6faf99719a
commit 5847245638
12 changed files with 398 additions and 3 deletions
+8
View File
@@ -0,0 +1,8 @@
//go:build bundled && !(linux && (amd64 || arm64))
package parser
// pdftotext is only built for Linux, as a static musl executable; there is
// nothing to embed for this platform. Build without -tags bundled and install
// poppler-utils instead.
var _ = bundled_pdftotext_is_only_available_for_linux_amd64_and_linux_arm64