petergtz / pegomock

Pegomock is a powerful, yet simple mocking framework for the Go programming language
Apache License 2.0
252 stars 28 forks source link

pegomock generate panics with `cannot find module for path` #86

Closed MrCreosote closed 5 years ago

MrCreosote commented 5 years ago

I'm following the docs to the best of my ability, but can't seem to get around this issue (note I scrubbed the module and user names from the path):

~/go/bin$ wget --quiet -O pegomock_2.2.0 https://github.com/petergtz/pegomock/releases/download/v2.2.0/pegomock_2.2.0_linux_x86_64
~/go/bin$ chmod a+x pegomock_2.2.0 

~/go/bin$ cd ~/VisualStudioCode/go/<module>/core/
~/VisualStudioCode/go/<module>/core$ go get github.com/petergtz/pegomock@v2.2.0
go: finding github.com/petergtz/pegomock v2.2.0
go: finding github.com/onsi/gomega/format latest
~/VisualStudioCode/go/<module>/core$ grep -n2 "UUIDGen interface" core.go 
28-
29-// UUIDGen is an interface for a type that generates random UUIDs.
30:type UUIDGen interface {
31- GetUUID() uuid.UUID
32-}
~/VisualStudioCode/go/<module>/core$ pegomock_2.2.0 generate UUIDGen
panic: Loading input failed: exit status 1 caused by:
build command-line-arguments: cannot find module for path _/home/<user>/VisualStudioCode/go/<module>/VisualStudioCode/go/<module>/core

goroutine 1 [running]:
github.com/petergtz/pegomock/pegomock/filehandling.GenerateMockSourceCode(0xc000094c80, 0x2, 0x2, 0x0, 0x0, 0xc000080642, 0x9, 0x0, 0x0, 0x0, ...)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/filehandling/filehandling.go:110 +0x5ea
github.com/petergtz/pegomock/pegomock/filehandling.GenerateMockFile(0xc000094c80, 0x2, 0x2, 0xc000074240, 0x52, 0x0, 0x0, 0xc000080642, 0x9, 0x0, ...)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/filehandling/filehandling.go:64 +0xf0
github.com/petergtz/pegomock/pegomock/filehandling.GenerateMockFileInOutputDir(0xc000094c80, 0x2, 0x2, 0xc00001c004, 0x3d, 0x0, 0x0, 0x0, 0x0, 0xc000080642, ...)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/filehandling/filehandling.go:40 +0x17f
main.Run(0xc000078060, 0x3, 0x3, 0x7e6f80, 0xc00008a000, 0x7e6f60, 0xc000084000, 0xc0000e8690, 0xc0000741e0)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/main.go:116 +0x226e
main.main()
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/main.go:37 +0xa8

~/VisualStudioCode/go/<module>$ ls go.*
go.mod  go.sum
petergtz commented 5 years ago

Hi @MrCreosote,

Thanks for reporting this. This one looks a bit nasty, specifically, because I haven't worked with go modules yet (but I should have!). To troubleshoot it, can we try the following 2 things:

  1. Can you reproduce the problem within a simpler setup, i.e. can you create separate project and create a minimal core.go with just the UUIDGen interface. And after doing that can you try again? What is the outcome of that.

  2. Completely different approach: Within your current project, try:

    ~/VisualStudioCode/go/<module>/core$ pegomock_2.2.0 generate --use-experimental-model-gen UUIDGen

    It will generate the mock with a completely separate implementation which might not suffer from the problems you've described above.

MrCreosote commented 5 years ago

2 (Experimental gen) first:

~/VisualStudioCode/go/<module>/core$ pegomock_2.2.0 generate --use-experimental-model-gen UUIDGen
cannot find package "../../VisualStudioCode/go/<module>/core" in:
    /home/<user>/VisualStudioCode/go/VisualStudioCode/go/<module>/core
panic: no initial packages were loaded

goroutine 1 [running]:
github.com/petergtz/pegomock/modelgen/loader.GenerateModel(0xc0001060f0, 0x28, 0x7ffea05a1291, 0x7, 0x52, 0xc000047900, 0x443676)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/modelgen/loader/loader.go:18 +0x5c1
github.com/petergtz/pegomock/pegomock/filehandling.GenerateMockSourceCode(0xc0000ec4c0, 0x2, 0x2, 0x0, 0x0, 0xc000110172, 0x9, 0x0, 0x0, 0x0, ...)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/filehandling/filehandling.go:102 +0x2a9
github.com/petergtz/pegomock/pegomock/filehandling.GenerateMockFile(0xc0000ec4c0, 0x2, 0x2, 0xc00013c060, 0x52, 0x0, 0x0, 0xc000110172, 0x9, 0x0, ...)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/filehandling/filehandling.go:64 +0xf0
github.com/petergtz/pegomock/pegomock/filehandling.GenerateMockFileInOutputDir(0xc0000ec4c0, 0x2, 0x2, 0xc00001e004, 0x3d, 0x0, 0x0, 0x0, 0x0, 0xc000110172, ...)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/filehandling/filehandling.go:40 +0x17f
main.Run(0xc00000e080, 0x4, 0x4, 0x7e6f80, 0xc00000c020, 0x7e6f60, 0xc00000c010, 0xc00013a000, 0xc00013c000)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/main.go:116 +0x226e
main.main()
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/main.go:37 +0xa8
MrCreosote commented 5 years ago

1 (minimal example):

~/VisualStudioCode/go/pegotest$ tree
.
├── core
│   └── core.go
├── go.mod
└── go.sum

1 directory, 3 files
~/VisualStudioCode/go/pegotest/core$ cat core.go 
package core

import (
    "github.com/google/uuid"
)

// UUIDGen is an interface for a type that generates random UUIDs.
type UUIDGen interface {
    GetUUID() uuid.UUID
}
:~/VisualStudioCode/go/pegotest/core$ go get github.com/petergtz/pegomock@v2.2.0
go: finding github.com/petergtz/pegomock v2.2.0
go: finding github.com/onsi/gomega/format latest
~/VisualStudioCode/go/pegotest/core$ pegomock_2.2.0 generate UUIDGen
panic: Loading input failed: exit status 1 caused by:
build command-line-arguments: cannot find module for path _/home/<user>/VisualStudioCode/go/pegotest/VisualStudioCode/go/pegotest/core

goroutine 1 [running]:
github.com/petergtz/pegomock/pegomock/filehandling.GenerateMockSourceCode(0xc00000acc0, 0x2, 0x2, 0x0, 0x0, 0xc0000186e0, 0x9, 0x0, 0x0, 0x0, ...)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/filehandling/filehandling.go:110 +0x5ea
github.com/petergtz/pegomock/pegomock/filehandling.GenerateMockFile(0xc00000acc0, 0x2, 0x2, 0xc00001c300, 0x51, 0x0, 0x0, 0xc0000186e0, 0x9, 0x0, ...)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/filehandling/filehandling.go:64 +0xf0
github.com/petergtz/pegomock/pegomock/filehandling.GenerateMockFileInOutputDir(0xc00000acc0, 0x2, 0x2, 0xc00001a044, 0x3c, 0x0, 0x0, 0x0, 0x0, 0xc0000186e0, ...)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/filehandling/filehandling.go:40 +0x17f
main.Run(0xc00000e0c0, 0x3, 0x3, 0x7e6f80, 0xc00000c020, 0x7e6f60, 0xc00000c010, 0xc0000c8690, 0xc00001c2a0)
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/main.go:116 +0x226e
main.main()
    /Users/pego/workspace/go/src/github.com/petergtz/pegomock/pegomock/main.go:37 +0xa8
petergtz commented 5 years ago

@MrCreosote OK, cool. Let me work with that and get back to you. I might need a couple of days, as this seems not trivial.

petergtz commented 5 years ago

@MrCreosote I could reproduce your problem and I found the root cause: Pegomock currently relies on $GOPATH to be set. It's not working with Go modules yet.

Good news is: I'm almost done with a fix. Will post back with updates soon.

petergtz commented 5 years ago

@MrCreosote I gave it a first shot on the develop branch. Please build the pegomock binary from that branch and check if you're able to generate your mock.

petergtz commented 5 years ago

@MrCreosote Can I take your 👍 as a "it works"? :-)

If so, I'll merge it into master and make a new release.

MrCreosote commented 5 years ago

@petergtz That's not my +1 :)

Sorry, I haven't had a chance to try it out yet. Hopefully this weekend.

petergtz commented 5 years ago

@MrCreosote Ha! Good point :-). Sorry, my mistake. Alright, will wait until you've tried it out.

MrCreosote commented 5 years ago

This is probably because I'm an extreme go newbie, but I can't seem to get pegomock to build correctly:

~/pegogit/src/github.com/petergtz/pegomock$ echo $GOPATH
/home/<user>/go:/home/<user>/pegogit
~/pegogit/src/github.com/petergtz/pegomock$ git status
On branch develop
Your branch is up to date with 'origin/develop'.
*snip*
~/pegogit/src/github.com/petergtz/pegomock$ go install
~/pegogit/src/github.com/petergtz/pegomock$ ls
_config.yml                   model
dsl.go                        modelgen
dsl_test.go                   panic_with_message_matcher_test.go
generate_test_mocks           panic_with_message_to_matcher_test.go
ginkgo_compatible             pegomock
internal                      README.md
invocation_count_matchers.go  scripts
LICENSE                       testing_t_support.go
matcher_factories.go          test_interface
matcher.go                    types.go
mockgen                       vendor
~/pegogit/src/github.com/petergtz/pegomock$ ls ~/go/bin
dlv  gocode        godoc      golint      gopls      go-symbols  pegomock_2.2.0
g    gocode-gomod  gofmt      go-outline  gorename   guru
go   godef         goimports  gopkgs      goreturns  mockery
# if I don't specify output I get nothing
~/pegogit/src/github.com/petergtz/pegomock$ go build -o pgmk 
~/pegogit/src/github.com/petergtz/pegomock$ chmod a+x pgmk
~$ cd VisualStudioCode/go/<module>/core/
~/VisualStudioCode/go/<module>/core$ ~/pegogit/src/github.com/petergtz/pegomock/pgmk generate UUIDGen
/home/<user>/pegogit/src/github.com/petergtz/pegomock/pgmk: line 1: syntax error near unexpected token `newline'
/home/<user>/pegogit/src/github.com/petergtz/pegomock/pgmk: line 1: `!<arch>'

# try a few more install strategies
~/pegogit/src/github.com/petergtz/pegomock$ go build pegomock/main.go 
# command-line-arguments
pegomock/main.go:97:26: undefined: DeterminePackageNameIn
~/pegogit/src/github.com/petergtz/pegomock/pegomock$ go install
~/pegogit/src/github.com/petergtz/pegomock/pegomock$ ls
filehandling  main_test.go     package_name_test.go  testutil  watch
main.go       package_name.go  remove                util
~/pegogit/src/github.com/petergtz/pegomock/pegomock$ ls ..
_config.yml                   modelgen
dsl.go                        panic_with_message_matcher_test.go
dsl_test.go                   panic_with_message_to_matcher_test.go
generate_test_mocks           pegomock
ginkgo_compatible             pgmk
internal                      README.md
invocation_count_matchers.go  scripts
LICENSE                       testing_t_support.go
matcher_factories.go          test_interface
matcher.go                    types.go
mockgen                       vendor
model
~/pegogit/src/github.com/petergtz/pegomock/pegomock$ ls ~/go/bin
dlv  gocode        godoc      golint      gopls      go-symbols  pegomock_2.2.0
g    gocode-gomod  gofmt      go-outline  gorename   guru
go   godef         goimports  gopkgs      goreturns  mockery
~/pegogit/src$ go install github.com/petergtz/pegomock/pegomock
~/pegogit/src$ ls ~/go/bin
dlv  gocode        godoc      golint      gopls      go-symbols  pegomock_2.2.0
g    gocode-gomod  gofmt      go-outline  gorename   guru
go   godef         goimports  gopkgs      goreturns  mockery
~/pegogit/src$ ls github.com/petergtz/pegomock/
_config.yml                   modelgen
dsl.go                        panic_with_message_matcher_test.go
dsl_test.go                   panic_with_message_to_matcher_test.go
generate_test_mocks           pegomock
ginkgo_compatible             pgmk
internal                      README.md
invocation_count_matchers.go  scripts
LICENSE                       testing_t_support.go
matcher_factories.go          test_interface
matcher.go                    types.go
mockgen                       vendor
model
~/pegogit/src$ ls github.com/petergtz/pegomock/pegomock/
filehandling  main_test.go     package_name_test.go  testutil  watch
main.go       package_name.go  remove                util

All I do for my own modules is go build <file>

petergtz commented 5 years ago

@MrCreosote Go to the following directory

~/pegogit/src/github.com/petergtz/pegomock/pegomock

(notice the 2nd pegomock in that path). Then do a

go install

That should do the trick to get the binary.

MrCreosote commented 5 years ago

Ugh, I was looking in the wrong bin dir.

~/pegogit/src/github.com/petergtz/pegomock$ git status
On branch develop
Your branch is up to date with 'origin/develop'.
*snip*

~/pegogit/src/github.com/petergtz/pegomock$ cd pegomock/
~/pegogit/src/github.com/petergtz/pegomock/pegomock$ go install

~/VisualStudioCode/go/<module>/core$ ~/pegogit/bin/pegomock generate UUIDGen
pegomock: error: Couldn't determine package path from directory: Directory is not within a Go package path. GOPATH:/home/<user>/go:/home/<user>/pegogit; dir: /home/<user>/VisualStudioCode/go/<module>/core
*snip*

~/VisualStudioCode/go/<module>/core$ cd ..
~/VisualStudioCode/go/<module>$ ~/pegogit/bin/pegomock generate core.UUIDGen
pegomock: error: Couldn't determine package path from directory: Directory is not within a Go package path. GOPATH:/home/<user>/go:/home/<user>/pegogit; dir: /home/<user>/VisualStudioCode/go/<module>
*snip*

~/VisualStudioCode/go/<module>$ cd ../pegotest/core/
~/VisualStudioCode/go/pegotest/core$ ~/pegogit/bin/pegomock generate UUIDGen
pegomock: error: Couldn't determine package path from directory: Directory is not within a Go package path. GOPATH:/home/<user>/go:/home/<user>/pegogit; dir: /home/<user>/VisualStudioCode/go/pegotest/core
*snip*

~/VisualStudioCode/go/pegotest/core$ cd ..
~/VisualStudioCode/go/pegotest$ ~/pegogit/bin/pegomock generate core.UUIDGen
pegomock: error: Couldn't determine package path from directory: Directory is not within a Go package path. GOPATH:/home/<user>/go:/home/<user>/pegogit; dir: /home/<user>/VisualStudioCode/go/pegotest
petergtz commented 5 years ago

@MrCreosote Okay, cool, you've got the correct binary now.

From the error message it looks like pegomock is running in "GOPATH mode", not in "Go modules mode". This is usually the case when you have set GOPATH to a value, but didn't specify GO111MODULE=off (it pretty much follows the go CLI commands).

It is very likely that this is the case in your case. From the error message output it looks like you specified multiple paths in GOPATH: /home/<user>/go:/home/<user>/pegogit. According to documentation only a single path is allowed in GOPATH. I think this could be one reason why pegomock is getting confused.

But the actual way to resolve this, is probably that want to operate in "Go modules" mode. Therefore, I think it is even better to unset GOPATH in your shell and try again with

~/VisualStudioCode/go/<module>/core$ ~/pegogit/bin/pegomock generate UUIDGen

Assuming that there is a go.mod somewhere in that directory tree. (Make sure echo $GOPATH is empty)

MrCreosote commented 5 years ago

From the error message it looks like pegomock is running in "GOPATH mode", not in "Go modules mode". This is usually the case when you have set GOPATH to a value, but didn't specify GO111MODULE=off (it pretty much follows the go CLI commands).

Hmm... I've been working solely with modules since I started learning go and the go tools work with the GOPATH set as long as the module isn't in the GOPATH. That's what I glean from the docs as well:


When do I get old behavior vs. new module-based behavior?

In general, modules are opt-in for Go 1.11, so by design old behavior is preserved by default.

Summarizing when you get the old 1.10 status quo behavior vs. the new opt-in modules-based behavior:

All that being said, if I unset GOPATH the mocks are generated. I tried with a single value GOPATH but got the same error as previously.

Thanks for the fix!

petergtz commented 5 years ago

@MrCreosote you're absolutely right. I misread the first bullet point originally. I will make that change to fix the behavior and be really in line with the other go commands. But I'm glad you already got your mock generated. Will keep you posted.

petergtz commented 5 years ago

@MrCreosote I've just pushed another fix on develop, that should follow the documentation as you've posted it above. With that change, you should be able to generate your mocks even without unsetting your GOPATH. Would you mind trying it out one more time?

MrCreosote commented 5 years ago

Lookin' good, my man

~/pegogit/src/github.com/petergtz/pegomock$ git log -1 --pretty=%B
Fix logic to determine Go modules mode

https://github.com/petergtz/pegomock/issues/86#issuecomment-493797705

~/pegogit/src/github.com/petergtz/pegomock$ echo $GOPATH
/home/<user>/go:/home/<user>/pegogit
~/pegogit/src/github.com/petergtz/pegomock$ cd pegomock/
~/pegogit/src/github.com/petergtz/pegomock/pegomock$ go install
~/pegogit/src/github.com/petergtz/pegomock/pegomock$ cd ~/go
~/go$ export GOPATH=`pwd`
~/go$ echo $GOPATH
/home/<user>/go
~/go$ cd ~/VisualStudioCode/go/<module>/core/
~/VisualStudioCode/go/<module>/core$ ~/pegogit/bin/pegomock generate UUIDGen
petergtz commented 5 years ago

Lookin' good, my man

:-D

Okay, will merge the changes into master and make a release. I'm sure there are still some cases which don't properly work, but we can iterate on those.

Thanks again for reporting this and all the help troubleshooting it, @MrCreosote.

petergtz commented 5 years ago

Changes released in https://github.com/petergtz/pegomock/releases/tag/v2.4.0.