Using custom domain for your Go lang package

How to use custom domain in package import path of Go lang project. Adding meta tags read by go get command explained in details.

Go programming language provides an extensive list of packages in standard library. Need to work with strings? import "strings" will do the job. Calculating some high precision numbers? Then math/big should be imported. But what happens when some custom package needs to be imported?

With code hosted on GitHub it’s quite straightforward, however, if on-premises code repository is used in development process, some extra steps needed to use custom domain in import path.

Why use custom domain?

When using packages from GitHub, importing packages is super easy: for example, to introduce colors in CLI application you can use github.com/fatih/color – including it to your project looks like this:

import (
  "github.com/fatih/color"
)

Don't get confused by the fact import path corrensponds to actual URL of web-based code repository (in this case GitHub) – that is not necessarily default behavior and I will first demonstrate a particular use case.

To suggest fixes and improvements for awesome lightweight blogging platform WriteFreely which instance I run at fedi.dev, I have forked their repository to github.com/gytisrepecka/writefreely – that is typical to be able to suggest Pull Requests like this one. As it is hosted on GitHub, standard approach to import this package source repository would work.

But what happens if I decide to migrate to GitLab or any other alternative, like self-hosted Gitea? That would mean import path would change and I would never want that. For the very same reason people and companies buy a domain name – regardless of current or future provider address to reach you is always the same. Luckily, we can do that with Go packages as well!

Now, if by any chance you were curious to try out my fork of WriteFreely (I recommend that in my building WriteFreely on CentOS tutorial), easiest way to get sources is following:

go get -d -u -v code.gyt.is/writefreely

Notice code.gyt.is – that is an actual website with folder writefreely. Well, it's quite plain and not appealing, however, it has couple very important meta tags:

<meta name="go-import" content="code.gyt.is/writefreely git https://github.com/gytisrepecka/writefreely" />
<meta name="go-source" content="code.gyt.is/writefreely https://github.com/gytisrepecka/writefreely https://github.com/gytisrepecka/writefreely/tree/master{/dir} https://github.com/gytisrepecka/writefreely/blob/master{/dir}/{file}#L{line}" />

They are indeed the magic behind – go get will read those meta tags and will understand where exactly it can download actual sources from.

Notice the structure of URLs in go-source – it refers to master branch and provides path where individual files are.

Beauty of such solution is that even if I change where code is hosted, users will be able to continue using code.gyt.is/writefreely in their projects regardless. Above example works with repositories hosted at GitHub and yes, you got it correctly – GitHub adds those meta tags automatically if importing from github.com provided URL directly.

Some time ago I decided I need to run on-premises code repository and chose Gitea – very fast software written in Go. The first project hosted on it is publically available open source library to watermark images written in Go. Named it webimg. Interestingly enough it has a bit different URL structure from GitHub therefore meta tags to make go get work are a bit different:

<meta name="go-import" content="code.gyt.is/webimg git https://source.gyt.is/gytisrepecka/webimg.git" />
<meta name="go-source" content="code.gyt.is/webimg https://source.gyt.is/gytisrepecka/webimg https://source.gyt.is/gytisrepecka/webimg/src/branch/master{/dir} https://source.gyt.is/gytisrepecka/webimg/src/branch/master{/dir}/{file}#L{line}" />

Figured them from gopkg fork that creators of WriteFreely runs to generate Go import paths for their projects automatically. Yet again perfect example how open source software helps to learn!

So in the end it’s easy to import webimg into any Go lang project by using custom domain:

import (
	"code.gyt.is/webimg"
)

You can make much more beautiful website than code.gyt.is is – style it using CSS, make it with static site generator like Hugo or even have WordPress site with custom meta tags added.

And in case you need a domain, buy one from Name.com (United States), FlokiNET (Iceland) or Interneto Vizija (Lithuania).


“Inretio”, MB @inretio@fedi.lt