Golang Module Use - go

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

Related

Compilation error only building a module, not main package

I'm making a Go program and have created a module to divide it. Here is my working tree (the minimal directory is in $GOPATH/src/):
minimal/
├── main.go
└── ui
├── go.mod
├── go.sum
└── ui.go
In the ui module I have the following:
package ui
import "github.com/satori/go.uuid"
func SomeFunction() {
id, err := uuid.NewV4()
if err == nil {
print(id.String())
} else {
print(err)
}
}
The main package uses this module as follows
package main
import "minimal/ui"
func main() {
ui.SomeFunction()
}
Here is the go.mod file:
module minimal/ui
go 1.14
require github.com/satori/go.uuid v1.2.0
When running go build in the main package folder, everything works and the binary is generated. However, when building only the ui module, it gives the following compilation error:
ui$ go build
# minimal/ui
./ui.go:6:10: assignment mismatch: 2 variables but uuid.NewV4 returns 1 values
You can check https://github.com/satori/go.uuid to see that the function returns two values. What has me puzzled is that building the main package works, but the module doesn't. Why is that?
github.com/satori/go.uuid documentation appears to support GOPATH builds. go module builds, however, produce inconsistent results.
Take the simple API usage from it's README.md:
package main
import "github.com/satori/go.uuid"
func main() {
u, err := uuid.NewV4()
_, _ = u, err
}
And try to compile it with go modules:
go mod init
go build
go: finding module for package github.com/satori/go.uuid
go: found github.com/satori/go.uuid in github.com/satori/go.uuid v1.2.0
./main.go:6:9: assignment mismatch: 2 variables but uuid.NewV4 returns 1 values
it pulled tagged v1.2.0 and it failed to compile.
So now pull the latest commit:
go get github.com/satori/go.uuid#master
go: github.com/satori/go.uuid master => v1.2.1-0.20181028125025-b2ce2384e17b
Now it compiles:
go build && echo $?
0
So what is happening here?
github.com/satori/go.uuid is tagged with a mature v1 release, so all dot releases should be feature enhancements with no breaking changes.
The latest tagged version v1.2.0 returns only one value from uuid.NewV4().
The latest commit (which go modules infers a pseudo dot release version of v1.2.1-0.20181028125025-b2ce2384e17b) has code that matches the README.md.
If this repo ever becomes tagged as v1.2.1 - this would be a breaking change, as it changes the signature of a function published in a previous v1 release. This would be a violation of semver rules.
Conclusion:
The documentation matches a GOPATH (i.e. non-go modules) build. GOPATH builds always pull the latest commit.
From a go modules perspective, while one may be able to coerce a working build, it does not look like it's supported. Yes, the git repo uses semver tags, but there is no go.mod.
I would not trust this package with a go modules build. Perhaps consider using github.com/google/uuid which does.
The uuid package has different versions. In the latest version, function NewV4() returns just one variable but in the previous versions, it returns two variables which one of them is an error.
You create a go.mod file in the subdirectory of your project, So when you compile your project in the main directory, go-compiler uses one version, and in your ui directory it uses another version to compile. You should just edit the version of uuid package in your go.mod file.

Go 'mod init' creating new folders? what is the significance of path?

Just 3 days experience in Go language. Hope an example will be more apt to understand my confusion.
root#freebsd1:/usr/home/arun/go-start/src/test2 # go mod init f1/f2/f3/f4/f5/hello
go: creating new go.mod: module f1/f2/f3/f4/f5/hello
root#freebsd1:/usr/home/arun/go-start/src/test2 #
Here in above example go mod init is creating all these folders(f1/f2/f3/f4/f5/hello)?. I searched a lot, couldn't find any such folders in system. Then what is the significance of this path.
Even though below command will not run if this path is not mentioned as it is
# go install f1/f2/f3/f4/f5/hello
--:EDIT:--
May be this will help someone later ( Just walk through the steps to understand this in a proper way, especially for newbies )
I am planning to create a program 'calculator' and will upload in GitHub later.
I will keep the functions in different packages like sum,multiply etc
first step #go mod init github.com/go-arun/calculator( Don't confuse here , this is just an assumption that, in future I may create a repository in github for this project )
created folder sum(one of the package folder , and created sum.go inside )
See those in by system:
1.
root#debian1:/home/arun/lab# go mod init github.com/go-arun/calculator
go: creating new go.mod: module github.com/go-arun/calculator
root#debian1:/home/arun/lab# cat go.mod
module github.com/go-arun/calculator
go 1.15
2.
root#debian1:/home/arun/lab# cat sum/sum.go
package sum
import "fmt"
func Sum(num1,num2 int)(){
fmt.Println(num1+num2)
}
3.
root#debian1:/home/arun/lab# cat main.go
package main
import(
"github.com/go-arun/calculator/sum"
)
func main(){
n1 := 10
n2 := 10
sum.Sum(n1,n2)
}
4.
root#debian1:/home/arun/lab# tree
.
|-- go.mod
|-- main.go
`-- sum
`-- sum.go
go mod init does not create those folders. You pass the "module path" to go mod init which is recorded in the go.mod file it creates.
The "module path" is the import path prefix corresponding to the module root. The module path and the relative path to the module root together form the complete import path which must be unique in an app.
So for example if your module contains a folder named foo (and a package foo in it), it is imported by a path being modulepath/foo. In your case it would be f1/f2/f3/f4/f5/hello/foo.
It is allowed for moduleA to contain a foo package, and also for moduleB to have a foo package. When used / imported, first would be imported like moduleA/foo the latter like moduleB/foo, so it's unambiguous which one you're importing. The module path is like a namespace.
It's recommended to use a module path that corresponds to a repository you plan or will publish your module to, so when you do, go get will be able to automatically fetch, build and install your module. For example you may choose a module path github.com/bob/hello, so when you publish your module, everyone can get it by simply using import "github.com/bob/hello" in their app.
Also note that you don't need to publish your code to a remote repo before you can build it. But it's still recommended to follow this pattern so you'll have less work to make it work in the future if you decide to publish it. Nothing to lose here.
More in the docs: Command go: Defining a module
Also: How to Write Go Code: Code organization

People can't use my v2+ semantic versioning release using gomodules

I am maintaining a company go library which uses Semantic Versioning for releases. I switched to go modules for dependency management within the library and created a new release after v2+. I used the first strategy documented here which involves modifying the go.mod file and import paths.
Now when people use the go get command (in a repo that is also using go modules) an error appears:
invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v3
Is anyone familiar with this issue?
To make things simpler I created a similar and simple example:
I have repo (github.com/Graphmasters/testing-gomod-versioning) with three files (not including .gitignore). These files are:
methods/method.go
package methods
func Method() {
println("Method")
}
main.go
package main
import (
"github.com/Graphmasters/testing-gomod-versioning/v3/methods"
)
func main() {
methods.Method()
}
go.mod
module github.com/Graphmasters/testing-gomod-versioning/v3
go 1.13
In the repo I created a release with the tag v3.0.0 based on the branch with this code.
The aforementioned error is encountered when the following command is run in a repo that is using go modules:
go get "github.com/Graphmasters/testing-gomod-versioning#v3.0.0"
The module name must be github.com/Graphmasters/testing-gomod-versioning/v3 or github.com/Graphmasters/testing-gomod-versioning.v3 and not github.com/Graphmasters/testing-gomod-versioning
Users should be able to do github.com/Graphmasters/testing-gomod-versioning/v3#v3.0.0 instead of github.com/Graphmasters/testing-gomod-versioning#v3.0.0
Example: You can check the mod file of the following v3 package - https://search.gocenter.io/gotest.tools~2Fv3/info?version=v3.0.0

Can't load package in brand new Go project

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.

How to share a local module in Go 1.11+ for Golang using monolithic repo architecture outside GOPATH [duplicate]

I've created a library as the module for personal use outside of "GOPATH" in "database" folder with this command "go mod init database," and I don't know:
How to use/import this module in another module?
OS: Windows 7, Go: v1.11
The easiest and working out-of-the-box solution is to put your database package / module into a VCS (e.g. github.com), so other packages (inside other modules) can simply refer to it by importing it like:
import "github.com/someone/database"
If you do so, you don't even have to fiddle with the go.mod files manually, everything will be taken care of by the go tool: it will automatically recognize and resolve this dependency, download and install the required package, and will also update go.mod automatically.
Staying entirely on local disk
If you don't want to use a VCS (e.g. you're just experimenting or you haven't decided what to use yet), then you can still do it. The how is detailed in the official Go Wiki: Can I work entirely outside of VCS on my local filesystem?
So you created a database folder outside of GOPATH, and you created a module in it. And you created another module, let's call it main, and you want to use this database package.
What you must do is:
go.mod of your main module must list the database package as a "requirement". Give a temporary VCS name to your database package:
require (
example.com/me/database v0.0.0
)
You must tell the go tool where this package is located, because the full package name we used is just a temporary / fantasy name. Use the replace directive to make this database package point to a folder on your local disk; you may use absolute and relative paths:
replace example.com/me/database => ../database
And that's all.
Working example
Let's see a working example. Let's create a pretty module. Create a pretty folder with 2 files in it:
pretty.go:
package pretty
import "fmt"
func Pretty(v ...interface{}) {
fmt.Println(v...)
}
go.mod (can be created by running go mod init pretty):
module pretty
Now let's create another, main module. Let's create a folder osinf (it may be whatever) next to the pretty folder. 2 files in it:
osinf.go (note we intend to use our pretty package / module, we import it by "example.com/me/pretty"):
package main
import "example.com/me/pretty"
func main() {
pretty.Pretty("hi")
pretty.Pretty([]int{1, 3, 5})
}
go.mod:
module main
require example.com/me/pretty v0.0.0
replace example.com/me/pretty => ../pretty
And that's all.
Running go run osinf.go in the osinf folder, the output is:
hi
[1 3 5]
Run:
go mod init yellow
Then create a file yellow.go:
package yellow
func Mix(s string) string {
return s + "Yellow"
}
Then create a file orange/orange.go:
package main
import "yellow"
func main() {
s := yellow.Mix("Red")
println(s)
}
Then build:
go build
https://golang.org/doc/code.html

Resources