From edfbdf98cd12960362859e924a2b60036047a990 Mon Sep 17 00:00:00 2001 From: Hariom Verma Date: Thu, 2 May 2024 20:52:03 +0530 Subject: [PATCH] feat!: forbid importing '/r' from '/p' --- tm2/pkg/std/memfile.go | 20 ++++++++ tm2/pkg/std/memfile_test.go | 92 +++++++++++++++++++++++++++++++++---- 2 files changed, 103 insertions(+), 9 deletions(-) diff --git a/tm2/pkg/std/memfile.go b/tm2/pkg/std/memfile.go index 5655876c9bb..556bad02f07 100644 --- a/tm2/pkg/std/memfile.go +++ b/tm2/pkg/std/memfile.go @@ -2,6 +2,8 @@ package std import ( "fmt" + "go/parser" + "go/token" "regexp" "sort" "strings" @@ -80,6 +82,24 @@ func (mempkg *MemPackage) Validate() error { prev = file.Name } + // Check if package imports realm + // TODO(hariom): move this to a separate helper + if strings.HasPrefix(mempkg.Path, "gno.land/p") { // TODO(hariom): Use !gnolang.IsRealmPath() instead + for _, file := range mempkg.Files { + fset := token.NewFileSet() + astFile, err := parser.ParseFile(fset, file.Name, file.Body, parser.ImportsOnly) + if err != nil { + return fmt.Errorf("unable to parse %q", file.Name) + } + for _, imp := range astFile.Imports { + importPath := strings.TrimPrefix(strings.TrimSuffix(imp.Path.Value, `"`), `"`) + if strings.HasPrefix(importPath, "gno.land/r") { // TODO(hariom): Use gnolang.IsRealmPath() instead + return fmt.Errorf("package %q imports realm %q", mempkg.Path, importPath) + } + } + } + } + return nil } diff --git a/tm2/pkg/std/memfile_test.go b/tm2/pkg/std/memfile_test.go index 375e0d1a41a..abbe5dd1c27 100644 --- a/tm2/pkg/std/memfile_test.go +++ b/tm2/pkg/std/memfile_test.go @@ -15,30 +15,104 @@ func TestMemPackage_Validate(t *testing.T) { { "Correct", &MemPackage{ - Name: "hey", - Path: "gno.land/r/demo/hey", - Files: []*MemFile{{Name: "a.gno"}}, + Name: "hey", + Path: "gno.land/r/demo/hey", + Files: []*MemFile{ + { + Name: "a.gno", + Body: "package hey", + }, + }, }, "", }, { "Unsorted", &MemPackage{ - Name: "hey", - Path: "gno.land/r/demo/hey", - Files: []*MemFile{{Name: "b.gno"}, {Name: "a.gno"}}, + Name: "hey", + Path: "gno.land/r/demo/hey", + Files: []*MemFile{ + { + Name: "b.gno", + Body: "package hey", + }, + { + Name: "a.gno", + Body: "package hey", + }, + }, }, `mempackage "gno.land/r/demo/hey" has unsorted files`, }, { "Duplicate", &MemPackage{ - Name: "hey", - Path: "gno.land/r/demo/hey", - Files: []*MemFile{{Name: "a.gno"}, {Name: "a.gno"}}, + Name: "hey", + Path: "gno.land/r/demo/hey", + Files: []*MemFile{ + { + Name: "a.gno", + Body: "package hey", + }, + { + Name: "a.gno", + Body: "package hey", + }, + }, }, `duplicate file name "a.gno"`, }, + { + "Package Imports Package", + &MemPackage{ + Name: "hey", + Path: "gno.land/p/demo/hey", + Files: []*MemFile{ + { + Name: "a.gno", + Body: `package hey + + import "gno.land/p/demo/hello" + `, + }, + }, + }, + "", + }, + { + "Realm Imports Realm", + &MemPackage{ + Name: "hey", + Path: "gno.land/r/demo/hey", + Files: []*MemFile{ + { + Name: "a.gno", + Body: `package hey + + import "gno.land/r/demo/hello" + `, + }, + }, + }, + "", + }, + { + "Package Imports Realm", + &MemPackage{ + Name: "hey", + Path: "gno.land/p/demo/hey", + Files: []*MemFile{ + { + Name: "a.gno", + Body: `package hey + + import "gno.land/r/demo/heyrealm" + `, + }, + }, + }, + `package "gno.land/p/demo/hey" imports realm "gno.land/r/demo/heyrealm"`, + }, } for _, tc := range tt { t.Run(tc.name, func(t *testing.T) {