bobg / mingo

MIT License
21 stars 0 forks source link

Invalid version detection when tests present #14

Closed alexdyukov closed 3 months ago

alexdyukov commented 3 months ago

Hey!

There is an invalid version detected with mingo on repo with tests . If i run go test by 1.16 version its work OK:

$ docker run -w /go/src -v .:/go/src golang:1.16 go test ./...
ok      github.com/alexdyukov/httpencoder   0.004s

but mingo tell me to upgrade go.mod up to 1.18 because testing.MainStart found:

$ go run github.com/bobg/mingo/cmd/mingo@latest -tests -check -v
/mnt/src/httpencoder/httpencoder.go:14:14: 7 ("context".Context)
/home/user/.cache/go-build/da/da4e65ca611572657c91072fb1a91ebac4181a9803104dff938df30632d6743c-d:57:7: 18 ("testing".MainStart)
Error scanning directory: go.mod declares version 1.16 but computed minimum is 1.18 [/home/user/.cache/go-build/da/da4e65ca611572657c91072fb1a91ebac4181a9803104dff938df30632d6743c-d:57:7: 18 ("testing".MainStart)]
exit status 1
bobg commented 3 months ago

Thank you for the report!

I don't have a convenient way to test my fix, would you like to help? Simply run the same command as you did above, but replace @latest with @3ed5fa8 (the commit containing the fix). Does mingo produce the right output in that case?

alexdyukov commented 3 months ago

Sure. Same error:

$ go run github.com/bobg/mingo/cmd/mingo@3ed5fa8 -tests -check -v
go: downloading github.com/bobg/mingo v0.9.7-0.20240705165823-3ed5fa8c1205
warning: GOPATH set to GOROOT (/home/user/go) has no effect
/mnt/c/Users/Lenovo/Downloads/FTA/src/httpencoder/decode.go:9:25: 3 ("sync".Pool)
/mnt/c/Users/Lenovo/Downloads/FTA/src/httpencoder/httpencoder.go:15:14: 7 ("context".Context)
/home/user/.cache/go-build/0e/0e70fa0823bc74d50197606763f245c57182455839ab3766d19b7bd229a94a14-d:57:7: 18 ("testing".MainStart)
Error scanning directory: go.mod declares version 1.16 but computed minimum is 1.18 [/home/user/.cache/go-build/0e/0e70fa0823bc74d50197606763f245c57182455839ab3766d19b7bd229a94a14-d:57:7: 18 ("testing".MainStart)]
exit status 1
$ go env | grep CACHE
warning: GOPATH set to GOROOT (/home/user/go) has no effect
GOCACHE='/home/user/.cache/go-build'
GOMODCACHE='/home/user/go/pkg/mod'
alexdyukov commented 3 months ago

I run go install and got same error:

$ go install github.com/bobg/mingo/cmd/mingo@latest
warning: GOPATH set to GOROOT (/home/user/go) has no effect
$ mingo -tests -check -v
/mnt/c/Users/Lenovo/Downloads/FTA/src/httpencoder/decode.go:9:25: 3 ("sync".Pool)
/mnt/c/Users/Lenovo/Downloads/FTA/src/httpencoder/httpencoder.go:15:14: 7 ("context".Context)
/home/user/.cache/go-build/0e/0e70fa0823bc74d50197606763f245c57182455839ab3766d19b7bd229a94a14-d:57:7: 18 ("testing".MainStart)
Error scanning directory: go.mod declares version 1.16 but computed minimum is 1.18 [/home/user/.cache/go-build/0e/0e70fa0823bc74d50197606763f245c57182455839ab3766d19b7bd229a94a14-d:57:7: 18 ("testing".MainStart)]
alexdyukov commented 3 months ago

I think os.Getenv() not the proper way to get GOCACHE env variable, cause i did not set it in my command line:

user@DESKTOP-D8T7N02:~/src/httpencoder$ go env | grep CACHE
warning: GOPATH set to GOROOT (/home/user/go) has no effect
GOCACHE='/home/user/.cache/go-build'
GOMODCACHE='/home/user/go/pkg/mod'
user@DESKTOP-D8T7N02:~/src/httpencoder$ echo $GOCACHE

user@DESKTOP-D8T7N02:~/src/httpencoder$
bobg commented 3 months ago

Derp, of course! Sorry, and thank you again.

Here is a new commit that should work better 🤞: 44c0f53

alexdyukov commented 3 months ago

Nice, error is gone, but mingo computes wrong version now. Lets close this issue and open another one?

The right version should be 1.16 (i do rewrite go.mod file of course):

user@DESKTOP-D8T7N02:~/src/httpencoder$ docker run -w /go/src -v .:/go/src golang:1.16 go test ./...
ok      github.com/alexdyukov/httpencoder       0.007s
user@DESKTOP-D8T7N02:~/src/httpencoder$ docker run -w /go/src -v .:/go/src golang:1.15 go test ./...
# github.com/alexdyukov/httpencoder
./decode.go:55:18: undefined: io.NopCloser
FAIL    github.com/alexdyukov/httpencoder [build failed]
FAIL

but now it decodes as 1.7:

user@DESKTOP-D8T7N02:~/src/httpencoder$ go run github.com/bobg/mingo/cmd/mingo@44c0f53 -tests -check -v
warning: GOPATH set to GOROOT (/home/user/go) has no effect
/mnt/c/Users/Lenovo/Downloads/FTA/src/httpencoder/decode.go:9:25: 3 ("sync".Pool)
/mnt/c/Users/Lenovo/Downloads/FTA/src/httpencoder/httpencoder.go:15:14: 7 ("context".Context)
Error scanning directory: go.mod declares version 1.16 but computed minimum is 1.7 [/mnt/c/Users/Lenovo/Downloads/FTA/src/httpencoder/httpencoder.go:15:14: 7 ("context".Context)]
exit status 1
bobg commented 3 months ago

Thank you again for your help!

What is in your code or dependencies that makes you think the answer should be 1.16? (The version declaration in go.mod does not count.)

bobg commented 3 months ago

Oh never mind - I see it's io.NopCloser.

No need for a new issue, I will keep investigating. Meanwhile, it would help me if you can easily share a minimal reproducible case.

alexdyukov commented 3 months ago

system library uses:

sync.Pool           go1.3
bytes.Buffer{}          go1.0
context.Context         go1.7
io.Writer           go1.0
http.Request.Header.Get     go1.0
http.Handler.ServeHTTP      go1.0
bytes.Buffer.Bytes()        go1.0
http.DetectContentType      go1.0
http.ResponseWriter.WriteHeader go1.0
http.Error          go1.0
io.NopCloser            go1.16

by cmd output i see mingo detects context.Context and sync.Pool, but missing calling io.NopCloser. I make a test code with same error. Feel free debugging with it:

user@DESKTOP-D8T7N02:~/src/benchmarks$ go run github.com/bobg/mingo/cmd/mingo@44c0f53 -check -v
warning: GOPATH set to GOROOT (/home/user/go) has no effect
/mnt/c/Users/Lenovo/Downloads/FTA/src/benchmarks/main.go:10:64: 1 (function body with no final return statement)
Error scanning directory: go.mod declares version 1.18 but computed minimum is 1.1 [/mnt/c/Users/Lenovo/Downloads/FTA/src/benchmarks/main.go:10:64: 1 (function body with no final return statement)]
exit status 1
user@DESKTOP-D8T7N02:~/src/benchmarks$ cat main.go
package main

import (
        "bytes"
        "fmt"
        "io"
)

func main() {
        fmt.Println(len(customReadAll(io.NopCloser(&bytes.Buffer{}))))
}

func customReadAll(reader io.Reader) []byte {
        buf := make([]byte, 100)
        retVal := []byte{}
        for {
                n, err := reader.Read(buf)

                retVal = append(retVal, buf...)
                buf = buf[:0]

                if n < 100 || err != nil {
                        return retVal
                }
        }

        return nil
}
bobg commented 3 months ago

Eureka - your example helped me find that mingo was overlooking the arguments to builtin functions like len. Thank you for your help!