What does "inconsistent vendoring" mean in Go? - go

I'm getting this inconsistent vendoring error and I'm a total Go newbie. Can anyone explain to me how go.mod interacts with vendor/modules.txt? I found this question helpful, and now I'm wondering if I should even have a vendor directory. Would that be created by running go mod vendor? I inherited this project and it already has the vendor directory in git.
Here's the relevant part of my go.mod file -
module mymodule
go 1.17
require (
gopkg.in/redis.v5 v5.2.9
)
And then the related error message:
go: inconsistent vendoring
gopkg.in/redis.v5#v5.2.9: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
In vendor/modules.txt I have:
#gopkg.in/redis.v5 v5.2.9
gopkg.in/redis.v5
gopkg.in/redis.v5/internal
gopkg.in/redis.v5/internal/consistenthash
gopkg.in/redis.v5/internal/hashtag
gopkg.in/redis.v5/internal/pool
gopkg.in/redis.v5/internal/proto
For what it's worth I'm getting this error for every dependency in my go.mod file, I just included the one about redis.

go.mod and vendor/modules.txt (if present) must be in sync.
Whenever go.mod changes and there is a vendor directory, go mod vendor needs to be run to update the contents of the vendor directory.
All direct dependencies (not marked // implicit in go.mod) are "explicit" and marked accordingly in vendor/modules.txt starting from Go 1.14.
After running go mod vendor notice the new line ## explicit added after the package reference:
#gopkg.in/redis.v5 v5.2.9
## explicit
. . .

Just to add to #rustyx's answer, in order to fix this error, I deleted the vendor folder and then I ran again go mod vendor, and the error disappeared.

For me updating the version solved the issue. I was running go1.16 and I updated to go1.18.2. Before the update I tried go mod vendor and also updating the modules.txt didn't work then, I started ignoring the vendor directory by running
go build -mod=mod to build the application or go run -mod=mod main.go to run the main.go file

Related

Lock a specific version of a third party package in Go

Using modules, when I try to lock down a specific version of a package using the following command:
go mod edit -require "google.golang.org/grpc#v1.10.0"
It shows this under the require section in the go.mod file:
google.golang.org/protobuf v1.10.0
And then when I run:
go mod vendor
It is always pulling down the latest version which is currently v1.24.0. Under the require section in the go.mod file it shows:
google.golang.org/protobuf v1.24.0
Is there a way to lock a specific version no matter what?
I am currently using go version 1.14.3.
Thanks!
It seems that it is possible to tell go mod to only get the versions specified without bumping the version.
go -mod=readonly mod vendor
Can be found at: https://github.com/thepudds/go-module-knobs/blob/master/README.md
One way to fix this problem is do go build once you have made specific changes to go mod file. This will ensure you have go.sum file built into your codebase. This is nothing but checksum of your fetched package. By doing this, all the future pull will match the checksum of go.sum file

Does it make sense to add `go mod vendor` to a pre-commit hook?

Setup:
Our project is using golang 1.12.14
We are using go build -mod=vendor
Issue: When new dependencies are added to go.mod the vendor folder isn't updated and people are committing code and forgetting to run go mod vendor to update the folder. My understanding is that since -mod=vendor specifies to use packages from the vendor folder, the go.mod file will have discrepancies from what we are actually using when building the project.
Question: Should go mod vendor be added to a pre-commit hook?
As of Go 1.14, the go command automatically checks for consistency between the vendor directory and the go.mod file whenever the vendor directory is used. In addition, it uses the vendor directory by default if the module specifies go 1.14 or higher (see https://tip.golang.org/doc/go1.14#go-command).
As of today, the oldest supported version of the Go toolchain is Go 1.15.13.
So if you upgrade to a supported version of the Go toolchain, it should not be necessary to run go mod vendor as a pre-commit hook. The go command itself will flag inconsistencies whenever the vendor directory is used.

Go Modules management

While I try to build I am getting the following error:
go.mod requires settings-management-service but vendor/modules.txt does not include it.
run 'go mod tidy; go mod vendor' to sync
I tried running go mod tidy; go mod vendor, but didn't help.
First, try deleting your vendor folder, and then running go mod vendor again.
If settings-management-service is a local dependency, check if you are importing it correctly.
The first line of your go.mod file should show the name of your module. Considering the name is app, and settings-management-service is a internal module, it should be imported as :
import "app/settings-management-service"
Do check if all deps are being downloaded correctly, and run go mod download.

How to remove an installed package using go modules

I've installed a package using go modules (go get in Go 1.13) and now I want to remove it. In the documentation there is nothing about this and in go get docu neither.
Removing the package from go.mod manually doesn't solve the issue so it remains in go.sum.
How should I remove a package in a clean way?
Found it https://go.dev/blog/using-go-modules#removing-unused-dependencies
go mod tidy
So basically, once the package is not being imported in any package you can perform a go mod tidy and it will safely remove the unused dependencies.
And if you are vendoring the dependencies, then run the command below to make the module changes be applied in the vendor folder:
go mod vendor
#jesugmz answer doesn't say, what if you wanna remove a currently using package in go modules.
So, if you're using go modules (you have a go.mod file in your project) and you want to remove a currently using package, check $GOPATH/pkg/mod/ directory and simply remove the package named package#version.
For example, if you have github.com/some/project package installed, you should run the following command:
rm -rf $(go env GOPATH)/pkg/mod/github.com/some/project#v1.0.0
You can find the using package version in go.mod file.

go mod vendor without update to latest

I’m trying to figure out if it’s possible to run go mod vendor without the go tool updating my go.mod file.
I specifically go get package/subpackage#commit and commit my go.mod with the correct version.
Then I run go mod vendor and it automatically bumps the version of the package that I just specifically set.
I’ve looked at this page to no avail: https://github.com/golang/go/wiki/Modules#how-do-i-use-vendoring-with-modules-is-vendoring-going-away
I need to use vendor because I run a script that edits some of the vendored deps., I’m looking at the following build flow:
GO111MODULE=on go get package/subpackge#commit
GO111MODULE=on go mod vendor
./Script/patch_vendors.sh --write
GO111MODULE=off go build
My other option is modifying the copied source wherever go mod vendor donwloads it to, but
not sure how to approach that.
Thanks in advance
Per https://tip.golang.org/cmd/go/#hdr-Maintaining_module_requirements:
The go command itself automatically updates the go.mod file to maintain a standard formatting and the accuracy of require statements.
Any go command that finds an unfamiliar import will look up the module containing that import and add the latest version of that module to go.mod automatically. […]
Any go command can determine that a module requirement is missing and must be added […].
The go mod vendor command copies in all of the transitive imports of your packages and their tests, so it will automatically update the go.mod file to ensure that all of the imported packages are present.
So the problem here is likely that the commit you've selected for package/subpackage fails to provide some package that appears in the transitive imports of your program. If that is correct, you should find that go list all, go test all, and go mod tidy all make that same edit to your module's requirements.

Resources