AUR+GitHub

  Линукс

Как известно в AUR у многих пакетов есть клон с суффиксом -git (-hg и др.) в имени. То есть такой пакет собирается на основе самой свежей версии исходников в репозитории. В общем случае это потенциально нестабильная сборка, тем не менее во многих случаях очень удобно. У меня например установлено меньше десятка таких пакетов, в основном это что-то активно используемое, где я в курсе последних изменений и зачем они мне нужны. Но есть такая проблема, что клонирование всего репозитория может занимать очень много времени (напр. для QGIS до 20 минут). Учитывая, что такие пакеты обновляются часто, то возникает желание как-то ускорить процесс.

Далее речь пойдёт только о GitHub репозиториях, возьмем для примера OpenOrienteering Mapper. Первое, что приходит в голову – а зачем клонировать весь репозиторий, если можно просто скачать master.tar.gz архив по прямой ссылке? С этим нет проблемы, но как тогда определить pkgver? Напомню как она обычно вычисляется:

  • определяем последний релиз по тегу
> RELEASE=$(git describe --tags $(git rev-list --tags --max-count=1))
> echo $RELEASE
v0.6.7
  • sha-хеш последнего коммита
> HEAD=$(git rev-parse --short HEAD)
> echo $HEAD
d77941c9
  • и количество коммитов на master бранче
> COUNT=$(git rev-list --count HEAD)
> echo $COUNT
3204

Итого получаем:

> printf "%s.r%s.%s" "${RELEASE#?}" "${COUNT}" "${HEAD}"
0.6.7.r3204.d77941c9

Cпособ получить то же самое без клонирования оказывается есть — это воспользоваться GitHub API v3. Распарсить JSON ответ можно многими способами, например с помощью jq:

> RELEASE=$(curl -s "https://api.github.com/repos/OpenOrienteering/mapper/releases/latest" | \
  jq '.tag_name' | sed 's/"//g'
> HEAD=$(curl -s "https://api.github.com/repos/OpenOrienteering/mapper/git/refs/heads/master" | \
  jq '.object.sha' | sed 's/"//g' | cut -c1-8

Или используя python, чтобы не вводит новые зависимости:

> RELEASE=$(curl -s "https://api.github.com/repos/OpenOrienteering/mapper/releases/latest" | \
  python -c "import sys, json; print(json.load(sys.stdin)['tag_name'])")
> HEAD=$(curl -s "https://api.github.com/repos/OpenOrienteering/mapper/git/refs/heads/master" | \
  python -c "import sys, json; print(json.load(sys.stdin)['object']['sha'][:8])")

К сожалению нет "прямого" способа получить количество коммитов через API. Так что используем не столь очевидный. Тут предполагается, что мы знаем хеш первого коммита (8a8986ec) и он не изменится:

> git rev-list --format="%h %ci %s" --max-parents=0 HEAD
commit c0076c87a1d7dd1181be708cc61cae6c221c5c7b
c0076c87 2015-11-28 21:02:29 +0100 Squashed 'doc/manual/pages/' content from commit 66225bf
commit 8a8986ec690a48e8edc4d3794dbb9d93cc67437b
8a8986ec 2011-10-04 15:56:33 +0000 Initial import
> COUNT=$(curl -s "https://api.github.com/repos/OpenOrienteering/mapper/compare/8a8986ec...${HEAD}" | \
  python -c "import sys, json; print(json.load(sys.stdin)['total_commits'] + 1)")

В ответе на StackOverflow можно найти еще один способ получить количество коммитов на master бранче — просуммировать вклад всех контрибьюторов:

> COUNT=$(curl -s "https://api.github.com/repos/OpenOrienteering/mapper/contributors?per_page=50" | \
  python -c "import sys, json; from functools import reduce; print(reduce(lambda x, y: {'contributions': x['contributions'] + y['contributions']}, json.load(sys.stdin))['contributions'])")

Но это дает результат 2540 коммитов вместо 3204, немного поэкспериментировал с этим, но так и не понял, что же возвращается в поле contributions.

Ссылки

  View Comments    AUR GitHub ArchLinux

Категории

Все теги