Obsługa VCS w makepkg

21 luty 2014

Co prawda opisywane poniżej zmiany i nowe funkcje w makepkg nie są już w żaden sposób nowością, bo trafiły one wraz z nowym pacmanem do repozytorium około 9 miesięcy temu, jednak jakimś cudem nie wszyscy opiekunowie pakietów AUR z nich korzystają. Obsługa systemów kontroli wersji sprzed wydania 4.1.0 miała następujące wady:

  • wymagała użycia dziwnych, chociaż udokumentowanych zmiennych takich jak _gitname i $_gitroot
  • kod odpowiedzialny za pobieranie i aktualizowanie repozytoriów z kodem pojawiał się osobno w każdym PKGBUILD-zie, poza tym nie był zbyt urodziwy…
build() {
  cd $srcdir
  if [ -d $_gitname ]; then
    (cd $_gitname && git-pull origin)
  else
    git clone $_gitroot
  fi
  msg "GIT checkout done or server timeout"
  msg "Starting make..."
  [ -d $_gitname-build ] && rm -rf $_gitname-build
  cp -r $_gitname $_gitname-build
  cd $_gitname-build
  # …i dopiero tutaj właściwa treść funkcji
}
  • pkgver nie był aktualizowany na podstawie daty ostatniej zmiany w kodzie, tylko bieżącej w systemie. Sprytniejszy opiekunowie, którzy potrafili obejść ten problem za pomocą git describe (lub w jakkolwiek inny sposób oparty o VCS), zderzali się z kolejnym murem – makedepends były instalowane po aktualizacji pkgver.
  • zbudowanie wybranego commita, gałęzi czy tagu wymagała modyfikacji ww. kodu. To samo tyczy się kompilacji offline.
  • --holdver miało wpływ tylko na pkgver, ale nie na repozytorium
  • i pewnie jeszcze więcej, których nie jestem świadomy.

Logiczną propozycją było umiejscowienie odnośników do zdalnych repozytoriów w tablicy source, ale jak to zwykle bywa w Archu, głównym przedmiotem dyskusji stała się składnia, która musiała być jednolita z obecnym formatem. Ostatecznie ustalono następujący sposób zapisu:

source=([katalog::][vcs+]url[#sufiks])

url nie wymaga wyjaśnień. Problem w tym, że nie zawsze możliwe jest jednoznaczne stwierdzenie, jaki system kontroli wersji kryje się pod danym odnośnikiem. Przykładowo repozytoria git bez włączonego własnego protokołu zaczynają się od http://. Aby to obejść, można dodać opcjonalny przedrostek, np. git+http://. (Pomysł pochodzi od podobnego sposobu oznaczania repo Subversion.)

Na początku wpisu w tablicy znajduje się zagadkowe ::. Ta raczej rzadko używana funkcja służy do podpowiedzenia makepkg pod jaką nazwą ma zapisać dany plik. Zazwyczaj jest na tyle sprytne, że samo znajdzie sensowną nazwę, często jednak przydatne jest wymuszenie własnej. Chyba nie muszę nikogo przekonywać, że mplayer mówi znacznie więcej niż trunk.

Natomiast sufiks pozwala zdefiniować rewizję/commit, gałąź albo tag, jaki zostanie użyty przy budowie pakietu. (Niezależnie od tego co wpiszemy, pobrane zostanie całe repozytorium.) Przykładowo, w następujący sposób "pobieramy" źródła libvpx (niewiernych odsyłam do ABS) i używam wybranej wersji:

source=($pkgname::git+http://code.google.com/p/webm.libvpx#tag=v$pkgver)

Repozytorium http://code…/p/webm.libvpx zostaje sklonowane do katalogu libvpx (pkgname), przy czym makepkg użyje tagu v1.3.0 (pkgver). Wspierane VCS i odpowiednie przyrostki opisane są na stronach man PKGBUILD.

Pozostaje jeszcze kwestia automatycznego aktualizowania pkgver. Otóż domyślnie nie dzieje się to wcale – powyższy przykład dobrze pokazuje, czemu takie zachowanie jest oczekiwane. Jeżeli jednak istnieje potrzeba zmiany pkgver, można zdefiniować własną funkcję o tej nazwie, która zwraca potrzebny łańcuch znaków. Przykłady można mnożyć: zazwyczaj jest to git describe | sed 's/^v//;s/-/./g'. Jako że nie wszyscy programiści wpadli na genialny pomysł używania tagów (potrzebnych do użycia wcześniejszego polecenia), w mplayer2 (niegdyś w repo, teraz w AUR) używam następującej funkcji, która zwraca nic innego jak datę ostatnich zmian:

pkgver() {
  cd $pkgname
  git log -1 --format="%cd" --date=short | sed 's|-||g'
}

Mercurial? Proszę uprzejmie:

pkgver() {
  cd vim
  hg log -r . --template '{latesttag}-{latesttagdistance}-{node|short}\n' | sed 's/^v//;s/-/./g'
}

Stary sposób na obsługę VCS nie przestał działać wraz z nowym wydaniem pacmana – co najwyżej pkgver przestał być aktualizowany. Widać jednak, że obecna, zalecana przez nas metoda nie tylko jest czytelniejsza, ale także bardziej kuloodporna.