Po co pakiety
Pojedynczy plik .0 wystarczy, gdy uczysz się języka albo testujesz fragment kodu. Gdy tylko projekt wyrośnie poza jeden plik, potrzebujesz pakietu: katalogu z manifestem i znanym układem, który rozumie toolchain.
Korzyści z przejścia od luźnych plików do pakietu:
- Jedno kanoniczne miejsce na nazwę projektu, wersję i metadane.
- Wiele punktów wejścia (plik wykonywalny, biblioteka, testy) w jednym drzewie.
- Przewidywalny układ: narzędzia znajdują twój kod bez konfiguracji.
zero check/zero builddla całego drzewa, a nie plik po pliku.
Tworzenie szkieletu pakietu
Najszybciej zacząć od zero new:
zero new cli hello
To polecenie tworzy katalog hello/ o takim układzie:
hello/
├── zero.json
└── src/
└── main.0
cli to nazwa szablonu: tworzy wykonywalny program wiersza poleceń. Inne szablony (biblioteka, program systemowy) mają ten sam kształt z innymi ustawieniami domyślnymi.
Przejdź przez cd do nowego katalogu, uruchom program i gotowe:
cd hello
zero run
Gdy wywołujesz zero run w katalogu pakietu bez podawania pliku, polecenie bierze domyślny cel z zero.json i go uruchamia.
Manifest zero.json
Manifest z wygenerowanego pakietu cli wygląda tak:
{
"package": { "name": "hello", "version": "0.1.0" },
"targets": { "cli": { "kind": "exe", "main": "src/main.0" } }
}
Dwa klucze najwyższego poziomu: package i targets. Pierwszy identyfikuje pakiet, drugi mówi kompilatorowi, co zbudować.
package
"package": {
"name": "hello",
"version": "0.1.0"
}
name: slug identyfikujący pakiet. Używaj małych liter i łączników.version: wersja w formacie semver. Pakiety przed wersją 1.0 używają0.x.y.
Inne pola metadanych (opis, autor, licencja, repozytorium) mogą być obsługiwane: wiążący schemat znajdziesz w aktualnej dokumentacji Zero, bo manifest wciąż się rozwija.
targets
"targets": {
"cli": { "kind": "exe", "main": "src/main.0" }
}
Klucze (tutaj cli) to wybrane przez ciebie nazwy celów. Wartości opisują każdy cel:
kind: czym jest cel.exeoznacza plik wykonywalny. Inne rodzaje (biblioteka, test) mają ten sam kształt.main: plik źródłowy z punktem wejścia, względem katalogu głównego pakietu.
W jednym pakiecie możesz zadeklarować więcej niż jeden cel:
{
"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" }
}
}
Konkretny cel zbudujesz w CLI, podając jego nazwę:
zero build convert
zero run resize
Katalog src/
Wszystkie pliki źródłowe leżą w src/. Kompilator automatycznie przechodzi przez ten katalog: nie wymieniasz każdego pliku w manifeście. Pole main każdego celu wskazuje jego plik wejściowy; stamtąd kompilator podąża za importami, aby znaleźć wszystko, czego potrzebuje.
Pakiet z kilkoma modułami pomocniczymi może wyglądać tak:
image-tools/
├── zero.json
└── src/
├── convert.0
├── resize.0
├── lib.0
└── internal/
├── decoder.0
└── encoder.0
Podkatalog internal/ to tylko konwencja: manifest nie wymienia tych plików. Importy w convert.0 sięgają bezpośrednio do internal/decoder.0.
Budowanie i uruchamianie
Typowe czynności wewnątrz pakietu:
zero check # sprawdza typy w całym drzewie
zero run # buduje i uruchamia domyślny cel
zero run convert # buduje i uruchamia wskazany cel
zero build # buduje domyślny cel
zero build --all # buduje wszystkie cele (gdy jest obsługiwane)
zero test # uruchamia wszystkie cele testowe
CLI czyta zero.json, ustala, co zrobić, i działa. Wewnątrz pakietu rzadko trzeba podawać ścieżki.
Wiele plików źródłowych: krótki przykład
Załóżmy, że src/main.0 wywołuje funkcję pomocniczą z src/math.0. Plik pomocniczy:
pub fun double(value: i32) -> i32 {
return value * 2
}
Plik wejściowy:
pub fun main(world: World) -> Void raises {
let result = double(21)
if result == 42 {
check world.out.write("czterdzieści dwa\n")
}
}
Uruchom go przez zero run. W tym prostym przypadku kompilator rozwiązuje odwołanie do double w pozostałej części drzewa źródeł bez jawnej deklaracji importu. Gdy pakiety rosną, widocznością między modułami zajmuje się jawny system importów: jego składnię znajdziesz w aktualnej dokumentacji Zero, bo to jeden z obszarów, które najpewniej zmienią się przed wersją 1.0.
Czego nie dodawać do gita
.gitignore dla pakietu Zero zwykle zawiera:
# artefakty budowania i cache
/build/
/target/
# śmieci z edytora
.DS_Store
*.swp
Dokładna nazwa katalogu z wynikami budowania może się różnić (sprawdź aktualną dokumentację toolchaina), ale zasada jest prosta: kod źródłowy trafia do repozytorium, artefakty budowania nie.
Udostępnianie pakietów
Zero jest przed wersją 1.0, a rejestr pakietów nie należy jeszcze do stabilnej powierzchni. Na razie praktyczne sposoby udostępniania pakietu to:
- Git: sklonuj repozytorium i uruchom na nim
zero check. - Kopia w projekcie: wklej kopię źródeł do innego projektu.
Gdy pojawi się rejestr, odwołania do pakietów prawdopodobnie przeniosą się do pola zależności w zero.json. Traktuj to jako funkcję na przyszłość, a nie coś, na czym można dziś opierać skrypty.
Dalej: podstawy języka
Masz już wszystko, czego potrzeba do zorganizowania prawdziwego projektu w Zero. Następny rozdział przygląda się samemu językowi, zaczynając od wiązań let, czyli tego, jak wartości w Zero dostają nazwy.
Najczęściej zadawane pytania
Czym jest pakiet Zero?
Pakiet Zero to katalog z manifestem zero.json i folderem src/ zawierającym pliki źródłowe .0. Manifest deklaruje nazwę pakietu, wersję i jeden lub więcej 'celów' (targets). Każdy cel mówi kompilatorowi, jak zbudować coś ze źródeł: plik wykonywalny, bibliotekę albo plik binarny z testami.
Jak utworzyć nowy pakiet Zero?
Uruchom zero new <template> <name>, na przykład zero new cli hello. CLI tworzy katalog z zero.json, src/main.0 i innymi plikami, których potrzebuje wybrany szablon. Potem możesz w pakiecie używać zero check, zero run i zero build.
Co zawiera zero.json?
zero.json?Co najmniej obiekt package z polami name i version oraz obiekt targets opisujący wszystko, co pakiet buduje. Cel ma kind (na przykład exe dla pliku wykonywalnego) oraz main wskazujące plik źródłowy z punktem wejścia. W jednym manifeście możesz zadeklarować wiele celów.
Czy jeden pakiet Zero może mieć wiele celów?
Tak. Pakiet może deklarować dowolną liczbę celów, na przykład jeden cel exe dla CLI, jeden cel lib dla biblioteki wielokrotnego użytku i jeden lub więcej celów testowych. Każdy cel ma własny punkt wejścia w src/, a z CLI można budować lub uruchamiać je osobno.
Gdzie kompilator umieszcza wynik budowania?
Artefakty budowania trafiają do katalogu build wewnątrz pakietu (dokładna ścieżka zależy od implementacji i może się zmienić, dopóki Zero jest przed wersją 1.0). Drzewo źródeł w src/ nigdy nie jest modyfikowane. Traktuj katalog build jako jednorazowy: dodawanie go do gita to zły pomysł.