Go modules - unable to get a sub-package to work
alexellis opened this issue · 7 comments
Description
When adding a sub-package to a function using golang-middleware and Go modules, I'm unable to get it to build. The unit tests fails immediately, then the go build fails if the test step is commented out.
Step 17/29 : RUN go build --ldflags "-s -w" -a -installsuffix cgo -o handler .
---> Running in cd54e2e66fb9
build handler: cannot load github.com/alexellis/vend/vend/handlers: git ls-remote -q origin in /go/pkg/mod/cache/vcs/15c84a3c22a2d4367cca03dcf38500ba216f1f2e95fa3fdd4255f8434c417d89: exit status 128:
fatal: could not read Username for 'https://github.com': terminal prompts disabled
Confirm the import path was entered correctly.
If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.
Sample repo
https://github.com/alexellis/golang-middleware-relative-import
The top-level entry-point is main.go
main.go is a module and references a folder "function" which is also a module.
The basic path of a function handler with no other packages seems to work without Go modules, but when adding a sub-package i.e. handlers and referencing that, the tests and build fail.
main -> function -> handlers (sub-package)
This should have been a basic happy path scenario tested in #24, so I'm surprised to see that this didn't work. Pinging the people who tested / reviewed the PR.
@ewilde @LucasRoesler @bmcstdio @jonatasbaldin @stefanprodan
I imagine this is the same issue for go and golang-http also.
When using dep and a vendor folder this can be worked-around so that it works in the container, but not on a local system. The ideal resolution would have OpenFaaS functions with sub-packages working well in an IDE with highlighting and goreturns etc all working fine, and also working in a docker build.
Per the official wiki https://github.com/golang/go/wiki/Modules#gomod
excludeandreplacedirectives only operate on the current (“main”) module. exclude and replace directives in modules other than the main module are ignored when building the main module. The replace and exclude statements, therefore, allow the main module complete control over its own build, without also being subject to complete control by dependencies. (See FAQ below for a discussion of when to use a replace directive).
@LucasRoesler can you highlight what you want us to take from that quote, it isn't obvious to me what I'm supposed to get from it.
only operate on the current (“main”) module
this means nested uses of replace will not work
There is an alternative without Go modules which appears to work in Docker, but does not work properly on the local system.
In the repo, I can set this relative import, and then turn off go modules -> faas-cli build --build-arg GO111MODULE=off - then both the tests and the build work fine.
package function
import (
"net/http"
"handler/function/handlers"
)
func Handle(w http.ResponseWriter, r *http.Request) {
handlers.Echo(w, r)
}Setting "handler/function/handlers" works only because it matches the GOPATH in the Docker build of /go/src/handler/, it fails to work in an IDE or on a local system because the relative path is not the same.
Given the promise of Go modules and enthusiasm from the community for them, we need to find a way to make this work. What ideas to people have?
So here is a hacky suggestion, can we offer a MOD_REPLACE.txt that can be injected into the root-level main.go?
By default it'd be:
module handler
go 1.13
replace handler/function => ./function
Then users could write into GO_REPLACE.txt like follows:
replace github.com/alexellis/vend/vend/handlers => ./function/handlers
And the final Go.mod file for main.go would have that appended.
I've opened #34 which seems to work and provide a workable solution. @LucasRoesler @stefanprodan did you have any other ideas to unblock this, or anything else we should try?