Remix.run Logo
▲ thih9 9 hours ago

> In my opinion, every commerical software development team using Go should be using custom domains for namespacing their internal libraries and packages.

I’d remove “go” from the above, i.e. I think same applies to other stacks.

Even using GitHub domain links in code comments gets problematic long term. Ie when a migration happens and those links start pointing nowhere.

▲zahlman 6 hours ago | parent | next [-]

I think TFA is specifically targeted at Go because of how their package system works.

▲mort96 9 hours ago | parent | prev | next [-]

I mean yeah, but other languages don't make it quite so easy to make this mistake. Once your Go project gets to a size where it makes sense for different files to live in different folders (which, given Go's folder-based module system, often happens at just a couple hundred lines of code), the most straightforward way which the tooling nudges you towards means putting GitHub URLs (or URLs to whatever git host website you happen to use) in your source code.

▲someonebaggy 5 hours ago | parent [-]

Or example.com/yourname if your module is never going to be imported from another project.

▲handoflixue 9 hours ago | parent | prev [-]

I'm confused by the article, and this comment, treating these URLs as difficult to replace.

Why can't you just search-and-replace? Presumably all of them refer to "GitHub.com" and not much else code will, so I'd think this was an exceptionally easy case.

Even easier for comments, since them being obsolete for a few hours during a migration doesn't exactly break anything.

▲mort96 9 hours ago | parent | next [-]

I've gone through such a migration. Huge Go code base distributed across a lot of git repositories had to be moved to a different git host.

It was horrible. A team of people spent weeks. Different projects depended on different versions of the same internal libraries, we had to create a branch for each depended-on commit and make a version of that commit with the new URLs. The expressed goal was to end up with a system that's "exactly the same" as the old, just on a new host. Changing which version of libraries projects depends on would introduce unnecessary risk.

And the result is a code base where bisects are broken and where it's impossible to build an old version of any of the code without a ton of work.

▲sjbzbeiks 33 minutes ago | parent | next [-]

I think is usually a symptom of how hard it is for the organization to do things, the technical side of this is not actually that hard.

I say this because I’ve gone through a few of these, some with monorepos (the easiest, search and replace and you’re done), some not (yes the hardest but you can just vendor).

At least in the situations I’ve faced this was genuinely not horrible beyond just the organization itself being complicated about the solution.

▲oefrha 3 hours ago | parent | prev | next [-]

> And the result is a code base where bisects are broken and where it's impossible to build an old version of any of the code without a ton of work.

That makes no sense? As long as you’re using go modules, you can just host an internal go proxy for internal modules similar to proxy.golang.org to archive the old versions, and they won’t depend on the old git host.

▲dlisboa 6 hours ago | parent | prev | next [-]

Isn’t this exactly why the Go team recommended vendoring deps for years and years before go modules came up? Even now it takes one simple command to vendor them.

▲dmoy 6 hours ago | parent | prev [-]

> Different projects depended on different versions of the same internal libraries, we had to...

This is one of the main motivations for using a monorepo with all third party dependencies imported all the way in, and only one version for everything.

Of course it causes a whole bunch of other problems and is kinda expensive to scale, so most places won't do it.

▲mbreese 8 hours ago | parent | prev | next [-]

What about anyone else using your code? You can find and replace your own code, but do you have access to all of the code relying on your go library? Is it all yours? Customers? Other developers?

Even in the case where it’s an internal only Lu array, it can be complicated to refactor a library name.

▲lelandbatey 9 hours ago | parent | prev | next [-]

Even easier than that, you can use the 'replace' statement in your go mod to change where the Go build system will try to pull the dependencies from; you can point to a folder on disk or to another forge, and if you want total control you can indirect everything to your own artifact cache via GOPROXY (which can be something as simple as a static folder of source code).

The "module name is network path" is a convenient convention but not at all some "limitation" of the tooling.

▲quectophoton 2 hours ago | parent | next [-]

> you can use the 'replace' statement in your go mod to change where the Go build system will try to pull the dependencies from

Heads up for anyone who doesn't know: this only works at the "top level". Any replace directives in your dependencies will be ignored[1].

So for example if you have a dependency tree like [main -> thirdpartyframework -> golang.org/x/net/http2], and thirdpartyframework uses a vulnerable version of `golang.org/x/net/http2`, you can't just fix it by patching the thirdpartyframework repository with a replace directive; no, because that would be too convenient. Instead, the replace directive needs to be at the main module, where it doesn't make sense and is inconvenient.

Even though I like Go, it really seems like they don't care about anything other than monorepos. As soon as you need to work with forks, mirrors, or even just private modules[2][3], the tooling actively works against you. Also using your custom module proxy is a pain.

[1] See: https://go.dev/ref/mod#go-mod-file-replace:~:text=replace%20...

[2]: If you've only used private modules hosted on GitHub you might not have noticed too much pain because the Go tooling has hardcoded behavior specifically for GitHub and a few mainstream forges. You don't find out about this until you try to self-host something like Forgejo on your own domain thinking it would Just Work(tm), but it doesn't, and now you're left wondering why tf it works with GitHub but not with your own forge instance.

[3]: I think there's no hardcoded code for SourceHut, so you might be able to experience the inconvenience by hosting private modules in there.

▲mort96 9 hours ago | parent | prev [-]

And now all your source files contain URLs to abandoned infrastructure. Is that what you'd want long term?

▲gravypod 9 hours ago | parent | prev [-]

It's harder to replace in history.