no matching versions for query "latest" with a local package - go

go version go1.15.2 darwin/amd64
within my folder I have two files: main.go and user.go along with other files such as go.mod, go.sum etc.
when trying to import the package from user.go I get the error in my imports:
no matching versions for query "latest"
user.go
package user
import (
"os"
"os/user"
"path/filepath"
)
main.go
import (
"fmt"
"bufio"
"github.com/ctfrancia/go-dot/user" // <--- error here
// ...
)
I tried following some suggestions such as go clean -modcache as suggested in a git hub issue
I'm using gomods so I don't want to disable it. Thanks

so my mistake was that the folder in the directory is the package name... well best practice:
so: goApplication/pkg/hello all the subsequent .go files should have package hello at the top

Your files user.go and main.go are in same directory, in golang if you want to work with custom packages you have to create directories with the same name as your package name in your case your directory structure will be something like:
goApplication/rootDir
- main.go
- user
-- user.go
Note: You can also use pkg/user directory but it is not mandatory for small projects and community has positive as well as negative remarks for this layout structure.

Related

Multimodule Go Importing From Wrong Path

I have the following structure:
gateway-service
config
config.go
go.mod
go.sum
service.go
logger
logger.go
go.mod
go.sum
In config.go I import the following:
import (
"errors"
"os"
"strings"
"github.com/spf13/viper"
)
Now, the top level packages are fine and import correctly. However, the viper package does not. The error message is:
could not import github.com/spf13/viper (cannot find package "github.com/spf13/viper" in any of
/Users/me/.go/src/github.com/spf13/viper (from $GOROOT)
/Users/me/go/src/github.com/spf13/viper (from $GOPATH))compiler
The same issue happens in the logger.go file:
package logger
import (
"context"
"go.uber.org/zap"
)
The error is:
could not import go.uber.org/zap (cannot find package "go.uber.org/zap" in any of
/Users/me/.go/src/go.uber.org/zap (from $GOROOT)
/Users/me/go/src/go.uber.org/zap (from $GOPATH))compiler
I've tried installing with:
go get github.com/spf13/viper
go get go.uber.org/zap
go mod tidy
gateway-service/go.mod
module github.com/puul/gateway-service
go 1.15
require github.com/spf13/viper v1.3.2
logger/go.mod
module github.com/puul/logger
go 1.15
require (
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.16.0
)
Go env:
▶ echo $GOPATH
/Users/me/go
▶ echo $GOROOT
/Users/me/.go
On a related note, I'd love to know if there was a simpler way to achieve a structure like this:
pkg
logger
logger.go
services
gateway
Edit
My guess is that I have a conflict somehow between modules and GOPATH. Frankly, it's not clear from documentation how the two interact. Autoimports appear to be broken in VSCode as a result. It should be pulling from the path given in the import but it is not. What determines that import path is the core issue.
The (from $GOPATH) strings in the error message indicates that the go command invocation that produced that error was running in GOPATH mode, not module mode — which probably means that your current working directory was not within either of the two modules.
In general we recommend using a single module for your code unless you have a strong need to release different sets of packages at different times.
If you are using VSCode to edit code across multiple modules, you may need to configure your workspace to tell it which is the main module; see the build.experimentalWorkspaceModule setting.
You may also need (or want) to plumb the logger module into the gateway-service module using a replace directive.

Local packages and directory structure

This is the directory structure for my Go project:
my_project
|
main.go
- my_package
|
- my_package.go
On main.go this works ok:
import (
"my_package/my_package"
)
But when I create a new folder "examples" to test some new functionalities of the package, tha main.go cannot import the package as expected:
my_project
|
main.go
- my_package
|
- my_package.go
- examples
|
- main.go
importing package from parent directory:
import (
"../my_package/my_package"
)
Trying running examples/main.go does not work:
cd examples
go run main.go
build _/mypath/my_project/my_package: cannot find module for path _/mypath/my_project/my_package
Shouldn't I import local packages from parent directories?
Is it always compulsory to have the package modules on subfolders of main.go?
Is there any simple and clear way to organize main/test/debug go programs w/ shared dependencies on local packages?
I've read on golang modules and local packages that maybe I should use abosulte paths for importing packages, but I don't like that option because this is a code meant to be uloaded to a repository, so absolute paths wouldn't work on other implementations.
The way to proceed according to stackoverflow masters (and it works perfectly well indeed) is to import a fake repository and then replace it with a local redirection as stated on How to use a module that is outside of "GOPATH" in another module?
In main.go:
import (
my_package "my_fake_repository/myself/my_project/my_package"
)
In go.mod:
require my_fake_repository/myself/my_project/my_package v0.0.0
replace my_fake_repository/myself/my_project/my_package => ../my_package
It works! Thx a lot!

Can't import a package from a different file in GO

I am using go1.13.4 and below is my project structure:
src/types/type.go
src/utils/util.go
go.mod
In go.mod:
module example.com/graphql
go 1.13
require github.com/graph-gophers/graphql-go v0.0.0-20191031232829-adde0d0f76a3
In src/types/type.go:
package types
type USER struct {
...
}
In src/utils/util.go,
package utils
import (
"example.com/graphql/types"
"fmt"
"io/ioutil"
"os"
)
I got tan error when build the project:
$ go build ./...
src/utils/utils.go:4:2: cannot find module providing package example.com/graphql/types
I wonder why it can't find the package example.com/graphql/types? I am reading https://blog.golang.org/using-go-modules and I already set the module name in go.mod file at the root of my project.
With your current layout, import path of types is example.com/graphql/src/types.
go.mod should be inside src if you have that structure. Or better would be to get rid of src. go.mod must be next to the types and utils folders.

How to import local packages in go?

I am new to go and working on an example code that I want to localize.
In the original main.go import statement it was:
import (
"log"
"net/http"
"github.com/foo/bar/myapp/common"
"github.com/foo/bar/myapp/routers"
)
Now I have common and routers package in /home/me/go/src/myapp
So I converted the import statement to:
import (
"log"
"net/http"
"./common"
"./routers"
)
But when I run go install myapp I get these errors:
can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package
Also, when I use common and routers instead of ./common and ./routers in the import statement, I get:
myapp/main.go:7:3: cannot find package "common" in any of:
/usr/local/go/src/common (from $GOROOT)
/home/me/go/src/common (from $GOPATH)
myapp/main.go:8:2: cannot find package "routers" in any of:
/usr/local/go/src/routers (from $GOROOT)
/home/me/go/src/routers (from $GOPATH)
How can I fix this?
Well, I figured out the problem.
Basically Go starting path for import is $HOME/go/src
So I just needed to add myapp in front of the package names, that is, the import should be:
import (
"log"
"net/http"
"myapp/common"
"myapp/routers"
)
If you are using Go 1.5 above, you can try to use vendoring feature.
It allows you to put your local package under vendor folder and import it with shorter path.
In your case, you can put your common and routers folder inside vendor folder
so it would be like
myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go
and import it like this
import (
"common"
"routers"
"routers/middleware"
)
This will work because Go will try to lookup your package starting at your project’s vendor directory (if it has at least one .go file) instead of $GOPATH/src.
FYI: You can do more with vendor, because this feature allows you to put "all your dependency’s code" for a package inside your own project's directory so it will be able to always get the same dependencies versions for all builds. It's like npm or pip in python, but you need to manually copy your dependencies to you project, or if you want to make it easy, try to look govendor by Daniel Theophanes
For more learning about this feature, try to look up here
Understanding and Using Vendor Folder by Daniel Theophanes
Understanding Go Dependency Management by Lucas Fernandes da Costa
I hope you or someone else find it helpfully
You should have created your package with go mod init e.g. go mod init github.com/my-org/my-package
Now in my-package you have a sub module called utils for example.
main.go
utils
|- randstr.go
And your randstr.go looks like this:
package utils
func RandStr(n int) string {
// TODO: Generate random string....
return "I am a random string"
}
And then anywhere in your project you would use exported functions from the utils package like this, for example in main.go:
package main
import (
"fmt"
// "github.com/my-org/my-package" is the module name at the
// top of your `go.mod`
"github.com/my-org/my-package/utils"
)
func main() {
fmt.Printf("Random string: %s\n", utils.RandStr(20))
}
Import paths are relative to your $GOPATH and $GOROOT environment variables. For example, with the following $GOPATH:
GOPATH=/home/me/go
Packages located in /home/me/go/src/lib/common and /home/me/go/src/lib/routers are imported respectively as:
import (
"lib/common"
"lib/routers"
)
an example:
in ./greetings, do go mod init example.com/greetings
from another module, do go mod edit -replace=example.com/greetings=../greetings
go get example.com/greetings
from the go tutorial
Local package is a annoying problem in go.
For some projects in our company we decide not use sub packages at all.
$ glide install
$ go get
$ go install
All work.
For some projects we use sub packages, and import local packages with full path:
import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage
But if we fork this project, then the subpackages still refer the original one.
Follow instructions here https://go.dev/doc/tutorial/call-module-code
Mainly you need the replace call in your go.mod file.
module example.com/hello
go 1.16
replace example.com/greetings => ../greetings
As in the question, the folder structure is:
/home/me/go/src/myapp
└─ common
└─ routers
So go to myapp dir
cd /home/me/go/src/myapp
Do
go mod init myapp
This will create a go.mod file which lets Go know the name of the module myapp so that when it’s looking at import paths in any package, it knows not to look elsewhere for myapp
Then you can do the following in the code:
import (
"log"
"net/http"
"myapp/common"
"myapp/routers"
)
Now package common and routers gets imported.
Another approach, available since go1.18, is to use a go.work file.
First, the local common package has to be a module, so provide a go.mod file inside the common folder:
module common
go 1.18
You can now create a go.work file in the root of your directory manually or call go work init, then go work use . and finally go work use ./common. It will look like this:
go 1.18
use (
.
./common
)
Finally you can import the package in your code by name
package main
import "common"
Just remember to not commit your go.work files :)
The key is how you name your module in the following command
go mod init <TheNameGiven>
Then refer the modules in the inner folder with,
TheNameGiven/folder
I have found the best solution here... Read More
Try to change the package name with the go mod init command.
So, I have go 1.17, and I have the same import problem. My project directory is $GOPATH/src/myswagger/app-swagger-test. I ran this command into app-swagger-test dir:
go mod init app-swagger-test
go mod tidy
In my new go.mod file the package name is app-swagger-test. For example, this import was wrong:
import (
...
"myswagger/app-swagger-test/internal/generated/restapi"
"myswagger/app-swagger-test/internal/generated/restapi/operations"
)
So I removed go.mod and go.sum. And I ran next commands into app-swagger-test dir:
go mod init myswagger/app-swagger-test
go mod tidy
After that all imports in the project were imported successfully. In the new go.mod file the first line is:
module myswagger/app-swagger-test
Maybe this information is common, but I did not find it. Thanks!

Does it make sense to have two packages in the same directory?

I have a project that provides a library (exports some funcs) and also must provide a command-line interface (there must be an executable file).
Example of directory structure:
whatever.io/
myproject/
main.go
myproject.go
The go compiler needs the package main and func main to start execution. My library needs the package myproject where I put stuff on it. This is what the go tool says when I am building another project that tries to import myproject:
main.go:5:2: found packages myproject (myproject.go) and main (main.go) in $GOPATH/src/whatever.io/myproject
So I believe there is no way to do it.
Should I move the library or the CLI to another package?
Just move your packages inside a new folder within the same directory of main.go.
Remember to import the new package from the reference of the $GOPATH.
Example:
user#user:~/p/go/test/so-multipack$ ls -R
.:
a main.go
./a:
a.go
user#user:~/p/go/test/so-multipack$ cat main.go
package main
import (
"../so-multipack/a"
)
func main(){
a.Hello()
}
user#user:~/p/go/test/so-multipack$ cat a/a.go
package a
import (
"fmt"
)
func Hello(){
fmt.Println("hello from a")
}
user#user:~/p/go/test/so-multipack$ go run main.go
hello from a
user#user:~/p/go/test/so-multipack$ go build
user#user:~/p/go/test/so-multipack$ ls
a main.go so-multipack
user#user:~/p/go/test/so-multipack$
Useful link:
go build vs go build file.go
You cannot have two packages per directory, hence the error. So the solution as #Larry Battle said to move your myproject.go to a new directory.
From How to write go code
Go code must be kept inside a workspace. A workspace is a directory
hierarchy with three directories at its root:
src contains Go source files organized into packages (one package per directory),
pkg contains package objects, and
bin contains executable commands.
In most cases, no. However, there is an exception for unit tests.
Working Example:
Here are 2 different packages (mypackage and mypackage_test) in 1 directory (mypackage). The compiler will not complain about this.
mypackage folder:
mypackage/
foo.go
foo_test.go
mypackage/foo.go:
package mypackage
func Add(a int, b int) int {
return a + b
}
mypackage/foo_test.go:
package mypackage_test
// Unit tests...
Rules:
The 2 packages must have the following names:
NameOfDirectory.
NameOfDirectory + _test.
The names of the files in the _test package must end with _test.go
If you're receiving a confusing compiler error along the lines of found packages "foo" and "bar", you've probably broken one or more of these rules.
You can't have two golang files in one directory with two packages. So you need to move main.go out of myproject.
the directory structure before move
whatever.io/
go.mod
myproject/
main.go
myproject.go
After move
whatever.io/
go.mod
main.go
myproject/
myproject.go
And you need to change your main.go's import path. If the module name is aaa
Before
import "aaa"
Need change to this
import "aaa/myproject"

Resources