go get/build can't resolve a local-only project package - go

project.go:6:2: cannot find package "example.com/project/package" in any of:
/usr/local/Cellar/go/1.1.2/libexec/src/pkg/example.com/project/package (from $GOROOT)
/Users/me/go/src/example.com/project/package (from $GOPATH)
Fetching https://example.com/project/package?go-get=1
ignoring https fetch with status code 404 Fetching http://example.com/project/package?go-get=1
Parsing meta tags from http://example.com/project/package?go-get=1 (status code 404)
import "example.com/project/package": parse http://example.com/project/package?go-get=1: no go-import meta tags
package example.com/project/package: unrecognized import path "example.com/project/package"
Why can't go get/build find the local package. I understand go get will fail on my repo because it's bare, but it seems like go get is completely ignoring the local file, forcing me to commit and push my code before I can compile it. This is, per the snippet, OSX 10.8 and Go 1.1.2 installed via brew. GOPATH is set to /Users/me/go and GOROOT is empty.
I should note that I don't have this problem at all when using go get in gitbash on my Windows machine. I've tried all the google-fu I can think of to search this, but everyone claims you can use relative "project/package" imports, which also completely fail in this case.

Upgrading from go1.1.2 to go1.2 through brew upgrade go fixed this problem

You can work with code locally without having pushed it - you just need your folder structure to mimic the import path.
Put your library code inside a src/ directory, with a folder structure mimicking the import path:
[15:42] foa:home $ tree
.
├── myprogram.go
└── src
└── example.com
└── project
└── mypackage
└── mypackage.go
Then set GOPATH to the directory that has src/ in it, and you'll be able to build the project:
[15:42] foa:home $ export GOPATH=`pwd`
[15:42] foa:home $ go build
Here's myprogram.go:
package main
import "example.com/project/mypackage"
func main() {
mypackage.Run()
}
And mypackage.go:
package mypackage
import "fmt"
func Run() {
fmt.Println("It works.")
}
It's common to lay out your working directories like this, and then root the actual git repositories at the lowest level (e.g. in src/example.com/project/mypackage) so that they work cleanly with go get and go install for other users.

Related

Call function in another files

I don't know how I can use function in another file.
my project architecture:
.
├── main.go
└── src
└── function.go
1 directory, 2 files
main.go
package main
import "src/funcrion"
func main() {
funcrion.Display();
}
function.go
package src
import "fmt";
func Display() {
fmt.Println("Hello World");
}
For start my project I use:
go run main.go
error:
main.go:3:8: cannot find package "src/funcrion" in any of:
/usr/local/opt/go/libexec/src/src/funcrion (from $GOROOT)
/Users/clementbolin/go/src/src/funcrion (from $GOPATH)
In first, I want to resolve this problem. In second time I want to know what is the best option for compile a real project with more 10 files for example, do I need to use Makefile? Or like in Rust go has package manager?
When you do import "src/funcrion" the go compiler will try to search for this in GOPATH and GOROOT, as you see in your error message. It does not try to search in the current folder. Since it doesn't find a package with that name in either GOPATH or GOROOT, it gives you that error.
A good way to reference "the current folder" would be using go modules. On the root of your project do $ go mod init myproject. (replace myproject for a more appropriate name for your project)
After you do that, you can use "myproject" to reference the project folder in package names, like:
package main
import "myprject/src"
func main() {
src.Display();
}
Also note that the import goes only up to the package name and not the file name. So, in your case, you shouldn't do import myproject/src/function just because you have a function.go file inside a src package.
And since your Display function is inside the src package, you refer to it simply with src.Display() after importing the package. No need to specify the name of the file anywhere.
You can read more about go modules here: https://blog.golang.org/using-go-modules
Another tip is to not use src as a package name. In Go, it's common to not have a "src" folder, and as a package name is also not very good. For instance, see the line that reads src.Display(). Instinctively, i would read this as something like "the Display of the source", which has no meaning. But if instead of src you name your package text, that same line would read text.Display() which would read as "display some text", which is more accurate and meaningful to what the function is doing.
I believe the package name is src but I see you are trying to import src\funcrion There is no such package called funcrion.
I think you should just do something like this main.go
package main
import "src"
func main() {
src.Display();
}
or if you would like to call your src package as funcrion, then just import it like below,
import funcrion "src"
And make sure your file structure is as below and inside $GOPATH
Users
└── clementbolin
└── go
└── src
├── main.go
└── src
└── function.go

Go Modules - how to reference a branch in GitHub

I'm using Coreos OIDC library and would like to know how to reference (in go.mod file) a branch, since they don't develop under master but use v2 instead.
I tried github.com/coreos/go-oidc#v2 but I get:
go: github.com/coreos/go-oidc#v2#v2.0.0+incompatible: invalid github.com/ import path "github.com/coreos/go-oidc#v2"
go: error loading module requirements
The phrase import path in the error message suggests that somewhere in your code you have written something like:
import "github.com/coreos/go-oidc#v2"
But the import path of a Go package does not include its version: only the entries in the go.mod and go.sum files do.
So instead you should write:
import "github.com/coreos/go-oidc"
and update your go.mod and go.sum files by running
go get -d github.com/coreos/go-oidc#v2
That should result in an entry in your go.mod file like:
require github.com/coreos/go-oidc v2.0.0+incompatible

go mod: cannot find module providing package

I am creating a go project with version 1.12.1.
If I run GOPATH="$(pwd)/vendor:$(pwd)" GOBIN="$(pwd)/bin" go clean I get the following error:
can't load package: package github.com/marvincaspar/go-example: unknown import path "github.com/marvincaspar/go-example": cannot find module providing package github.com/marvincaspar/go-example
This is only for go clean, go run or go build works fine.
Here is the folder structure of main code:
.
├── Makefile
├── cmd
│ └── server
│ └── main.go
├── go.mod
├── go.sum
└── pkg
└── storage
└── mysql
└── storage.go
Here is how the go.mod file looks like:
module github.com/marvincaspar/go-example
go 1.12
require (
github.com/go-sql-driver/mysql v1.4.1
)
And finally the main.go file:
package main
import (
"fmt"
"os"
"github.com/marvincaspar/go-example/pkg/storage/mysql"
)
func main() {
if err := run(); err != nil {
fmt.Fprintf(os.Stderr, "%v", err)
os.Exit(1)
}
}
func run() error {
// init storage
s := mysql.NewStorage()
// do some other stuff...
}
Any ideas what I am doing wrong?
I generally use go get and go mod tidy for same. It works all the time.
go mod tidy
Normally this new project approach works for me:
go mod init <project_name>
go test
I have found that developing projects outside of GOROOT and GOPATH are much easier
Go build/install is trying to find main package in your root directory, it is not checking sub-directories (cmd/server) in your case. Hence you are getting package not found error.
To properly build your code, you can run:
go build github.com/marvincaspar/go-example/cmd/server
Similarly, to run your project, you will have to provide module-name/main-package-path:
go run github.com/marvincaspar/go-example/cmd/server
Go clean can be executed in same way, by providing module-name/path-with-main-package
go clean github.com/marvincaspar/go-example/cmd/server
or
GOPATH="$(pwd)/vendor:$(pwd)" GOBIN="$(pwd)/bin" go clean github.com/marvincaspar/go-example/cmd/server
However, as per https://blog.learngoprogramming.com/code-organization-tips-with-packages-d30de0d11f46, just put your source files into your project’s root. It’s better that way.
This can also happen if you are using workspaces. It seems like you can't use one package without workspaces if you are using others with workspaces.
So try going into your top level workspace and do
go work use ./problemPackage.
At least this worked for me.
To solve this problem you have to do few things, First, go to the project directory via the Terminal then run the following command ( If you are using git clone then go to the clone directory folder via Terminal and run the following command):
Step 1: sudo go mod init your-program.go
Step 2: sudo go mod tidy
Step 3: sudo go build your-program.go

How can I resolve dependencies in nested application binary in Go project?

This sounds stupid, but I am trying for build my new golang project for a while now and I am stuck with following error
can't load package: package github.com/kuskmen/yamq/cmd/yamq-client: found packages main (main.go) and yamqclient (yamq-client.go) in C:\projects\yamq\cmd\yamq-client
I know this should be straightforward to fix, but I come from .NET and I am still not experienced in Go projects and its dependency resolution model hence the struggle.
My project structure looks like so
/yamq
/cmd
/yamq-client // yamq client application binary
main.go // package main
yamq-client.go // package yamqclient
/yamq-server // yamq server application binary
main.go // package main
yamq-server.go // package yamqserver
go.mod // contains only "module github.com/kuskmen/yamq" for now
... // some library files that will probably be moved to /shared folder
so far so good, when I do go build in outermost directory ( /yamq ) it is building successfully (or at least it is not showing any errors), but when I try to build either yamq-client or yamq-server binaries I get the aforementioned error and every time I try to google it or find something useful I got some old article or answer that dates back 2013-2016 that suggests something about $GOPATH and etc which shouldn't be the case here since I am trying to use go modules.
Help a fellow .NET developer join Go community by explaining him how exactly modules work cause I found this and this useless or at least I am missing the point, thanks in advance!
To follow up from my comment above:
From https://golang.org/doc/code.html:
Go programmers typically keep all their Go code in a single workspace.
A workspace contains many version control repositories (managed by Git, for example).
Each repository contains one or more packages.
Each package consists of one or more Go source files in a single directory.
The path to a package's directory determines its import path.
For your project, I'd do something like this:
$ tree
.
├── clientlib
│   └── lib.go
├── cmd
│   ├── client
│   │   └── main.go
│   └── server
│   └── main.go
├── go.mod
└── serverlib
└── lib.go
5 directories, 5 files
$ cat go.mod
module myproject.com
The module name is arbitrary (could be github.com/yourname/yourproject).
For the server side:
$ cat serverlib/lib.go
package serverlib
import "fmt"
func Hello() {
fmt.Println("Hello from serverlib.Hello")
}
$ cat cmd/server/main.go
package main
import (
"fmt"
"myproject.com/serverlib"
)
func main() {
fmt.Println("Running server")
serverlib.Hello()
}
And now we can build and run it:
$ go build -o server cmd/server/main.go
$ ./server
Running server
Hello from serverlib.Hello
The client side looks symmetrical.
Variations: you could name the .go files in cmd/... by their actual binary names - like server.go and client.go. The package in each is still main, but then go build creates an executable with the file's name (sans the .go) without needing to -o explicitly.

How can I use a sub-packages with Go on Google Cloud Functions?

I'd like to use a helper package from Go Cloud Function. The package has some helper logic that can be shared between multiple functions. But, what is the right way to structure the packages so they all work? The package should be in the same project - not published and public as a completely separate package.
I work at Google. The goal for this question is to proactively answer common questions and help developers starting off with Go on GCF.
You can use subpackages with Go modules. Go modules are Go's new dependency management solution - they let you work outside of GOPATH and let you manage the exact versions of each dependency you have.
Modules also let you define a group of Go packages with the same import path prefix. When you're writing a function, this lets you import other packages in your module.
The function you're deploying needs to be at the root of your module.
Here is an example file structure and how packages would be imported:
.
├── cmd
│ └── main.go # Useful for testing. Can import and setup your function.
├── function.go # Can import example.com/foo/helperpackage
├── function_test.go
├── go.mod # module example.com/foo
└── helperpackage
└── helper.go
This setup has your function in function.go and tested by function_test.go. They are in a module named example.com/foo. helperpackage can be imported by function.go using example.com/foo/helperpackage.
This also has a cmd directory, which may be helpful for local testing. You can import example.com/foo and start an HTTP server which registers your function as an HTTP handler. For example:
package main
import (
"log"
"net/http"
"example.com/foo"
)
func main() {
http.Handle("/HelloHTTP", foo.HelloHTTP)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Note: You could use a vendor directory to achieve the same result. But, all of the packages your function imports would need to be in the vendor directory (with the full import path), which works, but is cumbersome to maintain. It's uncommon to copy sub-packages into your vendor directory, so I wouldn't recommend this.
We also ran into this issue. The go.mod approach provided by #TylerBui-Palsulich (https://stackoverflow.com/a/54255486/2307346) didn't work as we also had to download dependencies from a private repository.
From the Google documentation:
If your function's dependencies are hosted in a repository that is not publicly accessible, you must use a vendor directory to fetch your dependencies before deploying your function
(https://cloud.google.com/functions/docs/writing/specifying-dependencies-go#using_a_vendor_directory)
Given the following package structure:
cloudfunctions.go
sharedpackage
-> shared.go
go.mod
In our go.mod file we defined the following namespace: module some/namespace
The cloudfunctions.go file has the following package definition and imports
package foobar
import (
"bitbucket.org/some/private/dependency"
"some/namespace/sharedpackage"
)
Because of the private dependency we cannot use the go.mod file. Instead we provide a vendor directory.
Warning: If you have both a go.mod file and a vendor directory at the root of your project, the contents of the vendor directory will be ignored when your function is built in the cloud. To ensure that your vendor directory is used, you must exclude the go.mod file from your project's source code prior to deployment. If you are using the gcloud command-line tool, you can ensure that go.mod is not uploaded by using .gcloudignore.
(https://cloud.google.com/functions/docs/writing/specifying-dependencies-go#using_a_vendor_directory)
gcloud deploy will ignore the vendor directory if it finds go.mod, we fix this with a .gloudignore file with the following content:
go.mod
go.sum
At the end we have the following file structure:
cloudfunctions.go
sharedpackage
-> shared.go
go.mod
vendor
.gcloudignore
The last step, Fixing the cannot find package error
When running the deploy step you will still run into an error similar to:
(gcloud.functions.deploy) OperationError: code=3, message=Build failed: /tmp/sgb/gopath/src/serverlessapp/vendor/some/namespace/cloud_functions.go:5:2: cannot find package "some/namespace/sharedpackage" in any of:...
This is because the go.mod file, containing the module name, is ignored. now the Go compiler no longer knows that some/namespace/sharedpackage refers to the local sharedpackage directory.
We managed to get it working by changing the module name to match the package name:
Change module name in go.mod to module foobar
Change the imports in cloudfunctions.go to: "foobar/sharedpackage":
package foobar
import (
"bitbucket.org/some/private/dependency"
"foobar/sharedpackage"
)
Now the Go compiler is able to detect that foobar/sharedpackage is a subpackage of the foobar package.

Resources