arp242 / uni

Query the Unicode database from the commandline, with good support for emojis
MIT License
790 stars 19 forks source link

Make v2 installable via "go install" #26

Closed c4rlo closed 3 years ago

c4rlo commented 3 years ago

Currently, go install arp242.net/uni@latest installs the latest 1.x version. Also, https://pkg.go.dev/arp242.net/uni claims version 1.1.1 is the latest.

With the way Go module versioning works, I believe the module name should be updated to arp242.net/uni/v2 now, and this should be reflected in the go.mod. Possibly https://arp242.net/uni/v2 also needs to be enabled, not sure.

See https://golang.org/doc/modules/major-version, https://golang.org/doc/modules/release-workflow#breaking.

arp242 commented 3 years ago

Hm, I can't really get it to work... I added the /v2, but:

$ GOPROXY="direct" go get -v arp242.net/uni
[..]
go get: added arp242.net/uni v1.1.1

Okay, gets 1.1.1, which is expected; let's try with /v2:

$ GOPROXY="direct" go get -v arp242.net/uni/v2
get "arp242.net/uni": found meta tag vcs.metaImport{Prefix:"arp242.net/uni", VCS:"git", RepoRoot:"https://github.com/arp242/uni.git"} at //arp242.net/uni?go-get=1
go get: module arp242.net/uni@upgrade found (v1.1.1), but does not contain package arp242.net/uni/v2

Hmkay? It doesn't load https://arp242.net/uni/v2.html

Adding a version is even weirder:

$ GOPROXY="direct" go get -v arp242.net/uni/v2@v2.0.0
get "arp242.net/uni": found meta tag vcs.metaImport{Prefix:"arp242.net/uni", VCS:"git", RepoRoot:"https://github.com/arp242/uni.git"} at //arp242.net/uni?go-get=1
go get arp242.net/uni/v2@v2.0.0: arp242.net/uni@v2.0.0: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2

I hate this whole v2 thing so much about modules. I've never been able to get it to work.

arp242 commented 3 years ago

Maybe it needs to add the /v2 to the meta tag as well in:

<meta name="go-import" content="arp242.net/uni git https://github.com/arp242/uni.git">

But can you still fetch v1.1.1 then?

I need to modify the Jekyll plugin I wrote to generate these pages to test that, which I don't really feel like doing right now 😅

c4rlo commented 3 years ago

Yeah wow, this is super confusing. I looked around for how other modules with a custom domain do this, and found https://pkg.go.dev/goa.design/goa/v3 as an example that manages to pull this off:

$ export GOPROXY=direct
$ go get -v goa.design/goa/v3/http
get "goa.design/goa/v3/http": found meta tag vcs.metaImport{Prefix:"goa.design/goa/v3", VCS:"git", RepoRoot:"https://gopkg.in/goadesign/goa.v3"} at //goa.design/goa/v3/http?go-get=1
get "goa.design/goa": found meta tag vcs.metaImport{Prefix:"goa.design/goa", VCS:"git", RepoRoot:"https://gopkg.in/goadesign/goa.v2"} at //goa.design/goa?go-get=1
get "goa.design/goa/v3/http": verifying non-authoritative meta tag
get "goa.design/goa/v3": found meta tag vcs.metaImport{Prefix:"goa.design/goa/v3", VCS:"git", RepoRoot:"https://gopkg.in/goadesign/goa.v3"} at //goa.design/goa/v3?go-get=1
go: downloading goa.design/goa/v3 v3.4.3
[...]
go get: added goa.design/goa/v3 v3.4.3

Confirming how it does it:

$ curl -sS https://goa.design/goa/v3/http | grep go-import
  <meta name="go-import" content="goa.design/goa/v3 git https://gopkg.in/goadesign/goa.v3">
$ curl -sS https://goa.design/goa/v3 | grep go-import
  <meta name="go-import" content="goa.design/goa/v3 git https://gopkg.in/goadesign/goa.v3">

So it seems that you might need arp242.net/uni/v2 to return:

<meta name="go-import" content="arp242.net/uni/v2 git https://github.com/arp242/uni.git">

But can you still fetch v1.1.1 then?

Presumably that should still work, as long as https://arp242.net/uni remains as it is currently.


Assuming I've got this right, I actually think the Go docs are plain wrong on this. https://golang.org/ref/mod#vcs-find says:

The <meta> tag must have the form:

<meta name="go-import" content="root-path vcs repo-url">

root-path is the repository root path, the portion of the module path that corresponds to the repository's root directory.

And according to https://golang.org/ref/mod#module-path, the /v2 suffix is not part of the "repository root path".

arp242 commented 3 years ago

Thanks for looking in to this; it looks you also need to modify the go-source meta tag:

$ curl -sL https://goa.design/goa/v3/http | grep go-
<meta name="go-import" content="goa.design/goa/v3 git https://gopkg.in/goadesign/goa.v3">
<meta name="go-source" content="goa.design/goa/v3 https://github.com/goadesign/goa https://github.com/goadesign/goa/tree/v3/{/dir} https://github.com/goadesign/goa/blob/v3{/dir}/{file}#L{line}">

I modified the HTML page:

$ curl -sL https://arp242.net/uni | grep go-
<meta name="go-import" content="arp242.net/uni/v2 git https://github.com/arp242/uni.git">
<meta name="go-source" content="arp242.net/uni/v2 https://github.com/arp242/uni https://github.com/arp242/uni/tree/master/{/dir}/ https://github.com/arp242/uni/tree/master/{/dir}">

But it still doesn't work:

$ GOPROXY=direct go get -v arp242.net/uni@master
go: arp242.net/uni@v1.1.1: unrecognized import path "arp242.net/uni": parse https://arp242.net/uni?go-get=1: no go-import meta tags (meta tag arp242.net/uni/v2 did not match import path arp242.net/uni)

$ GOPROXY=direct go get -v arp242.net/uni/v2@master
go: arp242.net/uni@v1.1.1: unrecognized import path "arp242.net/uni": parse https://arp242.net/uni?go-get=1: no go-import meta tags (meta tag arp242.net/uni/v2 did not match import path arp242.net/uni)

It still wants to fetch v1.1.1 🤔 I tried a bunch of different variations, but couldn't come up with anything that works.

I think the problem is that the entire idea behind "v2" is that it's a different path: that is, a v2 subdirectory or a v2 branch that's separate from v1. At least, that's what I remember from the design docs and rationale in the vgo documents from Russ Cox. That's what they do on that goa thing, where they have a v3 branch. That's also why the path to their GitHub repo has v3 in there.

It's an annoying limitation and I really don't want that. master should just be the latest version; not doing that means that the README will be outdated and it's a ton of annoyance having the actual "master branch" be v2, and I don't want to spend the effort of keeping master and v2 branch in sync (and duplicating all code in a v2 directory is even more of a non-starter). I already have my reservations about this entire scheme for libraries, but for things like CLI tools it's just annoying and non-useful.

I don't mind going slightly out of my way to have this work, but there's a limit to that. I think having go get work is too small of a benefit to inconvenience all development work.

The only issue is the arp242.net/uni/unidata package, which is intended as re-usable library, but can just live at arp242.net/unidata as a new package.

I'll leave things as they are for now in case I've missed something, but otherwise I'll just back out the entire /v2 changes and live with the fact that "go get" doesn't work 🤷

arp242 commented 3 years ago

Okay, I had another idea:

$ curl -sL https://arp242.net/uni | grep go-
<meta name="go-import" content="arp242.net/uni git https://github.com/arp242/uni.git">
<meta name="go-source" content="arp242.net/uni https://github.com/arp242/uni https://github.com/arp242/uni/tree/master/{/dir}/ https://github.com/arp242/uni/tree/master/{/dir}">

$ curl -sL https://arp242.net/uni/v2 | grep go-
<meta name="go-import" content="arp242.net/uni/v2 git https://github.com/arp242/uni.git">
<meta name="go-source" content="arp242.net/uni/v2 https://github.com/arp242/uni https://github.com/arp242/uni/tree/master/{/dir}/ https://github.com/arp242/uni/tree/master/{/dir}">

So arp242.net/uni is left as before, and arp242.net/uni/v2 has /v2 added.

$ GOPROXY=direct go get -v arp242.net/uni
get "arp242.net/uni": found meta tag vcs.metaImport{Prefix:"arp242.net/uni", VCS:"git", RepoRoot:"https://github.com/arp242/uni.git"} at //arp242.net/uni?go-get=1
get "golang.org/x/sys": found meta tag vcs.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at //golang.org/x/sys?go-get=1
go: downloading arp242.net/uni v1.1.1
go: downloading golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e

Okay, so that still fetches v1.1.1, hmm, but:

$ GOPROXY=direct go get -v arp242.net/uni/v2@master
get "arp242.net/uni/v2": found meta tag vcs.metaImport{Prefix:"arp242.net/uni/v2", VCS:"git", RepoRoot:"https://github.com/arp242/uni.git"} at //arp242.net/uni/v2?go-get=1
get "arp242.net/uni": found meta tag vcs.metaImport{Prefix:"arp242.net/uni", VCS:"git", RepoRoot:"https://github.com/arp242/uni.git"} at //arp242.net/uni?go-get=1
go: downloading arp242.net/uni/v2 v2.1.1-0.20210530155800-9a30c448bd46
get "zgo.at/zli": found meta tag vcs.metaImport{Prefix:"zgo.at/zli", VCS:"git", RepoRoot:"https://github.com/zgoat/zli.git"} at //zgo.at/zli?go-get=1
get "zgo.at/zstd": found meta tag vcs.metaImport{Prefix:"zgo.at/zstd", VCS:"git", RepoRoot:"https://github.com/zgoat/zstd.git"} at //zgo.at/zstd?go-get=1
get "golang.org/x/sys": found meta tag vcs.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at //golang.org/x/sys?go-get=1
get "golang.org/x/term": found meta tag vcs.metaImport{Prefix:"golang.org/x/term", VCS:"git", RepoRoot:"https://go.googlesource.com/term"} at //golang.org/x/term?go-get=1
go: downloading zgo.at/zli v0.0.0-20210330134141-b5f2a73532d6
go: downloading zgo.at/zstd v0.0.0-20210322015326-ca7824321150
go: downloading golang.org/x/term v0.0.0-20210317153231-de623e64d2a6
go: downloading golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005
arp242.net/uni/v2/unidata
arp242.net/uni/v2
go get: added arp242.net/uni/v2 v2.1.1-0.20210530155800-9a30c448bd46

Okay, so I created and pushed a v2.2.0 tag so the latest v2.* version has arp242.net/uni/v2 in the go.mod, and now:

$ go install arp242.net/uni/v2
go: downloading arp242.net/uni v1.1.1
go: downloading arp242.net/uni/v2 v2.2.0
go: downloading zgo.at/zli v0.0.0-20210330134141-b5f2a73532d6
go: downloading zgo.at/zstd v0.0.0-20210322015326-ca7824321150
go: downloading golang.org/x/term v0.0.0-20210317153231-de623e64d2a6
go: downloading golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005

And if I type uni I get v2; huzzah! It still has v1.1.1 in there though, but whatever.

Using go install arp242.net/uni still fetches v1.1.1; I think there's no real way around that, I can add a README note for that.

Fuck's sake all of this was almost more time-consuming and complicated than writing the v2 in the first place (and certainly a lot less fun)...

c4rlo commented 3 years ago

Okay, so I created and pushed a v2.2.0 tag so the latest v2.* version has arp242.net/uni/v2 in the go.mod, and now:

$ go install arp242.net/uni/v2
go: downloading arp242.net/uni v1.1.1
go: downloading arp242.net/uni/v2 v2.2.0
go: downloading zgo.at/zli v0.0.0-20210330134141-b5f2a73532d6
go: downloading zgo.at/zstd v0.0.0-20210322015326-ca7824321150
go: downloading golang.org/x/term v0.0.0-20210317153231-de623e64d2a6
go: downloading golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005

And if I type uni I get v2; huzzah! It still has v1.1.1 in there though, but whatever.

I can confirm: this works for me too. (Outside of a Go project, you need to do go install arp242.net/uni/v2@latest, but that's just how this works.)

Thanks a lot!

I hadn't actually realized that v2.1.0 didn't have the /v2 suffix in the go.mod, that's what misled me a bit. (I sort of wonder if that was the only problem, and whether you didn't need the /v2 in the meta tag after all, but whatever.)

Using go install arp242.net/uni still fetches v1.1.1; I think there's no real way around that, I can add a README note for that.

Yeah I think that's just how it's meant to work.

Fuck's sake all of this was almost more time-consuming and complicated than writing the v2 in the first place (and certainly a lot less fun)...

Totally agree, Go modules are amazingly subtle and complicated for a language priding itself on being simple.

arp242 commented 3 years ago

I hadn't actually realized that v2.1.0 didn't have the /v2 suffix in the go.mod, that's what misled me a bit. (I sort of wonder if that was the only problem, and whether you didn't need the /v2 in the meta tag after all, but whatever.)

Ah yeah, I added those in master only yesterday, but because I wasn't sure that was going to work I didn't tag anything yet. Adding @master should have worked ... I think.

Either way, it works now so I'm hesitant to muck with it further 😅 I'll probably do a follow-up blog on this at some point, so I'll figure out the nuances then.

Totally agree, Go modules are amazingly subtle and complicated for a language priding itself on being simple.

It's one of those things that sound great and simple in theory, but doesn't work all that well in reality. When I first read through all the proposals I thought it was a great idea. After having worked with it ... a bit less so.

Besides, "simple" is not necessarily the same as "easy"; I wrote about that before: Go is not an easy language

I did a "proper" v2.2.0 release, so closing as this is solved. Thanks for your help in figuring this out!