Go module import from github - go

I am new to golang and trying to import and use modules from this Github repo. https://github.com/Darkbladecr/ccxt/tree/go/go
I am using go module to manage dependencies but importing is failed.
package main
import (
"fmt"
"github.com/Darkbladecr/ccxt/go/pkg/ccxt/models"
)
But I got this error.
go: finding github.com/Darkbladecr/ccxt latest
build command-line-arguments: cannot load github.com/Darkbladecr/ccxt/go/pkg/ccxt/models: cannot find module providing package github.com/Darkbladecr/ccxt/go/pkg/ccxt/models
Is it possible to import a specific directory for go like this repo?

You can either go get the branch containing that package explicitly, or add explicit version tags on that branch in the format that the go tool recognizes (with a leading v prefix on the tags, such as v1.18.445 or v0.1.0-go).

Related

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.

How do I stop the auto importing of imported item in go outside of my project?

I have my projects that have many packages which import each other and import outside packages. When I make a change to one of my low lever packages, and then push it to git it is fine and works in that section. When I go get it for use in another project that was working perfectly I now get this go get this error:
module declares its path as: github.com/xdg-go/scram
but was required as: github.com/xdg/scram
None of my code uses either of those directly. It looks like it automatically updated some lower external packages and broke things the used to then old import.
How do I either find out the package that is importing the wrong name or stop all auto-updates?
The go.mod file at github.com/xdg/scram declares itself as github.com/xdg-go/scram:
module github.com/xdg-go/scram
go 1.11
require (
github.com/xdg-go/stringprep v1.0.2
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
)
The go.mod file should be updated to reflect the correct import path.
Unfortunately if this module is for you an indirect dependency, the best fix possible is to update whatever project you import that is directly importing it.
When that is not an option, a solution to this error is to clone the problematic repository locally and use the replace directive in your go.mod file:
module mymodule
replace github.com/xdg/stringprep => ../strprep
go 1.16.2
require (
github.com/divjotarora/mgo v0.0.0-20190308170442-1d451d2a3149
)
where ../strprep is where the code of the required module exists in your local machine, relative to the go.mod file of your project.
The downside of this of course is that you have to replicate this palliative fix wherever you plan to go get your modules.
Note also:
divjotarora/mgo is just a random example of a project that imports one of those packages using their old import path.
I'm using xdg/stringprep as an example because I can't find modules that import xdg/scram instead, but apparently it suffers from the same issue
Beside, you can use:
go mod why <package> to find out why a certain package is listed as a dependency of your project
go mod graph to show the full dependency graph. The output is in <package> <requirement> format

Go 1.12 modules: local import in non-local import

I'm currently using Go 1.12 modules and really tired about importing.
I'm making the rest-api using gin(web microservices) and gorm(golang orm). Everything still ok while working in golang modules. But getting trouble with local packages importing
The directory tree:
The go.mod:
module github.com/Aragami1408/go-gorm
go 1.12
require (
github.com/gin-gonic/gin v1.4.0
github.com/jinzhu/gorm v1.9.9
github.com/lib/pq v1.1.1
github.com/satori/go.uuid v1.2.0
)
The db.go:
package db
//code below...
The tasks.go:
package task
import (
"../db"
)
But when I run and still get this error:
local import "../db" in non-local package
I've searched a lot on google and nothing helps
From "Do modules work with relative imports like import "./subdir"?"
In modules, there finally is a name for the subdirectory.
If the parent directory says "module m" then the subdirectory is imported as "m/subdir", no longer "./subdir".
In your case:
import "github.com/Aragami1408/go-gorm/db"
# or maybe
import "go-gorm/db"
This assumes, as commented below by Silvio Lucas, that you have set GO111MODULE=on.
If you are using go modules you can replace your package by a local one using:
go mod edit -replace github.com/username/project=/localpath
then just call
go get github.com/username/project
and everything should work fine.
When migrating to go as "package manager", you may create the file go mod using the command :
go mod init myhost/myrepo/mymodule
Then the file will be created go.mod will be created :
module myhost/myrepo/mymodule
go 1.15
Now you can leverage this file to list your dependencies to other modules :
# i.e: your module mymodule depennds on github.com/gorilla/mux
got get github.com/gorilla/mux
You run it ? then check again the content of go.mod
module myhost/myrepo/mymodule
go 1.15
require (
github.com/gorilla/mux v1.7.4
)
You are happy because you leverage the package manager features and you are managing dependencies like a Boss.
However,....
However, you forget that you need to maintain all go files which imports directories with relative paths.
example :
if you have main.go
package main
import (
"fmt"
"./router" // !! RELATIVE PATH
)
You must migrate also by replacing the relative path by [module-name]/relative-path. in this case, it must become :
package main
import (
"fmt"
"myhost/myrepo/mymodule/router" // !! 💼 No more RELATIVE PATH
)

Accessing local packages within a go module (go 1.11)

I'm trying out Go's new modules system and am having trouble accessing local packages. The following project is in a folder on my desktop outside my gopath.
My project structure looks like:
/
- /platform
- platform.go
- main.go
- go.mod
// platform.go
package platform
import "fmt"
func Print() {
fmt.Println("Hi")
}
// main.go
package main
import "platform"
func main() {
platform.Print()
}
go build main.go tells me
cannot find module for path platform
Let me define this first modules are collections of packages. In Go 11, I use go modules like the following:
If both packages are in the same project, you could just do the following:
In go.mod:
module github.com/userName/moduleName
and inside your main.go
import "github.com/userName/moduleName/platform"
However, if they are separate modules, i.e different physical paths and you still want to import local packages without publishing this remotely to github for example, you could achieve this by using replace directive.
Given the module name github.com/otherModule and platform, as you've called it, is the only package inside there. In your main module's go.mod add the following lines:
module github.com/userName/mainModule
require "github.com/userName/otherModule" v0.0.0
replace "github.com/userName/otherModule" v0.0.0 => "local physical path to the otherModule"
Note: The path should point to the root directory of the module, and can be absolute or relative.
Inside main.go, to import a specific package like platform from otherModule:
import "github.com/userName/otherModule/platform"
Here's a gentle introduction to Golang Modules
I would strongly suggest you to use go toolchain which takes care of these issues out of the box. Visual Studio Code with vscode-go plugin is really useful.
Problem here is that Go requires relative paths with respect to your $GOPATH/src or module in import statement. Depending on where you are in your GOPATH, import path should include that as well. In this case, import statement must include go module path in go.mod
GOPATH
Assume your project resides here:
$GOPATH/src/github.com/myuser/myproject
Your import path should be:
import "github.com/myuser/myproject/platform"
VGO
Assume your go.mod file is:
module example.com/myuser/myproject
Your import path should be:
import "example.com/myuser/myproject/platform"
As someone new to go I didn't immediately understand the accepted answer – which is great, by the way. Here's a shorter answer for those very new people!
In go modules/packages are expressed as urls that you import in your code:
import your.org/internal/fancy_module
But wait! My code isn't at a url, what's happening??
This is the cleverness of go. You pretend there's a url even when there isn't one. Because:
This makes including easier as no matter where your file is located the import uses the same url (the code stays the same even if the files move!)
You can have packages that having naming conflicts. So google.com/go-api/user doesn't conflict with the definitions at your.org/internal/user
Someday you might publish a url on GitHub and all the code will just work
That's all great Evan, but how do I import a relative path?
Good question! You can import by changing your go.mod file to have this line:
module fancy_module
go 1.16
replace your.org/fancy_module => ../path/to/fancy_module
Given the Golang Project structure
/
- /platform
- platform.go
- main.go
- go.mod
To access the methods or structs...etc (which are public) from local packages of /platform is simple, shown below
// main.go
package main
import (
p "./platform"
)
func main() {
p.Print()
}
this should work

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!

Resources