Nächste: , Vorige: , Nach oben: Software-Entwicklung   [Inhalt][Index]


7.3 Stufe 2: Das Repository als Kanal

Jetzt haben wir ein Git-Repository mit (unter anderem) einer Paketdefinition (siehe Stufe 1: Erstellen mit Guix). Wäre es nicht besser, wenn wir daraus einen Kanal machen würden (siehe Kanäle in Referenzhandbuch zu GNU Guix)? Schließlich sind Kanäle entwickelt worden, um Nutzer mit Paketdefinitionen zu versorgen, und genau das tun wir mit guix.scm.

Tatsächlich sollten wir es zu einem Kanal machen, aber aufgepasst: Die .scm-Datei(en) unseres Kanals gehören in ein gesondertes Verzeichnis, damit guix pull nicht versucht, die falschen .scm-Dateien zu laden, wenn jemand damit den Kanal herunterlädt – und in Guile gibt es viele .scm-Dateien! Wir fangen mit der Trennung an, behalten aber auf oberster Ebene eine symbolische Verknüpfung guix.scm zur Nutzung mit guix shell:

mkdir -p .guix/modules
mv guix.scm .guix/modules/guile-package.scm
ln -s .guix/modules/guile-package.scm guix.scm

Damit es als Kanal verwendet werden kann, erweitern wir unsere guix.scm-Datei zu einem Paketmodul (siehe Paketmodule in Referenzhandbuch zu GNU Guix). Das geschieht, indem wir die use-modules-Form am Anfang durch eine define-module-Form ersetzen. Auch müssen wir dann eine Paketvariable exportieren, mit define-public, und dennoch am Ende der Datei den Paketwert zurückliefern, damit guix shell und guix build -f guix.scm weiterhin funktionieren. Das Endergebnis sieht so aus (ohne zu wiederholen, was wir nicht verändern):

(define-module (guile-package)
  #:use-module (guix)
  #:use-module (guix git-download)   ;für ‚git-predicate‘
  )

(define vcs-file?
  ;; Wahr zurückliefern, wenn die angegebene Datei unter
  ;; Versionskontrolle steht.
  (or (git-predicate (dirname (dirname (current-source-directory))))
      (const #t)))                                ;es ist kein Git-Checkout

(define-public guile
  (package
    (name "guile")
    (version "3.0.99-git")                          ;komische Versionsnummer
    (source (local-file "../.." "guile-checkout"
                        #:recursive? #t
                        #:select? vcs-file?))
    ))

;; Das oben definierte Paketobjekt muss am Modulende zurückgeliefert werden.
guile

Zuletzt brauchen wir noch eine .guix-channel-Datei, um Guix zu erklären, woher es die Paketmodule in unserem Repository bekommt:

;; Mit dieser Datei kann man dieses Repo als Guix-Kanal eintragen.

(channel
  (version 0)
  (directory ".guix/modules"))  ;Paketmodule finden sich unter .guix/modules/

Zusammengefasst liegen diese Dateien jetzt im Repository:

.
├── .guix-channel
├── guix.scm  .guix/modules/guile-package.scm
└── .guix
    └── modules
       └── guile-package.scm

Und das war alles: Wir haben einen Kanal erschaffen! (Noch besser wäre es, auch Kanalautorisierungen zu unterstützen, damit Benutzer wissen, dass der heruntergeladene Code echt ist. Wir ersparen Ihnen die Feinheiten hier, aber ziehen Sie es in Betracht!) Nutzer können von diesem Kanal pullen, indem sie ihn zu ~/.config/guix/channels.scm hinzufügen, etwa so:

(append (list (channel
                (name 'guile)
                (url "https://git.savannah.gnu.org/git/guile.git")
                (branch "main")))
        %default-channels)

Nach einem Aufruf von guix pull sind die neuen Pakete zu sehen:

$ guix describe
Generation 264  26. Mai 2023 16:00:35    (aktuell)
  guile 36fd2b4
    Repository-URL: https://git.savannah.gnu.org/git/guile.git
    Branch: main
    Commit: 36fd2b4920ae926c79b936c29e739e71a6dff2bc
  guix c5bc698
    Repository-URL: https://git.savannah.gnu.org/git/guix.git
    Commit: c5bc698e8922d78ed85989985cc2ceb034de2f23
$ guix package -A ^guile$
guile   3.0.99-git      out,debug       guile-package.scm:51:4
guile   3.0.9           out,debug       gnu/packages/guile.scm:317:2
guile   2.2.7           out,debug       gnu/packages/guile.scm:258:2
guile   2.2.4           out,debug       gnu/packages/guile.scm:304:2
guile   2.0.14          out,debug       gnu/packages/guile.scm:148:2
guile   1.8.8           out             gnu/packages/guile.scm:77:2
$ guix build guile@3.0.99-git
[…]
/gnu/store/axnzbl89yz7ld78bmx72vpqp802dwsar-guile-3.0.99-git-debug
/gnu/store/r34gsij7f0glg2fbakcmmk0zn4v62s5w-guile-3.0.99-git

Auf diesem Weg liefern Sie, als Entwickler, Ihre Software direkt in die Hände der Nutzer! Es gibt keine Mittelsmänner, trotzdem bleiben Transparenz und Provenienzverfolgung erhalten.

Auf dieser Grundlage kann außerdem jeder leicht Docker-Abbilder, Pakete als Deb/RPM oder einen einfachen Tarball mit guix pack anfertigen (siehe Aufruf von guix pack in Referenzhandbuch zu GNU Guix):

# Sie wünschen ein Docker-Image mit unserem Guile-Snapshot?
guix pack -f docker -S /bin=bin guile@3.0.99-git

# Und ein verschiebliches RPM?
guix pack -f rpm -R -S /bin=bin guile@3.0.99-git

Nächste: Bonus: Paketvarianten, Vorige: Stufe 1: Erstellen mit Guix, Nach oben: Software-Entwicklung   [Inhalt][Index]