Warum überhaupt Pakete?
Eine einzelne .0-Datei reicht, wenn du die Sprache lernst oder ein Snippet ausprobierst. Sobald dein Projekt über eine Datei hinauswächst, willst du ein Paket – ein Verzeichnis mit einem Manifest und einem bekannten Layout, das die Toolchain versteht.
Die Vorteile, von losen Dateien auf ein Paket zu wechseln:
- Ein kanonischer Ort für Name, Version und Metadaten des Projekts.
- Mehrere Einstiegspunkte (Executable, Bibliothek, Tests) in einem Baum.
- Vorhersagbares Layout: Tools finden deinen Quellcode ohne Konfiguration.
- Ein
zero check/zero buildgegen den ganzen Baum, nicht Datei für Datei.
Ein Paket gerüstartig anlegen
Der schnellste Einstieg ist zero new:
zero new cli hello
Das erstellt ein Verzeichnis hello/ mit folgendem Aufbau:
hello/
├── zero.json
└── src/
└── main.0
cli ist der Template-Name – er erzeugt ein ausführbares Kommandozeilenprogramm. Andere Templates (Library, System-Programm) folgen demselben Muster mit anderen Defaults.
Wechsel mit cd in das neue Verzeichnis, führ es aus und los geht's:
cd hello
zero run
Wenn du zero run aus einem Paketverzeichnis aufrufst, ohne eine Datei zu benennen, nimmt es das Default-Target aus zero.json und führt das aus.
Das zero.json-Manifest
Das Manifest eines gerüstartig angelegten cli-Pakets sieht so aus:
{
"package": { "name": "hello", "version": "0.1.0" },
"targets": { "cli": { "kind": "exe", "main": "src/main.0" } }
}
Zwei Top-Level-Keys: package und targets. Der erste identifiziert das Paket; der zweite sagt dem Compiler, was zu bauen ist.
package
"package": {
"name": "hello",
"version": "0.1.0"
}
name– ein Slug, der das Paket identifiziert. Verwende Kleinbuchstaben und Bindestriche.version– ein semver-String. Pre-1.0-Pakete verwenden0.x.y.
Weitere Metadatenfelder (description, author, license, repository) werden eventuell unterstützt – verlass dich auf die aktuelle Zero-Doku für das maßgebliche Schema, da sich das Manifest noch entwickelt.
targets
"targets": {
"cli": { "kind": "exe", "main": "src/main.0" }
}
Die Keys (hier cli) sind Target-Namen, die du selbst wählst. Die Werte beschreiben jedes Target:
kind– was das Target ist.exefür ein Executable. Andere Arten (library, test) folgen demselben Muster.main– die Einstiegsquelldatei, relativ zur Paketwurzel.
Du kannst mehrere Targets im selben Paket deklarieren:
{
"package": { "name": "image-tools", "version": "0.1.0" },
"targets": {
"convert": { "kind": "exe", "main": "src/convert.0" },
"resize": { "kind": "exe", "main": "src/resize.0" },
"lib": { "kind": "lib", "main": "src/lib.0" }
}
}
Ein bestimmtes Target baust du über die CLI, indem du es benennst:
zero build convert
zero run resize
Das src/-Verzeichnis
Alle Quelldateien leben unter src/. Der Compiler läuft dieses Verzeichnis automatisch ab – du musst nicht jede Datei im Manifest auflisten. Das main-Feld jedes Targets zeigt auf seine Einstiegsdatei; der Compiler folgt von dort den Imports, um alles weitere zu finden.
Ein Paket mit ein paar Hilfsmodulen könnte so aussehen:
image-tools/
├── zero.json
└── src/
├── convert.0
├── resize.0
├── lib.0
└── internal/
├── decoder.0
└── encoder.0
Das internal/-Unterverzeichnis ist reine Konvention – nichts im Manifest benennt diese Dateien. Imports in convert.0 greifen direkt auf internal/decoder.0 zu.
Bauen und ausführen
Übliche Abläufe, sobald du innerhalb eines Pakets arbeitest:
zero check # den ganzen Baum typprüfen
zero run # das Default-Target bauen und ausführen
zero run convert # ein bestimmtes benanntes Target bauen und ausführen
zero build # das Default-Target bauen
zero build --all # jedes Target bauen (wo unterstützt)
zero test # jedes Test-Target ausführen
Die CLI liest zero.json, überlegt, was zu tun ist, und legt los. Sobald du in einem Paket arbeitest, musst du selten Pfade ausschreiben.
Mehrere Quelldateien: ein kurzes Beispiel
Nehmen wir an, src/main.0 ruft einen Helfer aus src/math.0 auf. Die Hilfsdatei:
pub fun double(value: i32) -> i32 {
return value * 2
}
Die Einstiegsdatei:
pub fun main(world: World) -> Void raises {
let result = double(21)
if result == 42 {
check world.out.write("forty two\n")
}
}
Ausführen mit zero run. Der Compiler löst die Referenz auf double im einfachen Fall ohne explizite Import-Deklaration gegen den restlichen Quellbaum auf. Wenn Pakete größer werden, regelt ein explizites Import-System die modulübergreifende Sichtbarkeit – sieh in der aktuellen Zero-Doku nach der Import-Syntax, die zu den Bereichen gehört, die sich vor 1.0 am ehesten ändern.
Was du nicht in git einchecken solltest
Ein .gitignore für ein Zero-Paket will meistens:
# Build-Artefakte und Caches
/build/
/target/
# Editor-Krempel
.DS_Store
*.swp
Der genaue Name des Build-Output-Verzeichnisses kann sich unterscheiden – schau in die aktuelle Toolchain-Doku – aber die Regel lautet: Quellcode rein, Build-Artefakte raus.
Pakete teilen
Zero ist pre-1.0 und eine Paket-Registry gehört noch nicht zur stabilen Oberfläche. Praktische Wege, ein Paket heute zu teilen:
- Git: das Repo klonen und
zero checkdagegen laufen lassen. - Vendored Copy: eine Kopie des Quellcodes in ein anderes Projekt legen.
Sobald eine Registry kommt, wandern Paket-Referenzen wahrscheinlich in ein Dependencies-Feld in zero.json. Behandle das als zukünftiges Feature, nicht als etwas, gegen das du heute schon Skripte schreibst.
Als Nächstes: Sprachgrundlagen
Du hast jetzt alles, was du brauchst, um ein echtes Zero-Projekt zu organisieren. Das nächste Kapitel zoomt in die Sprache selbst hinein, beginnend mit Let-Bindings – wie Zero-Werte Namen bekommen.
Häufig gestellte Fragen
Was ist ein Zero-Paket?
Ein Zero-Paket ist ein Verzeichnis mit einem zero.json-Manifest und einem src/-Ordner voller .0-Quelldateien. Das Manifest deklariert Name, Version und ein oder mehrere „Targets“ – jedes Target sagt dem Compiler, wie er etwas (ein Executable, eine Bibliothek, eine Test-Binary) aus dem Quellcode bauen soll.
Wie lege ich ein neues Zero-Paket an?
Führe zero new <template> <name> aus, zum Beispiel zero new cli hello. Die CLI gerüstet ein Verzeichnis mit zero.json, src/main.0 und allen weiteren Dateien, die das gewählte Template braucht. Von dort kannst du zero check, zero run und zero build innerhalb des Pakets nutzen.
Was enthält zero.json?
zero.json?Mindestens ein package-Objekt mit name und version sowie ein targets-Objekt, das jedes Build-Artefakt beschreibt. Ein Target hat eine kind (z. B. exe für ein Executable) und ein main, das auf die Einstiegsquelldatei zeigt. In einem Manifest darfst du mehrere Targets deklarieren.
Kann ein einzelnes Zero-Paket mehrere Targets haben?
Ja. Ein Paket kann beliebig viele Targets deklarieren – zum Beispiel ein exe-Target für eine CLI, ein lib-Target für eine wiederverwendbare Bibliothek und ein oder mehrere Test-Targets. Jedes Target hat seinen eigenen Einstiegspunkt unter src/, und du kannst sie einzeln über die CLI bauen oder ausführen.
Wohin legt der Compiler die Build-Ausgaben?
Build-Artefakte landen in einem Build-Verzeichnis innerhalb des Pakets (der genaue Pfad ist implementierungsabhängig und kann sich ändern, solange Zero pre-1.0 ist). Der Quellbaum unter src/ wird nie verändert. Behandle das Build-Verzeichnis als Wegwerf – ins git einzuchecken ist keine gute Idee.