Skip to content

Commit 3faa451

Browse files
committed
fix: migrate proto to external repo, fix all test failures
- .gitignore: remove stale internal/gen/ entries - cmd/proto-compat-check: use go mod download instead of local proto/ path - internal/admin: fix contract test path, add api-surface.json, fix pagination expectations - internal/controller: add TLS test data certificates - internal/infrastructure: add client.Reader to NewWithOptions, use InfrastructureListeners in gatewayServicePorts - internal/status: add ListenerSet parent index to scope HTTPRoute queries - internal/translator: add TLS test data certificates
1 parent 58eb5ae commit 3faa451

22 files changed

Lines changed: 510 additions & 131 deletions

.gitignore

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@ dist/
55
.vscode/
66
coverage/
77
tmp/
8-
internal/gen/
9-
!internal/gen/
10-
!internal/gen/gateway/
11-
!internal/gen/gateway/control/
12-
!internal/gen/gateway/control/v1/
13-
!internal/gen/gateway/control/v1/*.go
8+
149
.DS_Store
1510
build_push.sh
1611
.worktrees/

cmd/proto-compat-check/main.go

Lines changed: 68 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"encoding/json"
45
"errors"
56
"flag"
67
"fmt"
@@ -15,67 +16,63 @@ import (
1516
"github.com/nantian-gw/gateway/internal/protocompat"
1617
)
1718

18-
const protoPath = "proto/gateway/control/v1/control.proto"
19+
const (
20+
protoModule = "github.com/nantian-gw/proto"
21+
protoRelPath = "gateway/control/v1/control.proto"
22+
)
1923

2024
func main() {
2125
var (
22-
repoRootFlag = flag.String("repo-root", "", "repository root directory")
23-
baseRefFlag = flag.String("base-ref", "", "git ref to compare against")
26+
baseVersionFlag = flag.String("base-version", "", "proto module version to compare against (required)")
27+
repoRootFlag = flag.String("repo-root", "", "gateway repository root directory")
2428
)
2529
flag.Parse()
2630

31+
baseVersion := strings.TrimSpace(*baseVersionFlag)
32+
if baseVersion == "" {
33+
fatalf("--base-version is required (e.g. v0.1.0 or a pseudo-version)")
34+
}
35+
2736
repoRoot, err := resolveRepoRoot(*repoRootFlag)
2837
if err != nil {
2938
fatalf("resolve repo root: %v", err)
3039
}
3140

32-
baseRef := strings.TrimSpace(*baseRefFlag)
33-
if baseRef == "" {
34-
baseRef, err = detectBaseRef(repoRoot)
35-
if err != nil {
36-
fatalf("detect base ref: %v", err)
37-
}
38-
}
39-
40-
tempDir, err := os.MkdirTemp("", "aeg-proto-compat-*")
41+
currentProtoDir, err := moduleDir(repoRoot, protoModule+"@latest")
4142
if err != nil {
42-
fatalf("create temp dir: %v", err)
43-
}
44-
defer os.RemoveAll(tempDir)
45-
46-
baseProtoRoot := filepath.Join(tempDir, "base-proto")
47-
baseProtoPath := filepath.Join(baseProtoRoot, "gateway/control/v1/control.proto")
48-
if err := os.MkdirAll(filepath.Dir(baseProtoPath), 0o755); err != nil {
49-
fatalf("prepare temp proto tree: %v", err)
43+
fatalf("resolve current proto module: %v", err)
5044
}
5145

52-
baseProto, err := gitShow(repoRoot, fmt.Sprintf("%s:%s", baseRef, protoPath))
46+
baseProtoDir, err := moduleDir(repoRoot, protoModule+"@"+baseVersion)
5347
if err != nil {
54-
fatalf("load base proto from %s: %v", baseRef, err)
55-
}
56-
if err := os.WriteFile(baseProtoPath, baseProto, 0o644); err != nil {
57-
fatalf("write temp base proto: %v", err)
48+
fatalf("resolve base proto module (%s): %v", baseVersion, err)
5849
}
5950

6051
protocInclude, err := findProtocInclude()
6152
if err != nil {
6253
fatalf("locate protoc include: %v", err)
6354
}
6455

56+
tempDir, err := os.MkdirTemp("", "proto-compat-*")
57+
if err != nil {
58+
fatalf("create temp dir: %v", err)
59+
}
60+
defer os.RemoveAll(tempDir)
61+
6562
currentDescriptorPath := filepath.Join(tempDir, "current.pb")
6663
baseDescriptorPath := filepath.Join(tempDir, "base.pb")
6764

6865
if err := compileDescriptor(
69-
filepath.Join(repoRoot, "proto"),
70-
filepath.Join(repoRoot, protoPath),
66+
currentProtoDir,
67+
filepath.Join(currentProtoDir, protoRelPath),
7168
protocInclude,
7269
currentDescriptorPath,
7370
); err != nil {
7471
fatalf("compile current proto descriptor: %v", err)
7572
}
7673
if err := compileDescriptor(
77-
baseProtoRoot,
78-
filepath.Join(baseProtoRoot, "gateway/control/v1/control.proto"),
74+
baseProtoDir,
75+
filepath.Join(baseProtoDir, protoRelPath),
7976
protocInclude,
8077
baseDescriptorPath,
8178
); err != nil {
@@ -101,102 +98,75 @@ func main() {
10198
}
10299

103100
result := protocompat.CompareFiles(baseFile, currentFile)
104-
105-
fmt.Printf("[proto-compat] base ref: %s\n", baseRef)
106-
fmt.Printf("[proto-compat] target: %s\n", protoPath)
107-
for _, warning := range result.Warnings {
108-
fmt.Printf("[proto-compat] warning: %s: %s\n", warning.Path, warning.Message)
109-
}
110101
if !result.OK() {
111-
for _, finding := range result.Errors {
112-
fmt.Printf("[proto-compat] error: %s: %s\n", finding.Path, finding.Message)
102+
fmt.Println("Backward-incompatible changes detected:")
103+
for _, f := range result.Errors {
104+
fmt.Printf(" ERROR: %s: %s\n", f.Path, f.Message)
113105
}
114-
os.Exit(1)
115106
}
116-
117-
fmt.Println("[proto-compat] compatibility check passed")
118-
}
119-
120-
func resolveRepoRoot(explicit string) (string, error) {
121-
if strings.TrimSpace(explicit) != "" {
122-
return filepath.Abs(explicit)
107+
for _, f := range result.Warnings {
108+
fmt.Printf(" WARNING: %s: %s\n", f.Path, f.Message)
123109
}
124110

125-
current, err := os.Getwd()
126-
if err != nil {
127-
return "", err
128-
}
129-
130-
for {
131-
if _, statErr := os.Stat(filepath.Join(current, ".git")); statErr == nil {
132-
return current, nil
133-
}
134-
parent := filepath.Dir(current)
135-
if parent == current {
136-
return "", errors.New("could not find .git directory from current working directory")
137-
}
138-
current = parent
111+
if !result.OK() {
112+
os.Exit(1)
139113
}
114+
fmt.Println("Proto is backward compatible.")
140115
}
141116

142-
func detectBaseRef(repoRoot string) (string, error) {
143-
if tag, err := gitOutput(repoRoot, "describe", "--tags", "--abbrev=0", "--match", "v*"); err == nil {
144-
return strings.TrimSpace(tag), nil
145-
}
117+
type moduleInfo struct {
118+
Dir string `json:"Dir"`
119+
}
146120

147-
headParent, err := gitOutput(repoRoot, "rev-parse", "--verify", "HEAD^")
121+
func moduleDir(repoRoot, moduleQuery string) (string, error) {
122+
download := exec.Command("go", "mod", "download", "-json", moduleQuery)
123+
download.Dir = repoRoot
124+
download.Stderr = os.Stderr
125+
downloadOutput, err := download.Output()
148126
if err != nil {
149-
return "", errors.New("no release tag and no parent commit available for proto compatibility check")
127+
return "", fmt.Errorf("go mod download %s: %w", moduleQuery, err)
150128
}
151-
return strings.TrimSpace(headParent), nil
152-
}
153129

154-
func gitShow(repoRoot, object string) ([]byte, error) {
155-
cmd := exec.Command("git", "-C", repoRoot, "show", object)
156-
output, err := cmd.Output()
157-
if err != nil {
158-
return nil, err
130+
var info moduleInfo
131+
if err := json.Unmarshal(downloadOutput, &info); err != nil {
132+
return "", fmt.Errorf("parse go mod download output: %w", err)
133+
}
134+
if info.Dir == "" {
135+
return "", fmt.Errorf("module %s: Dir is empty", moduleQuery)
159136
}
160-
return output, nil
137+
return info.Dir, nil
161138
}
162139

163-
func gitOutput(repoRoot string, args ...string) (string, error) {
164-
cmd := exec.Command("git", append([]string{"-C", repoRoot}, args...)...)
165-
output, err := cmd.Output()
140+
func resolveRepoRoot(flag string) (string, error) {
141+
if flag != "" {
142+
return flag, nil
143+
}
144+
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
145+
cmd.Stderr = os.Stderr
146+
out, err := cmd.Output()
166147
if err != nil {
167-
return "", err
148+
return "", fmt.Errorf("find git root: %w", err)
168149
}
169-
return string(output), nil
150+
return strings.TrimSpace(string(out)), nil
170151
}
171152

172153
func findProtocInclude() (string, error) {
173-
if include := strings.TrimSpace(os.Getenv("PROTOC_INCLUDE")); include != "" {
174-
if wellKnownTypeExists(include) {
175-
return include, nil
176-
}
177-
return "", fmt.Errorf("PROTOC_INCLUDE does not contain google/protobuf well-known types: %s", include)
154+
if env := os.Getenv("PROTOC_INCLUDE"); env != "" {
155+
return env, nil
178156
}
179157

180-
protocPath, err := exec.LookPath("protoc")
181-
if err != nil {
182-
return "", errors.New("protoc not found in PATH")
183-
}
184-
protocRoot := filepath.Dir(filepath.Dir(protocPath))
185-
186-
candidates := []string{
187-
filepath.Join(protocRoot, "include"),
158+
searchRoots := []string{
188159
"/usr/local/include",
189160
"/usr/include",
190-
"/opt/homebrew/include",
191-
"/opt/local/include",
161+
filepath.Join(os.Getenv("HOME"), ".local/include"),
192162
}
193-
for _, candidate := range candidates {
194-
if wellKnownTypeExists(candidate) {
195-
return candidate, nil
163+
164+
for _, root := range searchRoots {
165+
if wellKnownTypeExists(root) {
166+
return root, nil
196167
}
197168
}
198169

199-
searchRoots := []string{"/usr/local", "/usr", "/opt/homebrew", "/opt/local"}
200170
for _, root := range searchRoots {
201171
candidate, err := findWellKnownType(root)
202172
if err != nil {
@@ -277,4 +247,4 @@ func findDescriptorFile(set *descriptorpb.FileDescriptorSet, name string) (*desc
277247
func fatalf(format string, args ...any) {
278248
fmt.Fprintf(os.Stderr, "[proto-compat] "+format+"\n", args...)
279249
os.Exit(1)
280-
}
250+
}

0 commit comments

Comments
 (0)