Deploying Go subpackages to Google Cloud Functions fails - go

I'm trying to deploy a function to GCF but it's failing no matter what I try. This is the error returned every time:
Build failed: 2021/03/02 18:02:46 Unable to extract package name: unable to find Go package in /workspace/serverless_function_source_code.
exit status 1; Error ID: aba1aa6a
I've read a few answers here and I tried to fix the issue as told, but I keep having this error and I'm lost at this point.
My project structure is as follow:
.
|--function.go
|--go.mod
|--go.sum
|--subpackage
` |--subpackage.go
My main function uses some stuff from subpackage.go and the function.go import is:
package function
import (
"fmt"
"log"
"net/http"
// remote imports //
modname/subpackage
)
and then the go.mod file:
module modname
go 1.13
require (
// remote imports //
modname/subpackage
)
The subpackage is initialized as package subpackage and I think this is what the GCF docs say.
In function.go I have a function called Start that I indicated as the entrypoint in the setup. I'm lost and I have no idea how to work around this.

Ok, found the problem. If you have my issue, ignore the go.mod file in my question, as it was rigthly suggested on an other answer that you should not include the local packages.
But my problem wasn't that. I was zipping and uploading the FOLDER containing the project, not the file inside the folder. GCF than unzipped the .zip and found an other folder with the project inside.
Your go.mod and function.go files have to be at the first level. Hope this will save time for someone else.

Delete the reference of your subpackage in your go.mod file. When the subpackage is bellow the function.go file you don't need to reference it in the go.mod file.

Related

GO (Golang) does not see other .go files inside the same dir

PROBLEM: functions exported from other packages are undefined, invisible from inside of main.go
SOLUTION:
Put main.go into a separate folder (name it app or main, doesn't matter). Only go.mod remains in root, with the folders "app" and "package1" "package2" etc. After this VSCode automatically added imports on save, I didn't even need to do anything. If I have main.go in root then it doesn't work (most of the time) as it doesn't "see" functions from other modules (undefined).
I found the solution HERE,(see post by davidbost). The solution on this page by Andrey Dyatlov worked too for a while and then stopped working.
It took me probably 10 hours of try and error and searching.
Hopefully the above will help others. Thank you, everyone!
_______________________________________________________________________
Original Problem Description:
Windows 10, Go 1.17, VS Code with Go extension.
Hello, I am new to Go and I was not able to follow a single tutorial due to the following issue. When I create another .go file in the same directory (or inside a folder of the same directory) as the main.go, I receive error saying .\main.go:7:2: undefined: SayHi
main.go file:
package main
import "fmt"
func main() {
fmt.Println("1st")
SayHi()
}
another .go file inside /something folder:
package something
import "fmt"
func SayHi() {
fmt.Println("Hi!")
}
Running go run main.go results in the undefined SayHi error
I googled the issue with no luck.
$ go build // gives out the same error
$ go install // gives out the same error
without using functions from other files $ go run main.go runs just fine.
I also tried go init with adding my github directory with no luck (by following a tutorial). I also tried the official starting guide with go run init, and the exported Capitalized function is still undefined. What's worse is that autocomplete for the SayHi function works, yet it won't compile because undefined.
I have set PATH to C:\Users\xxx\go and put my files there, I also tried using C:\Go with no luck, it's still undefined. I'm about to give up on Go...
It' would be hard to fix your project without knowing its current state. Please, try to start from scratch:
Create a directory for your project anywhere outside $GOPATH:
mkdir myproject
cd myproject
Run the following command to create a go.mode file that describes your project (module) and its dependencies; let's call the module github.com/me/myproject:
go mod init github.com/me/myproject
Create the first file; let's call it main.go:
package main
import "fmt"
import "github.com/me/myproject/something"
func main() {
fmt.Println("1st")
something.SayHi()
}
Create a directory for the package called github.com/me/myproject/something:
mkdir something
Create a file with path something/something.go:
package something
import "fmt"
func SayHi() {
fmt.Println("Hi!")
}
From the myproject directory, run go build.
Launch your first Go program:
./myproject
1st
Hi!

Conflict in repo name and module name

I created the github.com project qjson/qjson-go that contains the package name qjson that you can see here. I named the github project this way because github.com/qjson/ contains other projects for different languages (e.g. qjson-c).
Unfortunately, I get the following error when I try to import the project as github.com/qjson/qjson-go:
$ go mod tidy
go: finding module for package github.com/qjson/qjson-go
go: downloading github.com/qjson/qjson-go v0.0.0-20210128102242-170c47e2db46
github.com/xxx/xxx imports
github.com/qjson/qjson-go: module github.com/qjson/qjson-go#latest found (v0.0.0-20210128102242-170c47e2db46), but does not contain package github.com/qjson/qjson-go
I’m apparently doing it wrong. I understand that due to the import statement we are then expected to use gjson-go as package identifier.
What must I do so that the git project can be named qjson-go and the package qjson ?
I assume that one solution is to create a sub-directory named qjson inside qjson-go and move all package files in it. The user would then import "github.com/qson/qson-go/qjson". Is that correct ? Is there another solution avoiding the stutter ?
This program works as expected:
package main
import (
"fmt"
"github.com/qjson/qjson-go/qjson"
)
func main() {
fmt.Println(qjson.ErrDivisionByZero)
}
The issue is that you are using this file structure:
qjson/engine.go
qjson/errors.go
When you should just be putting them at the top level, like this:
engine.go
errors.go
So you can either fix the directory, and tag a new version, or just leave the
files as is, and change your imports to match what I have above.

Project structure and importing packages

I'm just starting to learn Go and I'm wondering how to best organize my project and import packages. I created a project at $GOPATH/src/my_project. It contains the file main.go and the folder foo containing the file bar.go.
$GOPATH/src/my_project
main.go
foo/
bar.go
My main.go looks as follows
package main
import (
"./foo"
"fmt"
)
func main() {
fmt.Println("Main")
foo.Baz()
}
Here is the foo.go
package foo
import "fmt"
func Baz() {
fmt.Println("Baz")
}
It works the way I expect it to, but I wonder if this is really the right way to structure a project and import packages, because most tutorials only import packages from github and never from local.
Thanks for your answers..
Relative imports are possible in Go but they are not encouraged to be used.
Instead you always use the full path of the package. In your case that would be my_project/foo. This is is relative to the GOPATH/src folder.
However, since we have Go modules now which make things a tiny bit more complicated to start with but have a lot of advantages in the long run.
Just earlier today I gave a step by step guide on how to set up a new project with Go modules: After go install the import doesn't recognize the package
The module name in this guide is the basis for your project then and all paths in the module build on that path. Let me give an example:
Let's say you name your module github.com/yourName/myProject. Then you can import the subpackage foo with github.com/yourName/myProject/foo.
Note: The module path should be the same as the git URL, that way you can just get the module with go get. If you don't plan on ever uploading the project to github or another git URL, you should still choose a unique name. Starting with a domain you own is a good idea -- for uniqueness.

How to include my `log` package instead of built-in `log` package in `golang`?

I have an log package in my project src folder. But when I include the log package from an another package as following, the go seams find the log in the system folder instead of my package.
import ("log")
And seams I cannot using relative path to import log package, because go install give following error:
local import "./log" in non-local package
So how can I let the go using my log package?
You need to add your package inside $GOPATH
So if your package is in
$GOPATH/src/github.com/ZijingWu/awesomeapp/src/
your log package would be in
$GOPATH/src/github.com/ZijingWu/awesomeapp/src/log
then it would be possible to use
import("github.com/ZijingWu/awesomeapp/src/log")
The paths seams a bit strange tho, and maybe you should consider adding the log package as a completely separate repository on github, so it would look something like.
import("github.com/ZijingWu/log")
Just using github as an example here, could of course be placed wherever, also just guessing at your username there. Doesnt need to be in github either you can just place it localy on your computer in the $GOPATH, but then noone else would be able to build your package.

multiple Go modules in a monorepo and custom dir structure

I have 2 possibly related issues.
I have a test monorepo setup, with 2 subdirectories (mod1 and mod2).
Each one of them has a go.mod file in them, and each of the modules has a single .go file with basic printing code. in mod2 there is a subdirectory mod2_lib (that holds one of those simple .go files with basic printing code), since I read that Go modules are basically their own little GOPATH's.
Id like to call function Run() thats in a package mod2/mod2_lib from mod1, but all Im getting is build github.com/account_name/test/mod1: cannot find module for path github.com/account_name/test/mod2/mod2_lib.
here are the files Im using to figure this out:
mod1/t.go
package main
import (
"fmt"
"github.com/account_name/test/mod2/mod2_lib"
)
func main() {
fmt.Println("mod1")
mod2_lib.Run()
}
mod2/mod2_lib/t_lib.go
package mod2_lib
import "fmt"
func Run() {
fmt.Println("RUNS")
}
the second issue is that in this monorepo I'd like to have related Python and Rust code in top-level dirs py and rust. So I'd like to place all my Go packages in the go/src dir. How would other people import this go/src path into their project (possibly still having the "github.com/account_name/test/mod2/mod2_lib" as the import path, and not "github.com/account_name/test/go/src/mod2/mod2_lib")?
can anyone give me some pointers on these issues? I want to move to using Golang modules, and abandon the GOPATH.
the issue was that it was a private github.com repo. making it public fixed it! :) have to figure out authentication now for the module system.

Resources