====== LPM — der Lyx Package Manager ====== ''lpm'' verwaltet Lyx-Pakete: Abhängigkeiten auflösen, Archive bauen, in einer Registry veröffentlichen. Diese Seite führt vom leeren Verzeichnis bis zum veröffentlichten Paket. Alle Beispiele sind gegen **''lpm 0.1.0''** (Stand ''7ba9aa4'') und ''https://lpm.seolizer.de'' ausgeführt; die Ausgaben stehen so, wie sie im Terminal erscheinen. → [[lyx_-_programmiersprache:tools|Tools-Übersicht]] · [[lyx_-_programmiersprache:tools:compiler-parameter|CLI-Referenz des Compilers]] · [[lyx_-_programmiersprache:erste-schritte|Erste Schritte]] ===== Unterseiten ===== * [[lyx_-_programmiersprache:tools:lpm:registry-protokoll|Registry-Protokoll]] — URL-Layout, Indexformat, Statuscodes, Integrität * [[lyx_-_programmiersprache:tools:lpm:registry-betreiben|Eine Registry betreiben]] — Server einrichten, Token vergeben, Publish-Endpunkt * [[lyx_-_programmiersprache:tools:lpm:compiler-integration|Compiler-Integration]] — ''lpm resolve'' als Schnittstelle für ''lyxc'' ---- ===== Überblick ===== Ein Lyx-Projekt beschreibt sich in einer einzigen Datei: ''lyx.toml''. Darin stehen Paketname, Version und Abhängigkeiten. ''lpm'' liest sie und weiß damit alles Nötige. **Zum Benutzen von Paketen braucht es keine Anmeldung.** Suchen, Installieren, Auflösen und Bauen laufen ohne Token. Erst das **Veröffentlichen** verlangt einen, und den vergibt der Betreiber der Registry von Hand — eine Selbstregistrierung gibt es nicht (→ [[#4. Einen Token bekommen]]). ^ Befehl ^ Was passiert ^ | ''lpm init'' | ''lyx.toml'' anlegen | | ''lpm install'' | Abhängigkeiten auflösen, laden, SHA256 prüfen, ''lyx.lock'' schreiben | | ''lpm remove'' | Abhängigkeit aus ''lyx.toml'' entfernen | | ''lpm search'' / ''info'' | Registry durchsuchen, Details und Versionen anzeigen | | ''lpm list'' | was ist aufgelöst? | | ''lpm pack'' | Verzeichnis zu einem ''.lxpkg'' packen | | ''lpm publish'' | frisch packen und hochladen | | ''lpm login'' / ''logout'' | Token je Registry hinterlegen und entfernen | | ''lpm update'' | Index auffrischen und Pakete im Rahmen der Constraints aktualisieren; ''lpm update <pkg>'' für ein einzelnes | | ''lpm cache list'' / ''clean'' / ''add'' / ''remove'' | lokalen Cache verwalten | | ''lpm resolve'' | Import-Auflösung für ''lyxc'' — schreibt einen Pfad auf stdout | ^ Globale Option ^ Wirkung ^ | ''--offline'' | kein Netzzugriff, nur lokaler Cache und Spiegel | | ''--registry=<url>'' | andere Registry (Vorgabe: ''https://lpm.seolizer.de'') | | ''--verbose'' / ''-v'' | ausführliche Ausgabe, zeigt die geholten URLs | | ''--version'' / ''-V'' | Version ausgeben | ---- ===== 1. Installieren ===== Vorausgesetzt wird eine gebaute ''lyxc''-Toolchain (**≥ 1.0.19E**) aus dem ''aurum''-Repository. git clone git@github.com:SEOLizer/lyx-lpm.git cd lyx-lpm make make install PREFIX=~/.local # ohne sudo, wenn ~/.local/bin im PATH liegt Prüfen: $ lpm --version lpm 0.1.0 Systemweit ginge ''sudo make install'' (nach ''/usr/local/bin''), entfernen mit ''make uninstall'' unter Angabe desselben ''PREFIX''. > **Nach jedem ''make'' neu installieren.** Sonst läuft im Terminal weiter die alte Fassung, während ''bin/lpm'' im Repo schon die neue ist. ---- ===== 2. Ein Projekt anlegen und Pakete benutzen ===== $ mkdir hallo && cd hallo $ lpm init --name=demo/hello lpm: Paket 'demo/hello' initialisiert. lpm: lyx.toml wurde erstellt. Das erzeugte Manifest: [package] name = "demo/hello" version = "0.1.0" author = "" license = "MIT" description = "" [build] entry = "main.lyx" Ein Paket suchen und einbinden: $ lpm search http net/http@0.3.0 — HTTP client for Lyx lpm: 1 Treffer. $ lpm install net/http lpm: hole net/http@0.3.0 von https://lpm.seolizer.de lpm: 1 Paket(e) aufgeloest, lyx.lock geschrieben. ''install'' trägt die Abhängigkeit in ''lyx.toml'' ein, löst sie auf, lädt das Archiv, prüft dessen SHA256 und entpackt es nach ''~/.lpm/cache/''. Das Ergebnis steht in ''lyx.lock'': # Automatisch generiert — nicht manuell bearbeiten [[package]] name = "net/http" version = "0.3.0" sha256 = "75e7cbae5eaa87a569d1edd626647d260d14f97df1888facfbb6c8ae3c92f23c" source = "https://lpm.seolizer.de/packages/net/http/0.3.0.lxpkg" ==== Version festlegen ==== Ohne Angabe steht ''"latest"'' im Manifest — also „immer die neueste": $ lpm install net/http@^0.3.0 # Caret-Range: 0.3.x, nicht 0.4.0 $ lpm install net/http@~0.3.0 # Tilde-Range: nur Patch-Stand $ lpm install net/http@0.3.0 # exakt diese Version Unterstützt werden Caret-Ranges (''^''), Tilde-Ranges (''~''), ''%%>=%%'' und exakte Versionen. Für Reproduzierbarkeit sorgt in jedem Fall ''lyx.lock'' — **die Datei gehört ins Repository**, sie pinnt jede Version samt Prüfsumme. $ lpm list Aufgeloeste Pakete (lyx.lock): net/http@0.3.0 $ lpm info net/http net/http HTTP client for Lyx latest: 0.3.0 Versionen: 0.3.0 1 Version(en). $ lpm remove net/http # aus lyx.toml entfernen, Lock neu schreiben ---- ===== 3. Ein eigenes Paket bauen ===== Ein Paket ist ein Verzeichnis mit einem ''lyx.toml'' und mindestens einer Unit: mein-paket/ lyx.toml http.lyx ← die Unit docs/readme.md ← darf mit, muss nicht Das Manifest braucht mindestens ''name'' und ''version'': [package] name = "net/http" version = "1.2.0" description = "HTTP client for Lyx" # erscheint in lpm search license = "MIT" author = "Anna Beispiel " [dependencies] "std/io" = ">=1.0.0" [build] entry = "http.lyx" # welche Datei die Unit ist **Paketnamen** sind hierarchisch und passen damit zur Import-Syntax: ''net/http'' wird zu ''import net.http''. Erlaubt sind ''[a-z0-9_/.-]'' — keine Großbuchstaben, keine Leerzeichen, keine ''..''-Segmente. **''entry''** sagt ''lpm resolve'', welche Datei die Unit ist. Fehlt der Eintrag, wird ''<letztes Namenssegment>.lyx'' gesucht, danach ''.lyu''. ==== Packen ==== $ lpm pack lpm: demo/beispiel@1.2.0 gepackt: ./demo_beispiel-1.2.0.lxpkg sha256 4f5007e67688426c5036f8534bf8f0d148da2cf8e452bb49c49bd58647e2f9af 595 Bytes Das Archiv ist ein ''tar.zst'' und **reproduzierbar**: zweimal gepackt ergibt denselben SHA256 — nachgemessen mit einer Sekunde Abstand zwischen beiden Läufen. Dateien werden sortiert aufgenommen, Zeitstempel und Rechte sind fest. Andernfalls wäre die Prüfsumme in ''lyx.lock'' nur eine Momentaufnahme. Der Inhalt des Archivs: beispiel.lyx docs/readme.md lyx.toml FILES.sha256 ''FILES.sha256'' entsteht beim Packen und enthält eine Zeile je Datei. **Was nicht eingepackt wird:** versteckte Dateien (auch ''.git''), ''lyx.lock'' (gehört dem Anwender), ''bin/'' und bereits vorhandene ''.lxpkg''. Alles andere kommt mit, bis Verzeichnistiefe 4. === Nicht deklarierte Imports werden angemahnt === ''pack'' und ''publish'' vergleichen die ''import''-Zeilen der Units mit ''[dependencies]'' und melden, was dort fehlt: $ lpm pack lpm: warning: 2 Import(e) stehen nicht in [dependencies]: crypto/tls demo/base Wer sie aus der Registry bezieht, traegt sie ein: lpm install **Es ist eine Warnung, kein Fehler** — das Archiv entsteht trotzdem. ''lpm'' kann nicht wissen, woher eine Unit kommen soll: sie mag aus der Registry stammen, aus dem eigenen Projektbaum kommen oder von Hand danebenliegen. Die Entscheidung bleibt beim Autor. Sind die Pakete eingetragen, schweigt der Befehl. Dahinter steckt **kein Parser**, sondern eine Zeilensuche: ''import'' am Zeilenanfang, Name bis zum Semikolon oder Leerraum, Punkte zu Schrägstrichen. Dass der Name am Leerraum endet, ist der Grund, warum ''grant [%%…%%]'' nicht mitgezählt wird. Vier Fälle sind ausgenommen, sonst würde die Warnung Legitimes anmahnen: ^ Ausgenommen ^ Warum ^ | Compiler-Units — ''std/'', ''data/'', ''src/'' | kommen mit dem Compiler, nicht aus der Registry | | Das eigene Paket | ''demo/luecke'' in einem Paket namens ''demo/luecke'' | | Alles unterhalb des eigenen Pakets | ''demo/luecke/intern'' — eine Unter-Unit desselben Pakets | | Units, die als Datei danebenliegen | der Fall „mehrere Units in einem Paket" aus dem Abschnitt oben | Die letzten beiden Ausnahmen sind aus einem Fehlalarm entstanden: ohne sie hätte die Warnung dauerhaft genau das Layout gerügt, das dieses Handbuch als richtig beschreibt. ==== Mehrere Units — ein Paket oder mehrere? ==== **Ein Paket ist immer ein Verzeichnis.** Der Manifestname ''lyx.toml'' liegt fest; zwei Manifeste nebeneinander im selben Ordner gibt es nicht. Das ist mehr als eine Formalie, denn ''lpm pack'' nimmt **alles** aus dem Verzeichnis. Liegen vier Units flach beieinander: demo/ lyx.toml name = "demo/http", entry = "http.lyx" http.lyx json.lyx tls.lyx buffer.lyx dann enthält das gebaute Archiv alle vier — ''entry'' wählt **nicht aus**, sondern benennt nur die Haupt-Unit: $ lpm pack && zstd -dc demo_http-1.0.0.lxpkg | tar -t buffer.lyx http.lyx json.lyx lyx.toml tls.lyx FILES.sha256 Die Reihenfolge ist alphabetisch — daher steht ''lyx.toml'' mitten drin und ''FILES.sha256'' als Erzeugtes am Schluss. Die Frage ist deshalb nicht „wie teile ich die Dateien auf", sondern: **sollen die Units einzeln importierbar sein?** **Ja — dann je ein Verzeichnis:** projekte/ http/ lyx.toml (demo/http) http.lyx json/ lyx.toml (demo/json) json.lyx tls/ lyx.toml (demo/tls) tls.lyx buffer/ lyx.toml (demo/buffer) buffer.lyx Abhängigkeiten untereinander stehen in den jeweiligen ''[dependencies]'', ganz normal. Veröffentlicht wird je Verzeichnis: for d in http json tls buffer; do (cd "$d" && lpm publish); done **Nein — dann ein Paket mit mehreren Dateien.** Sinnvoll, wenn ''json.lyx'' und ''buffer.lyx'' Innereien von ''demo/http'' sind und niemand sie einzeln einbinden soll. **''lpm resolve'' liefert pro Paket genau //eine// Datei.** Schreibt jemand ''import demo.json'', sucht ''lpm'' ein **Paket** namens ''demo/json'' — und findet keins, auch wenn ''json.lyx'' im Paket ''demo/http'' mitliegt: $ ls ~/.lpm/cache/demo/http/1.0.0/ buffer.lyx FILES.sha256 http.lyx json.lyx lyx.toml tls.lyx $ lpm resolve demo.http --entry /home/andreas/.lpm/cache/demo/http/1.0.0/http.lyx $ lpm resolve demo.json --entry lpm: error: Paket nicht in der Registry — demo/json (*) Die Datei **ist da** und wird trotzdem nicht gefunden. Mit-Units sind also nur innerhalb ihres Pakets brauchbar; für öffentlich importierbare Units führt kein Weg an einem eigenen Verzeichnis vorbei. Einen **Workspace-Modus**, der mehrere Pakete eines Repositories gemeinsam verwaltet und in einem Rutsch veröffentlicht, gibt es noch nicht (WP-PM-11). Bis dahin ist die Schleife oben der Weg. ---- Wer nur lokal testen will, braucht die Registry nicht: $ lpm cache add ./net_http-1.2.0.lxpkg net/http 1.2.0 lpm: net/http@1.2.0 entpackt nach /home/du/.lpm/cache/net/http/1.2.0 ---- ===== 4. Einen Token bekommen ===== **Zum Lesen der Registry braucht es nichts.** Suchen, Installieren, Auflösen und Bauen funktionieren ohne Anmeldung — wer nur fremde Pakete benutzt, kann dieses Kapitel und das nächste überspringen. Ein Token wird ausschließlich zum **Veröffentlichen** gebraucht. ==== Es gibt keine Selbstregistrierung ==== ''lpm.seolizer.de'' liefert nur Paketdaten aus. Die Wurzel der Registry ist bewusst geschlossen: $ curl -o /dev/null -w '%{http_code}\n' https://lpm.seolizer.de/ 403 $ curl -o /dev/null -w '%{http_code}\n' https://lpm.seolizer.de/index.json 200 Es gibt also **kein Anmeldeformular, keine Weboberfläche und kein Benutzerkonto**. Token werden von Hand vergeben. Das ist Absicht: der Namensraum eines Paketmanagers lässt sich nur begrenzt zurückholen, wenn er einmal belegt ist. ==== Den Token anfragen ==== Anfragen laufen über ein **Issue im Repository des Paketmanagers**: → https://github.com/SEOLizer/Lyx-Package-Manager/issues Ein Titel, der mit ''Token:'' beginnt, macht die Anfrage für das LPM-Team auf den ersten Blick erkennbar — etwa ''Token: Namensraum net/''. Vier Angaben gehören hinein, damit die Anfrage ohne Rückfragen bearbeitet werden kann: ^ Angabe ^ Wozu ^ | **Namensraum** (z. B. ''net/'') | Der Token wird auf dieses Präfix eingeschränkt. Ohne Angabe gälte ''*'', also alles — das wird nicht vergeben | | **Publisher-Name** | Kurzname für die Token-Verwaltung. Er erscheint im Paketindex als ''publisher'' und ist damit öffentlich sichtbar | | **Zweck bzw. geplantes Paket** | Ein oder zwei Sätze, was dort veröffentlicht werden soll. Namensraum-Konflikte fallen so früh auf, nicht erst beim ersten ''publish'' | | **Kontaktweg für die Übergabe** | Wohin der Token geschickt werden kann — siehe der Kasten unten | Ein Beispiel: Titel: Token: Namensraum net/ Namensraum: net/ Publisher: anna Zweck: HTTP-Client und ein kleiner URL-Parser; net/http und net/url Kontakt: anna@example.org **Der Token gehört nicht ins Issue.** Ein GitHub-Issue ist öffentlich und bleibt es auch nach dem Schließen. Deshalb wird im Issue nur die **Anfrage** verhandelt; der Token selbst geht über den dort genannten Kontaktweg zurück. Wer versehentlich einen Token öffentlich gemacht hat, meldet das im selben Issue — er wird dann entzogen und neu ausgestellt. ==== Was zurückkommt ==== Eine Zeichenkette aus **64 Hexziffern**. Sie wird **genau einmal angezeigt**: der Server speichert nur ihren SHA256-Hash und kann sie nicht erneut ausgeben. Geht sie verloren, wird der alte Zugang entzogen und ein neuer ausgestellt — bereits veröffentlichte Pakete bleiben davon unberührt. Die Namensraum-Grenze wird tatsächlich durchgesetzt. Ein Token für ''net/'' kann ''net/http'' veröffentlichen, ''crypto/tls'' aber nicht: {"ok": false, "error": "Dieser Token darf unter \"net/boese\" nicht veroeffentlichen."} Wie die Vergabe auf der Serverseite abläuft, steht unter [[lyx_-_programmiersprache:tools:lpm:registry-betreiben|Eine Registry betreiben]] — das betrifft nur Betreiber einer eigenen Registry. ==== Eine eigene Registry statt eines Tokens ==== Für Pakete, die gar nicht öffentlich sein sollen, ist der Umweg über einen Token unnötig. Eine eigene Registry lässt sich mit ''--registry=<url>'' ansprechen — und rein lokal geht es ganz ohne: $ lpm pack $ lpm cache add ./demo_beispiel-1.2.0.lxpkg firma/intern 1.0.0 lpm: firma/intern@1.0.0 entpackt nach /home/andreas/.lpm/cache/firma/intern/1.0.0 $ lpm cache list Gecachte Pakete in /home/andreas/.lpm/cache: firma/intern@1.0.0 net/http@0.3.0 2 Paket-Version(en). $ lpm resolve firma.intern --entry --offline /home/andreas/.lpm/cache/firma/intern/1.0.0/beispiel.lyx Das Paket ist damit auflösbar, **obwohl es in keiner Registry steht** — auch mit ''--offline''. Für firmeninterne Units, Zwischenstände und Versuche ist das der kürzeste Weg; ein Token wird erst gebraucht, wenn andere das Paket über das Netz beziehen sollen. Zu beachten: Name und Version gibt hier der Aufrufer an, sie müssen nicht zum ''lyx.toml'' im Archiv passen. Welche Datei als Unit gilt, entscheidet weiterhin ''[build] entry'' — im Beispiel ''beispiel.lyx'', nicht etwa ''intern.lyx'' nach dem Namenssegment. ---- ===== 5. Anmelden ===== Einmalig je Registry: $ lpm login --token=3f9a… lpm: angemeldet an https://lpm.seolizer.de Token in ~/.lpm/credentials (nur fuer dich lesbar). Die Datei bekommt Modus ''0600'' und enthält eine Zeile je Registry: https://lpm.seolizer.de 3f9a… Für eine andere Registry: $ lpm login --token=… --registry=https://registry.intern.example Beide Anmeldungen bestehen nebeneinander; welche gilt, entscheidet ''--registry'' beim jeweiligen Aufruf. Abmelden mit ''lpm logout'', ebenfalls je Registry. > Der Token wird von ''lpm'' **nirgends ausgegeben** — auch nicht gekürzt und auch nicht unter ''--verbose''. Ein Protokoll, das weitergegeben wird, enthält ihn also nicht. ---- ===== 6. Veröffentlichen ===== Im Paketverzeichnis: $ lpm publish lpm: veroeffentliche net/http@1.2.0 an https://lpm.seolizer.de lpm: net/http@1.2.0 ist veroeffentlicht. sha256 6e8701a7f14e40ca549e760c2f65127f65ca2d502000ae8101bc468d4754645b ''publish'' **packt immer frisch** — ein herumliegendes ''.lxpkg'' wird nicht hochgeladen. Sonst veröffentlicht man irgendwann den Stand von vorgestern. Mitgeschickt werden Name, Version, Prüfsumme, die Dependencies aus dem Manifest und die Beschreibung. Der Server prüft die Prüfsumme gegen den empfangenen Rumpf, legt das Archiv ab und aktualisiert beide Indizes. **Eine veröffentlichte Version lässt sich nicht überschreiben:** $ lpm publish lpm: error: diese Version ist bereits veroeffentlicht HTTP 409 Für eine Korrektur wird die Versionsnummer erhöht. Der Grund: ein ''lyx.lock'' mit gepinntem SHA256 muss auch in einem Jahr noch stimmen. ---- ===== 7. Alltag ===== ^ Aufgabe ^ Befehl ^ | Pakete aktualisieren | ''lpm update'' | | Suchen (Name und Beschreibung) | ''lpm search <text>'' | | Details und Versionen | ''lpm info <paket>'' | | Gecachte Pakete anzeigen | ''lpm cache list'' | | Ein Paket aus dem Cache werfen | ''lpm cache remove <name> [<version>]'' | | Cache leeren | ''lpm cache clean'' | | Ohne Netz arbeiten | jeder Befehl mit ''--offline'' | | Andere Registry | jeder Befehl mit ''--registry=<url>'' | | Mehr Ausgabe | ''--verbose'' | **Der Index wird eine Stunde lang gespiegelt.** Innerhalb dieser Zeit fragen ''search'' und ''info'' nicht erneut nach; ''lpm update'' umgeht die Frist. ==== Pakete aktualisieren ==== ''lpm update'' holt den Index frisch und löst danach neu auf — **innerhalb der Constraints aus ''lyx.toml''**. Geändert wird nur ''lyx.lock'': $ lpm update lpm: hole demo/base@1.5.0 von https://lpm.seolizer.de ~ demo/base 1.0.0 -> 1.5.0 lpm: 1 Aenderung(en). ^ Zeichen ^ Bedeutung ^ | ''~'' | Version geändert | | ''+'' | neu hinzugekommen | | ''-'' | weggefallen | Steht ein Caret-Range ''"^1.0.0"'' im Manifest, kommt ''update'' bis 1.5.0, **aber nicht auf 2.0.0**. Das Manifest rührt ''update'' nie an — wer über die Constraint-Grenze hinaus will, ändert sie dort selbst. ''lpm update <pkg>'' — also mit Paketnamen — bewegt nur dieses eine; alle übrigen bleiben auf ihrer Lock-Version. Gibt es nichts zu tun, sagt der Befehl das auch: $ lpm update lpm: alles ist bereits aktuell. ==== Einzelne Pakete aus dem Cache entfernen ==== ''lpm cache clean'' ist der Holzhammer. Wer nur ein Paket loswerden will — etwa um einen Download wirklich neu zu erzwingen — nimmt ''cache remove'': $ lpm cache remove demo/base 1.5.0 lpm: demo/base@1.5.0 aus dem Cache entfernt. $ lpm cache remove demo/base lpm: demo/base entfernt (1 Version(en)). Ohne Version fallen **alle** Versionen des Pakets. Die Meldung nennt die Zahl, damit erkennbar bleibt, wie viel tatsächlich weg ist. **Leergeräumte Zwischenebenen verschwinden mit.** Nach dem Entfernen des letzten Pakets unter ''net/'' bleibt kein leeres ''net/''-Verzeichnis zurück, das in ''cache list'' ein Paket vortäuschen würde. Liegt dort noch eine andere Unit — etwa ''demo/http'' neben ''demo/base'' — bleibt die Ebene natürlich stehen. Ein unbekanntes Paket ist ein Fehler, kein stiller Erfolg: $ lpm cache remove gibts/nicht lpm: gibts/nicht liegt nicht im Cache. Exit-Code 1 — in einem Skript also prüfbar. ==== Der Cache wird geprüft ==== Jedes gepackte Paket trägt ein ''FILES.sha256''. Vor der Benutzung wird der Cache dagegen abgeglichen — eine unter ''~/.lpm/cache'' veränderte Datei fällt damit auf: $ lpm install lpm: warning: net/http@0.3.0: Datei im Cache wurde veraendert (http.lyx) wird verworfen und neu geholt. lpm: hole net/http@0.3.0 von https://lpm.seolizer.de lpm: 1 Paket(e) aufgeloest, lyx.lock geschrieben. Das beschädigte Verzeichnis wird verworfen und durch die Fassung aus der Registry ersetzt. Mit ''--offline'' bleibt es bei der Meldung: $ lpm install --offline lpm: warning: net/http@0.3.0: Datei im Cache wurde veraendert (http.lyx) --offline ist gesetzt — das Paket wird nicht neu geholt. lpm: fehlt im Cache: net/http@0.3.0 Fehlt ''FILES.sha256'' — bei Paketen aus der Zeit vor ''lpm pack'' — gilt das nicht als Fehler; unter ''--verbose'' wird es erwähnt. > **Das ersetzt keine Signatur.** Die Prüfliste liegt im selben Archiv wie die Dateien; wer beides ändern kann, ändert eben beides. Gegen versehentliches Bearbeiten im Cache und gegen halb entpackte Pakete hilft sie trotzdem — und das sind die Fälle, die im Alltag vorkommen. **''--offline''** benutzt ausschließlich den lokalen Cache und den vorhandenen Spiegel. Fehlt dort etwas, sagt ''lpm'' das dazu: $ lpm install --offline gibts/nichtda lpm: error: Paket nicht in der Registry — gibts/nichtda (latest) --offline ist gesetzt — gesucht wurde nur im lokalen Spiegel. lpm: lyx.toml bleibt unveraendert. Die letzte Zeile ist wichtiger, als sie aussieht: **ein gescheitertes ''install'' hinterlässt keine halbe Abhängigkeit** im Manifest. Dasselbe gilt beim Versionskonflikt, wo zusätzlich kein ''lyx.lock'' geschrieben wird. ==== Abhängigkeiten von Abhängigkeiten ==== Das läuft von selbst. Fordert das Projekt ''demo/top'', und das braucht ''demo/mid'', das wiederum ''demo/base'': $ lpm install lpm: hole demo/base@1.0.0 … lpm: hole demo/mid@1.1.0 … lpm: hole demo/top@2.0.0 … lpm: 3 Paket(e) aufgeloest, lyx.lock geschrieben. Fordern zwei Pakete dasselbe Paket in unvereinbaren Versionen, bricht ''lpm'' ab, nennt beide Bedingungen und schreibt **kein** ''lyx.lock'': lpm: error: unvereinbare Versions-Constraints — demo/base (^1.0.0 gegen ^2.0.0) Genannt werden also beide Bedingungen — hier ein Caret-Range ''^1.0.0'' gegen ''^2.0.0'', die sich nicht überschneiden. ---- ===== 8. Wenn etwas schiefgeht ===== ^ Meldung ^ Bedeutung ^ | ''nicht angemeldet — erst 'lpm login --token=<token>' ausfuehren'' | Kein Token für diese Registry hinterlegt | | ''nicht angemeldet oder nicht berechtigt (lpm login)'' | Token abgelehnt (401) oder Namensraum verboten (403) | | ''diese Version ist bereits veroeffentlicht'' | 409 — Versionsnummer erhöhen | | ''Paket nicht in der Registry'' | Name unbekannt; mit ''--offline'' wurde nur der lokale Spiegel durchsucht | | ''unvereinbare Versions-Constraints'' | Zwei Pakete fordern Unvereinbares, beide Bedingungen werden genannt | | ''SHA256 stimmt nicht'' | Heruntergeladenes Archiv passt nicht zu ''lyx.lock''. Wird gelöscht, nie entpackt | | ''kein lyx.toml in diesem Verzeichnis'' | ''lpm pack''/''publish'' im falschen Verzeichnis | | ''lyx.toml ist unvollstaendig'' | ''name'' oder ''version'' fehlt | | ''keine Datei zum Einpacken gefunden'' | Alles im Verzeichnis fällt unter die Ausschlüsse | | ''Datei im Cache wurde veraendert'' | Ein Paket unter ''~/.lpm/cache'' weicht von seinem ''FILES.sha256'' ab. Es wird verworfen und neu geholt; mit ''--offline'' bleibt es bei der Meldung | | ''Registry-Index ist beschaedigt'' | Spiegel unbrauchbar — ''lpm update'' holt ihn neu | | ''Antwort der Registry zu gross'' | Index über 4 MiB bzw. Archiv über 64 MiB | Bei Netzproblemen hilft ''--verbose'': es zeigt, welche URL geholt wird. Der lokale Zustand liegt vollständig unter ''~/.lpm/'': ~/.lpm/ cache/ entpackte Pakete registry/ gespiegelte Indizes (+ .meta mit dem Zeitstempel) tmp/ Archive während des Downloads credentials Token, Modus 0600 Im Zweifel: ''lpm cache clean'' und ''~/.lpm/registry/'' löschen — beides wird beim nächsten Aufruf neu aufgebaut. Die Anmeldung bleibt dabei erhalten; ''credentials'' fasst nur ''lpm login'' und ''lpm logout'' an. ---- ===== 9. Was noch nicht geht ===== Diese Liste steht bewusst hier — sie spart Suchzeit. * **Keine Signaturen.** Die Prüfsumme sichert den Transportweg, nicht die Herkunft: wer die Registry kontrolliert, kontrolliert die Pakete. Ed25519 mit Trust-on-first-use ist geplant (WP-PM-10). * **Kein Zurückziehen über den Client.** ''yanked'' muss der Betreiber von Hand setzen (→ [[lyx_-_programmiersprache:tools:lpm:registry-betreiben|Registry betreiben]]). * **Keine Selbstregistrierung.** Token werden von Hand vergeben, angefragt über ein Issue (→ [[#4. Einen Token bekommen]]). Es gibt weder Weboberfläche noch Benutzerkonto, und damit auch keine Möglichkeit, einen eigenen Token selbst zu erneuern oder zu widerrufen — beides läuft über den Betreiber. * **Der Compiler ruft ''lpm'' noch nicht selbst auf.** ''lpm resolve'' liegt bereit, die Compiler-Seite fehlt (→ [[lyx_-_programmiersprache:tools:lpm:compiler-integration|Compiler-Integration]]). * **Keine ''[dev-dependencies]''-Auswertung.** Das Feld wird geparst, bei der Auflösung aber nicht berücksichtigt. * **Kein Workspace.** Mehrere Pakete in einem Repository müssen einzeln gebaut und veröffentlicht werden, je Verzeichnis ein Aufruf (WP-PM-11). * **Der Resolver geht greedy vor**, ohne Backtracking: er nimmt je Paket die höchste passende Version und nimmt eine Wahl nicht zurück, wenn sie später in eine Sackgasse führt. Dann kommt ein Konflikt, obwohl eine ältere Version des Elternpakets gepasst hätte. Abhilfe: das Constraint selbst enger fassen.