Menu

Pacchetti Zero: zero.json, src/ e target spiegati

Com'è organizzato un pacchetto Zero: il manifest zero.json, la cartella src/ e il sistema dei target, che permette a un solo pacchetto di produrre eseguibili, librerie e test dallo stesso albero di sorgenti.

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 build sull'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 usano 0.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. exe per 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 check su 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?

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.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA