Perché i pacchetti
Un singolo file .0 va bene quando stai imparando il linguaggio o provando un frammento di codice. Nel momento in cui il progetto supera un file, ti serve un pacchetto: una cartella con un manifest e una struttura nota che la toolchain capisce.
I vantaggi di passare da file sparsi a un pacchetto:
- Un unico punto di riferimento per nome, versione e metadati del progetto.
- Più punti di ingresso (eseguibile, libreria, test) nello stesso albero.
- Una struttura prevedibile: gli strumenti trovano i tuoi sorgenti senza configurazione.
- Un
zero check/zero buildsull'intero albero, non file per file.
Creare un pacchetto
Il modo più rapido per iniziare è zero new:
zero new cli hello
Questo crea una cartella hello/ organizzata così:
hello/
├── zero.json
└── src/
└── main.0
cli è il nome del template: produce un programma eseguibile a riga di comando. Gli altri template (libreria, programma di sistema) seguono la stessa struttura con impostazioni predefinite diverse.
Entra con cd nella nuova cartella, eseguilo e sei pronto:
cd hello
zero run
Quando lanci zero run dall'interno della cartella di un pacchetto senza indicare un file, prende il target predefinito da zero.json ed esegue quello.
Il manifest zero.json
Il manifest di un pacchetto cli appena creato è così:
{
"package": { "name": "hello", "version": "0.1.0" },
"targets": { "cli": { "kind": "exe", "main": "src/main.0" } }
}
Due chiavi di primo livello: package e targets. La prima identifica il pacchetto; la seconda dice al compilatore cosa costruire.
package
"package": {
"name": "hello",
"version": "0.1.0"
}
name: uno slug che identifica il pacchetto. Usa lettere minuscole e trattini.version: una stringa semver. I pacchetti pre-1.0 usano0.x.y.
Potrebbero essere supportati altri campi di metadati (descrizione, autore, licenza, repository): fai riferimento alla documentazione attuale di Zero per lo schema ufficiale, perché il manifest è ancora in evoluzione.
targets
"targets": {
"cli": { "kind": "exe", "main": "src/main.0" }
}
Le chiavi (qui cli) sono nomi di target che scegli tu. I valori descrivono ciascun target:
kind: cosa è il target.exeper un eseguibile. Gli altri tipi (libreria, test) seguono la stessa struttura.main: il file sorgente di ingresso, relativo alla radice del pacchetto.
Puoi dichiarare più di un target nello stesso pacchetto:
{
"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" }
}
}
Compila un target specifico con la CLI indicandone il nome:
zero build convert
zero run resize
La cartella src/
Tutti i file sorgente stanno in src/. Il compilatore percorre questa cartella automaticamente: non devi elencare ogni file nel manifest. Il campo main di ogni target punta al suo file di ingresso; da lì il compilatore segue gli import per trovare tutto il resto che gli serve.
Un pacchetto con alcuni moduli di supporto potrebbe essere così:
image-tools/
├── zero.json
└── src/
├── convert.0
├── resize.0
├── lib.0
└── internal/
├── decoder.0
└── encoder.0
La sottocartella internal/ è solo una convenzione: nel manifest non compare nessuno di quei file. Gli import dentro convert.0 raggiungono direttamente internal/decoder.0.
Compilare ed eseguire
I flussi di lavoro comuni una volta dentro un pacchetto:
zero check # controlla i tipi dell'intero albero
zero run # compila ed esegue il target predefinito
zero run convert # compila ed esegue un target specifico con nome
zero build # compila il target predefinito
zero build --all # compila ogni target (quando supportato)
zero test # esegue ogni target di test
La CLI legge zero.json, capisce cosa fare e procede. Quando lavori dentro un pacchetto raramente devi scrivere dei percorsi.
Più file sorgente: un breve esempio
Supponi che src/main.0 chiami una funzione di supporto da src/math.0. Il file di supporto:
pub fun double(value: i32) -> i32 {
return value * 2
}
Il file di ingresso:
pub fun main(world: World) -> Void raises {
let result = double(21)
if result == 42 {
check world.out.write("quarantadue\n")
}
}
Eseguilo con zero run. In questo caso semplice il compilatore risolve il riferimento a double nel resto dell'albero dei sorgenti senza bisogno di una dichiarazione di import esplicita. Quando i pacchetti crescono, un sistema di import esplicito gestisce la visibilità tra moduli: fai riferimento alla documentazione attuale di Zero per la sintassi degli import, che è una delle aree con più probabilità di cambiare prima della 1.0.
Cosa non aggiungere a git
Un .gitignore per un pacchetto Zero di solito contiene:
# artefatti di build e cache
/build/
/target/
# file di scarto dell'editor
.DS_Store
*.swp
Il nome esatto della cartella di output della build potrebbe essere diverso (controlla la documentazione attuale della toolchain), ma la regola è: i sorgenti dentro, gli artefatti di build fuori.
Condividere i pacchetti
Zero è pre-1.0 e un registro dei pacchetti non fa ancora parte dell'interfaccia stabile. Per ora, i modi pratici per condividere un pacchetto sono:
- Git: clona il repository ed esegui
zero checksu di esso. - Copia inclusa: metti una copia dei sorgenti dentro un altro progetto.
Quando arriverà un registro, i riferimenti ai pacchetti si sposteranno probabilmente in un campo delle dipendenze in zero.json. Consideralo una funzionalità futura, non qualcosa su cui scrivere script oggi.
Prossimo passo: le basi del linguaggio
Ora hai tutto ciò che ti serve per organizzare un vero progetto Zero. Il prossimo capitolo si concentra sul linguaggio stesso, a partire dai binding let, cioè da come i valori di Zero ricevono un nome.
Domande frequenti
Cos'è un pacchetto Zero?
Un pacchetto Zero è una cartella che contiene un manifest zero.json e una cartella src/ con i file sorgente .0. Il manifest dichiara il nome del pacchetto, la versione e uno o più 'target': ogni target dice al compilatore come costruire qualcosa (un eseguibile, una libreria, un binario di test) a partire dal sorgente.
Come creo un nuovo pacchetto Zero?
Esegui zero new <template> <name>, per esempio zero new cli hello. La CLI crea una cartella con un zero.json, un src/main.0 e tutti gli altri file richiesti dal template scelto. Da lì puoi usare zero check, zero run e zero build dentro il pacchetto.
Cosa contiene zero.json?
zero.json?Come minimo, un oggetto package con name e version, più un oggetto targets che descrive ogni cosa che il pacchetto costruisce. Un target ha un kind (come exe per un eseguibile) e un main che punta al file sorgente di ingresso. Puoi dichiarare più target in un solo manifest.
Un singolo pacchetto Zero può avere più target?
Sì. Un pacchetto può dichiarare un numero qualsiasi di target, per esempio un target exe per una CLI, un target lib per una libreria riutilizzabile e uno o più target di test. Ogni target ha il proprio punto di ingresso in src/, e puoi compilarli o eseguirli singolarmente dalla CLI.
Dove mette il compilatore l'output della build?
Gli artefatti della build finiscono in una cartella di build dentro il pacchetto (il percorso esatto dipende dall'implementazione e potrebbe cambiare finché Zero è pre-1.0). L'albero dei sorgenti in src/ non viene mai modificato. Considera la cartella di build usa e getta: aggiungerla a git è una cattiva idea.