Can't load package in brand new Go project - go

I'm trying modules in Go. I'm outside the GOPATH and using version 1.12.6:
GOBIN="/home/x80486/Workshop/go/bin/"
GOPATH="/home/x80486/Workshop/go/"
GOROOT="/home/x80486/.asdf/installs/golang/1.12.6/go/"
I created a new project and initialized it as a module inside: /home/x80486/Workshop/Development/gauge-basics. I then created a file example_spec.go with this content:
package stepImpl
import (
"github.com/getgauge-contrib/gauge-go/gauge"
)
var _ = gauge.Step("Run me before any other", func() {})
...and I ran go test:
[x80486#uplink gauge-basics]$ go test
go: finding github.com/getgauge-contrib/gauge-go/gauge latest
go: finding github.com/getgauge/common latest
go: finding github.com/golang/protobuf/proto latest
go: finding github.com/dmotylev/goproperties latest
? github.com/x80486/gauge-basics [no test files]
Everything is somehow OK, but as soon as I move this file into a folder named stepImpl, nothing works:
[x80486#uplink gauge-basics]$ go build
can't load package: package github.com/x80486/gauge-basics: unknown import path "github.com/x80486/gauge-basics": cannot find module providing package github.com/x80486/gauge-basics
I can't understand why moving a file to a folder with the package name would break the project.
This is the generated go.mod file:
module github.com/x80486/gauge-basics
go 1.12
require (
github.com/dmotylev/goproperties v0.0.0-20140630191356-7cbffbaada47 // indirect
github.com/getgauge-contrib/gauge-go v0.1.3 // indirect
github.com/getgauge/common v0.0.0-20190514095629-619e107433ce // indirect
github.com/golang/protobuf v1.3.2 // indirect
)

There are no .go files under github.com/x80486/gauge-basics, because you moved them under a different directory. You can run go build under the directory containing the source files or add another .go in the gauge-basics directory importing them.

Related

Proper way to import a package

Being new to Go this is the way I'm currently importing a package that I created. As an example:
folder path: loader\types
filename: types.go
package types
func SomeVal() string {
return "ABC"
}
folder path: loader
filename: main.go
package main
import (
"loader/types
)
func main() {
fmt.PrintLn(SomeVal())
}
My question is I create another application name tester and want to reuse the types.go code, I would have to do the following
folder path: tester\types
filename: types.go
package types
func SomeVal() string {
return "ABC"
}
folder path: tester
filename: main.go
package main
import (
"tester/types"
)
func main() {
fmt.PrintLn(SomeVal())
}
Is there a way to avoid calling the root folder "tester" or "loader" in the import from the main.go files? The issue I'm facing is that I have another package
folder path: loader\view
filename: view.go
package view
import (
"loader/types"
)
func AnotherValue() string {
return SomeVal()
}
So if I decide to use both loader/types and loader/view in another project, I would have to change the root folder when importing.
Again I'm new to Go so I could be looking at it incorrectly.
Thanks
If you want to use your modules (loader) which contains types and view packages in other project (e.g. in other repositories), you would need to transform loader into a reusable module/library. Go makes use of Git for this.
This involves creating a go.mod file to indicate that this project is a valid Go module. As you said, https://go.dev/doc/tutorial/create-module is a good starting point.
Usually, you can put this module in your repository, or in github, and so the module name should be the Git repo path, e.g. gihub.com/adviner/loader, something that you would put on top of your go.mod file.
go.mod in loader project:
module github.com/adviner/loader
go 1.19
If this module is hosted in public repo like github, Go will be able to retrieve it later. If you host it in a private repository that requires authentication to download, read more about using the GOPRIVATE environment variable from https://go.dev/ref/mod#environment-variables. Another approach is to just store this module in your local directory and use replace when using this module from another project.
It is a best practice that a Go project always have a go.mod file. So when you create a new project, let's say projecta, you might have a go.mod like this:
module github.com/adviner/projecta
go 1.19
require (
github.com/adviner/loader v1.0.0
)
replace (
github.com/adviner/loader => ../path/to/loader
)
We can use replace to replace the module with a local path so Go does not try to look for the module in github.com. This is not meant to be a permanent solution though. Usually you can just put your library in github or other private repository and remove the replace statement so you can work on the same project without having to transfer the loader module from one device to another.
PS. v1.0.0 here is the version that is tagged in your loader module. It is usually a tag that is added in your Git commit. If you don't have any Git tag in the commit you can use the commit ID.
PS. When naming your module github.com/adviner/loader, importing packages inside loader should now be done like so (even in the loader project itself): import github.com/adviner/loader/view and no longer loader/view.
Reference to go.mod and Go module system can be found here: https://go.dev/ref/mod

go mod tidy duplicates path for importing local package, go.mod replace is "./b" but path to module is reading github.com/x/y/src/a/b/src/a/b/go.mod

I have local 2 packages that I need to import, that are at different levels within root a
Note: a the root folder name and the file name - a/a.go
src structure is:
--src
--a/
a.go
go.mod
--b/
b.go
go.mod
I need to import package b into package a
github.com/x/y/src/a/a.go
github.com/x/y/src/a/b/b.go
a is a package that uses other packages that i've written, like custom logging tools etc
a.go:
package A
import (
b "github.com/x/y/src/a/b"
When I run:
go mod tidy
I get error:
go: github.com/x/y/src/a/a#v0.0.0 requires
github.com/x/y/src/a/b#v0.0.0: reading github.com/x/y/src/a/b/src/a/b/go.mod
at revision src/a/b/v0.0.0: unknown revision src/a/b/v0.0.0
Why is src/a/b being duplicated in the path it's reading from?!?!?!
Here's a's go.mod file, it's at the root directory and I need to import packages in folders one level down, so b is ./b/b.go and a is ./a.go :
module A
go 1.13
replace (
github.com/x/y/src/a/b => ./b // look inside folder b for b.go from path where a is located
)
require (
github.com/x/y/src/a/b v0.0.0
)
b's go.mod:
module a/b
go 1.13
require golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
Can someone tell be why go mod tidy is duplicating the path to b:
github.com/x/y/src/a/b/src/a/b/go.mod
It should be:
github.com/x/y/src/a/b/go.mod

Can't import local project from other project: cannot find module providing package <package_name>

I have a project I am working on named project1.
Couple of months ago I worked on project2 which contains package named engine and I want to use it inside project1.
These projects are local so I read here how to import local projects and tried it but received an error:
Cannot resolve file `project2`
One interesting thing is that when I type the name of project2 in the import(..) section, Goland identify it as module but after I press on it I received the error that it can't be resolve.
With Goland I have an option to run sync packages of 'project1' but when I pressed on it I also received an error:
project1/pkg/utils imports
project2: cannot find module providing package project2
I also tried to create vendor folder in project1 and copy-paste the whole project2 beneath the vendor folder but it still didn't help.
Any idea why it doesn't being resolve ?
If you have both of your projects under your $GOPATH, you can check out this example for importing projects.
EDIT:
If you are using go modules and want to import local modules, then you can make use of the replace directive.
So, basically you have to add in your go.mod of your Project1 these lines:
require /$module-name-project2/$package-name v0.0.0
replace $module-name-project2/$package-name => ../$localpath-to-project2
More info here
A quick example (both my projects are outside of $GOPATH and using go modules):
Project1 is located under .../go-experiments/project1
main.go:
package main
import "go-experiments/project2/greeting"
func main() {
println("How to greet?")
greeting.English()
}
go.mod:
module go-experiments/project1
require go-experiments/project2/greeting v0.0.0
replace go-experiments/project2/greeting => ../project2
go 1.14
Project2 is located under .../go-experiments/project2
greeter.go:
package greeting
func English() {
println("hi, i am boo")
}
go.mod:
module go-experiments/project2
go 1.14

Golang Module Use

I am trying to link to some code online: https://github.com/TheCacophonyProject/audiobait
I am helping out with this project and have altered that repository to create a new package called audiofilelibrary.
I am then trying to use that code in a very simple program:
package main
import (
"fmt"
"github.com/TheCacophonyProject/audiobait/audiofilelibrary"
"github.com/TheCacophonyProject/audiobait/playlist"
)
func main() {
audio := audioFileLibrary.AudioFileLibrary{}
fmt.Println(audio.soundsDirectory)
sched := playlist.Schedule{}
fmt.Println(sched.Description)
}
You'll see I'm importing 2 packages from that repository, audiofilelibrary and playlist. playlist works, audiofilelibrary does not. They seem to be coded in the same way.
This is the error I get:
$ go build
go: finding github.com/TheCacophonyProject/audiobait v2.0.0
go: finding github.com/nathan-osman/go-sunrise latest
go: finding github.com/TheCacophonyProject/audiobait/audiofilelibrary latest
build audiobaitpackagetest: cannot load
github.com/TheCacophonyProject/audiobait/audiofilelibrary:
cannot find module providing package
github.com/TheCacophonyProject/audiobait/audiofilelibrary
And this is my go.mod file, which is in a directory called audiobaitpackagetest:
module audiobaitpackagetest
go 1.13
require github.com/TheCacophonyProject/audiobait v0.0.0-20191013210352-81b0afd9a085
I created the module with the command go mod init audiobaitpackagetest.
How can I see the audiofilelibrary package please? As in, how can I import it into other code?
The code for this question is all here, so it can be easily cloned and run: https://github.com/Davo36/audiobaitpackagetest
Any help much appreciated.
You are using version v2.0.0 of github.com/TheCacophonyProject/audiobait.
This version doesn't contain audiofilelibrary package. But the master branch contains it.
You can change your go.mod file like this to use the master branch.
module audiobaitpackagetest
go 1.13
require github.com/TheCacophonyProject/audiobait master
Then run this commands:
go mod tidy
go mod vendor # if you want to vendor it

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
)

Resources