3

I am trying to deploy a Google Cloud Function in Go, but got an error while deploying because I use, at the same time, subpackages and "internal modules" (only defined on my host, not deployed anywhere). I have the following structure :

.
├── function
│   ├── package1
│   │   └── file1.go
│   ├── function.go
│   ├── go.mod
│   └── go.sum
└── common
    ├── common.go
    ├── go.mod
    └── go.sum

Contents of my function.go (entrypoint of my Cloud Function) :

package function

import (
    "github.com/.../function/package1"
    "github.com/.../common"
)

// use functions from package1 and common

Topics have been covered individually here :

The first post indicates to use vendoring and exclude go.mod and go.sum from the source to be able to use common module, while the 2nd indicates to include go.mod and go.sum without vendoring to be able to use subpackages.

But I am wondering : is it possible to use both at the same time? Or vendoring dependencies requires to put all .go source files in the same directory (no subpackages)? Likewise, using subpackages requires to not use vendoring? How can I structure my code to avoid those restrictions, or what can I do (deploy common module somewhere, ...)?

Also, the documentation on "Specifying dependencies" for Go Cloud Functions states that :

Cloud Functions in Go must provide all of their dependencies via either Go modules with a go.mod file, or a vendor directory. Your function cannot specify dependencies using both Go modules and a vendor directory at the same time.

norbjd
  • 10,166
  • 4
  • 45
  • 80
  • You can absolutely use vendoring with multiple packages. Pretty much any non-throwaway project (so, anything that would be inclined to vendor dependencies) will be made up of multiple packages, so this is the typical use case. – Adrian Apr 02 '19 at 15:17
  • Are you sure you need the inner package defined as its own module? – Adrian Apr 02 '19 at 15:21
  • @Adrian This module is used by other cloud functions, so to avoid code duplication, it should be defined in a separated module. Are you sure about your assumption `You can absolutely use vendoring with multiple packages` when applied to Google Cloud Functions? In Go (in general), I agree with you, but here it does not seem possible. – norbjd Apr 02 '19 at 15:26
  • Code re-use is a good reason to have it in a separate *package*, not a separate module. Modules can contain multiple packages. It's only necessary to declare them as separate *modules* if you need to maintain separate module versions for each: https://github.com/golang/go/wiki/Modules#faqs--multi-module-repositories or if they are truly, completely distinct (but in that case they would typically be in separate repositories). – Adrian Apr 02 '19 at 15:53
  • So if I understand correctly, I should have created a single *module*, and define `function` and `common` as *packages*? If this is correct, I don't think it fits Google Cloud Function deployment model (https://cloud.google.com/functions/docs/writing/specifying-dependencies-go). – norbjd Apr 02 '19 at 15:59
  • I don't see anything on that page suggesting that you can't deploy a module containing multiple packages. I'd be extremely surprised if that was a constraint, given that 99% of modules (and programs) contain multiple packages. – Adrian Apr 02 '19 at 16:02
  • There are multiple constraints concerning code structure to deploy a Cloud Function in Go (see the docs : https://cloud.google.com/functions/docs/writing/#functions-writing-file-structuring-go). As for the usage of packages, it's stated in this doc : `Note: You must use Go modules, by providing a go.mod file, to use sub-packages.`. Packaging in the context of Cloud Functions can be somewhat different of "classical" packaging in Go, that's why it brings confusion. – norbjd Apr 03 '19 at 08:05
  • The second bullet on that page shows an example of a package and sub-package with only the outer package having a go.mod file. – Adrian Apr 03 '19 at 13:32
  • Yes, it's the upper part of the hierarchy shown in my question. But there is no other directory **at the same level** as `function/`, like I've presented. This topic is also covered by this link : https://stackoverflow.com/questions/54255485/how-can-i-use-a-sub-packages-with-go-on-google-cloud-functions I provided in my question. But I'm afraid that is not the point I'm addressing. – norbjd Apr 03 '19 at 14:16
  • If you have any experience in deploying Cloud Functions in Go, could you please write a simple example showing how to deploy a Cloud Function, based on the code structure I provided? Remembering that `common` should be separated because code inside is used by other Functions (located at the same level as `function/`). That would be very helpful because I think there is a misunderstanding between us. – norbjd Apr 03 '19 at 14:17

0 Answers0