`go get` : unexpected end of JSON input - go

What version of Go are you using (go version)?
$ go version
v1.12
The module yiigo has tag v3.0.0, but when I run go get github.com/iiinsomnia/yiigo, it gets the v2.1.0 and when I run go get github.com/iiinsomnia/yiigo#v3.0.0, it shows: go get github.com/iiinsomnia/yiigo#v3.0.0: unexpected end of JSON input

The primary issue seems to be that the v3.0.0 version of iiinsomnia/yiigo is missing the required /v3 at the end of the module line in its go.mod file:
https://github.com/iiinsomnia/yiigo/blob/v3.0.0/go.mod#L1
module github.com/iiinsomnia/yiigo <<<< wrong, missing required /v3 at end
go 1.12
require (
github.com/go-sql-driver/mysql v1.4.1-0.20190217072658-972a708cf979
...
That has since been corrected.
Because it is now a proper v3 module, the go get command should include a /v3 before the #:
module github.com/iiinsomnia/yiigo/v3#v3.2.2
From the Go modules wiki:
If the module is version v2 or higher, the major version of the module must be included as a /vN at the end of the module paths used in go.mod files (e.g., module github.com/my/mod/v2, require github.com/my/mod/v2 v2.0.0) and in the package import path (e.g., import "github.com/my/mod/v2/mypkg").
Also, it looks like a related issue was opened, with the theory being that the odd "unexpected end of JSON input" error might have come from some proxy:
https://github.com/golang/go/issues/30494

A way I've accomplished this in the past is by using git tags- for your case this should work fine.
Steps:
go get -u github.com/iiinsomnia/yiigo
cd ~/go/src/github.com/iiinsomnia/yiigo
git tag
locate tag release version you'd like to install within list
git checkout v3.0.0
go install
This will overwrite the package previously installed in your GOPATH with a new one for the specific tag version you have checked out.
Note: there is likely a better way to do this since the release of go modules.
This related post also provides alternative solutions on how to retrieve a specific version of a project's source code that may lend some help.

Related

Golang grpc go.mod issue

Hi guys does anyone would know what is the issue with this package:
go: loading module retractions for github.com/googleapis/gax-go/v2#v2.0.1: parsing go.mod: go.mod:8:2: require google.golang.org/genproto: version "b98a9ff5e252" invalid: must be of the form v1.2.3
after doing go get -u ./... or how to work around to fix this ?
The go.mod file of the module you are trying to import is broken. As the message you posted says, the version number should start with "v" (see here)
It seems that the module was broken by a bot https://github.com/googleapis/gax-go/commit/735836c34b8124d657958d469998865569e14742
The solution would be to revert the commit on the googleapis/gax-go repository.

How to prevent from `go build` to update the latest version of modules

I am using an open source project called "yaegi" in a large project.
I need to use older version of "yaegi": v.0.8.11, so I modified the go.mod file and replaced:
github.com/traefik/yaegi v0.9.2 // indirect with github.com/containous/yaegi v0.8.11
But when I build the project, it starts to update all the modules and replace it back to the most updated version:
root#ubuntu:~/myproj1# go build main.go
go: finding module for package github.com/traefik/yaegi/stdlib/unsafe
go: finding module for package github.com/traefik/yaegi/stdlib
go: finding module for package github.com/traefik/yaegi/interp
go: found github.com/traefik/yaegi/interp in github.com/traefik/yaegi v0.9.2
How can I prevent it and keep it using the old version v.0.8.11?
I read that according to 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 […].
Maybe there is a way to bypass it?
//indirect in go.mod means that at least one of your other modules you’re importing is dependent on that version of module, therefore go build shall automatically update that module, no matter how you changed that line in your go.mod. In your case if you don’t want to use yaegi module of v0.9.2 you have to first get rid of other dependencies dependent on that module from your project, and then fix your go.mod to make your project require yaegi v0.8.11. You can just delete them or make them require earlier version of yaegi by using their older version or editing their source code. Also, instead of editing go.mod directly, I’d run something like go get -v github.com/containous/yaegi#0.8.11 to checkout to a specific version of a module.

How can I force a specific package version using go.mod?

In my go.mod, I have:
...
require (
...
sigs.k8s.io/controller-runtime v0.2.0-alpha.0
)
and for some reason, when I save my files, my go.sum gets updated to include:
sigs.k8s.io/controller-runtime v0.2.0-alpha.0 h1:WM6lus3SNU4SsMlDYvjJ5fyLsG9nW3ffb/4/FpE2ZGrtnc=
sigs.k8s.io/controller-runtime v0.2.0-alpha.0/go.mod h1:HFAsYoOh6XMV+jKF1rsUjFwrknPbowfyHEHH5fRdJMf2jMX8=
sigs.k8s.io/controller-runtime v0.6.3 h1:SBbr+inLPEKhrf87vlJtrvDcwIpm+uhDvp63Bl72xYJtoOE=
sigs.k8s.io/controller-runtime v0.6.3/go.mod h1:WlZNXcMs40++oyaQt4B7Cs2lEE5JYRs8vJUznj4aRP4N4JpdAY=
The first 2, I understand why they are there. However, why does the latest version (0.6.3) of the package also appear all of a sudden?
When I run, go mod tidy, I get errors suggesting that 2 files in my codebase point to packages in the latest version (0.6.3) of this package. What can I do to strictly use the 0.2.2 version in go modules + in my codebase?
go mod tidy:
<filename here> imports
sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder: module sigs.k8s.io/controller-runtime#latest found (v0.6.3), but does not contain package sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder
v0.2.0-alpha.0 appears to already be the version that your module is using, so you don't need to do anything to “force” it. (The version of the go command that you are using may be erroneously saving the go.sum file before it errors out. If that reproduces with the latest version — currently go1.16rc1 — please file an issue, with steps to reproduce it, at https://golang.org/issue/new .)
The error message is telling you that the go command is looking for a missing package (sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder).
It is checking in the latest version of the modules that may contain that package, but the latest version (which is v0.6.3, whereas your module requires v0.2.0-alpha.0) still does not contain that package.
So the go command is telling you, essentially: “I am missing the package sigs.k8s.io/controller-runtime/pkg/webhook/admission/builder, and I cannot fix it by upgrading because v0.6.3 does not contain that package either”.

go.mod has post-v0 module path "git.example.com/owner/repo/v3" at revision ...?

My coworker pushed a tag v3.0.1 before updating go.mod to have /v3 suffix (https://github.com/golang/go/wiki/Modules#releasing-modules-v2-or-higher). I have updated module path (go.mod) and all import paths (*.go) to fix it, tagged as v3.0.2.
Now the problem is:
go get -v git.example.com/owner/repo#v3.0.2
go: finding git.example.com/owner/repo v3.0.2
go: git.example.com/owner/repo#v0.0.0-20190722053407-d85c4f69ad17: go.mod has post-v0 module path "git.example.com/owner/repo/v3" at revision
d85c4f69ad17
Found this: go build keeps complaining that: go.mod has post-v0 module path
So, I deleted both v3.0.0 and v3.0.1 tags, pointed it to the latest commit, re-pushed but the problem still stand.
I noticed that go.mod still refered to the old version as an indirect dependency:
require (
git.example.com/owner.repo v0.1.2 // indirect
Even if I changed it to /v3 v3.0.2 it will be restored to v0.1.12 automatically.
Why?
Did I miss something?
Tue Jul 23 05:54:56 +07 2019
rm go.*
go mod init git.example.com/dependent/project
go mod tidy
and go.mod is updated correctly now:
require (
- git.example.com/owner/repo v0.1.2
+ git.example.com/owner/repo/v3 v3.0.2
but go get -v git.example.com/owner/repo#v3.0.2 still returned the error:
go: finding git.example.com/owner/repo v3.0.2
go: git.example.com/owner/repo#v0.0.0-20190722053407-d85c4f69ad17: go.mod has post-v0 module path "git.example.com/owner/repo/v3" at revision
d85c4f69ad17
(d85c4f69ad17 is the latest commit in master)
I noticed that there are both v0.1.2 and v3.0.2 in go.sum:
git.example.com/owner/repo v0.1.2 h1:mCGJEmyrFDTCGkRfUIORpqdrNkSONQ6K+AcTNgxqveY=
git.example.com/owner/repo v0.1.2/go.mod h1:FfUKnyPrARCtAXQZ3BQVJI7h2eJ0UpQBMLg4bNs4Kdc=
git.example.com/owner/repo/v3 v3.0.2 h1:mJtDKLeiP8vMRSZo08i/k/KDbIoZTlKW2aWu7DUBvMM=
git.example.com/owner/repo/v3 v3.0.2/go.mod h1:64LE0ts0Lk9InIQyhPYGmnxs6LZIl6H4Iorl1EXfqxo=
Please pay attention to my go get command:
go get -v git.example.com/owner/repo#v3.0.2
It should be:
go get -v git.example.com/owner/repo/v3#v3.0.2
for example you can replace repository with this hack: https://github.com/golang/go/wiki/Modules
require {
...
}
replace git.example.com/owner.repo v0.1.2 => git.example.com/owner.repo v3.0.2
or you can use go get at the commit hash you want:
go get git.example.com/owner.repo#af044c0995fe
go get will correctly update the dependency files (go.mod, go.sum).
For more information: https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies
or for last example you should clean cache
remove go.mod and go.sum
go cache clean
go mod vendor
Expanding on the answer from #quanta...
You are doing:
go get -v git.example.com/owner/repo#v3.0.2
Because it is a v3 module, the go get command should include a /v3 before the #:
go get -v git.example.com/owner/repo/v3#v3.0.2
Once a v3.x.y package is a module with its own go.mod, then whenenver you are operating with modules enabled, you pretty much always include the /v3 whenever you reference the v3.x.y module, including in:
arguments to go get on the command line
import statements in .go code for the consumer
require statements in a consumer's go.mod
replace or exclude statements in a consumer's go.mod
the module line of the v3 module's go.mod file
internal import statements in .go code inside the v3 module importing other packages in the v3 module
etc.
One way to think about it is that the module's name is now effectively git.example.com/owner/repo/v3, where its name includes the trailing /v3.
If you are a consumer of a vN module and need to update your import paths in your .go files to include the vN, then
github.com/marwan-at-work/mod is a commonly used tool from the community that automates adding the /vN in all the required spots. Separately, it also automates placing the /vN in all the required spots if you are a module author for a v2+ module.
From the "Semantic Import Versioning" section of the Go modules wiki:
If the module is version v2 or higher, the major version of the module must be included as a /vN at the end of the module paths used in go.mod files (e.g., module github.com/my/mod/v2, require github.com/my/mod/v2 v2.0.0) and in the package import path (e.g., import "github.com/my/mod/v2/mypkg").
I may have had a similiar issue where I updated a module to use the /v2 import path but go getting the module always returned an error about invalid go.mod
The solution was to go get -u github.com/<me>/<pkg>/v2

How do I import a specific version of a package using go get?

coming from a Node environment I used to install a specific version of a vendor lib into the project folder (node_modules) by telling npm to install that version of that lib from the package.json or even directly from the console, like so:
$ npm install express#4.0.0
Then I used to import that version of that package in my project just with:
var express = require('express');
Now, I want to do the same thing with go. How can I do that?
Is it possible to install a specific version of a package? If so, using a centralized $GOPATH, how can I import one version instead of another?
I would do something like this:
$ go get github.com/wilk/uuid#0.0.1
$ go get github.com/wilk/uuid#0.0.2
But then, how can I make a difference during the import?
Go 1.11 will have a feature called go modules and you can simply add a dependency with a version. Follow these steps:
go mod init .
go mod edit -require github.com/wilk/uuid#0.0.1
go get -v -t ./...
go build
go install
Here's more info on that topic - https://github.com/golang/go/wiki/Modules
Really surprised nobody has mentioned gopkg.in.
gopkg.in is a service that provides a wrapper (redirect) that lets you express versions as repo urls, without actually creating repos. E.g. gopkg.in/yaml.v1 vs gopkg.in/yaml.v2, even though they both live at https://github.com/go-yaml/yaml
gopkg.in/yaml.v1 redirects to https://github.com/go-yaml/yaml/tree/v1
gopkg.in/yaml.v2 redirects to https://github.com/go-yaml/yaml/tree/v2
This isn't perfect if the author is not following proper versioning practices (by incrementing the version number when breaking backwards compatibility), but it does work with branches and tags.
A little cheat sheet on module queries.
To check all existing versions: e.g. go list -m -versions github.com/gorilla/mux
Specific version #v1.2.8
Specific commit #c783230
Specific branch #master
Version prefix #v2
Comparison #>=2.1.5
Latest #latest
E.g. go get github.com/gorilla/mux#v1.7.4
You can use git checkout to get an specific version and build your program using this version.
Example:
export GOPATH=~/
go get github.com/whateveruser/whateverrepo
cd ~/src/github.com/whateveruser/whateverrepo
git tag -l
# supose tag v0.0.2 is correct version
git checkout tags/v0.0.2
go run whateverpackage/main.go
Glide is a really elegant package management for Go especially if you come from Node's npm or Rust's cargo.
It behaves closely to Godep's new vendor feature in 1.6 but is way more easier. Your dependencies and versions are "locked" inside your projectdir/vendor directory without relying on GOPATH.
Install with brew (OS X)
$ brew install glide
Init the glide.yaml file (akin to package.json). This also grabs the existing imported packages in your project from GOPATH and copy then to the project's vendor/ directory.
$ glide init
Get new packages
$ glide get vcs/namespace/package
Update and lock the packages' versions. This creates glide.lock file in your project directory to lock the versions.
$ glide up
I tried glide and been happily using it for my current project.
Nowadays you can just use go get for it. You can fetch your dependency by the version tag, branch or even the commit.
go get github.com/someone/some_module#master
go get github.com/someone/some_module#v1.1.0
go get github.com/someone/some_module#commit_hash
more details here - How to point Go module dependency in go.mod to a latest commit in a repo?
Go get will also install the binary, like it says in the documentation -
Get downloads the packages named by the import paths, along with their dependencies. It then installs the named packages, like 'go install'.
(from https://golang.org/cmd/go/)
Update 18-11-23: From Go 1.11 mod is official experiment. Please see #krish answer.
Update 19-01-01: From Go 1.12 mod is still official experiment.
Starting in Go 1.13, module mode will be the default for all development.
Update 19-10-17: From Go 1.13 mod is official package manager.
https://blog.golang.org/using-go-modules
Old answer:
You can set version by offical dep
dep ensure --add github.com/gorilla/websocket#1.2.0
From Go 1.5 there's the "vendor experiment" that helps you manage dependencies. As of Go 1.6 this is no longer an experiment. Theres also some other options on the Go wiki..
Edit: as mentioned in this answer gopkg.in is a good option for pinning github-depdencies pre-1.5.
dep is the official experiment for dependency management for Go language. It requires Go 1.8 or newer to compile.
To start managing dependencies using dep, run the following command from your project's root directory:
dep init
After execution two files will be generated: Gopkg.toml ("manifest"), Gopkg.lock and necessary packages will be downloaded into vendor directory.
Let's assume that you have the project which uses github.com/gorilla/websocket package. dep will generate following files:
Gopkg.toml
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
[[constraint]]
name = "github.com/gorilla/websocket"
version = "1.2.0"
Gopkg.lock
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/gorilla/websocket"
packages = ["."]
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
version = "v1.2.0"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "941e8dbe52e16e8a7dff4068b7ba53ae69a5748b29fbf2bcb5df3a063ac52261"
solver-name = "gps-cdcl"
solver-version = 1
There are commands which help you to update/delete/etc packages, please find more info on official github repo of dep (dependency management tool for Go).
go get is the Go package manager. It works in a completely decentralized way and how package discovery still possible without a central package hosting repository.
Besides locating and downloading packages, the other big role of a package manager is handling multiple versions of the same package. Go takes the most minimal and pragmatic approach of any package manager. There is no such thing as multiple versions of a Go package.
go get always pulls from the HEAD of the default branch in the repository. Always. This has two important implications:
As a package author, you must adhere to the stable HEAD philosophy. Your default branch must always be the stable, released version of your package. You must do work in feature branches and only merge when ready to release.
New major versions of your package must have their own repository. Put simply, each major version of your package (following semantic versioning) would have its own repository and thus its own import path.
e.g. github.com/jpoehls/gophermail-v1 and github.com/jpoehls/gophermail-v2.
As someone building an application in Go, the above philosophy really doesn't have a downside. Every import path is a stable API. There are no version numbers to worry about. Awesome!
For more details : http://zduck.com/2014/go-and-package-versioning/
The approach I've found workable is git's submodule system. Using that you can submodule in a given version of the code and upgrading/downgrading is explicit and recorded - never haphazard.
The folder structure I've taken with this is:
+ myproject
++ src
+++ myproject
+++ github.com
++++ submoduled_project of some kind.
That worked for me
GO111MODULE=on go get -u github.com/segmentio/aws-okta#v0.22.1
There's a go edit -replace command to append a specific commit (even from another forked repository) on top of the current version of a package.
What's cool about this option, is that you don't need to know the exact pseudo version beforehand, just the commit hash id.
For example, I'm using the stable version of package "github.com/onsi/ginkgo v1.8.0".
Now I want - without modifying this line of required package in go.mod - to append a patch from my fork, on top of the ginkgo version:
$ GO111MODULE="on" go mod edit -replace=github.com/onsi/ginkgo=github.com/manosnoam/ginkgo#d6423c2
After the first time you build or test your module, GO will try to pull the new version, and then generate the "replace" line with the correct pseudo version. For example in my case, it will add on the bottom of go.mod:
replace github.com/onsi/ginkgo => github.com/manosnoam/ginkgo v0.0.0-20190902135631-1995eead7451
It might be useful.
Just type this into your command prompt while cd your/package/src/
go get github.com/go-gl/mathgl#v1.0.0
You get specific revision of package in question right into your source code, ready to use in import statement.
The current way to do this is to use go install
https://golang.org/doc/go-get-install-deprecation
Starting in Go 1.17, installing executables with go get is deprecated. go install may be used instead.
go install github.com/someone/some_module
Specific version
go install github.com/someone/some_module#v1.1.0
Specific commit
go install github.com/someone/some_module#commit_hash

Resources