From 37db1788efd18b5940a89703e75f037cc9ae5ced Mon Sep 17 00:00:00 2001 From: Jan Hartman Date: Thu, 14 May 2026 13:50:22 +0200 Subject: [PATCH 1/2] Add regexp raw pattern API --- query/query.go | 9 +++++++-- query/regexp_test.go | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/query/query.go b/query/query.go index c77499bd7..8b60f89bb 100644 --- a/query/query.go +++ b/query/query.go @@ -79,6 +79,11 @@ type Regexp struct { CaseSensitive bool } +// RegexpString returns the marshaled raw regexp pattern for q. +func (q *Regexp) RegexpString() string { + return syntaxutil.RegexpString(q.Regexp) +} + func (q *Regexp) String() string { pref := "" if q.FileName { @@ -87,7 +92,7 @@ func (q *Regexp) String() string { if q.CaseSensitive { pref = "case_" + pref } - return fmt.Sprintf("%sregex:%q", pref, syntaxutil.RegexpString(q.Regexp)) + return fmt.Sprintf("%sregex:%q", pref, q.RegexpString()) } // gobRegexp wraps Regexp to make it gob-encodable/decodable. Regexp contains syntax.Regexp, which @@ -100,7 +105,7 @@ type gobRegexp struct { // GobEncode implements gob.Encoder. func (q Regexp) GobEncode() ([]byte, error) { - gobq := gobRegexp{Regexp: q, RegexpString: syntaxutil.RegexpString(q.Regexp)} + gobq := gobRegexp{Regexp: q, RegexpString: q.RegexpString()} gobq.Regexp.Regexp = nil // can't be gob-encoded/decoded return json.Marshal(gobq) } diff --git a/query/regexp_test.go b/query/regexp_test.go index 27a9dbab4..49a8e2be3 100644 --- a/query/regexp_test.go +++ b/query/regexp_test.go @@ -101,3 +101,25 @@ func TestOptimize(t *testing.T) { }) } } + +func TestRegexpRegexpString(t *testing.T) { + tests := []struct { + in string + want string + }{ + {in: `abc`, want: `abc`}, + {in: `a.*b`, want: `a(?-s:.)*b`}, + } + + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + q := &Regexp{Regexp: mustParseRE(tt.in)} + if got := q.RegexpString(); got != tt.want { + t.Fatalf("RegexpString(%q) = %q, want %q", tt.in, got, tt.want) + } + if got := q.String(); got == tt.want { + t.Fatalf("String(%q) = raw pattern %q, want query formatting", tt.in, got) + } + }) + } +} From 49f60ff827d28bc5cfe7063923a90674bee26706 Mon Sep 17 00:00:00 2001 From: Jan Hartman Date: Fri, 15 May 2026 10:48:44 +0200 Subject: [PATCH 2/2] Use RegexpString() in ToProto --- query/query_proto.go | 2 +- query/query_proto_test.go | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/query/query_proto.go b/query/query_proto.go index 08f2438ae..6e058bc83 100644 --- a/query/query_proto.go +++ b/query/query_proto.go @@ -115,7 +115,7 @@ func RegexpFromProto(p *webserverv1.Regexp) (*Regexp, error) { func (r *Regexp) ToProto() *webserverv1.Regexp { return &webserverv1.Regexp{ - Regexp: r.Regexp.String(), + Regexp: r.RegexpString(), FileName: r.FileName, Content: r.Content, CaseSensitive: r.CaseSensitive, diff --git a/query/query_proto_test.go b/query/query_proto_test.go index a1d6aaaa4..36cc25d83 100644 --- a/query/query_proto_test.go +++ b/query/query_proto_test.go @@ -103,6 +103,15 @@ func TestQueryRoundtrip(t *testing.T) { } } +func TestRegexpProtoUsesRegexpString(t *testing.T) { + q := &Regexp{Regexp: regexpMustParse(`a.*b`)} + protoQ := q.ToProto() + + if got, want := protoQ.GetRegexp(), q.RegexpString(); got != want { + t.Fatalf("ToProto().Regexp = %q, want %q", got, want) + } +} + func regexpMustParse(s string) *syntax.Regexp { re, err := syntax.Parse(s, syntax.Perl) if err != nil {