💾 Archived View for idiomdrottning.org › go-install-forks captured on 2023-05-24 at 17:56:20. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-03-20)

➡️ Next capture (2023-12-28)

-=-=-=-=-=-=-

go install a fork

Golang has become pretty rough on installing forks. I ran into the same frustrations as these peeps:

proposal: cmd/go: allow “go install” a forked repository with cmd · Issue #50278 · golang/go · GitHub

It only affects forks of packages that uses go’s module system, so there’s no problem for mdna.

But if you have a fork of a go package that does use modules, you’ll run into this error when you go install it:

module declares its path as: path/to/their/repo
        but was required as: path/to/your/repo

This is a serious obstacle for open source collaboration so it’s pretty imperative that go lang fixes the issue. It’s a bug in go install as far as I’m concerned.

mdna — a branch of Molly Brown

My definition of a “bug”

Meanwhile, you have three bad compromised options:

Keep only their version canonical

Do not rename the package paths and jump through serious hoops in order to compile your local version from the source tree:

Forking Golang repositories on GitHub and managing the import path – code.openark.org

The downside is that no-one else can install your version, cutting down on software ecosystem diversity and decentralized collaboration and testing, and you can’t easily install your version on other machines either. This option is OK when upstream is awesome and immortal and rapidly responsive and they love all your patches and you have a good working relationship with them, but even so, you have to struggle to build & test your binaries.

Also, I don’t know how to run install from these local source trees; the pkgs got put into $GOPATH but the binary didn’t. When I ran go build it placed the binary in the source dir, not in $GOPATH. I could manually copy it into fakeroot’s /usr/bin in order to build a .deb, but that was because it was a single binary. I don’t know how to handle projects with a more complex artifact story.

Keep both versions canonical

Maintain two repos, once where you’ve renamed the paths and one where you haven’t. The rename should be in a single commit.

If you are sending patches rather than pull requests, you might make do with a single repo (just as long as your patches don’t contain the commit that has the renames).

Branches alone can’t hack it since go install, to the best of my current knowledge, isn’t branch-aware, it relies on fetching whatever branch the repo’s HEAD is set to, so you need two separate repos. In other words, I’m not aware of a go install equivalent for git clone -b.

Of course, those two separate repos can be implemented with branches, where the HEAD pointer is the only difference between your two repos, but you still need two different repo URLs to pull from, one for them to pull changes from and another for go install.

This is bad because it’s a ton of work for you, the contributor.

It’s (by far) what’s best for everyone else, for the rest of society, but talk about hoop city. If I end up doing a lot of golang stuff I might consider cooking up something to automate this approach while we wait for golang to sober the heck up.

Sayonara upstream

Obviously if you’re taking over maintainership completely, there’s no problem. Just rename the paths and your version is the official one from now on. The easiest solution, but it’s not collaborative in spirit. It’s going to be fiddly for upstream to use your changes. If you at least kept your path renames in one separate commit, upstream can do some Magit juggling to keep up but it’s gonna be a chore for them.

Hybrid approaches

A gentler Sayonara

One way is to create a temporary repo with your changes (but with paths not renamed). Send your patches or pull requests from there. Then fork your own temporary repo into a separate location, and change the names of the paths there, and from then on it’s the “Sayonara upstream” approach. You give them one chance and then you move on.

This combines most of the drawbacks of the Sayonara approach but gives upstream the benefit of one drive-by commit. It’s not super collaborative but it’s ever-so-slightly more sociable than the pure Sayonara approach while being minimally more difficult and space-consuming.

A future Sayonara

Another way is to start with the “keep only their version canonical” approach, and stick with it as long as they’re alive (and by "alive" I only mean "an active maintainer", no need to get morbid) and once they’ve moved on, you switch to the Sayonara approach.

This is not good because it’s an approach built only for optimists. You are presuming you’re gonna be alive when it’s time to make the switch when they’re gone. That’s not necessarily gonna work out. Unmaintained commits can end up in an unusable limbo.

Conclusion

The “keep both versions canonical” approach is the “best” in some sense of the word. When that’s too much of an effort, use one of the two hybrid approaches. All five of the approaches outlined here are severely compromised so I’m staring daggers at the go install design team.