====== LPM — Pakete anlegen und in die Registry einreichen ======
LPM ist der Lyx Package Manager. Er löst Abhängigkeiten auf, baut ''.lxpkg''-Archive und kommuniziert mit der zentralen Registry unter ''lpm.seolizer.de''.
Ein Lyx-Projekt beschreibt sich selbst in einer einzigen Datei: ''lyx.toml''. Darin steht der Paketname, die Version, die Abhängigkeiten — und optional der Einstiegspunkt für den Compiler. LPM liest diese Datei und weiß damit alles was es braucht: welche Pakete geladen werden müssen, wie das Archiv heißt und wohin es hochgeladen wird.
Die Registry speichert jedes Paket versioniert und unveränderlich. Wer ein Paket unter ''mein.paket@1.2.0'' einreicht, kann diese Version nicht nachträglich ändern — das schützt alle, die diese Version als Abhängigkeit deklariert haben. Neue Versionen werden immer als eigener Eintrag veröffentlicht.
**Was LPM kann:**
^ Befehl ^ Was passiert ^
| ''lpm init'' | ''lyx.toml'' mit Grundstruktur anlegen |
| ''lpm install'' | Abhängigkeiten aus ''lyx.toml'' auflösen, herunterladen und verifizieren (SHA256) |
| ''lpm publish'' | Paket packen, signieren und in die Registry hochladen |
| ''lpm resolve'' | Versionsauflösung testen — wird von ''lyxc'' als Hook aufgerufen |
| ''lpm info'' / ''search'' | Registry nach Paketen und Versionen abfragen |
LPM arbeitet direkt mit ''lyxc'' zusammen: nach ''lpm install'' gibt ''lpm resolve'' dem Compiler die ''-I''-Pfade zu den heruntergeladenen Paketen — der eigene Code muss nichts weiter tun als ''import andreas.stringutils.trim;'' zu schreiben.
→ [[lyx_-_programmiersprache:tools|Tools-Übersicht]] · [[lyx_-_programmiersprache:tools:compiler-parameter|Compiler-Parameter]] · [[lyx_-_programmiersprache:erste-schritte|Erste Schritte]]
----
===== 1. Voraussetzungen =====
Config einmalig anlegen (''~/.lpm/config.yml''):
registry: https://lpm.seolizer.de
api_key:
Den Token vergibt der Server-Admin:
php admin.php add-token
----
===== 2. Neues Paket anlegen =====
mkdir mein.paket && cd mein.paket
lpm init --name mein.paket
''lpm init'' erzeugt eine ''lyx.toml'' mit Pflichtfeldern. Fehlende Felder ergänzen:
[package]
name = "mein.paket"
version = "0.1.0"
author = "Andreas Röne"
license = "MIT"
description = "Kurze Beschreibung des Pakets"
[build]
entry = "main.lyx"
[dependencies]
std.string = "^1.0.0"
anderes.paket = "^2.1.0"
----
===== 3. Paket-Struktur =====
mein.paket/
├── lyx.toml ← Pflicht
├── main.lyx ← Einstiegspunkt (gemäß entry in lyx.toml)
├── core/
│ └── util.lyx
└── README.md ← optional
Die ''unit''-Deklaration in jeder Datei muss zum Paketnamen passen:
unit mein.paket;
pub fn main(argc: int64, argv: int64): int64 {
...
}
----
===== 3b. Library-Paket (kein Einstiegspunkt) =====
Nicht jedes Paket hat eine ''main''-Funktion. Bei einer reinen Bibliothek lässt du den ''[build]''-Abschnitt einfach weg — LPM publiziert das Archiv trotzdem:
[package]
name = "andreas.stringutils"
version = "1.0.0"
author = "Andreas Röne"
license = "MIT"
description = "Erweiterte String-Hilfsfunktionen für Lyx"
[dependencies]
std.string = "^1.0.0"
Kein ''entry'', kein ''main''. Der Server prüft nicht ob ein Einstiegspunkt vorhanden ist.
**Unit-Benennung:** Der Paketname aus ''lyx.toml'' ist der Namespace-Präfix. Jede Quelldatei deklariert ihre eigene Sub-Unit darunter:
andreas.stringutils/
├── lyx.toml
├── trim.lyx → unit andreas.stringutils.trim;
├── split.lyx → unit andreas.stringutils.split;
└── format.lyx → unit andreas.stringutils.format;
unit andreas.stringutils.trim;
import std.string;
import std.alloc;
pub fn StrTrimLeft(s: int64): int64 { ... }
pub fn StrTrimRight(s: int64): int64 { ... }
pub fn StrTrim(s: int64): int64 { ... }
Nur ''pub''-Funktionen sind nach außen sichtbar.
**Nutzer der Bibliothek:**
[dependencies]
andreas.stringutils = "^1.0.0"
lpm install
unit mein.projekt;
import andreas.stringutils.trim;
import andreas.stringutils.split;
pub fn main(argc: int64, argv: int64): int64 {
var s: int64 := StrTrim(" hallo "c);
...
}
''lyxc'' findet die installierten Units über den Cache-Pfad, den ''lpm'' als ''-I''-Flag weitergibt — das übernimmt ''lpm resolve'' (der lyxc-Hook) automatisch.
**Faustregeln:**
^ Typ ^ [build] ^ entry ^ main-Funktion ^
| Executable | ja | ja | ja (''pub fn main'') |
| Library | nein | — | nein |
| Hybrid | ja | ja | ja — plus zusätzliche exportierte ''pub''-Funktionen |
Ein Hybrid macht Sinn wenn das Paket sowohl eine CLI liefert als auch eine API für andere Pakete — wie z.B. ''lpm'' selbst: es hat ''pub fn main'', aber ''lpm.core.*'' ist für andere Pakete importierbar.
----
===== 4. Version hochzählen =====
Vor jedem Publish die Version in ''lyx.toml'' erhöhen — SemVer:
^ Änderung ^ Beispiel ^ Wann ^
| Patch | ''0.1.0 → 0.1.1'' | Bugfix, keine API-Änderung |
| Minor | ''0.1.0 → 0.2.0'' | Neue Funktion, rückwärtskompatibel |
| Major | ''0.1.0 → 1.0.0'' | Breaking Change |
Bereits veröffentlichte Versionen können nicht überschrieben werden — immer neue Versionsnummer.
----
===== 5. Publish =====
cd mein.paket/
lpm publish
LPM führt dabei aus:
- ''lyx.toml'' lesen
- Alle ''.lyx''-Dateien in ein ''.lxpkg''-Archiv packen
- SHA256 berechnen
- Hochladen: ''POST /v1/publish'' mit Bearer-Token
Erfolgsmeldung:
lpm: mein.paket@0.1.0 veröffentlicht (sha256: abc123...)
----
===== 6. Paket aktualisieren =====
Version in ''lyx.toml'' erhöhen, dann erneut publishen:
# lyx.toml: version = "0.2.0"
lpm publish
----
===== 7. Paket als Abhängigkeit nutzen =====
In ''lyx.toml'' eines anderen Projekts:
[dependencies]
mein.paket = "^0.2.0"
lpm install
LPM löst die Version auf, lädt das ''.lxpkg'' herunter und verifiziert den SHA256.
----
===== 8. Abhängigkeiten aktualisieren (lpm update) =====
''lpm update'' aktualisiert installierte Pakete auf die neueste Version, die mit der Versionsangabe in ''lyx.toml'' kompatibel ist. Die Constraint-Zeilen in ''lyx.toml'' bleiben dabei unverändert — nur der tatsächlich installierte Stand wird angehoben.
**Alle Abhängigkeiten auf einmal aktualisieren:**
lpm update
LPM prüft für jede Abhängigkeit, ob in der Registry eine neuere Version existiert, die noch in den deklarierten Bereich fällt. ''std.string = "^1.0.0"'' erlaubt z.B. jede ''1.x.y''-Version, nicht aber ''2.0.0''.
**Einzelnes Paket aktualisieren:**
lpm update andreas.stringutils
Nützlich wenn nur ein bestimmtes Paket eine kritische Bugfix-Version erhalten hat und der Rest stabil bleiben soll.
**Was '''^''' bedeutet:**
^ Constraint ^ Erlaubt ^ Nicht erlaubt ^
| ''^1.0.0'' | ''1.0.1'', ''1.2.0'', ''1.9.9'' | ''2.0.0'' |
| ''^0.2.0'' | ''0.2.1'', ''0.2.9'' | ''0.3.0'', ''1.0.0'' |
| ''^0.0.3'' | ''0.0.3'' | ''0.0.4'', ''0.1.0'' |
Bei ''0.x.y''-Versionen schützt '''^''' auch vor Minor-Bumps — solange die Major-Version 0 ist, gilt jede Minor-Erhöhung als potenzieller Breaking Change.
**Breaking Change: Major-Version anheben**
Wenn ein Paket eine neue Major-Version veröffentlicht (''1.x.x → 2.0.0''), greift ''lpm update'' bewusst nicht — die ''^''-Constraint verhindert es. Die Abhängigkeit in ''lyx.toml'' muss manuell angepasst werden:
[dependencies]
andreas.stringutils = "^2.0.0" # war: ^1.0.0
lpm install
Das ist Absicht: ein Major-Bump signalisiert Breaking Changes, die eine bewusste Entscheidung erfordern.
----
===== 9. Nützliche Befehle =====
^ Befehl ^ Wirkung ^
| ''lpm info mein.paket'' | Paket-Infos und alle veröffentlichten Versionen anzeigen |
| ''lpm search '' | Registry nach Paketen durchsuchen |
| ''lpm list'' | Lokal installierte Pakete auflisten |
| ''lpm cache clean'' | Lokalen Paket-Cache leeren |
| ''lpm resolve mein.paket'' | Versionsauflösung testen (lyxc-Hook) |
Letzte Aktualisierung: 2026-06-12