Package: dh-go
Version: 1.71
Severity: important
Tags: patch
X-Debbugs-Cc: [email protected]

When a package is installed at two import paths and ships one of them as a
symlink, go.work ends up with two replace directives pointing at one
directory, and go refuses the workspace:

  go: ./src/go.podman.io/storage@ used for two different module paths
      (github.com/containers/storage and go.podman.io/storage)

The two lines, as dh-go writes them:

  replace go.podman.io/storage => ./src/go.podman.io/storage
  replace github.com/containers/storage => ./src/go.podman.io/storage

golang-github-containers-storage-dev 1.64.0-1 is the case at hand. It ships
/usr/share/gocode/src/go.podman.io/storage and, next to it,
/usr/share/gocode/src/github.com/containers/storage as a symlink to
../../go.podman.io/storage.

In golang.pm, the dummy dependency loop takes the symlink branch, reads the
module name out of the target's go.mod and writes the replace straight to the
target directory. The code a few lines above, for DH_GOLANG_MODULE_MAPPINGS,
already avoids this error by replacing through a symlink under src/MAPPINGS,
and its comment quotes the same go message with the redigo example. The patch
makes the symlink branch do what that one does, and is also sent as
https://salsa.debian.org/go-team/dh-go/-/merge_requests/12

It is latent: the duplicate is in go.work whether or not it matters, and go
only complains once the build graph reaches both module paths.

Reproducer, 12 lines of Go and 5 files in debian/, with
golang-github-containers-storage-dev as its only real build dependency:

  go.mod:
    module example.com/dhgorepro
    go 1.25
    require (
        github.com/containers/storage v1.64.0
        go.podman.io/storage v1.64.0
    )

  repro.go imports pkg/stringid under both module paths, which pulls nothing
  in from outside the module:
    import (
        compat  "github.com/containers/storage/pkg/stringid"
        current "go.podman.io/storage/pkg/stringid"
    )

In a clean sid chroot: with dh-go 1.70 and with 1.71 the build fails with
exactly the error above and nothing else, and with the patch applied it is
Status successful and the .deb comes out. 1.71 does not change this, the
lexical loop variable from #1153300 is in a different branch of the code.

Found in the field by the syft packaging work: syft 1.54.1 fails to build
against stereoscope 0.4.1, and the single trigger, bisected over stereoscope's
go.mod, is containerd/v2 moving from v2.4.1 to v2.4.2. That makes the selected
version differ from the one syft lists, so Go expands containerd's go.mod,
which requires checkpointctl, which requires github.com/containers/storage.
With stereoscope 0.3.4 the duplicate replace is in go.work too, just never
reached. Same failure with 1.69, 1.70 and 1.71, so it is older than all three.

Reply via email to