Skip to content

Commit

Permalink
feat(cmd/gno): lint all files in folder before panicking (#2202)
Browse files Browse the repository at this point in the history
This Pull request intents to follow up on #2011. As said on that Pull
request, currently we show all lint errors on the first analyzed file.
If in a folder we have `a.gno` & `b.gno` both with lint errors. `gno
lint | run | test` will only find the errors related to one of those
files.

**This PR aims to show all the lint errors present on the current
folder**.

Changes:
for lint &  test cmd:
- we modified ParseMemPackage function on gnovm/pkg/gnoland/nodes.go.
Before this function returned as soon as an error was found while
Parsing the gno file. So we introduced an error slice to keep track of
all Parse errors. After parsing all the files we panic with the list of
errors only if this list is not empty.
- we did the same on parseMemPackageTests function 
- create a function printRuntimeError that handles the print of the
errors inside `catchRuntimeError` function. We did this change in order
to be able to recursively call the funtion and handle the case of an
[]error type composed of scanner.ErrorList errors.

### Results
* running on gnovm/tests/integ/several-files-multiple/errors
LINT (before):
```sh
several-files-multiple-errors % gno lint .
file2.gno:3: expected 'IDENT', found '{' (code=2).
file2.gno:5: expected type, found '}' (code=2).
```

LINT (after):
```sh
gno lint .
file2.gno:3: expected 'IDENT', found '{' (code=2).
file2.gno:5: expected type, found '}' (code=2).
main.gno:5: expected ';', found example (code=2).
main.gno:6: expected '}', found 'EOF' (code=2).
exit status 1
```

<!-- please provide a detailed description of the changes made in this
pull request. -->

<details>

<summary>Contributors' checklist...</summary>

- [ ] Added new tests, or not needed, or not feasible
- [ ] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [ ] Updated the official documentation or not needed
- [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [ ] Added references to related issues and PRs
- [ ] Provided any useful hints for running manual tests
- [ ] Added new benchmarks to [generated
graphs](https://gnoland.github.io/benchmarks), if any. More info
[here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
</details>
  • Loading branch information
Villaquiranm authored Oct 21, 2024
1 parent 6fafe0e commit 464c7f1
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 7 deletions.
17 changes: 12 additions & 5 deletions gnovm/cmd/gno/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/gnolang/gno/gnovm/tests"
"github.com/gnolang/gno/tm2/pkg/commands"
osm "github.com/gnolang/gno/tm2/pkg/os"
"go.uber.org/multierr"
)

type lintCfg struct {
Expand Down Expand Up @@ -174,12 +175,18 @@ func catchRuntimeError(pkgPath string, stderr io.WriteCloser, action func()) (ha
case *gno.PreprocessError:
err := verr.Unwrap()
fmt.Fprint(stderr, issueFromError(pkgPath, err).String()+"\n")
case scanner.ErrorList:
for _, err := range verr {
fmt.Fprint(stderr, issueFromError(pkgPath, err).String()+"\n")
}
case error:
fmt.Fprint(stderr, issueFromError(pkgPath, verr).String()+"\n")
errors := multierr.Errors(verr)
for _, err := range errors {
errList, ok := err.(scanner.ErrorList)
if ok {
for _, errorInList := range errList {
fmt.Fprint(stderr, issueFromError(pkgPath, errorInList).String()+"\n")
}
} else {
fmt.Fprint(stderr, issueFromError(pkgPath, err).String()+"\n")
}
}
case string:
fmt.Fprint(stderr, issueFromError(pkgPath, errors.New(verr)).String()+"\n")
default:
Expand Down
4 changes: 4 additions & 0 deletions gnovm/cmd/gno/lint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ func TestLintApp(t *testing.T) {
args: []string{"lint", "../../tests/integ/several-lint-errors/main.gno"},
stderrShouldContain: "../../tests/integ/several-lint-errors/main.gno:5: expected ';', found example (code=2).\n../../tests/integ/several-lint-errors/main.gno:6",
errShouldBe: "exit code: 1",
}, {
args: []string{"lint", "../../tests/integ/several-files-multiple-errors/main.gno"},
stderrShouldContain: "../../tests/integ/several-files-multiple-errors/file2.gno:3: expected 'IDENT', found '{' (code=2).\n../../tests/integ/several-files-multiple-errors/file2.gno:5: expected type, found '}' (code=2).\n../../tests/integ/several-files-multiple-errors/main.gno:5: expected ';', found example (code=2).\n../../tests/integ/several-files-multiple-errors/main.gno:6: expected '}', found 'EOF' (code=2).\n",
errShouldBe: "exit code: 1",
}, {
args: []string{"lint", "../../tests/integ/run_main/"},
stderrShouldContain: "./../../tests/integ/run_main: missing 'gno.mod' file (code=1).",
Expand Down
5 changes: 5 additions & 0 deletions gnovm/cmd/gno/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ func TestRunApp(t *testing.T) {
args: []string{"run", "-expr", "Context()", "../../tests/integ/context/context.gno"},
stdoutShouldContain: "Context worked",
},
{
args: []string{"run", "../../tests/integ/several-files-multiple-errors/"},
stderrShouldContain: "../../tests/integ/several-files-multiple-errors/file2.gno:3: expected 'IDENT', found '{' (code=2).\n../../tests/integ/several-files-multiple-errors/file2.gno:5: expected type, found '}' (code=2).\n../../tests/integ/several-files-multiple-errors/main.gno:5: expected ';', found example (code=2).\n../../tests/integ/several-files-multiple-errors/main.gno:6: expected '}', found 'EOF' (code=2).",
errShouldBe: "exit code: 1",
},
// TODO: a test file
// TODO: args
// TODO: nativeLibs VS stdlibs
Expand Down
7 changes: 6 additions & 1 deletion gnovm/cmd/gno/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ func loadTestFuncs(pkgName string, t *testFuncs, tfiles *gno.FileSet) *testFuncs
func parseMemPackageTests(memPkg *std.MemPackage) (tset, itset *gno.FileSet) {
tset = &gno.FileSet{}
itset = &gno.FileSet{}
var errs error
for _, mfile := range memPkg.Files {
if !strings.HasSuffix(mfile.Name, ".gno") {
continue // skip this file.
Expand All @@ -586,7 +587,8 @@ func parseMemPackageTests(memPkg *std.MemPackage) (tset, itset *gno.FileSet) {
}
n, err := gno.ParseFile(mfile.Name, mfile.Body)
if err != nil {
panic(err)
errs = multierr.Append(errs, err)
continue
}
if n == nil {
panic("should not happen")
Expand All @@ -606,6 +608,9 @@ func parseMemPackageTests(memPkg *std.MemPackage) (tset, itset *gno.FileSet) {
memPkg.Name, memPkg.Name, n.PkgName, mfile))
}
}
if errs != nil {
panic(errs)
}
return tset, itset
}

Expand Down
8 changes: 7 additions & 1 deletion gnovm/pkg/gnolang/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/gnolang/gno/tm2/pkg/errors"
"github.com/gnolang/gno/tm2/pkg/std"
"go.uber.org/multierr"
)

// ----------------------------------------
Expand Down Expand Up @@ -1189,14 +1190,16 @@ func ReadMemPackageFromList(list []string, pkgPath string) *std.MemPackage {
// or [ParseFile] returns an error, ParseMemPackage panics.
func ParseMemPackage(memPkg *std.MemPackage) (fset *FileSet) {
fset = &FileSet{}
var errs error
for _, mfile := range memPkg.Files {
if !strings.HasSuffix(mfile.Name, ".gno") ||
endsWith(mfile.Name, []string{"_test.gno", "_filetest.gno"}) {
continue // skip spurious or test file.
}
n, err := ParseFile(mfile.Name, mfile.Body)
if err != nil {
panic(err)
errs = multierr.Append(errs, err)
continue
}
if memPkg.Name != string(n.PkgName) {
panic(fmt.Sprintf(
Expand All @@ -1206,6 +1209,9 @@ func ParseMemPackage(memPkg *std.MemPackage) (fset *FileSet) {
// add package file.
fset.AddFiles(n)
}
if errs != nil {
panic(errs)
}
return fset
}

Expand Down
5 changes: 5 additions & 0 deletions gnovm/tests/integ/several-files-multiple-errors/file2.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

type{

}
1 change: 1 addition & 0 deletions gnovm/tests/integ/several-files-multiple-errors/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/tests/severalerrors
6 changes: 6 additions & 0 deletions gnovm/tests/integ/several-files-multiple-errors/main.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package main

func main() {
for {
_ example
}

1 comment on commit 464c7f1

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Go Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 464c7f1 Previous: 6fafe0e Ratio
BenchmarkBinary/EmptyStruct:encode 479.8 ns/op 96 B/op 2 allocs/op 288.3 ns/op 96 B/op 2 allocs/op 1.66
BenchmarkBinary/EmptyStruct:encode - ns/op 479.8 ns/op 288.3 ns/op 1.66
BenchmarkBinary/EmptyStruct:decode 311.4 ns/op 0 B/op 0 allocs/op 140.2 ns/op 0 B/op 0 allocs/op 2.22
BenchmarkBinary/EmptyStruct:decode - ns/op 311.4 ns/op 140.2 ns/op 2.22
BenchmarkBinary/ShortArraysStruct:encode 787.7 ns/op 192 B/op 4 allocs/op 614.7 ns/op 192 B/op 4 allocs/op 1.28
BenchmarkBinary/ShortArraysStruct:encode - ns/op 787.7 ns/op 614.7 ns/op 1.28
BenchmarkBinary/ShortArraysStruct:decode 364.5 ns/op 0 B/op 0 allocs/op 231.7 ns/op 0 B/op 0 allocs/op 1.57
BenchmarkBinary/ShortArraysStruct:decode - ns/op 364.5 ns/op 231.7 ns/op 1.57
BenchmarkBinary/EmbeddedSt1:encode 6599 ns/op 2037 B/op 65 allocs/op 4635 ns/op 2037 B/op 65 allocs/op 1.42
BenchmarkBinary/EmbeddedSt1:encode - ns/op 6599 ns/op 4635 ns/op 1.42
BenchmarkRemoved 38.8 ns/op 0 B/op 0 allocs/op 29.18 ns/op 0 B/op 0 allocs/op 1.33
BenchmarkRemoved - ns/op 38.8 ns/op 29.18 ns/op 1.33
BenchmarkBcryptGenerateFromPassword/benchmark-security-param 63787927 ns/op 5130 B/op 9 allocs/op 31934980 ns/op 5125 B/op 9 allocs/op 2.00
BenchmarkBcryptGenerateFromPassword/benchmark-security-param - ns/op 63787927 ns/op 31934980 ns/op 2.00
BenchmarkBcryptGenerateFromPassword/benchmark-security-param 127510712 ns/op 5139 B/op 9 allocs/op 31934980 ns/op 5125 B/op 9 allocs/op 3.99
BenchmarkBcryptGenerateFromPassword/benchmark-security-param - ns/op 127510712 ns/op 31934980 ns/op 3.99
BenchmarkBcryptGenerateFromPassword/benchmark-security-param 254996749 ns/op 5158 B/op 9 allocs/op 31934980 ns/op 5125 B/op 9 allocs/op 7.98
BenchmarkBcryptGenerateFromPassword/benchmark-security-param - ns/op 254996749 ns/op 31934980 ns/op 7.98
BenchmarkBcryptGenerateFromPassword/benchmark-security-param 509961163 ns/op 5196 B/op 10 allocs/op 31934980 ns/op 5125 B/op 9 allocs/op 15.97
BenchmarkBcryptGenerateFromPassword/benchmark-security-param - ns/op 509961163 ns/op 31934980 ns/op 15.97
BenchmarkBcryptGenerateFromPassword/benchmark-security-param 1019782468 ns/op 5528 B/op 13 allocs/op 31934980 ns/op 5125 B/op 9 allocs/op 31.93
BenchmarkBcryptGenerateFromPassword/benchmark-security-param - ns/op 1019782468 ns/op 31934980 ns/op 31.93
BenchmarkBcryptGenerateFromPassword/benchmark-security-param - allocs/op 13 allocs/op 9 allocs/op 1.44
BenchmarkBcryptGenerateFromPassword/benchmark-security-param 2043637854 ns/op 5736 B/op 15 allocs/op 31934980 ns/op 5125 B/op 9 allocs/op 63.99
BenchmarkBcryptGenerateFromPassword/benchmark-security-param - ns/op 2043637854 ns/op 31934980 ns/op 63.99
BenchmarkBcryptGenerateFromPassword/benchmark-security-param - allocs/op 15 allocs/op 9 allocs/op 1.67
BenchmarkSigning 84318 ns/op 1856 B/op 36 allocs/op 25734 ns/op 64 B/op 1 allocs/op 3.28
BenchmarkSigning - ns/op 84318 ns/op 25734 ns/op 3.28
BenchmarkSigning - B/op 1856 B/op 64 B/op 29
BenchmarkSigning - allocs/op 36 allocs/op 1 allocs/op 36
BenchmarkSigning 84233 ns/op 1856 B/op 36 allocs/op 25734 ns/op 64 B/op 1 allocs/op 3.27
BenchmarkSigning - ns/op 84233 ns/op 25734 ns/op 3.27
BenchmarkSigning - B/op 1856 B/op 64 B/op 29
BenchmarkSigning - allocs/op 36 allocs/op 1 allocs/op 36
BenchmarkVerification 164562 ns/op 864 B/op 19 allocs/op 61021 ns/op 0 B/op 0 allocs/op 2.70
BenchmarkVerification - ns/op 164562 ns/op 61021 ns/op 2.70
BenchmarkVerification - B/op 864 B/op 0 B/op +∞
BenchmarkVerification - allocs/op 19 allocs/op 0 allocs/op +∞
BenchmarkVerification 166612 ns/op 864 B/op 19 allocs/op 61021 ns/op 0 B/op 0 allocs/op 2.73
BenchmarkVerification - ns/op 166612 ns/op 61021 ns/op 2.73
BenchmarkVerification - B/op 864 B/op 0 B/op +∞
BenchmarkVerification - allocs/op 19 allocs/op 0 allocs/op +∞
BenchmarkImmutableAvlTreeMemDB 4061861 ns/op 1100202 B/op 22398 allocs/op 3325964 ns/op 857704 B/op 17427 allocs/op 1.22
BenchmarkImmutableAvlTreeMemDB - ns/op 4061861 ns/op 3325964 ns/op 1.22
BenchmarkImmutableAvlTreeMemDB - B/op 1100202 B/op 857704 B/op 1.28
BenchmarkImmutableAvlTreeMemDB - allocs/op 22398 allocs/op 17427 allocs/op 1.29
BenchmarkRandomBytes/random 68.89 ns/op 16 B/op 1 allocs/op 32.66 ns/op 4 B/op 1 allocs/op 2.11
BenchmarkRandomBytes/random - ns/op 68.89 ns/op 32.66 ns/op 2.11
BenchmarkRandomBytes/random - B/op 16 B/op 4 B/op 4
BenchmarkRandomBytes/random 104.6 ns/op 32 B/op 1 allocs/op 32.66 ns/op 4 B/op 1 allocs/op 3.20
BenchmarkRandomBytes/random - ns/op 104.6 ns/op 32.66 ns/op 3.20
BenchmarkRandomBytes/random - B/op 32 B/op 4 B/op 8
BenchmarkRandomBytes/random 265.6 ns/op 112 B/op 1 allocs/op 32.66 ns/op 4 B/op 1 allocs/op 8.13
BenchmarkRandomBytes/random - ns/op 265.6 ns/op 32.66 ns/op 8.13
BenchmarkRandomBytes/random - B/op 112 B/op 4 B/op 28
BenchmarkRandomBytes/random 2333 ns/op 1024 B/op 1 allocs/op 32.66 ns/op 4 B/op 1 allocs/op 71.43
BenchmarkRandomBytes/random - ns/op 2333 ns/op 32.66 ns/op 71.43
BenchmarkRandomBytes/random - B/op 1024 B/op 4 B/op 256
BenchmarkSmall/boltdb-1000-100-16-40/update 1464955 ns/op 46705 B/op 396 allocs/op 997741 ns/op 37826 B/op 373 allocs/op 1.47
BenchmarkSmall/boltdb-1000-100-16-40/update - ns/op 1464955 ns/op 997741 ns/op 1.47
BenchmarkSmall/boltdb-1000-100-16-40/update - B/op 46705 B/op 37826 B/op 1.23
BenchmarkSmall/boltdb-1000-100-16-40/block - B/op 5581621 B/op 4604422 B/op 1.21
BenchmarkSmall/memdb-1000-100-16-40/block 15653451 ns/op 9085344 B/op 165390 allocs/op 11971467 ns/op 6577289 B/op 116694 allocs/op 1.31
BenchmarkSmall/memdb-1000-100-16-40/block - ns/op 15653451 ns/op 11971467 ns/op 1.31
BenchmarkSmall/memdb-1000-100-16-40/block - B/op 9085344 B/op 6577289 B/op 1.38
BenchmarkSmall/memdb-1000-100-16-40/block - allocs/op 165390 allocs/op 116694 allocs/op 1.42
BenchmarkMedium/boltdb-100000-100-16-40/update 6952487 ns/op 131336 B/op 1022 allocs/op 5177408 ns/op 99356 B/op 841 allocs/op 1.34
BenchmarkMedium/boltdb-100000-100-16-40/update - ns/op 6952487 ns/op 5177408 ns/op 1.34
BenchmarkMedium/boltdb-100000-100-16-40/update - B/op 131336 B/op 99356 B/op 1.32
BenchmarkMedium/boltdb-100000-100-16-40/update - allocs/op 1022 allocs/op 841 allocs/op 1.22
BenchmarkMedium/memdb-100000-100-16-40/update - B/op 357273 B/op 258282 B/op 1.38
BenchmarkMedium/memdb-100000-100-16-40/update - allocs/op 7077 allocs/op 4982 allocs/op 1.42
BenchmarkLevelDBBatchSizes/goleveldb-100000-400-16-40/update - B/op 48961 B/op 38908 B/op 1.26
BenchmarkLevelDBBatchSizes/goleveldb-100000-400-16-40/update - allocs/op 587 allocs/op 449 allocs/op 1.31
BenchmarkLevelDBBatchSizes/goleveldb-100000-2000-16-40/block - B/op 96204320 B/op 79473414 B/op 1.21
BenchmarkHash/ripemd160 2830 ns/op 25 B/op 1 allocs/op 709.3 ns/op 25 B/op 1 allocs/op 3.99
BenchmarkHash/ripemd160 - ns/op 2830 ns/op 709.3 ns/op 3.99
BenchmarkHash/sha2-256 521.5 ns/op 33 B/op 1 allocs/op 168.6 ns/op 33 B/op 1 allocs/op 3.09
BenchmarkHash/sha2-256 - ns/op 521.5 ns/op 168.6 ns/op 3.09
BenchmarkHash/sha3-256 1836 ns/op 33 B/op 1 allocs/op 716 ns/op 33 B/op 1 allocs/op 2.56
BenchmarkHash/sha3-256 - ns/op 1836 ns/op 716 ns/op 2.56
BenchmarkWriteSecretConnection 6120 ns/op 0 B/op 0 allocs/op 4027 ns/op 0 B/op 0 allocs/op 1.52
BenchmarkWriteSecretConnection - ns/op 6120 ns/op 4027 ns/op 1.52
BenchmarkReadSecretConnection 3436 ns/op 0 B/op 0 allocs/op 2358 ns/op 0 B/op 0 allocs/op 1.46
BenchmarkReadSecretConnection - ns/op 3436 ns/op 2358 ns/op 1.46
BenchmarkCacheStoreIterator100000 - allocs/op 25254 allocs/op 20208 allocs/op 1.25

This comment was automatically generated by workflow using github-action-benchmark.

CC: @ajnavarro @thehowl @zivkovicmilos

Please sign in to comment.