Зачем пакеты
Одного файла .0 достаточно, когда учите язык или пробуете фрагмент. Как только ваш проект перерастает один файл, нужен пакет — каталог с манифестом и известным layout, который понимает тулчейн.
Польза от перехода с россыпи файлов к пакету:
- Одно каноничное место для имени, версии и метаданных проекта.
- Несколько точек входа (исполняемый, библиотека, тесты) в одном дереве.
- Предсказуемый layout: инструменты находят ваш исходник без конфигурации.
zero check/zero buildпо всему дереву, а не файл за файлом.
Скаффолдинг пакета
Самый быстрый способ начать — zero new:
zero new cli hello
Создаёт каталог hello/ с такой структурой:
hello/
├── zero.json
└── src/
└── main.0
cli — это имя шаблона; он производит исполняемую CLI-программу. Другие шаблоны (библиотека, системная программа) следуют той же форме с другими дефолтами.
cd в новый каталог, запустите — и поехали:
cd hello
zero run
Когда вы дёргаете zero run из каталога пакета без имени файла, она подбирает цель по умолчанию из zero.json и запускает её.
Манифест zero.json
Манифест из скаффолдинга пакета cli выглядит так:
{
"package": { "name": "hello", "version": "0.1.0" },
"targets": { "cli": { "kind": "exe", "main": "src/main.0" } }
}
Два ключа верхнего уровня: package и targets. Первый идентифицирует пакет, второй говорит компилятору, что собирать.
package
"package": {
"name": "hello",
"version": "0.1.0"
}
name— slug, идентифицирующий пакет. Используйте нижний регистр и дефисы.version— semver-строка. Пакеты pre-1.0 используют0.x.y.
Другие поля метаданных (описание, автор, лицензия, репозиторий), возможно, поддерживаются — обратитесь к актуальной документации Zero за авторитетной схемой, так как манифест ещё эволюционирует.
targets
"targets": {
"cli": { "kind": "exe", "main": "src/main.0" }
}
Ключи (cli здесь) — это имена целей, которые вы выбираете. Значения описывают каждую цель:
kind— что это за цель.exeдля исполняемого. Другие виды (библиотека, тест) следуют той же форме.main— файл-точка входа, относительно корня пакета.
В одном пакете можно объявить больше одной цели:
{
"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" }
}
}
Соберите конкретную цель из CLI по имени:
zero build convert
zero run resize
Каталог src/
Все исходные файлы живут под src/. Компилятор автоматически обходит этот каталог — каждый файл в манифесте не перечисляют. Поле main каждой цели указывает на её файл-точку входа; компилятор идёт по импортам оттуда, чтобы найти всё остальное.
Пакет с несколькими вспомогательными модулями может выглядеть так:
image-tools/
├── zero.json
└── src/
├── convert.0
├── resize.0
├── lib.0
└── internal/
├── decoder.0
└── encoder.0
Подкаталог internal/ — это просто соглашение, ничего в манифесте эти файлы не называет. Импорты внутри convert.0 достают internal/decoder.0 напрямую.
Сборка и запуск
Частые рабочие схемы внутри пакета:
zero check # проверить типы по всему дереву
zero run # собрать и запустить цель по умолчанию
zero run convert # собрать и запустить именованную цель
zero build # собрать цель по умолчанию
zero build --all # собрать каждую цель (когда поддержано)
zero test # запустить каждую тестовую цель
CLI читает zero.json, понимает, что делать, и делает. Внутри пакета пути почти не приходится прописывать.
Несколько файлов исходника: короткий пример
Допустим, src/main.0 вызывает помощник из src/math.0. Файл-помощник:
pub fun double(value: i32) -> i32 {
return value * 2
}
Файл-точка входа:
pub fun main(world: World) -> Void raises {
let result = double(21)
if result == 42 {
check world.out.write("forty two\n")
}
}
Запустите через zero run. Компилятор разрешает ссылку на double против остального дерева исходников без явного объявления импорта в таком простом случае. По мере роста пакетов система явных импортов обрабатывает межмодульную видимость — обратитесь к актуальной документации Zero за синтаксисом импортов, это одна из областей, которая, скорее всего, изменится до 1.0.
Что не коммитить в git
.gitignore для пакета Zero обычно хочет:
# артефакты сборки и кэши
/build/
/target/
# мусор от редактора
.DS_Store
*.swp
Точное имя каталога вывода сборки может отличаться — сверьтесь с актуальной документацией тулчейна — но правило такое: исходник внутри, артефакты сборки снаружи.
Шеринг пакетов
Zero — pre-1.0, и реестр пакетов пока не часть стабильной поверхности. Сегодня практичные способы поделиться пакетом:
- Git: клонируйте репозиторий и запустите
zero checkв нём. - Вендоринг: положите копию исходников в другой проект.
Когда появится реестр, ссылки на пакеты, скорее всего, переедут в поле зависимостей в zero.json. Считайте это форвард-смотрящей фичей, а не тем, под что сегодня стоит писать скрипты.
Дальше: основы языка
Теперь у вас есть всё необходимое, чтобы организовать настоящий проект Zero. Следующая глава приближается к самому языку, начиная с let-привязок — как значения в Zero получают имена.
Часто задаваемые вопросы
Что такое пакет Zero?
Пакет Zero — это каталог с манифестом zero.json и папкой src/ с файлами .0. Манифест объявляет имя пакета, версию и одну или больше «целей» — каждая цель говорит компилятору, как собрать что-то (исполняемый, библиотеку, тестовый бинарник) из исходников.
Как создать новый пакет Zero?
Запустите zero new <template> <name>, например zero new cli hello. CLI скаффолдит каталог с zero.json, src/main.0 и любыми другими файлами, которые нужны выбранному шаблону. Дальше внутри пакета можно zero check, zero run и zero build.
Что содержит zero.json?
zero.json?Как минимум объект package с name и version, плюс объект targets, описывающий каждую вещь, которую собирает пакет. У цели есть kind (например, exe для исполняемого) и main, указывающий на файл-точку входа. В одном манифесте можно объявить несколько целей.
Может ли один пакет Zero иметь несколько целей?
Да. Пакет может объявлять любое число целей — например, одну exe-цель для CLI, одну lib-цель для переиспользуемой библиотеки и одну или несколько тестовых целей. У каждой цели своя точка входа в src/, и собирать или запускать их можно по отдельности из CLI.
Куда компилятор кладёт результаты сборки?
Артефакты сборки оказываются в build-каталоге внутри пакета (точный путь — реализационно-зависимый и может меняться, пока Zero pre-1.0). Дерево src/ никогда не изменяется. Считайте build-каталог расходным — коммитить его в git плохая идея.