Repository: tetratelabs/wazero
Pull request #1176 (2023-02-28 08:23:26)

Allows to set the version of CLI
Previously `wazero version` always prints `dev`.

```
$ go build -ldflags "-s -w -X github.com/tetratelabs/wazero/internal/version.version=12345" -o wazero ./cmd/wazero
$ ./wazero version                                                                                                
12345
```


Patch:
diff --git a/internal/engine/compiler/engine.go b/internal/engine/compiler/engine.go
index 16999429..a3269811 100644
--- a/internal/engine/compiler/engine.go
+++ b/internal/engine/compiler/engine.go
@@ -811,21 +811,17 @@ func (f *function) getSourceOffsetInWasmBinary(pc uint64) uint64 {
 	}
 }
 
-func NewEngine(ctx context.Context, enabledFeatures api.CoreFeatures, fileCache filecache.Cache) wasm.Engine {
-	return newEngine(ctx, enabledFeatures, fileCache)
+func NewEngine(_ context.Context, enabledFeatures api.CoreFeatures, fileCache filecache.Cache) wasm.Engine {
+	return newEngine(enabledFeatures, fileCache)
 }
 
-func newEngine(ctx context.Context, enabledFeatures api.CoreFeatures, fileCache filecache.Cache) *engine {
-	var wazeroVersion string
-	if v := ctx.Value(version.WazeroVersionKey{}); v != nil {
-		wazeroVersion = v.(string)
-	}
+func newEngine(enabledFeatures api.CoreFeatures, fileCache filecache.Cache) *engine {
 	return &engine{
 		enabledFeatures: enabledFeatures,
 		codes:           map[wasm.ModuleID][]*code{},
 		setFinalizer:    runtime.SetFinalizer,
 		fileCache:       fileCache,
-		wazeroVersion:   wazeroVersion,
+		wazeroVersion:   version.GetWazeroVersion(),
 	}
 }
 
diff --git a/internal/version/version.go b/internal/version/version.go
index 9aa10d2b..ab0b465a 100644
--- a/internal/version/version.go
+++ b/internal/version/version.go
@@ -5,17 +5,22 @@ import (
 	"strings"
 )
 
-// WazeroVersionKey is the key for holding wazero's version in context.Context.
-type WazeroVersionKey struct{}
+// version holds the current version from the go.mod of downstream users or set by ldflag for wazero CLI.
+var version string
 
-// GetWazeroVersion returns the current version of wazero in the go.mod.
-// This assumes that users of wazero imports wazero as "github.com/tetratelabs/wazero".
+// GetWazeroVersion returns the current version of wazero either in the go.mod or set by ldflag for wazero CLI.
+//
+// If this is not CLI, this assumes that downstream users of wazero imports wazero as "github.com/tetratelabs/wazero".
 // To be precise, the returned string matches the require statement there.
 // For example, if the go.mod has "require github.com/tetratelabs/wazero 0.1.2-12314124-abcd",
 // then this returns "0.1.2-12314124-abcd".
 //
 // Note: this is tested in ./testdata/main_test.go with a separate go.mod to pretend as the wazero user.
 func GetWazeroVersion() (ret string) {
+	if len(version) != 0 {
+		return version
+	}
+
 	info, ok := debug.ReadBuildInfo()
 	if ok {
 		for _, dep := range info.Deps {
@@ -33,6 +38,9 @@ func GetWazeroVersion() (ret string) {
 	if versionMissing(ret) {
 		return "dev" // don't return parens
 	}
+
+	// Cache for the subsequent calls.
+	version = ret
 	return ret
 }
 
diff --git a/runtime.go b/runtime.go
index a4f50757..c48f7d73 100644
--- a/runtime.go
+++ b/runtime.go
@@ -9,7 +9,6 @@ import (
 	"github.com/tetratelabs/wazero/api"
 	experimentalapi "github.com/tetratelabs/wazero/experimental"
 	internalsys "github.com/tetratelabs/wazero/internal/sys"
-	"github.com/tetratelabs/wazero/internal/version"
 	"github.com/tetratelabs/wazero/internal/wasm"
 	binaryformat "github.com/tetratelabs/wazero/internal/wasm/binary"
 	"github.com/tetratelabs/wazero/sys"
@@ -124,9 +123,6 @@ func NewRuntime(ctx context.Context) Runtime {
 
 // NewRuntimeWithConfig returns a runtime with the given configuration.
 func NewRuntimeWithConfig(ctx context.Context, rConfig RuntimeConfig) Runtime {
-	if v := ctx.Value(version.WazeroVersionKey{}); v == nil {
-		ctx = context.WithValue(ctx, version.WazeroVersionKey{}, wazeroVersion)
-	}
 	config := rConfig.(*runtimeConfig)
 	var engine wasm.Engine
 	var cacheImpl *cache
diff --git a/version.go b/version.go
deleted file mode 100644
index eda8def5..00000000
--- a/version.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package wazero
-
-import "github.com/tetratelabs/wazero/internal/version"
-
-// wazeroVersion holds the current version of wazero.
-var wazeroVersion string
-
-func init() {
-	wazeroVersion = version.GetWazeroVersion()
-}


Test patch:
diff --git a/internal/engine/compiler/engine_test.go b/internal/engine/compiler/engine_test.go
index 45668210..7d98b842 100644
--- a/internal/engine/compiler/engine_test.go
+++ b/internal/engine/compiler/engine_test.go
@@ -43,7 +43,7 @@ func (e *engineTester) ListenerFactory() experimental.FunctionListenerFactory {
 
 // NewEngine implements the same method as documented on enginetest.EngineTester.
 func (e *engineTester) NewEngine(enabledFeatures api.CoreFeatures) wasm.Engine {
-	return newEngine(context.Background(), enabledFeatures, nil)
+	return newEngine(enabledFeatures, nil)
 }
 
 // CompiledFunctionPointerValue implements the same method as documented on enginetest.EngineTester.
@@ -237,7 +237,7 @@ func TestCompiler_Releasecode_Panic(t *testing.T) {
 // See comments on initialStackSize and initialCallFrameStackSize.
 func TestCompiler_SliceAllocatedOnHeap(t *testing.T) {
 	enabledFeatures := api.CoreFeaturesV1
-	e := newEngine(context.Background(), enabledFeatures, nil)
+	e := newEngine(enabledFeatures, nil)
 	s := wasm.NewStore(enabledFeatures, e)
 
 	const hostModuleName = "env"
diff --git a/runtime_test.go b/runtime_test.go
index 1ba7291b..df549be3 100644
--- a/runtime_test.go
+++ b/runtime_test.go
@@ -14,7 +14,6 @@ import (
 	"github.com/tetratelabs/wazero/internal/leb128"
 	"github.com/tetratelabs/wazero/internal/platform"
 	"github.com/tetratelabs/wazero/internal/testing/require"
-	"github.com/tetratelabs/wazero/internal/version"
 	"github.com/tetratelabs/wazero/internal/wasm"
 	binaryformat "github.com/tetratelabs/wazero/internal/wasm/binary"
 	"github.com/tetratelabs/wazero/sys"
@@ -41,19 +40,6 @@ func (h *HostContext) Err() error { return nil }
 
 func (h *HostContext) Value(key interface{}) interface{} { return nil }
 
-func TestNewRuntimeWithConfig_version(t *testing.T) {
-	cfg := NewRuntimeConfig().(*runtimeConfig)
-	oldNewEngine := cfg.newEngine
-	cfg.newEngine = func(ctx context.Context, features api.CoreFeatures, _ filecache.Cache) wasm.Engine {
-		// Ensures that wazeroVersion is propagated to the engine.
-		v := ctx.Value(version.WazeroVersionKey{})
-		require.NotNil(t, v)
-		require.Equal(t, wazeroVersion, v.(string))
-		return oldNewEngine(ctx, features, nil)
-	}
-	_ = NewRuntimeWithConfig(testCtx, cfg)
-}
-
 func TestRuntime_CompileModule(t *testing.T) {
 	tests := []struct {
 		name          string