session_log_2026-06-25-3.md #1

  • //
  • p4lf/
  • dev/
  • ai/
  • session_log_2026-06-25-3.md
  • Markdown
  • View
  • Commits
  • Open Download .zip Download (5 KB)

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:

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

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

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)

# 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

kill -HUP $(pidof p4lf)
# Should reload config and rotate p4lf.log

7. systemd service

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

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.
# 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.
# Change User Description Committed
#1 32822 C. Thomas Tyler Session log 3: version stamping and Linux testing handoff.