Menu

Paquetes de Zero: zero.json, src/ y destinos explicados

Cómo se organiza un paquete de Zero: el manifest zero.json, el directorio src/ y el sistema de destinos que permite a un mismo paquete producir ejecutables, bibliotecas y tests desde el mismo árbol de fuentes.

Por qué paquetes

Un único archivo .0 está bien cuando estás aprendiendo el lenguaje o probando un snippet. En cuanto tu proyecto crece más allá de un archivo, vas a querer un paquete: un directorio con un manifest y un layout conocido que la cadena de herramientas entienda.

Los beneficios de pasar de archivos sueltos a un paquete:

  • Un sitio canónico para el nombre, la versión y los metadatos del proyecto.
  • Varios puntos de entrada (ejecutable, biblioteca, tests) en un mismo árbol.
  • Layout predecible: las herramientas encuentran tu código sin configuración.
  • Un zero check / zero build sobre todo el árbol, no archivo por archivo.

Crear un paquete

La forma más rápida de empezar es zero new:

zero new cli hello

Eso crea un directorio hello/ con la siguiente forma:

hello/
├── zero.json
└── src/
    └── main.0

cli es el nombre de la plantilla: produce un programa de línea de comandos ejecutable. Otras plantillas (biblioteca, programa de sistema) siguen la misma forma con valores por defecto distintos.

Entra (cd) al nuevo directorio, ejecútalo y listo:

cd hello
zero run

Cuando invocas zero run desde dentro de un directorio de paquete sin nombrar un archivo, el comando coge el destino por defecto de zero.json y lo ejecuta.

El manifest zero.json

El manifest de un paquete cli recién creado tiene esta pinta:

{
    "package": { "name": "hello", "version": "0.1.0" },
    "targets": { "cli": { "kind": "exe", "main": "src/main.0" } }
}

Dos claves de nivel superior: package y targets. La primera identifica el paquete; la segunda le dice al compilador qué construir.

package

"package": {
    "name": "hello",
    "version": "0.1.0"
}
  • name — un slug que identifica al paquete. Usa minúsculas y guiones.
  • version — cadena semver. Los paquetes pre-1.0 usan 0.x.y.

Es posible que se admitan otros campos de metadatos (descripción, autor, licencia, repositorio): consulta la documentación actual de Zero para el esquema autoritativo, ya que el manifest sigue evolucionando.

targets

"targets": {
    "cli": { "kind": "exe", "main": "src/main.0" }
}

Las claves (cli aquí) son nombres de destino que eliges tú. Los valores describen cada destino:

  • kind — qué es el destino. exe para un ejecutable. Otros tipos (biblioteca, test) siguen la misma forma.
  • main — el archivo fuente de entrada, relativo a la raíz del paquete.

Puedes declarar más de un destino en el mismo paquete:

{
    "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" }
    }
}

Construye un destino específico desde la CLI nombrándolo:

zero build convert
zero run resize

El directorio src/

Todo el código fuente vive bajo src/. El compilador recorre este directorio automáticamente: no listas cada archivo en el manifest. El campo main de cada destino apunta a su archivo de entrada; el compilador sigue los imports desde ahí para encontrar todo lo demás que necesite.

Un paquete con un par de módulos auxiliares podría verse así:

image-tools/
├── zero.json
└── src/
    ├── convert.0
    ├── resize.0
    ├── lib.0
    └── internal/
        ├── decoder.0
        └── encoder.0

El subdirectorio internal/ es solo una convención: nada en el manifest nombra esos archivos. Los imports dentro de convert.0 alcanzan internal/decoder.0 directamente.

Compilar y ejecutar

Flujos habituales una vez que estás dentro de un paquete:

zero check        # chequea tipos en todo el árbol
zero run          # compila y ejecuta el destino por defecto
zero run convert  # compila y ejecuta un destino concreto
zero build        # compila el destino por defecto
zero build --all  # compila cada destino (cuando esté soportado)
zero test         # ejecuta cada destino de test

La CLI lee zero.json, deduce qué hacer y va. Una vez dentro de un paquete rara vez tienes que deletrear rutas.

Varios archivos fuente: un ejemplo rápido

Supongamos que src/main.0 llama a un helper en src/math.0. El archivo helper:

pub fun double(value: i32) -> i32 {
    return value * 2
}

El archivo de entrada:

pub fun main(world: World) -> Void raises {
    let result = double(21)
    if result == 42 {
        check world.out.write("cuarenta y dos\n")
    }
}

Ejecútalo con zero run. El compilador resuelve la referencia a double contra el resto del árbol de fuentes sin necesidad de una declaración explícita de import en este caso simple. A medida que los paquetes crecen, un sistema explícito de imports gestiona la visibilidad entre módulos: consulta la documentación actual de Zero para la sintaxis de imports, que es una de las áreas con más probabilidad de cambiar antes de la 1.0.

Qué no debe ir en git

Un .gitignore para un paquete de Zero suele querer:

# artefactos y cachés de build
/build/
/target/

# basura del editor
.DS_Store
*.swp

El nombre exacto del directorio de salida puede variar — revisa la documentación actual del toolchain — pero la regla es: el código entra, los artefactos de build se quedan fuera.

Compartir paquetes

Zero es pre-1.0 y un registro de paquetes todavía no forma parte de la superficie estable. De momento, las formas prácticas de compartir un paquete son:

  • Git: clona el repo y ejecuta zero check contra él.
  • Copia incorporada: deja una copia del código en otro proyecto.

Cuando llegue el registro, las referencias a paquetes probablemente pasen a un campo de dependencias en zero.json. Trátalo como una funcionalidad futura, no como algo sobre lo que escribir scripts hoy.

Lo siguiente: lo básico del lenguaje

Ya tienes todo lo que necesitas para organizar un proyecto real de Zero. El próximo capítulo se centra en el lenguaje en sí, empezando por las ligaduras let — cómo los valores reciben un nombre en Zero.

Preguntas frecuentes

¿Qué es un paquete de Zero?

Un paquete de Zero es un directorio que contiene un manifest zero.json y una carpeta src/ con archivos fuente .0. El manifest declara el nombre, la versión y uno o varios 'destinos' (targets) del paquete — cada destino le dice al compilador cómo construir algo (un ejecutable, una biblioteca, un binario de test) a partir del código.

¿Cómo creo un nuevo paquete de Zero?

Ejecuta zero new <plantilla> <nombre>, por ejemplo zero new cli hello. La CLI genera un directorio con un zero.json, un src/main.0 y cualquier otro archivo que necesite la plantilla elegida. Desde ahí puedes ejecutar zero check, zero run y zero build dentro del paquete.

¿Qué contiene zero.json?

Como mínimo, un objeto package con name y version, más un objeto targets que describe cada cosa que el paquete construye. Un destino tiene un kind (como exe para un ejecutable) y un main que apunta al archivo fuente de entrada. Puedes declarar varios destinos en un mismo manifest.

¿Puede un paquete de Zero tener varios destinos?

Sí. Un paquete puede declarar cualquier número de destinos — por ejemplo, un destino exe para una CLI, un destino lib para una biblioteca reutilizable y uno o varios destinos de test. Cada destino tiene su propio punto de entrada bajo src/, y puedes construirlos o ejecutarlos individualmente desde la CLI.

¿Dónde pone el compilador la salida de build?

Los artefactos de build aterrizan en un directorio de build dentro del paquete (la ruta exacta es decisión de la implementación y puede cambiar mientras Zero sea pre-1.0). El árbol de fuentes bajo src/ nunca se modifica. Trata el directorio de build como desechable: meterlo en git es mala idea.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR