[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Best approach to update Go packages with the version in the go import path




On 6/9/20 3:13 PM, Shengjing Zhu wrote:
On Tue, Jun 9, 2020 at 3:41 PM Arnaud Rebillout
<arnaud.rebillout@collabora.com> wrote:
   Hello go team,

I'm wondering about the best approach to take for modern Go packages
that include the version in the Go path.

As an example, gotest.tools, ie. the Debian package
"golang-github-gotestyourself-gotest.tools-dev" [1].

   * current version in Debian is 2.x, and it goes by the Go import path
"gotest.tools"

   * latest version upstream is 3.x, with the Go import path
"gotest.tools/v3"

I think the problem is more complicated.
1. we are still using GOPATH
2. gotest.tools/v3 is a go module thing.

Let's look some examples.

golang-dbus-dev's version is 5.0.3-1, it has migrated to go module.
And it's import path declared in go.mod is github.com/godbus/dbus/v5.
But the source files are installed at
/usr/share/gocode/src/github.com/godbus/dbus/(no /v5).
However some packages still using github.com/godbus/dbus import path. See
https://codesearch.debian.net/search?q=github.com%2Fgodbus%2Fdbus+filetype%3Ago&literal=1&perpkg=1

And it seems there's no regression.

I'm very surprised to see it works magically.

I think the magic only happens when:
1. the package to be built has a go.mod file.
2. there's a /usr/share/gocode/src/github.com/godbus/dbus/go.mod file.

I find this magic when I build containerd/1.4 in exp.
See the patch https://sources.debian.org/src/containerd/1.4.0~beta1~ds1-1/debian/patches/0002-Add-go.mod-file.patch/


Thanks for this example, it was a good starting point to understand what's going on.

So the magic comes from the so-called “minimal module support” in GOPATH mode. Basically and as I understand it, Go rewrites the import path on the fly, so we can have godbus installed in the directory $GOPATH/src/github.com/godbus/dbus, despite the fact that ALL the import directives in the code refer to github.com/godbus/dbus/v5. The directory v5 does not need to exist.

It was implemented in https://github.com/golang/go/commit/28ae82663a1c57c185312b60a2eae8cf06cc24b4

More fun now: in the case of gotest.tools, this magic mechanism does not work, and the build fails with multiple lines such as:

    package gotest.tools: code in directory /tmp/gotestdir/src/gotest.tools expects import "gotest.tools/v3"

After much painful investigation, I found out that gotest.tools uses "import aliases" everywhere. That is, lines such as:

    package assert // import "gotest.tools/v3/assert"

The directive "// import ..." is an import alias, and that's what prevents Go from dealing with the import path successfully.



      
I'd like to update the package in Debian to 3.x, here are my options:

   1) just bump the package to latest. Problem: it will break any
package that build-depend on it, due to the change in the Go import path.

   2) introduce a new package that I will name
"golang-github-gotestyourself-gotest.tools-v3-dev". Problem: this new
package will have to go through the NEW queue again.

Option 3 is like what golang-dbus-dev has done.
No rename binary package and source package. No rename of file path in
/usr/share/gocode.
If the transition to go module is only import path, no API break. The
things will just wok magically.


I'll give a try with ratt and I will go this way if it's possible. Thanks!



Reply to: