Nowości w pacman 4.2.0

23 listopad 2014

Po blisko 18 miesiącach od ostatniej wersji pacmana, menedżera pakietów używanego głównie w Arch Linuksie, wielkimi krokami zbliża się kolejne wydanie. Daleki jestem od nazwania go rewolucyjnym, ale poza licznymi poprawkami na każdej płaszczyźnie pojawiło się też kilka ciekawych nowości. Poniższy mini-przegląd jest oczywiście czysto subiektywny. Ponadto większość ruchu łat odbywa się na liście dyskusyjnej pacman-dev i trafia do repozytorium git często z kilkumiesięcznym opóźnieniem, w związku z istnieje duże prawdopodobieństwo, że przeoczyłem coś godnego uwagi.

Ulepszony pacdiff

Wśród wielu narzędzi dostarczanych z pacmanem można wyróżnić pacdiff, skrypt ułatwiający znajdowanie nieaktualnych lub osieroconych plików konfiguracyjnych w systemie. Wraz z wydaniem 4.2.0 doczekał się gruntownych zmian, i chociaż daleko mu do dispatch-conf znanego z Gentoo, w końcu można o nazwać użytecznym. Dzięki pracy Jonathana Fraziera można zdefiniować program do porównywania plików (zmienna DIFFPROG) czy ograniczyć działanie skryptu do wypisania plików pacnew/pacorig/pacsave (-o). Zmieniła się również domyślna metoda wyszukiwania plików. Zamiast używania względnie naiwnego find /etc -name \*.pac(new|orig|save, pacdiff korzysta bezpośrednio z list plików przechowywanych w bazie danych pacmana. Takie rozwiązanie nie zawsze jest bardziej wydajne, ponadto nie bierze pod uwagę osieroconych plików, jednak po aktualizacji systemu są duże szanse, że cała baza pakietów pacmana znalazła się w pamięci podręcznej, w przeciwieństwie do plików z /etc/.

makepkg: zależności dla konkretnych architektur

Opiekunom pakietów opartych o pliki binarne dostarczane przez upstream czy [multilib] na pewno nieobce są podobne manewry w PKGBUILD-ach:

depends=('sdl' 'readline' 'sqlite')
[[ $CARCH == x86_64 ]] && depends=('lib32-sdl' 'lib32-readline' 'lib32-sqlite')

Na fali prac nad pkgbuild-introspection Dave Reisner zaimplementował obsługę tablic takich jak conflicts, replaces, depends czy source dla wskazanej architektury. Na przykład:

arch=('i686' 'x86_64')
depends=('foo')
depends_x86_64=('bar')

Taki kod sprawi, że pakiet dla architektury x86_64 będzie wymagał pakietów foo' ibar', podczas gdy pakiet dla i686 wyłącznie foo. Nic nie stoi na przeszkodzie, aby wykorzystać to także w podpakietach:

arch=('i686' 'x86_64')
depends=('foo')
…
package_paczka() {
  depends_x86_64=('bar')}

Analogicznie wszystkie pakiety wymienione w tablicy pkgname będą zależne od foo, natomiast paczka na x86_64 będzie wymagać jeszcze bar.

makepkg: validpgpkeys

Możliwość weryfikowania sygnatur archiwów z kodem źródłowym była do tej pory skrajnie nieprzydatna. Jeżeli makepkg nie znało klucza, wyrzucało w terminalu ostrzeżnie, nie podejmując żadnej akcji. Wraz z wydaniem 4.2.0 makepkg ogłosi strajk, jeśli klucz nie znajduje się w lokalnej bazie z kluczami oraz jego poziom zaufania jest ustawiony na ostateczny. Takie podejście ma oczywiście sens przy założeniu, że osoba tworząca pakiet faktycznie zweryfikowała prawdziwość klucza i zajmuje się pakietem w pojedynkę.

Aby ułatwić zespołowe zajmowanie się PKGBUILD-ami wprowadzono tablicę o nazwie validpgpkeys, do której dodaje się fingerprinty kluczy uznane za ufane. W efekcie makepkg zweryfikuje kod źródłowy tylko w oparciu o wcześniej zdefiniowane klucze, ignorując zawartość lokalnej bazy.

Przykładowe zastosowanie validpgpkeys można znaleźć w PKGBUILD-ach pakietów glibc, curl albo libtool.

makepkg-template

Jedną z głównych bolączek paczkowania modułów dla języków takich jak Perl czy Python jest powtarzalność pracy. Większość bibliotek buduje się w ten sam sposób, ewentualnie z niewielkimi różnicami. Dotychczasowym podejściem było żmudne odtwarzanie analogicznych linii, z wyjątkiem Ruby'ego i Perla, dla których powstały specjalne narzędzia tworzące cały PKGBUILD na podstawie informacji zawartych w Rubygems/CPAN.

Od marca bieżącego roku w repozytorium pacmana można znaleźć narzędzie o nazwie makepkg-template. Jak sugeruje nazwa, umożliwia ono wyłączenie części PKGBUILD-a do szablonu, który zostanie włączony na podstawie specjalnego znacznika. Rozważmy następujący PKGBUILD:

pkgname=python-flask
pkgver=0.10.1
pkgrel=1
pkgdesc='Micro webdevelopment framework for Python'
url='http://flask.pocoo.org/'
arch=('any')
license=('custom:BSD')
depends=('python-werkzeug' 'python-jinja' 'python-itsdangerous')
makedepends=('python-setuptools')
source=("http://pypi.python.org/packages/source/F/Flask/Flask-$pkgver.tar.gz")
sha256sums=('4c83829ff83d408b5e1d4995472265411d2c414112298f2eb4b359d9e4563373')

build() {
  cd "$pkgname-$pkgver"
  python setup.py build
}

check() {
  cd "$pkgname-$pkgver"
  python setup.py test
}

package() {
  cd $pkgname-$pkgver
  python setup.py install --prefix=/usr --root="$pkgdir" --optimize=1
  install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
}

W przypadku modułów Pythona zdecydowana większość posiada identyczne funkcje build, check i package. Zamiast powtarzać je n razy w różnych pakietach, można wydzielić je do pliku /gdziekolwiek/python-1.template i utworzyć dowiązanie symboliczne prowadzące do /gdziekolwiek/python.template.

Powyższe funkcje należy zastąpić znacznikiem:

# template start; name=python; version=1

# template end;

Przed rozpoczęciem kompilacji wystarczy uruchomić makepkg-template na danym PKGBUILD-zie:

makepkg-template --template-dir /gdziekolwiek/ -p PKGBUILD

Narzędzie to nie jest jeszcze idealne, ale znacząco ułatwi tworzenie nowych pakietów i zajmowanie się modułami niewymagającymi specjalnych zabiegów przed kompilacją.

pacman: odwrócone wyrażenia regularne

Kiedy ostatni raz próbowałem użyć NoExtract w pacman.conf do większych celów niż niewypakowywanie gvfsd-metadata, srogo się zawiodłem. Chociaż pacman obsługuje wyrażenia regularne, to robi to w ograniczonym zakresie, ignorując między innymi odwrócone wzorce.

Zmieniło się to wraz z commitem dfcea145. Tym samym stało się możliwe zastapienie localepurge czysto pacmanowym rozwiązaniem. Zakładając, że chce się zachować wyłącznie anglojęzyczne pliki językowe, w NoExtract wystarczy umieścić:

usr/share/locale/* !usr/share/locale/en !usr/share/locale/en_US !usr/share/locale/locale.alias usr/share/man/* !usr/share/man/man*

Po przeinstalowaniu wszystkich pakietów lub kilku aktualizacjach pacman przestanie wypakowywać wszystkie inne tłumaczenia programów.

To by było na tyle ze znaczących zmian w nowym wydaniu. Na pewno kolejne będzie znacznie ciekawsze – planowana jest obsługa hooks, która znacząco przyśpieszy instalację kilku{nastu,dziesięciu} pakietów, opóźniając regenerację cache ikon i aktywatorów na koniec operacji, a także zastąpienie ABS specjalną funkcją w pacmanie.