From 438dbb140071d1f05e04e4b521f36807075ed67a Mon Sep 17 00:00:00 2001 From: joeykchen <466719968@qq.com> Date: Fri, 21 Aug 2026 18:43:23 +0800 Subject: [PATCH] fix(runnative): propagate isolated session roots --- cmd/spx/internal/command/run.go | 33 +++++++++--------- cmd/spx/internal/command/run_test.go | 50 ++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/cmd/spx/internal/command/run.go b/cmd/spx/internal/command/run.go index 2e688f875..cad7a89ef 100644 --- a/cmd/spx/internal/command/run.go +++ b/cmd/spx/internal/command/run.go @@ -43,6 +43,10 @@ func (cmd *CmdTool) Run(arg string) (err error) { } func (cmd *CmdTool) RunPackMode(pargs ...string) error { + roots, err := cmd.interpretedRoots() + if err != nil { + return err + } dllPath := path.Join(cmd.RuntimeTempDir, filepath.Base(cmd.LibPath)) if err := util.CopyFile(cmd.LibPath, dllPath); err != nil { return err @@ -55,8 +59,17 @@ func (cmd *CmdTool) RunPackMode(pargs ...string) error { return err } - args := cmd.buildRuntimeArgs(pargs, cmd.RuntimeTempDir) - return util.RunCommandInDir(cmd.RuntimeTempDir, cmd.RuntimeCmdPath, args...) + engineCmd, err := interpruntime.PrepareCommand(context.Background(), interpruntime.CommandConfig{ + Roots: roots, Executable: cmd.RuntimeCmdPath, Args: pargs, Env: os.Environ(), + Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, PathPolicy: interpruntime.ReplacePath, + }) + if err != nil { + return err + } + if err := engineCmd.Run(); err != nil { + return fmt.Errorf("native Engine failed: %w", err) + } + return nil } func (cmd *CmdTool) RunWeb() error { @@ -165,22 +178,6 @@ func (cmd *CmdTool) RunInterpreted(pargs ...string) error { return nil } -// buildRuntimeArgs builds gdspxrt args. -func (cmd *CmdTool) buildRuntimeArgs(inputArgs []string, tempDir string, extraArgs ...string) []string { - args := []string{} - for i := 0; i < len(inputArgs); i++ { - if inputArgs[i] == "--path" { - i++ - continue - } - args = append(args, inputArgs[i]) - } - args = append(args, "--path", tempDir) - args = append(args, extraArgs...) - args = append(args, "--no-header") - return args -} - func (cmd *CmdTool) runtimeSearchDirs() []string { var dirs []string appendDir := func(dir string) { diff --git a/cmd/spx/internal/command/run_test.go b/cmd/spx/internal/command/run_test.go index e9b362876..ef7a31a0d 100644 --- a/cmd/spx/internal/command/run_test.go +++ b/cmd/spx/internal/command/run_test.go @@ -26,6 +26,7 @@ import ( "strings" "testing" + "github.com/goplus/spx/v3/internal/interpruntime" "github.com/goplus/spx/v3/internal/scaffold" ) @@ -330,6 +331,55 @@ func TestSetupInterpretedPathsKeepsWorkingDirectory(t *testing.T) { } } +func TestRunPackModeUsesSessionEnvironment(t *testing.T) { + projectDir := t.TempDir() + mustWriteAssetIndex(t, projectDir) + sessionDir := filepath.Join(projectDir, ".temp") + generatedDir := filepath.Join(projectDir, "project") + for _, dir := range []string{sessionDir, generatedDir} { + if err := os.MkdirAll(dir, 0o755); err != nil { + t.Fatal(err) + } + } + if err := os.WriteFile(filepath.Join(generatedDir, "runtime.gdextension.txt"), []byte("extension"), 0o644); err != nil { + t.Fatal(err) + } + + logPath := filepath.Join(t.TempDir(), "runtime.log") + runtimePath := filepath.Join(t.TempDir(), "runtime"+executableSuffix(runtime.GOOS)) + writeTestRuntimeExecutable(t, runtimePath, logPath) + libPath := filepath.Join(generatedDir, libraryFileName(envName, runtime.GOOS, runtime.GOARCH)) + if err := os.WriteFile(libPath, []byte("bridge"), 0o755); err != nil { + t.Fatal(err) + } + for _, key := range []string{interpruntime.ProjectDirEnv, interpruntime.AssetDirEnv, interpruntime.SessionDirEnv} { + t.Setenv(key, "/stale") + } + + cmd := CmdTool{ + TargetAbsDir: projectDir, ProjectDir: generatedDir, RuntimeTempDir: sessionDir, + RuntimeCmdPath: runtimePath, LibPath: libPath, + } + if err := cmd.RunPackMode("--path", "ignored"); err != nil { + t.Fatalf("RunPackMode returned error: %v", err) + } + + log, err := os.ReadFile(logPath) + if err != nil { + t.Fatal(err) + } + for _, want := range []string{ + "--path\n" + sessionDir, + "SPX_PROJECT_DIR=" + projectDir, + "SPX_ASSET_DIR=" + filepath.Join(projectDir, "assets"), + "SPX_SESSION_DIR=" + sessionDir, + } { + if !strings.Contains(string(log), want+"\n") { + t.Fatalf("runtime log = %q, want %q", log, want) + } + } +} + func TestRunInterpretedCreatesIsolatedSessionAndCopiesSharedLibrary(t *testing.T) { oldPrepareEmbeddedRuntimeAssets := prepareEmbeddedRuntimeAssets prepareEmbeddedRuntimeAssets = func(string, ...string) (string, bool, error) {