Установка пакетов данных: init и pack
Имена, города, регионы, компании и прочие списки — это пакеты данных.
Они поставляются отдельно от движка, так что обновление библиотеки никогда не затирает
ваши данные, а тяжёлые наборы не раздувают каждую установку. С пакетом из коробки едет
разумный набор по умолчанию (например, топ-1000 имён); полные и дополнительные наборы
докачиваются командой tdcv2 pack.
Весь процесс — это две команды:
- Один раз
tdcv2 init— настроить, куда класть данные и какая локаль по умолчанию. tdcv2 pack add …— скачать те наборы, которые вам действительно нужны.
init идёт первым, потому что отвечает на вопрос, который pack решить не может: какая
папка — ваша. Пакеты сознательно не лежат внутри установленной библиотеки: иначе каждое
npm update, pip install -U или обновление зависимости стирало бы гигабайт данных,
которые вы выбрали. init записывает папку, принадлежащую вашему проекту, и этот файл
читают все реализации, поэтому пакет, скачанный один раз, находят все.
Пропустите init — и pack будет некуда класть данные; он об этом скажет, а не станет
гадать:
tdcv2: no pack store configured — run `tdcv2 init` first
init и pack есть в каждой реализации, а не только в Node. Команды, их вывод и файл
конфигурации, который они пишут, одинаковы — это удерживает общая тестовая фикстура, по
которой все пять сверяются с одними и теми же байтами. Отличается лишь то, как получить
саму команду и как её написать:
| Ваш язык | Как получить команду | Как вызвать |
|---|---|---|
| Node.js | никак — npx скачает сам | npx tdcv2 pack add ru |
| Python | pip install tdcv2 | tdcv2 pack add ru |
| Rust | cargo install tdcv2 | tdcv2 pack add ru |
| C# | dotnet tool install --global Tdcv2.Cli | tdcv2 pack add ru |
| Java | скачать tdcv2-0.1.7-cli.jar с Maven Central | java -jar tdcv2-0.1.7-cli.jar pack add ru |
Три из них кладут команду tdcv2 в PATH, и дальше читаются одинаково. Node не требует
установки вообще — npx скачивает и запускает одним действием. Java выбивается потому,
что у Maven нет аналога npm-овского bin: добавление библиотеки в проект не может
положить команду в PATH, поэтому командная строка — это jar, который вы запускаете сами:
curl -LO https://repo1.maven.org/maven2/io/github/nickliapin/tdcv2/0.1.7/tdcv2-0.1.7-cli.jar
java -jar tdcv2-0.1.7-cli.jar pack add ru
Стоит завести алиас — alias tdcv2='java -jar /путь/к/tdcv2-0.1.7-cli.jar' — после этого
все команды на этой странице читаются так же, как везде.
Проект, настроенный одной реализацией, готов для остальных четырёх — тот же конфиг, то же
хранилище, тот же реестр. Поставить ru через Python и генерировать из него в Rust — это
не особый случай, а обычный.
Примеры вывода ниже иллюстративные — точное число файлов, размеры и пути зависят от вашей машины и версии ядра, но общий вид сохраняется.
tdcv2 init — настроить проект
init пишет файл конфигурации, чтобы вам никогда не приходилось править JSON руками. В
интерактивном терминале запускается короткий мастер (где хранить конфиг, куда качать пакеты,
какая локаль по умолчанию). В скрипте или CI передавайте флаги, чтобы ничего не зависало на
вопросе.
tdcv2 init # спросит и запишет
Wrote project config: /path/to/project/tdcv2.config.json data packs → /path/to/project/tdcv2-packs locale → en Next: run `tdcv2 pack` to download data packs into that folder.
Используйте один раз на проект, перед первым tdcv2 pack add. Каждый флаг ниже покрывает
случай, где мастер только мешал бы.
--yes / -y — без вопросов
Пропускает все вопросы и принимает значения по умолчанию (проектный конфиг, ./tdcv2-packs,
en). Это флаг для CI и скриптов, где отвечать мастеру некому.
tdcv2 init --yes
Wrote project config: /path/to/project/tdcv2.config.json data packs → /path/to/project/tdcv2-packs locale → en
--global / -g — один конфиг на все проекты
Пишет конфиг в домашнюю область (~/.config/tdcv2), а не в текущую папку. Пригодится, когда
вы хотите одно общее хранилище данных, из которого читают все проекты на машине, вместо папки
tdcv2-packs в каждом репозитории.
tdcv2 init --global
Wrote global config: /Users/you/.config/tdcv2/config.json data packs → /Users/you/.config/tdcv2/packs locale → en
--force / -f — перезаписать существующий конфиг
По умолчанию init отказывается затирать конфиг, который уже есть. Передайте --force, когда
вы намеренно хотите его сбросить — например, чтобы сменить папку пакетов или начать с чистого
листа.
Config already exists: /path/to/project/tdcv2.config.json Nothing written. Re-run with --force to overwrite.
--locale <loc> — выбрать локаль по умолчанию
Задаёт значение locale в конфиге, чтобы не указывать локаль при каждой генерации. en —
встроенное значение по умолчанию; передайте другой код, чтобы сделать его локалью проекта.
tdcv2 init --yes --locale ru
--data-path <dir> — выбрать папку пакетов
Задаёт, куда pack add качает данные (это packStore, см. ниже). Укажите общий диск или путь
вне репозитория, когда не хотите, чтобы пакеты лежали рядом с исходниками.
tdcv2 init --yes --data-path ../shared-tdc-packs
Файл tdcv2.config.json
init пишет вот такой небольшой файл:
{
"packStore": "./tdcv2-packs",
"locale": "ru"
}
packStore— кудаpackкачает пакеты. Каждый набор ложится в эту одну папку, а первыйpack addпрописывает саму папку вdataPaths. Как она устроена, описано в разделе «Внутри хранилища пакетов» ниже.locale— локаль по умолчанию (задаётся флагом--locale, см. выше).dataPaths— папки, которые движок реально сканирует в поисках пакетов.pack addвписывает туда хранилище за вас, а вы можете дописать сюда свои папки, чтобы указать движку на пакеты, написанные вами самими.
Конфиг ищется обходом вверх от текущей папки (так же, как инструменты находят
tsconfig.json). Когда одно и то же определено в нескольких источниках, приоритет идёт от
низшего к высшему:
встроенные пакеты < общий конфиг (~/.config/tdcv2) < проектный tdcv2.config.json < флаг --data-path
Пути внутри файла разрешаются относительно самого файла, а не относительно текущей рабочей папки — так что конфиг может переезжать вместе со своим проектом.
tdcv2 pack — скачать и удалить наборы
Без аргументов в терминале pack открывает меню выбора, а не вываливает на вас
каталог. 108 наборов на экран не помещаются, поэтому их листают так, как они устроены:
- Всё или выбрать нужное — первый вопрос, до всего остального.
- Языки — одним списком; страны — через континент, с карты.
/ищет из любого места: наберитеbraz, и Бразилия уже здесь, с пометкой континента.- space отмечает, а на континенте берёт весь континент сразу.
- backspace, esc или ← — шаг назад с любого экрана.
- Обзор перечисляет корзину и её общий размер; space убирает то, что вы передумали брать, enter применяет. До этого не качается ничего.
Карта показывает, что уже набрано: континент под курсором подсвечивается, а каждая выбранная страна зажигает искру там, где она и находится. m переключает между голыми береговыми линиями и залитой сушей.
Меню выбора во всех реализациях одно и то же, а как его рисовать, решает терминал:
полублоки и цвет там, где они есть, ASCII и простой контур там, где их нет (старая
консоль Windows, пайп, NO_COLOR). Меню в Java и Rust требует stty и поэтому работает
только на Unix; в Windows они вместо этого печатают список — Node, Python и C# так делать
не приходится, потому что их среды читают нажатие клавиши сами.
В скрипте — и вообще там, где терминала нет, — управляйте им подкомандами:
tdcv2 pack list # что есть в реестре
tdcv2 pack add ru common # скачать и подключить
tdcv2 pack remove common # удалить
Любая подкоманда принимает ещё и --registry <базовый-url> — он направляет pack
на другой каталог вместо публичного. По умолчанию берётся собственный реестр проекта:
tdcv2 pack list --registry https://packs.example.internal/tdc
tdcv2 pack add ru --registry=https://packs.example.internal/tdc
Пригодится для зеркала внутри компании или копии в изолированном контуре. URL здесь
базовый — пути к индексу и архивам pack добавляет сам, — а хвостовой слеш
игнорируется. Проверка sha256 при этом остаётся: зеркало, отдающее изменённые байты,
не установится ровно так же, как не установился бы публичный реестр.
pack list — посмотреть каталог
Печатает реестр и помечает то, что уже установлено, с размером загрузки каждого набора.
Available data packs: common Common (locale-agnostic) (0.0 MB) Generators bound to neither a language nor a country: uuid, hashes, ISBN/ISSN, GTIN/UPC/EAN, card PANs, MRZ, IPv4/IPv6/MAC, semver, and more. ru ✓ installed Russian (language) (0.1 MB) Content bound to the Russian language: given names, gendered surnames and patronymics, gender words, months and weekdays, colors, country names. Shared by every Russian-speaking locale. … yemen Yemen (country) (0.0 MB) Data specific to Yemen: docs, education, finance, geo, holiday, phone, sport. Install with: tdcv2 pack add <id>
Описания переносятся по ширине вашего окна, так что список остаётся списком, каким бы узким ни был терминал. В пайпе или при перенаправлении окна для замера нет, и все пять реализаций берут 80 колонок — поэтому сохранённый листинг выходит одним и тем же файлом, какая бы из них его ни писала.
В каталоге сегодня 108 наборов: common, десять языков и 97 стран. Языка или страны,
которых в списке нет, ещё не доделали: запись в каталоге — это обещание, что каждый адрес
под ней разрешается, поэтому папка с одним файлом такой записи не получает.
Пригодится, чтобы проверить, что нужно адресу перед генерацией, и подтвердить, что набор встал
после pack add.
pack add <id…> — скачать и зарегистрировать
pack add качает zip набора, сверяет его sha256 (подменённая или битая загрузка не
установится), распаковывает его в хранилище пакетов и прописывает это хранилище в
конфиг, так что данные сразу доступны по своим адресам через точку — без отдельного шага
подключения.
tdcv2 pack add ru
Installed ru: 355 files → /path/to/project/tdcv2-packs/ru registered ./tdcv2-packs in /path/to/project/tdcv2.config.json
Хранилище прописывается один раз, при первой установке. Следующие наборы ложатся в ту же
папку и сообщают already registered.
Можно установить несколько наборов за один вызов — tdcv2 pack add common ru russia — это
обычный способ собрать локаль (см. раздел «Пакеты осевые» ниже).
pack remove <id…> — удалить и отменить регистрацию
pack remove удаляет ровно те пути, которые принёс этот набор, и ничего рядом с ними.
Папка, опустевшая после удаления, уходит следом.
tdcv2 pack remove russia
Removed russia (/path/to/project/tdcv2-packs/countries/russia)
Хранилище остаётся в dataPaths, пока в нём что-то лежит: одна эта запись обслуживает все
наборы сразу. Уберите последний набор — уйдёт и запись:
Removed common (/path/to/project/tdcv2-packs/common) Removed ru (/path/to/project/tdcv2-packs/ru) store now empty — unregistered /path/to/project/tdcv2-packs from /path/to/project/tdcv2.config.json
Удаление набора безопасно: встроенный набор по умолчанию (см. раздел «Встроенный набор по умолчанию против докачки») по этим адресам возвращается сам собой.
Внутри хранилища пакетов
Каждый набор распаковывается в одну папку, которую называет packStore. Язык ложится
под своим кодом, страна — в countries/, а common — под своим именем:
tdcv2-packs/
├── .tdcv2-installed.json
├── common/…
├── ru/…
└── countries/russia/…
Эта папка — единственный корень сканирования, поэтому в конфиге одна запись dataPaths,
сколько бы наборов вы ни поставили:
{
"packStore": "./tdcv2-packs",
"locale": "ru",
"dataPaths": ["./tdcv2-packs"]
}
.tdcv2-installed.json — служебный учёт самого хранилища, править его руками не нужно. По
каждому набору там записаны пути, которыми он владеет, число принесённых файлов, sha256,
по которому сверялась загрузка, и версия, если реестр её публикует. Именно из этого файла
pack remove узнаёт, что удалять, а pack list — что пометить как ✓ installed.
Хранилище от предыдущей версии
Прежние версии распаковывали каждый набор в <store>/<id>/packs/… и давали ему отдельную
запись в dataPaths. На диске это давало три почти одинаковых уровня, а в конфиге — по
записи на набор: сотня пакетов стран означала сотню записей.
Первая же команда tdcv2 pack — любая из них — переносит такое хранилище к раскладке
выше, прямо на месте. Скачивать заново ничего не нужно. Сообщение уходит в stderr:
tdcv2: pack store "/path/to/project/tdcv2-packs" used the old per-bundle layout; moved it to the flat one. ru: ru/packs → ru (355 files) russia: russia/packs → countries/russia (18 files) dropped 2 per-bundle dataPaths entries registered ./tdcv2-packs instead
Все перемещения планируются до того, как что-то сдвинется. Если путь в новой раскладке уже занят, перенос отклоняется целиком, а конфликты называются поимённо — вместо того чтобы оставить хранилище наполовину в одной раскладке, наполовину в другой.
Пакеты осевые
Пакеты организованы по одной оси — язык, страна или локаль-независимый набор common — и
они компонуются. Данные для России по-русски — это не один монолитный пакет, а три слоя
друг на друге:
tdcv2 pack add common ru russia
Installed common: 145 files → /path/to/project/tdcv2-packs/common registered ./tdcv2-packs in /path/to/project/tdcv2.config.json Installed ru: 355 files → /path/to/project/tdcv2-packs/ru already registered in /path/to/project/tdcv2.config.json Installed russia: 18 files → /path/to/project/tdcv2-packs/countries/russia already registered in /path/to/project/tdcv2.config.json
В хранилище остаются три папки под одной записью dataPaths, которая покрывает их все, —
см. раздел «Внутри хранилища пакетов» выше.
Это не причуда формата файлов — так отражается, что язык и страна действительно независимы.
Русский язык общий для России, Беларуси и Казахстана, поэтому он качается один раз как ru; а
данные, специфичные для страны (регионы России, телефонные коды), лежат в russia. Смешивайте
и сочетайте, чтобы собрать любую нужную локаль.
Встроенный набор по умолчанию против докачки
Встроенный набор по умолчанию (едет внутри пакета) — это самый нижний слой, и он всегда на месте. Скачанный набор кладётся сверху и затеняет те же адреса, ничего не удаляя под собой. Отсюда два следствия:
- ставите полный набор → он перекрывает дефолтный по этим адресам;
pack remove→ дефолтный сам возвращается. Дыры в данных не будет.
То есть и докачка, и удаление безопасны: базовый набор на самом деле никогда не удаляется, только временно затеняется, пока над ним лежит более богатый набор.
Откуда берётся базовый слой
Этот базовый слой ищется тремя вопросами по порядку — одними и теми же, в одном и том же порядке, во всех пяти реализациях:
| Порядок | Где | Когда отвечает |
|---|---|---|
| 1 | TDCV2_PACKS, если это папка | Вы её задали — значит, она главнее всего остального |
| 2 | Чекаут исходников TDC | Только если сам TDC собран из исходников |
| 3 | Набор внутри установленного пакета | Обычный случай — именно так работает установленный пакет |
Шаг 2 нужен тем, кто работает над самим TDC: внутри чекаута все пять реализаций читают
data/packs из репозитория, то есть видят одну копию данных, а не пять, которые могут
разъехаться. Для установленного пакета этот шаг сработать не может, и он намеренно не
соглашается на любую папку с именем data/packs — папка должна быть узнаваемо репозиторием
TDC, чтобы ваша собственная папка с таким же именем случайно не подхватилась.
TDCV2_PACKS — это способ указать всем пяти реализациям на одну папку, ничего не правя
в конфигах:
TDCV2_PACKS=/srv/shared-packs tdcv2 users.tdc
Всё, что называют tdcv2.config.json и --data-path, кладётся поверх этого ответа,
а не вместо него.
Смотрите также
- Обзор пакетов данных — что такое пакет и как работают адреса через точку.
- Свой пакет данных — формат файлов пакета и правила адресации.
- Справочник по CLI — полный справочник командной строки.