package version_test
import (
"regexp"
"strings"
"testing"
"workshop.perforce.com/p4lf/internal/version"
)
func TestGet_ReturnsNonEmptySemVer(t *testing.T) {
info := version.Get()
if info.SemVer == "" {
t.Error("SemVer should not be empty")
}
}
func TestString_ContainsSemVer(t *testing.T) {
s := version.String()
if !strings.Contains(s, "p4lf") {
t.Errorf("version string should contain 'p4lf': %q", s)
}
if !strings.Contains(s, version.SemVer) {
t.Errorf("version string should contain SemVer %q: %q", version.SemVer, s)
}
}
// TestStreamParsing validates the depot-path → stream extraction logic used
// inside Get(), by replicating the same regex against representative inputs.
func TestStreamParsing(t *testing.T) {
idRe := regexp.MustCompile(`\$Id:\s*(//[^\s#]+)(#\d+)\s*\$`)
cases := []struct {
input string
wantStream string
wantRevision string
}{
{
input: "$Id: //p4lf/dev/internal/version/version.go#3 $",
wantStream: "//p4lf/dev",
wantRevision: "#3",
},
{
input: "$Id: //p4lf/main/internal/version/version.go#12 $",
wantStream: "//p4lf/main",
wantRevision: "#12",
},
{
input: "$Id: //p4lf/r26.1/internal/version/version.go#1 $",
wantStream: "//p4lf/r26.1",
wantRevision: "#1",
},
}
for _, tc := range cases {
m := idRe.FindStringSubmatch(tc.input)
if m == nil {
t.Errorf("regex did not match %q", tc.input)
continue
}
depotPath, revision := m[1], m[2]
if revision != tc.wantRevision {
t.Errorf("input %q: revision got %q, want %q", tc.input, revision, tc.wantRevision)
}
parts := strings.SplitN(strings.TrimPrefix(depotPath, "//"), "/", 3)
stream := ""
if len(parts) >= 2 {
stream = "//" + parts[0] + "/" + parts[1]
}
if stream != tc.wantStream {
t.Errorf("input %q: stream got %q, want %q", tc.input, stream, tc.wantStream)
}
}
}
func TestChangeParsing(t *testing.T) {
changeRe := regexp.MustCompile(`\$Change:\s*(\d+)\s*\$`)
cases := []struct{ input, want string }{
{"$Change: 32819 $", "32819"},
{"$Change: 1 $", "1"},
{"$Change: 999999 $", "999999"},
}
for _, tc := range cases {
m := changeRe.FindStringSubmatch(tc.input)
if m == nil {
t.Errorf("no match for %q", tc.input)
continue
}
if m[1] != tc.want {
t.Errorf("input %q: got %q, want %q", tc.input, m[1], tc.want)
}
}
}
func TestDateTimeParsing(t *testing.T) {
dateRe := regexp.MustCompile(`\$DateTime:\s*(\d{4}/\d{2}/\d{2})`)
cases := []struct{ input, want string }{
{"$DateTime: 2026/06/25 15:00:00 $", "2026/06/25"},
{"$DateTime: 2099/12/31 23:59:59 $", "2099/12/31"},
}
for _, tc := range cases {
m := dateRe.FindStringSubmatch(tc.input)
if m == nil {
t.Errorf("no match for %q", tc.input)
continue
}
if m[1] != tc.want {
t.Errorf("input %q: got %q, want %q", tc.input, m[1], tc.want)
}
}
}
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #2 | 32824 | C. Thomas Tyler |
Rename Go module path from github.com/rcowham/p4lf to workshop.perforce.com/p4lf. The rcowham prefix was a carryover from early research into go-libtail (which is hosted at github.com/rcowham/go-libtail). p4lf is hosted on the Perforce Public Depot / Workshop, not GitHub, so workshop.perforce.com is the correct canonical module path. Updated: go.mod, all *.go files with internal imports, Makefile (MODULE and LDFLAGS). Session logs retain the old path as accurate historical record. |
||
| #1 | 32819 | C. Thomas Tyler |
Add version stamping via Perforce keyword expansion. internal/version/version.go (type text+k): - SemVer var: hand-maintained Major.Minor.Patch, injectable via -ldflags - P4ID/P4Change/P4DateTime constants: expanded by Perforce on each submit/sync - Get() parses expanded keywords into an Info struct (stream, CL, date, revision) - String() produces: 'p4lf 0.1.0 (CL 32819, //p4lf/dev#3, 2026/06/25)' - Gracefully handles unexpanded state (pre-first-submit, non-P4 builds) internal/version/version_test.go: - Tests stream/revision parsing for dev, main, release streams - Tests Change and DateTime regex parsing cmd/p4lf/main.go: - Uses version.String() and version.SemVer instead of hardcoded const Makefile: - VERSION now read from internal/version/version.go - LDFLAGS target github.com/rcowham/p4lf/internal/version.SemVer |