Публикация пакетов

5 minute read

Стандартный go get прекрасно работает с популярными системами контроля версий. Но иногда хочется, чтоб пакеты были доступны для установки по кастомному урл. Например, если эти пакеты публикует какая-нибудь компания.

Простой пример

Есть некоторый пакет hello, который хоститься на гитхабе. Этот пакет можно установить так:

$ go get github.com/4gophers/hello

Теперь сделаем этот пакет доступным для установки как 4gophers.com/hello

Если команде go get указать путь не к одному из известных кодахостингов и без классификатора контроля версий, тогда программа попытается найти <meta> тег в ответе от сервера.

<meta name="go-import" content="import-prefix vcs repo-root">
  • import-prefix - это путь, который будет соответствовать корню хранилища. Именно это нужно будет указывать в импорте и при использовании go get
  • vcs - это указание, какая система контроля версий используется.
  • repo-root - это реальный корень нашего репозитория.

В нашем случае этот метатег будет выглядеть вот так:

<meta name="go-import" content="4gophers.com/hello git https://github.com/4gophers/hello">

Если нужно из репозитория тянуть больше одного пакета, то в import-prefix можно указать только 4gophers.com

<meta name="go-import" content="4gophers.com git https://github.com/4gophers/hello">

Таким образом, при обращении go get 4gophers.com/somepackage будет получен пакет github.com/4gophers/hello/somepackage

Немного динамики

Что происходит, когда мы запускаем go get 4gophers.com/hello? К нашему серверу приходят запросы вида:

https://4gophers.com/hello?go-get=1 (preferred)
http://4gophers.com/hello?go-get=1  (fallback)

Проверяется наличие метатега. Если есть тег, тогда приходит еще одни запрос к корню сайта http://4gophers.com?go-get=1 и тоже проверяется метатег.

Наличие в параметра go-get=1 дает нам возможность показывать метатег, только когда это действительно необходимо.