From 21c00d2f5f42e2d2bd63be25a9233aa5c3629b40 Mon Sep 17 00:00:00 2001 From: piux2 <90544084+piux2@users.noreply.github.com> Date: Tue, 14 Oct 2025 23:54:17 -0700 Subject: [PATCH 1/2] fix: matching with go run semantics --- gnovm/cmd/gno/run.go | 93 ++++++++++++++++--- gnovm/cmd/gno/run_test.go | 23 +++-- .../tests/integ/package_mismatched/hello.gno | 5 + gnovm/tests/integ/package_mismatched/main.gno | 5 + .../integ/package_testonly/hello_filetest.gno | 5 + .../integ/package_testonly/hello_test.gno | 5 + 6 files changed, 119 insertions(+), 17 deletions(-) create mode 100644 gnovm/tests/integ/package_mismatched/hello.gno create mode 100644 gnovm/tests/integ/package_mismatched/main.gno create mode 100644 gnovm/tests/integ/package_testonly/hello_filetest.gno create mode 100644 gnovm/tests/integ/package_testonly/hello_test.gno diff --git a/gnovm/cmd/gno/run.go b/gnovm/cmd/gno/run.go index 0bb0dbb48e4..87ffcb165af 100644 --- a/gnovm/cmd/gno/run.go +++ b/gnovm/cmd/gno/run.go @@ -78,28 +78,99 @@ func (c *runCmd) RegisterFlags(fs *flag.FlagSet) { ) } -func packageNameFromFirstFile(args []string) (string, error) { +func packageNameFromFiles(args []string) (string, error) { + var ( + firstPkgName string + firstPkgFile string + foundAny bool + ) + for _, arg := range args { - if s, err := os.Stat(arg); err == nil && s.IsDir() { + s, err := os.Stat(arg) + if err != nil { + continue + } + + // ---- Directory case ---- + if s.IsDir() { files, err := os.ReadDir(arg) if err != nil { return "", err } + + dirFoundAny := false + for _, f := range files { n := f.Name() - if isGnoFile(f) && - !strings.HasSuffix(n, "_test.gno") && - !strings.HasSuffix(n, "_filetest.gno") { - return gno.ParseFilePackageName(filepath.Join(arg, n)) + if !isGnoFile(f) || + strings.HasSuffix(n, "_test.gno") || + strings.HasSuffix(n, "_filetest.gno") { + continue } + + fullPath := filepath.Join(arg, n) + firstPkgName, firstPkgFile, err = updatePackageInfo(fullPath, firstPkgName, firstPkgFile) + if err != nil { + return "", err + } + foundAny = true + dirFoundAny = true } - } else if err != nil { + + // when directory has only test files + if !dirFoundAny { + return "", fmt.Errorf("gno: no non-test Gno files in %s", arg) + } + + continue + } + + // ---- File case ---- + n := filepath.Base(arg) + if strings.HasSuffix(n, "_test.gno") || strings.HasSuffix(n, "_filetest.gno") { + return "", fmt.Errorf("gno run: cannot run test files (%s), use gno test instead", n) + } + + firstPkgName, firstPkgFile, err = updatePackageInfo(arg, firstPkgName, firstPkgFile) + if err != nil { return "", err - } else { - return gno.ParseFilePackageName(arg) } + foundAny = true + } + + if !foundAny { + return "", fmt.Errorf("no valid gno file found") } - return "", nil + + return firstPkgName, nil +} + +// updatePackageInfo parses the package name of a given .gno file +// and compares it with the first known package. It returns updated values +// for firstPkgName and firstPkgFile, or an error if a mismatch is found. +func updatePackageInfo( + path string, + firstPkgName, firstPkgFile string, +) (string, string, error) { + pkgName, err := gno.ParseFilePackageName(path) + if err != nil { + return firstPkgName, firstPkgFile, err + } + + if firstPkgName == "" { + // First valid file sets the base package + return pkgName, path, nil + } + + if pkgName != firstPkgName { + return firstPkgName, firstPkgFile, fmt.Errorf( + "found mismatched packages %s (%s) and %s (%s)", + firstPkgName, filepath.Base(firstPkgFile), + pkgName, filepath.Base(path), + ) + } + + return firstPkgName, firstPkgFile, nil } func execRun(cfg *runCmd, args []string, cio commands.IO) error { @@ -125,7 +196,7 @@ func execRun(cfg *runCmd, args []string, cio commands.IO) error { } var send std.Coins - pkgPath, err := packageNameFromFirstFile(args) + pkgPath, err := packageNameFromFiles(args) if err != nil { return err } diff --git a/gnovm/cmd/gno/run_test.go b/gnovm/cmd/gno/run_test.go index 759600d5175..d3158cb90c9 100644 --- a/gnovm/cmd/gno/run_test.go +++ b/gnovm/cmd/gno/run_test.go @@ -21,7 +21,7 @@ func TestRunApp(t *testing.T) { }, { args: []string{"run", "../../tests/integ/does_not_exist"}, - errShouldContain: "no such file or directory", + errShouldContain: "no valid gno file found", }, { args: []string{"run", "../../tests/integ/run_namedpkg/main.gno"}, @@ -31,6 +31,14 @@ func TestRunApp(t *testing.T) { args: []string{"run", "../../tests/integ/run_package"}, errShouldContain: "name main not declared", }, + { + args: []string{"run", "../../tests/integ/package_mismatched"}, + errShouldContain: "found mismatched packages", + }, + { + args: []string{"run", "../../tests/integ/run_main/main.gno", "../../tests/integ/run_namedpkg"}, + errShouldContain: "found mismatched packages", + }, { args: []string{"run", "-expr", "Hello()", "../../tests/integ/run_package"}, stdoutShouldContain: "called Hello", @@ -66,10 +74,6 @@ func TestRunApp(t *testing.T) { args: []string{"run", "-expr", "WithArg(-255)", "../../tests/integ/run_package"}, stdoutShouldContain: "out of range!", }, - { - args: []string{"run", "../../tests/integ/undefined_variable/undefined_variables_test.gno"}, - recoverShouldContain: "--- preprocess stack ---", // should contain preprocess debug stack trace - }, { args: []string{"run", "-debug", "../../tests/integ/debugger/sample.gno"}, stdoutShouldContain: "Welcome to the Gnovm debugger", @@ -99,7 +103,14 @@ func TestRunApp(t *testing.T) { }(), errShouldBe: "exit code: 1", }, - // TODO: a test file + { + args: []string{"run", "../../tests/integ/undefined_variable/undefined_variables_test.gno"}, + errShouldContain: "gno run: cannot run test files (undefined_variables_test.gno)", + }, + { + args: []string{"run", "../../tests/integ/package_testonly"}, + errShouldContain: "no non-test Gno files in ../../tests/integ/package_testonly", + }, // TODO: args // TODO: nativeLibs VS stdlibs // TODO: with gas meter diff --git a/gnovm/tests/integ/package_mismatched/hello.gno b/gnovm/tests/integ/package_mismatched/hello.gno new file mode 100644 index 00000000000..3d8b7db4ed5 --- /dev/null +++ b/gnovm/tests/integ/package_mismatched/hello.gno @@ -0,0 +1,5 @@ +package hello + +func hello() { + println(hello) +} diff --git a/gnovm/tests/integ/package_mismatched/main.gno b/gnovm/tests/integ/package_mismatched/main.gno new file mode 100644 index 00000000000..0a4df1587b7 --- /dev/null +++ b/gnovm/tests/integ/package_mismatched/main.gno @@ -0,0 +1,5 @@ +package main + +func main() { + hello() +} diff --git a/gnovm/tests/integ/package_testonly/hello_filetest.gno b/gnovm/tests/integ/package_testonly/hello_filetest.gno new file mode 100644 index 00000000000..0a4df1587b7 --- /dev/null +++ b/gnovm/tests/integ/package_testonly/hello_filetest.gno @@ -0,0 +1,5 @@ +package main + +func main() { + hello() +} diff --git a/gnovm/tests/integ/package_testonly/hello_test.gno b/gnovm/tests/integ/package_testonly/hello_test.gno new file mode 100644 index 00000000000..3d8b7db4ed5 --- /dev/null +++ b/gnovm/tests/integ/package_testonly/hello_test.gno @@ -0,0 +1,5 @@ +package hello + +func hello() { + println(hello) +} From b4c3930290f0df42b8b08f3132fdb6a949712e70 Mon Sep 17 00:00:00 2001 From: piux2 <90544084+piux2@users.noreply.github.com> Date: Wed, 15 Oct 2025 01:22:18 -0700 Subject: [PATCH 2/2] early return and fix test --- gnovm/cmd/gno/run.go | 2 +- gnovm/cmd/gno/run_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gnovm/cmd/gno/run.go b/gnovm/cmd/gno/run.go index 87ffcb165af..b7fc088a4d3 100644 --- a/gnovm/cmd/gno/run.go +++ b/gnovm/cmd/gno/run.go @@ -88,7 +88,7 @@ func packageNameFromFiles(args []string) (string, error) { for _, arg := range args { s, err := os.Stat(arg) if err != nil { - continue + return "", err } // ---- Directory case ---- diff --git a/gnovm/cmd/gno/run_test.go b/gnovm/cmd/gno/run_test.go index d3158cb90c9..063ce3f7f58 100644 --- a/gnovm/cmd/gno/run_test.go +++ b/gnovm/cmd/gno/run_test.go @@ -21,7 +21,7 @@ func TestRunApp(t *testing.T) { }, { args: []string{"run", "../../tests/integ/does_not_exist"}, - errShouldContain: "no valid gno file found", + errShouldContain: "no such file or directory", }, { args: []string{"run", "../../tests/integ/run_namedpkg/main.gno"},