Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Troubles with Go modules and version mismatches #321

Open
theory opened this issue Nov 11, 2019 · 15 comments
Open

Troubles with Go modules and version mismatches #321

theory opened this issue Nov 11, 2019 · 15 comments

Comments

@theory
Copy link

theory commented Nov 11, 2019

I was just converting a project to a Go module, and was pleased to see #307 merged and v22.0.0 tagged. So I was trying to rely on the go-systemd module, but ran into an error:

github.com/coreos/go-systemd/journal: no matching versions for query "latest"

I can trigger this error with this simple program:

package main
import _ "github.com/coreos/go-systemd/journal"
func main() {}

I can fix it by changing the import to github.com/coreos/go-systemd/v22/journal; however, that doesn't help when I try to import, say, etcd, which gives me this error:

$  go mod tidy
go: finding golang.org/x/net latest
go: finding github.com/coreos/pkg latest
go: finding github.com/tmc/grpc-websocket-proxy latest
go: finding golang.org/x/time latest
go: finding github.com/xiang90/probing latest
go: finding github.com/golang/groupcache latest
go: finding github.com/coreos/go-systemd/journal latest
go: finding github.com/coreos/go-systemd latest
example.com/try imports
	go.etcd.io/etcd/embed imports
	github.com/coreos/pkg/capnslog imports
	github.com/coreos/go-systemd/journal: no matching versions for query "latest"

I guess this can be fixed by capnslog adding v22 to its import, but I don't think that package has been modularized, yet. Is there some other way I can get go mod and friends to find v22 as the latest?

@lucab
Copy link
Contributor

lucab commented Nov 11, 2019

Thanks for the report. I fear you are hitting intrinsic UX issues with the whole Go module machinery, and I don't think there is much I can do as a maintainer of this library.

For the standalone example, see #320 (comment) which explains the Go module switch.

For the etcd case, I think you can ask the etcd maintainers to bump the dependency on their side, or stick to use the same go-systemd version they pinned.

@jarsaccount
Copy link

jarsaccount commented Nov 12, 2019

I Add this in my go.mod

replace (
  github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 latest
)

then go mod tidy, and I made it.

It will become

require (
 github.com/coreos/go-systemd v0.0.0-00010101000000-000000000000 // indirect
)

@theory
Copy link
Author

theory commented Nov 12, 2019

For the standalone example, see #320 (comment) which explains the Go module switch.

Yes, I was aware of the switch, to Go Modules in v22.0.0, which is great. I don't know enough about modules yet, though, to properly understand the source of or reaseon this error, though.

For the etcd case, I think you can ask the etcd maintainers to bump the dependency on their side, or stick to use the same go-systemd version they pinned.

Or capnslog I guess. How do I pin the version? Or is it better to follow @jarsaccount's suggestion? I added

replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0

To my go.mod and now go mod tidy doesn't complain anymore.

@zhaojingtao

This comment has been minimized.

@lucab
Copy link
Contributor

lucab commented Nov 18, 2019

@theory to the best of my understanding, the "versionless replace" hack should work as long as the versioned and non-versioned releases of this library have no API-breaking changes.

@theory
Copy link
Author

theory commented Nov 18, 2019

Looks like capnslog does not pin a version of go-systemd, etcd does, so presumably if I copy that line it will continue to work. Would be nice to have a way to say "Pin whatever version this other module pins".

@lucab
Copy link
Contributor

lucab commented Dec 13, 2019

For casual readers landing here, Go modules require semver-imports as explained in the official docs: https://github.com/golang/go/wiki/Modules#semantic-import-versioning.

This means that the proper way to consume this library is via versioned imports as shown in the original bug-report here and in examples:

"github.com/coreos/go-systemd/v22/activation"

That also means that, in the future, updating to new API-breaking releases will require updating all import paths (e.g. from github.com/coreos/go-systemd/v22/foo to github.com/coreos/go-systemd/v23/foo, once v23 is released).

As an unfortunate side-effect of Go module design, mixing imports from modular and non-modular versions results in some pain (as shown above) and requires some hacks via replace. This is hopefully just a transient mess which will self-resolve as soon as all consumers migrate to Go modules.

@lucab lucab changed the title github.com/coreos/go-systemd/journal: no matching versions for query "latest" Troubles with Go modules and version mismatches Dec 13, 2019
@theory
Copy link
Author

theory commented Dec 15, 2019

Yes, but note that I demonstrated the issue with no dependencies, using nothing more than

package main
import _ "github.com/coreos/go-systemd/journal"
func main() {}

I think the solution is to either:

  1. Explicitly import the version you want: import github.com/coreos/go-systemd/v22/journal. This will get the proper line in go.mod:

     require github.com/coreos/go-systemd/v22 v22.0.0
    
  2. Or use replace even if you have no other dependencies, so you replace all instances of the non-version-qualified require statement with the versioned one:

     replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0
    

    Unfortunately that means the require line won't have the v22 requirement, oddly:

     require github.com/coreos/go-systemd v0.0.0-00010101000000-000000000000
    

Not sure why that is.

@lucab
Copy link
Contributor

lucab commented Dec 16, 2019

@theory to the best of my understanding, the import "github.com/coreos/go-systemd/journal" above is buggy and not valid under Go module importing rules, as stated by the official documentation (emphasis mine):

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.1) and in the package import path (e.g., import "github.com/my/mod/v2/mypkg"). This includes the paths used in go get commands (e.g., go get github.com/my/mod/[email protected]. Note there is both a /v2 and a @v2.0.1 in that example. One way to think about it is that the module name now includes the /v2, so include /v2 whenever you are using the module name).)

Thus, the correct import line would be import "github.com/coreos/go-systemd/vXYZ/journal" (with proper XYZ version replacement).
I understand this is catching a lot of consumers off guard, as this new model is a departure from traditional importing rules.

@theory
Copy link
Author

theory commented Dec 16, 2019

Oooh, okay, thanks for the clarification. I guess that makes sense, as it’s more consistently explicit.

@lucab
Copy link
Contributor

lucab commented Mar 6, 2020

@dalu please note that your comment tone is overly aggressive, and your reply doesn't bring any new/relevant content to this ticket. EDIT: it looks like the user got banned from GitHub and their comment removed as a whole.
For anybody, in order to reduce the amount of noise here, I'll dismiss any further similar ones in the future (as this is not a discussion forum).

Anyway, just to cover the technical side once more:

  • This repository has been tagged on a regular basis since years, way before gomod came and forced semver tags. Tags up to v21 exist but gomod does not accept them. Thus the jump to v22.0.0.
  • The (multiple) breaking changes at v22.0.0 are documented in the changelog. See Add go module support #307 for more in-depth analysis.
  • Other repositories like github.com/mongodb/mongo-go-driver do not (yet) feel the pain of versioned import because they are at major version <= 1.
  • If you have doubts on how gomod-style imports work, please consult the Golang official documentation. A relevant excerpt has been already quoted here in Troubles with Go modules and version mismatches #321 (comment).

@Bhagyashreek8

This comment has been minimized.

@Abirdcfly
Copy link

So. How to use the latest untag version

I Add this in my go.mod

replace (
  github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 latest
)

then go mod tidy, and I made it.

It will become

require (
 github.com/coreos/go-systemd v0.0.0-00010101000000-000000000000 // indirect
)

Just for memo. If someone want use latest untag version. You can change to

replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.1.1-0.20201123092900-87511f396ae9

😂

JeremyRand added a commit to JeremyRand/ncdns that referenced this issue Jun 17, 2021
JeremyRand added a commit to JeremyRand/ncdns that referenced this issue Jun 17, 2021
JeremyRand added a commit to JeremyRand/ncdns that referenced this issue Jun 17, 2021
@guenhter
Copy link

guenhter commented Jun 22, 2021

For those who don't want to use the import directive: This is how it can be done:

go.mod file:

module foo

go 1.16

require (
	github.com/coreos/go-systemd/v22 v22.3.2 // indirect
)

some go file

import (
	"context"

	"github.com/coreos/go-systemd/v22/dbus"
)

...

@cverna cverna unpinned this issue Sep 15, 2023
@enocom
Copy link

enocom commented Sep 18, 2023

For whatever reason I tripped over this. Adding the version in the import path is the correct solution.

import _ "github.com/coreos/go-systemd/v22/journal"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants