office-stamper started as a library you embed. The CLI grew on top of it
organically, and by June 2026 it had accreted into a Main class that did too
much. This commit gives it a shape.
Two responsibilities were tangled: turning a data file into a SpEL context, and reporting what happened. They’re now two seams.
Contextualizer parses a data file, JSON, YAML, properties, CSV, XLSX, XML or
HTML, into the context SpEL evaluates against, and it can stamp a directory of
templates in one pass.
Emitter is a single-method interface with two implementations, JsonEmitter
and LogEmitter:
public interface Emitter {
void emit(String level, String message, @Nullable Map<String, ?> fields);
}
One is for humans, the other for machines. The stamping logic doesn’t care which.
The command surface is now a stamp command:
officestamper -t template.docx -d data.json -o output.docx
officestamper -t template.docx -d data.json --watch
--watch re-runs stamping when the template or data files change, which turns
the CLI from a one-shot tool into the front half of a development loop.
The internals moved into a few small types: TemplateKind, the RunResult and
Item records, and PathUtils for the file plumbing. The Main entry point is
now mostly wiring.