openfaas / golang-http-template

Golang templates for OpenFaaS using HTTP extensions
https://www.openfaas.com/
MIT License
106 stars 57 forks source link

Go modules - unable to get a sub-package to work #33

Closed alexellis closed 4 years ago

alexellis commented 4 years ago

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.

LucasRoesler commented 4 years ago

Per the official wiki https://github.com/golang/go/wiki/Modules#gomod

exclude and replace directives 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).

alexellis commented 4 years ago

@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.

LucasRoesler commented 4 years ago

only operate on the current (“main”) module

LucasRoesler commented 4 years ago

this means nested uses of replace will not work

alexellis commented 4 years ago

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?

alexellis commented 4 years ago

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.

alexellis commented 4 years ago

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?