golang module name change causes local tests to fail - go

I have a fork of someone's code. Their module name is formatted like so:
module github.com/foo/bar/v3
I've made some changes locally and have updated the local go.mod to be v4 instead of v3 but this now causes the running of the tests locally to fail (see below, I've genericized the output).
Note: the go.sum at this point is empty.
$ go test -v
go: finding module for package github.com/foo/bar/v3
go: found github.com/foo/bar/v3 in github.com/foo/bar/v3 v3.0.0
# github.com/foo/bar/v4_test [github.com/foo/bar/v4.test]
./some_test.go:232:19: x.Y undefined (type *package.Example has no field or method Y)
FAIL github.com/foo/bar/v4 [build failed]
I'm not sure why it's trying to locate the actual v3 version of the package, and thus updating the go.sum to include it?
I can see from the test file that this package uses a different package name (e.g. package foo_test) so it doesn't rely on the exported data structures to exist when writing their test code. So maybe that's why this happens? it sees the reference to x.Y and then goes to lookup x in github.
But then I'm not sure why the test would run fine when I was using the v3 reference in the go.mod file?
Any ideas on what's happening here and what the right process should be for bumping a go module when you're working on a forked project?
Thanks.

If you change your module name in go.mod file, you have to replace all your import path with the updated module name.
As you replaced your module github.com/foo/bar/v3 with github.com/foo/bar/v4, you must find and replace all your reference of github.com/foo/bar/v3 with github.com/foo/bar/v4 throughout the whole project.
Then your $ go test -v should run properly.

Related

Can a go module have no go.mod file?

I ran into a repo that seems to be a Go module, but there's no go.mod file in it: github.com/confluentinc/confluent-kafka-go.
Is it ok for a go module to have no go.mod file with dependencies, or the authors of that library just didn't migrate to modules yet?
Dependency modules do not need to have explicit go.mod files.
The “main module” in module mode — that is, the module containing the working directory for the go command — must have a go.mod file, so that the go command can figure out the import paths for the packages within that module (based on its module path), and so that it has a place to record its dependencies once resolved.
In addition, any modules slotted in using replace directives must have go.mod files (in order to reduce confusion due to typos or other errors in replacement paths).
However, in general a module that lacks an explicit go.mod file is valid and fine to use. Its effective module path is the path by which it was required, which can be a bit confusing if the same repository ends up in use via multiple paths. Since a module with no go.mod file necessarily doesn't specify its own dependencies, consumers of that module will have to fill in those dependencies themselves (go mod tidy will mark them as // indirect in the consumer's go.mod file).
SHORT SUMMARY OF THE DISCUSSION:
The answer is "No"!
This project contains a set of go packages, but it is not a Go module as it doesn't contain go.mod file (although, it used to be a multi-module repo (Go) previously).
go get can run in both ways: module-aware mode and legacy GOPATH mode (as of Go 1.16).
To read more about this, refer to docs by using the go command:
$ go help gopath-get
and
$ go help module-get
It'd tell about how go get works in both cases.
Also, I noticed that it can download any repository and would treat it as a Go package, even if it contains an arbitrary Python project.
I did a simple test to demonstrate the same:
$ go get github.com/mongoengine/mongoengine
And it surprisingly worked.
Modules are defined by their go.mod file. Without a go.mod file, it is not a module.
See this from the Go Modules Reference
A module is a collection of packages that are released, versioned, and distributed together. Modules may be downloaded directly from version control repositories or from module proxy servers.
A module is identified by a module path, which is declared in a go.mod file, together with information about the module's dependencies. The module root directory is the directory that contains the go.mod file.
And
A module is defined by a UTF-8 encoded text file named go.mod in its root directory.

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

Google Cloud Function using internal private function

Project looks something like this
project
- internal
- package
code.go
- cmd
- function
main.go
In cmd/function, the go.mod looks like this:
module github.com/private/repo/cmd/function
go 1.13
require (
github.com/private/repo/internal/package v0.0.0-00010101000000-000000000000
)
replace github.com/private/repo/internal/package => ../../internal/package
Which works fine locally, however, when deploying as a Cloud Function, it doesn't work, as Cloud Function only contains the "cmd/function" directory.
Instead, I try to copy the module into the project directory and the replace.
project
- cmd
- function
main.go
- internal
- package
code.go
replace github.com/private/repo/internal/package => ./internal/package
But this replace seems to be ignored as the Cloud Function deploy build still tries to download this package.
Next, I try using go mod vendor instead, and ignore the go.mod and go.sum files. This seems to do the trick, but not fully, since removing the go.mod, I can't use the internal package anymore.
use of internal package function/vendor/github.com/private/repo/internal/package not allowed
Not sure how I would go about and solve this and still being able to use the internal package name.
Edit:
Added a repository showing the error and a simple fix by not using the internal keyword in the library name. https://github.com/lobbin/gcloud-function-error
Thank you for reporting this issue.
I filed a Feature Request for this improvement [1].
I suggest you to star the FR to give it more visibility and every time there is an update you will be notified through your email.
Please note there is no ETA for this request at this moment.
[1]. https://issuetracker.google.com/184141587

VS Code throwing error 'No package for import' but code compiles and runs fine

As a work requirement learning gRPC through an online course.
I have a project defined in folder greet (outside of GOPATH) with three packages called:
greet_client
greet_server
greetpb
In the go.mod file at the root of my project, I've specified the following:
module example.com/myuser/myproject
go 1.14
The code in greet_server/server.go makes a reference to greetpb.
I'm referencing it like the following:
I'm able to run server.go successfully.
It returns the expected the result:
My question is on the red squiggly lines VSCode throws saying it could not import greetpb:
Here's how package greetpb is defined (it's an auto generated file):
How can I get rid of this warning message?
Is it something I've not setup properly?
Update:
When I try to ctrl+click to view the module greetpb on the file server.go, I note that it's pointing to the url pkg.go.dev.
How can I make the program to do a "local" lookup?
Why would you use example.com? You don't have your package defined there.
Initialize go modules first i.e.
go mod init github.com/$USER/$REPO
Go mod vendor
go mod tidy && go mod vendor
That's it.

go build keeps complaining that: go.mod has post-v0 module path

Following the release of Go 1.11, I have been trying to move my repositories to Go modules, by adding a go.mod file at their root.
One of my root libraries my.host/root is in its version 17.0.1, so I wrote in its go.mod file:
module my.host/root/v17
I tagged that version v17.0.1 as documented in the Go modules manual.
When I try to make a new Go project that uses my root library, like:
package main
import root "my.host/root/v17"
func main() {
root.DoSomething()
}
And try to compile it, I get the following error:
go: my.host/root#v0.0.0-20180828034419-6bc78016491a: go.mod has post-v0 module path "my.host/root/v17" at revision 6bc78016491a
I am at loss figuring out why this happens. I explicitly added v17.0.1 in the go.mod file, yet every attempt at go build replaces the entry with a v0.0.0-20180828034419-6bc78016491a version which then fails because at that commit, the go.mod file module entry of my root library indeed ends with a v17, as it should.
For the record, this commit is the same as the tagged v17.0.1 version.
What am I doing wrong here? How can I debug this situation?
I had make two mistakes:
My initial v17.0.0 tag would point to a commit where go.mod did not contain the v17 import path suffix. As a result, it seems Go tooling considers the whole v17 major version as a v0/v1 instead, even if later v17 tags point to a commit with a correct go.mod directive, hence the commit ID "translation".
In my dependent projects, in the go.mod file, I mistakenly specified
require my.host/root v17.0.1 instead of
require my.host/root/v17 v17.0.1.
After fixing both those issues, everything seems back to normal and it works perfectly. I wish the documentation had been clearer about this but I guess this is a good opportunity to make a contribution!
The error I got was: github.com/emicklei/go-restful#v0.0.0-20180531035034-3658237ded10: go.mod has post-v0 module path "github.com/emicklei/go-restful/v2" at revision 3658237ded10
Appending github.com/emicklei/go-restful with v2 like so: github.com/emicklei/go-restful/v2 in my go.mod file fixed it for me.

Resources