Coding Bits
April 27th, 2024

Custom Import Paths In Go

Go

One of the craziest ideas I had recently was to move all my code from Github to a self-hosted SCM system. The impetus for this was to have import paths with a custom domain name for all my Go packages, rather than have all them start with github.com/lmika/(something). Fortunately, this proved to be unnecessary, as Go does allow one to customise the import path of packages hosted elsewhere.

This area of the docs has all the details, but here's the process in short.

Lets say you have a package hosted in Github at github.com/example/mypkg and you want to use the import path mypkg.example.com.

The first thing you'll need is some form of web host listening on that domain. This is because Go will make the HTTP request to that domain when it encounters the package in a project it's trying to build. The request is just a GET with the go-get query parameter, so a standard web-page will work here:

GET https://mypkg.example.com/?go-get=1

Go is looking for a HTML meta element with the name go-import. This encodes where the source of this package is located. In this example it will be something like:

<meta name="go-import" content="mypkg.example.com git https://github.com/example/mypkg">

Where:

  • `mypkg.example.com` indicates the prefix this directive applies to
  • `git` indicates how Go can fetch the source. This can be any of the supported SVC systems, or `mod` to use a module proxy server.
  • `https://github.com/example/mypkg` indicates where Go can find the code

You'll also need to return a meta field for any sub-package names as well. This is because Go will perform the HTTP fetch for each sub-package, along with the root.

For example, if a project were to add the sub-package mypkg.example.com/foobar, Go will make a request https://mypkg.example.com/foobar expecting the go-import meta element in the response. The meta tag content can be exactly the same as the root.

Once that's done, you're free to start using the custom import path. Don't forget to change the module path in "go.mod" as well.

Source: this Reddit thread.