# P4LF Session Log — 2026-06-25 (Session 3: Version Stamping + Handoff to Linux Testing) ## Session Goal Add Perforce keyword-based version stamping to the p4lf binary, and wrap up the macOS development phase in preparation for Linux integration testing. ## What Was Built / Changed ### Makefile (CL 32818 → 32821) Added in CL 32818 (previous session). Key targets: | Target | Purpose | |---|---| | `make build` | Current platform → `bin/p4lf` | | `make build-linux` | Linux amd64 → `bin/p4lf-linux-amd64` *(primary deploy target)* | | `make build-linux-arm64` | Linux arm64 | | `make build-darwin` / `build-darwin-amd64` | macOS builds | | `make build-all` | All four platforms | | `make check` | vet + fmt + test (CI gate) | | `make install INSTANCE=1` | Deploy binary + systemd unit to SDP paths | | `make release VERSION=x.y.z` | All platforms + `dist/` tarballs | ### Version stamping (CL 32819, 32820, 32821) `internal/version/version.go` is stored in Perforce as **type `text+k`**. Perforce expands three keywords on every submit/sync of this file: | Constant | Example after expansion | |---|---| | `P4ID` | `$Id: //p4lf/dev/internal/version/version.go#2 $` | | `P4Change` | `$Change: 32820 $` | | `P4DateTime` | `$DateTime: 2026/06/25 12:14:37 $` | `SemVer` is a hand-maintained `var` (`"0.1.0"`) that can also be overridden at build time: `make build VERSION=1.0.0`. **`p4lf -version` output:** ``` p4lf 0.1.0 (CL 32820, //p4lf/dev#2, 2026/06/25) ``` **Verifiable without running the binary:** ``` strings p4lf | grep 'Id:\|Change:\|DateTime:' ``` #### Key implementation detail: preventing regex expansion The regex patterns that parse the keyword values (e.g., `\$Id:\s*...`) must NOT themselves be expanded by Perforce. The fix: define `const dollar = "\x24"` (dollar sign in hex) and build patterns via string concatenation: ```go var idRe = regexp.MustCompile(`\` + dollar + `Id:\s*(//[^\s#]+)(#\d+)\s*\` + dollar) ``` P4 never sees `$Id:` as a contiguous byte sequence in the source, so it leaves the regex patterns alone. This was a bug in the first submit (CL 32819) and fixed in CL 32820. #### Makefile VERSION grep fix (CL 32821) The grep `SemVer\s*=` also matched the `-ldflags` example in the package doc comment, corrupting the VERSION value. Fixed by anchoring: `^var SemVer`. ## Current Depot State | CL | Description | |---|---| | 32818 | Initial Go implementation (all source files, Makefile, config, tailer, chunker, logger, systemd, example config, session logs) | | 32819 | Version stamping (version.go as text+k) — had regex expansion bug | | 32820 | Fix regex patterns with `const dollar = "\x24"` | | 32821 | Fix Makefile VERSION grep anchor | Latest: `//p4lf/dev` at CL 32821, all `make check` tests passing, all four platform binaries building cleanly. ## Testing Checklist for Linux Session The following should be verified on a Linux host with an SDP environment and running p4d instance: ### 1. Basic build ```bash go version # Confirm Go is available (1.20+ required) p4 sync # Sync workspace make build # Should produce bin/p4lf bin/p4lf -version # Should show: p4lf 0.1.0 (CL 32821, //p4lf/dev#N, ...) ``` ### 2. Config file ```bash cp p4lf.cfg.example /tmp/test-p4lf.cfg # Edit: set P4LogFile to your P4LOG path bin/p4lf -config /tmp/test-p4lf.cfg # Should start and log to /tmp/p4lf.log (since $LOGS not set) ``` ### 3. Chunk file creation - After one `LogTailDelay` interval, verify `log.*.gz` files appear in `LogChunksDir` - `gunzip -c log.*.gz | head` should show real P4LOG content ### 4. State file - Stop and restart the service - Verify offset is resumed (no duplicate chunks, no gap) - Check `$LOGS/p4lf.state` contains inode + offset JSON ### 5. Log rotation (inode-based detection) ```bash # Simulate a rotation while p4lf is running: mv $P4LOG $P4LOG.old && touch $P4LOG # p4lf should detect the inode change, log a rotation event, and reset to offset 0 ``` ### 6. SIGHUP ```bash kill -HUP $(pidof p4lf) # Should reload config and rotate p4lf.log ``` ### 7. systemd service ```bash sudo make install INSTANCE=1 # Edit /p4/common/site/log_feeder/p4lf.cfg sudo systemctl enable p4lf sudo systemctl start p4lf sudo systemctl status p4lf journalctl -u p4lf -f ``` ### 8. Graceful shutdown ```bash sudo systemctl stop p4lf # Should do final flush, write state, clean exit # Verify state file is current ``` ## Known Gaps / Items for Linux Session - **Tailer unit tests**: rotation detection, state file checkpoint/resume, and truncation handling are not unit-tested yet; rely on integration testing. - **Logger unit tests**: MaxLogSize trigger, gzip rotation not unit-tested. - **SDP environment file**: the systemd unit references `/p4/common/bin/p4_vars` for the `$LOGS` and `$P4LOG` env vars; verify this path is correct for the target SDP installation. - **`WaitUntilGuardsPassed` timeout**: currently waits indefinitely; may want a max-wait-and-warn after some number of retries. - **README.md**: not yet updated to reflect Go implementation and revised config.