Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions tools/extension-check/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ go run tools/extension-check/main.go \
Envoy source code can be found at `~/Codes/istio.io/envoy`.
Proxy source code can be found at `~/Codes/istio.io/proxy`.

First you need delete the first line of proxy extensions build config file, which is `load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")`.

```bash
sed -i '1d' ~/Codes/istio.io/proxy/bazel/extension_config/extensions_build_config.bzl
```

Then you can run the following command to check all core extensions are enabled in proxy.

```bash
Expand Down
43 changes: 39 additions & 4 deletions tools/extension-check/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ func main() {
flag.Parse()
envoyCoreExtensions, err := extensions(*envoyExtensionsBuildConfig, "EXTENSIONS")
if err != nil {
fmt.Printf("error: %v", err)
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}

proxyExtensions, err := extensions(*proxyExtensionsBuildConfig, "ENVOY_EXTENSIONS")
if err != nil {
fmt.Printf("error: %v", err)
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}

Expand Down Expand Up @@ -79,13 +79,18 @@ func main() {
// The file is expected to be a starlark file that defines a global variable.
// Depends on go.starlark.net/starlark.
func extensions(filename, key string) (map[string]string, error) {
src, err := os.ReadFile(filename)
if err != nil {
return nil, err
}

thread := &starlark.Thread{
Name: "extensions",
Print: func(_ *starlark.Thread, msg string) { fmt.Println(msg) },
}
globals, err := starlark.ExecFile(thread, filename, nil, nil)
globals, err := starlark.ExecFile(thread, filename, stripLoadStatements(string(src)), nil)
if err != nil {
panic(err)
return nil, err
}

if v, ok := globals[key]; ok {
Expand All @@ -100,3 +105,33 @@ func extensions(filename, key string) (map[string]string, error) {

return nil, errors.New("no extensions found")
}

// stripLoadStatements removes Bazel load() statements so build config files can
// be evaluated without resolving external repositories.
func stripLoadStatements(src string) string {
lines := strings.Split(src, "\n")
filtered := make([]string, 0, len(lines))
skippingLoad := false
parenDepth := 0

for _, line := range lines {
trimmed := strings.TrimSpace(line)
if !skippingLoad && strings.HasPrefix(trimmed, "load(") {
skippingLoad = true
}

if skippingLoad {
parenDepth += strings.Count(line, "(")
parenDepth -= strings.Count(line, ")")
if parenDepth <= 0 {
skippingLoad = false
parenDepth = 0
}
continue
}

filtered = append(filtered, line)
}

return strings.Join(filtered, "\n")
}
41 changes: 41 additions & 0 deletions tools/extension-check/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"os"
"path/filepath"
"testing"
)

func TestExtensionsIgnoresLoadStatements(t *testing.T) {
t.Parallel()

dir := t.TempDir()
path := filepath.Join(dir, "extensions.bzl")
content := `load(
"@bazel_skylib//lib:dicts.bzl",
"dicts",
)

EXTENSIONS = {"envoy.filters.http.router": "//source/extensions/filters/http/router:config"}
`
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
t.Fatal(err)
}

got, err := extensions(path, "EXTENSIONS")
if err != nil {
t.Fatalf("extensions() error = %v", err)
}

if got["envoy.filters.http.router"] != "//source/extensions/filters/http/router:config" {
t.Fatalf("extensions() returned unexpected map: %#v", got)
}
}

func TestExtensionsReturnsErrorForMissingFile(t *testing.T) {
t.Parallel()

if _, err := extensions(filepath.Join(t.TempDir(), "missing.bzl"), "EXTENSIONS"); err == nil {
t.Fatal("extensions() error = nil, want missing file error")
}
}