-
Notifications
You must be signed in to change notification settings - Fork 374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(gnomod): forbid require and find dependencies without it #3123
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Norman Meier <[email protected]>
…ould be reverted) Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
seems some tests are failing after merging master, my bad, will fix asap |
Signed-off-by: Norman Meier <[email protected]>
fixed |
Signed-off-by: Norman Meier <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments, that you for the require
removal 🙏
If this is the route we wanna go with, the PR I think accomplishes what it needs to accomplish.
Please check some comments for testing code, it's the only thing I believe we need to modify
res, err := gnoimports.PackageImports(root) | ||
_ = err | ||
|
||
entries, err := os.ReadDir(root) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this go before the PackageImports
call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we sort, it doesn't matter
sub := packageImportsRecursive(filepath.Join(root, entry.Name())) | ||
|
||
for _, imp := range sub { | ||
if !slices.Contains(res, imp) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just about to ask how we filter duplicates
This is probably alright, I'd be curious to see how performant this is in comparison to a map lookup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
map is faster for this after around 1K import statements: https://gist.github.com/n0izn0iz/3551867b864ef9ca155230a7ea8bb120
do you want me to replace with a map lookup?
} | ||
} | ||
|
||
sort.Strings(res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do they need to be sorted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code replaces getting the require
list of a module and go mod tidy
sorts imports. It might not be needed in this case though
gnovm/pkg/gnoimports/imports_test.go
Outdated
require.Equal(t, expected, imports) | ||
} | ||
|
||
func createTmpDir(t *testing.T) (string, func()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not simply use t.TempDir()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was moved from gnovm/cmd/gno/mod_test.go
Refactored in ed89ff6
seen := make(map[string]struct{}) | ||
for _, e := range entries { | ||
filename := e.Name() | ||
if !strings.HasSuffix(filename, ".gno") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have these values as constants anywhere?
I swear we repeat this string literal 9000 times in the codebase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't look like it, I wanted to create a gnofiles
package with these constants and related utils but it felt out of scope
gnovm/pkg/gnopkgfetch/gnopkgfetch.go
Outdated
} | ||
|
||
// not using gno client due to cyclic dep | ||
func qfile(tmClient tm2client.Client, pkgPath string) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we have a client method for something like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't seem so, gnoweb does something very similar here
btw the comment "not using gno client due to cyclic dep" was some confusion by me since gnoclient
is a pkg dedicated to mutations, not queries
gnovm/pkg/gnopkgfetch/gnopkgfetch.go
Outdated
// we need to know that gno.land/r/foo is not downloaded. | ||
// We do this by checking for the presence of gno.land/r/foo/gno.mod | ||
if err := os.WriteFile(modFilePath, []byte("module "+pkgPath+"\n"), 0o644); err != nil { | ||
return fmt.Errorf("failed to write modfile at %q: %w", modFilePath, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no cleanup if this fails, this is why I suggest you break up this mega func
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As was the case with the previous implementation
I agree with you, we also miss a filelock to avoid conflict between multiple gno
command instances. I intend to improve all this in the subsequent PRs towards the unified package loader but I feel it's out of scope of this one
@@ -0,0 +1,99 @@ | |||
package gnopkgfetch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a test file, so it's compiled into the binary. Please change it 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how to do it any other way, pls see #3123 (comment)
t.Fatalf("failed to get source path") | ||
} | ||
examplesDir := filepath.Join(filepath.Dir(filename), "..", "..", "..", "examples") | ||
oldClient := fetchClient |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:(
We can do better 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm open to ideas
examplesRoot string | ||
} | ||
|
||
func (m *examplesMockClient) SendRequest(ctx context.Context, request types.RPCRequest) (*types.RPCResponse, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we clean up this mock a bit? 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's very hard to read
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll clean up if you validate the new way it's injected :) otherwise I'll probably have to scrap it
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
|
||
res := ctypes.ResultABCIQuery{} | ||
|
||
finfo, err := os.Stat(target) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
This path depends on a
user-provided value
This path depends on a
user-provided value
This path depends on a
user-provided value
} | ||
|
||
if finfo.IsDir() { | ||
entries, err := os.ReadDir(target) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
This path depends on a
user-provided value
This path depends on a
user-provided value
This path depends on a
user-provided value
} | ||
res.Response.Data = []byte(strings.Join(files, "\n")) | ||
} else { | ||
content, err := os.ReadFile(target) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
This path depends on a
user-provided value
This path depends on a
user-provided value
This path depends on a
user-provided value
|
||
res := ctypes.ResultABCIQuery{} | ||
|
||
finfo, err := os.Stat(target) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression
} | ||
|
||
if finfo.IsDir() { | ||
entries, err := os.ReadDir(target) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression
} | ||
res.Response.Data = []byte(strings.Join(files, "\n")) | ||
} else { | ||
content, err := os.ReadFile(target) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
Signed-off-by: Norman Meier <[email protected]>
A step towards the importer package (#2932) and future of
gno.mod
(#2904)require
statement support fromgno.mod
.gno
filesimport
statements to find dependenciesgnovm/pkg/gnopkgfetch
GNO_PKG_HOSTS
env variable that takesdomain=rpcURL
coma-separated pairs to override pkg fetching behaviorgnovm/pkg/gnoimports
I decided to do this first to avoid having multiple ways to resolve dependencies lying around in the codebase and causing confusion in subsequent steps
Contributors' checklist...
BREAKING CHANGE: xxx
message was included in the description