From f3639cc7ee3383d3f7b3947094c192afb4ef20cb Mon Sep 17 00:00:00 2001 From: Khasbulat Abdullin Date: Wed, 7 Oct 2026 20:46:41 +0300 Subject: [PATCH 1/3] docs: explain metadata-free roots and Git input migration --- content/docs/cli/package-manager/index.mdx | 24 +++++++++++++++ content/docs/cli/package-manager/index.ru.mdx | 24 +++++++++++++++ content/docs/migration/easyp-v0.mdx | 30 ++++++++++++++++++- content/docs/migration/easyp-v0.ru.mdx | 30 ++++++++++++++++++- content/docs/reference/protobuf-lock.mdx | 8 ++++- content/docs/reference/protobuf-lock.ru.mdx | 8 ++++- 6 files changed, 120 insertions(+), 4 deletions(-) diff --git a/content/docs/cli/package-manager/index.mdx b/content/docs/cli/package-manager/index.mdx index 08c2381..e0e5a82 100644 --- a/content/docs/cli/package-manager/index.mdx +++ b/content/docs/cli/package-manager/index.mdx @@ -33,6 +33,30 @@ Module commands and get find the nearest ancestor protobuf.mo Major versions use Go-style identities: v0/v1 are unsuffixed; v2+ requires matching /vN. The +incompatible exception requires verified pre-native metadata; it never bypasses a native manifest. See [exact grammar and Git mapping](/docs/reference/protobuf-mod). +## Dependencies without import-root metadata + +Roots normally come from the pinned dependency's `protobuf.mod`, Buf or legacy EasyP config. A native manifest with omitted roots still declares `.`. Invalid metadata is an error. + +For an already declared dependency without root metadata, resolution can identify roots from a unique match between imports and tracked proto files. `import "svc.proto"` can match `api/svc/v1/svc.proto` under root `api/svc/v1`. Ambiguous layouts require an explicit hint: + +~~~bash +easyp get --import-root api/svc/v1 gitlab/products/svc +~~~ + +Repeat `--import-root` for multiple module-relative directories. Hints must remain inside the external module and agree with authoritative roots. Verified fallback roots are recorded in the dependency's `protobuf.lock` entry. Frozen and cold-cache operations replay that choice; resolution failures leave the manifest and lock unchanged. + +To generate the required dependency, select its identity in `easyp.gen.yaml`: + +~~~yaml +version: v1 +generate: + modules: + - gitlab/products/svc +plugins: [] +~~~ + +Resolved roots determine protobuf filenames. Module-local `paths` and `packages` restrict generation; paths refer to the external module directory. Add your local module to `modules` when both should generate. Root selection does not rewrite source imports or require a generation filter repeating the root. + ## Commands | Command | Behavior | diff --git a/content/docs/cli/package-manager/index.ru.mdx b/content/docs/cli/package-manager/index.ru.mdx index de14f1a..0356bc9 100644 --- a/content/docs/cli/package-manager/index.ru.mdx +++ b/content/docs/cli/package-manager/index.ru.mdx @@ -33,6 +33,30 @@ require ( Мажорные версии используют идентичность как в Go: v0/v1 — без суффикса, v2+ — с соответствующим /vN. Исключение +incompatible требует проверки домодульных метаданных и не обходит нативный manifest. См. [точную грамматику и Git mapping](/ru/docs/reference/protobuf-mod). +## Зависимости без метаданных корней импортов + +Обычно roots берутся из закреплённого `protobuf.mod`, Buf или legacy-конфига EasyP зависимости. Native-манифест без явного roots всё равно задаёт корень `.`. Некорректные метаданные вызывают ошибку. + +Для уже объявленной зависимости без метаданных корней резолвер может определить roots по однозначному соответствию импортов отслеживаемым proto-файлам. `import "svc.proto"` соответствует `api/svc/v1/svc.proto` при корне `api/svc/v1`. Неоднозначные варианты требуют явной подсказки: + +~~~bash +easyp get --import-root api/svc/v1 gitlab/products/svc +~~~ + +Для нескольких каталогов модуля повторите `--import-root`. Подсказки должны оставаться внутри внешнего модуля и согласовываться с корнями из его метаданных. Проверенные fallback-корни записываются в запись зависимости в `protobuf.lock`. Frozen и холодный кеш используют этот выбор; ошибки оставляют manifest и lock неизменными. + +Для генерации объявленной зависимости укажите её идентификатор в `easyp.gen.yaml`: + +~~~yaml +version: v1 +generate: + modules: + - gitlab/products/svc +plugins: [] +~~~ + +Разрешённые roots определяют protobuf-имена файлов. Module-local `paths` и `packages` ограничивают генерацию; paths считаются от каталога внешнего модуля. Для совместной генерации добавьте в `modules` и свой локальный модуль. Выбор корней не переписывает исходные импорты и не требует повторять root в фильтре генерации. + ## Команды | Команда | Поведение | diff --git a/content/docs/migration/easyp-v0.mdx b/content/docs/migration/easyp-v0.mdx index daee670..7a2b6d7 100644 --- a/content/docs/migration/easyp-v0.mdx +++ b/content/docs/migration/easyp-v0.mdx @@ -53,6 +53,34 @@ The converter preserves the effective selected lint rules, exceptions, rule sett Legacy direct and indirect requirements are converted to native require directives. The tool proves that local generation keeps the same protobuf files and import paths, using whole roots, literal generation paths or exact package selectors. +## Git inputs and custom roots + +Each `git_repo.url` becomes a `require` and a generation module selection, preserving its version and historical pin. `root` is an import-root resolution hint; `sub_directory` becomes a module-local generation path after verification. + +~~~yaml +generate: + inputs: + - git_repo: + url: gitlab/products/svc + root: api/svc/v1 + sub_directory: api/svc/v1/service +~~~ + +The initial preview accepts these selectors without dependency access. Authorized verification checks the pinned sources, historical hash and import-name mapping. Existing dependency roots retain priority. A metadata-free dependency can use the verified legacy root, recorded in `protobuf.lock`. Corrections appear in the verified preview; ambiguous or unrepresentable namespaces fail before files are written. + +The selected subtree can become: + +~~~yaml +version: v1 +generate: + modules: + - module: gitlab/products/svc + paths: [api/svc/v1/service] +plugins: [] +~~~ + +Paths are relative to the dependency module directory, while files keep import names such as `service/svc.proto` relative to root `api/svc/v1`. A plain module identity selects the full resolved module. Mixed local/Git inputs get separate module filters. + ## Keep default roots and source locations An omitted or empty legacy root means .. Native protobuf.mod has the same default when roots is omitted; there is no need to move proto files into a new directory. @@ -70,7 +98,7 @@ plugins: paths: source_relative ~~~ -Import roots stay unchanged and generated files keep their source-relative paths. The wizard first tries whole-root equality, then literal directory paths, then complete package selectors for mixed-root cases. Each choice must select exactly the same physical files with the same import names. Paths can preserve part of a package: ignored Gradle build copies outside `mcp` stay out of generation. Hidden/vendor/nested-module boundary changes and inferred local filters mixed with whole-module Git inputs remain blocked. Sources and fixed paths/packages are checked again before apply. +Import roots stay unchanged and generated files keep their source-relative paths. The wizard first tries whole-root equality, then literal directory paths, then complete package selectors for mixed-root cases. Each choice must select exactly the same physical files with the same import names. Paths can preserve part of a package: ignored Gradle build copies outside `mcp` stay out of generation. Hidden/vendor/nested-module boundary changes that cannot preserve the original selection remain blocked. Sources and fixed paths/packages are checked again before apply. `generate.paths` matches literal module-directory-relative files or directory subtrees, with `.` meaning all sources; `mcp` does not select `mcp-copy`. Paths intersect optional package selectors, and every selector must match a resulting source across the selected modules. Unknown selectors fail before plugins or descriptor writes, even without plugins or under `--all`. Required imports outside these paths remain available. These paths are separate from plugin `opts.paths`, which controls output layout. diff --git a/content/docs/migration/easyp-v0.ru.mdx b/content/docs/migration/easyp-v0.ru.mdx index 072d071..0d4e777 100644 --- a/content/docs/migration/easyp-v0.ru.mdx +++ b/content/docs/migration/easyp-v0.ru.mdx @@ -53,6 +53,34 @@ easyp migrate --dir . --module github.com/acme/contracts --resolve-lock --write Legacy-требования direct и indirect преобразуются в require. Мигратор доказывает, что локальная генерация сохраняет те же protobuf-файлы и import-пути, используя целые корни, буквальные пути генерации или точные selectors пакетов. +## Git inputs и custom roots + +Каждый `git_repo.url` переносится в `require` и выбор модуля для генерации с сохранением версии и исторического pin. `root` служит подсказкой для разрешения корня импортов; `sub_directory` после проверки становится module-local путём генерации. + +~~~yaml +generate: + inputs: + - git_repo: + url: gitlab/products/svc + root: api/svc/v1 + sub_directory: api/svc/v1/service +~~~ + +Начальный preview принимает эти selectors без доступа к зависимостям. После разрешения загрузки проверяются закреплённые исходники, исторический hash и соответствие имён импортов файлам. Корни из метаданных зависимости сохраняют приоритет. Для зависимости без метаданных проверенный legacy root записывается в `protobuf.lock`. Исправления отображаются в проверенном preview; неоднозначные или непредставимые пространства импортов отклоняются до записи файлов. + +Выбранное поддерево может стать: + +~~~yaml +version: v1 +generate: + modules: + - module: gitlab/products/svc + paths: [api/svc/v1/service] +plugins: [] +~~~ + +Paths считаются от каталога модуля зависимости, а файлы сохраняют import-имена вроде `service/svc.proto` относительно root `api/svc/v1`. Простой идентификатор модуля выбирает весь разрешённый модуль. Смешанные local/Git inputs получают отдельные фильтры модулей. + ## Сохранение корней по умолчанию и расположения исходников Пустой или отсутствующий legacy root означает .. В native protobuf.mod действует тот же корень по умолчанию, если roots не указан. Перемещать proto-файлы в новый каталог не требуется. @@ -70,7 +98,7 @@ plugins: paths: source_relative ~~~ -Корни импортов сохраняются, а сгенерированные файлы остаются по прежним source-relative путям. Мастер сначала проверяет совпадение целых корней, затем буквальные пути каталогов, затем selectors полных пакетов для смешанных корней. Каждый вариант должен выбирать точно те же физические файлы с теми же import-именами. Пути позволяют выбрать часть пакета: игнорируемые Gradle-копии вне `mcp` не становятся целями генерации. Изменение границ скрытых/vendor/вложенных модулей и сочетание выведенного локального фильтра с Git-input целого модуля отклоняются. Перед применением проверяются исходники и зафиксированные пути/пакеты. +Корни импортов сохраняются, а сгенерированные файлы остаются по прежним source-relative путям. Мастер сначала проверяет совпадение целых корней, затем буквальные пути каталогов, затем selectors полных пакетов для смешанных корней. Каждый вариант должен выбирать точно те же физические файлы с теми же import-именами. Пути позволяют выбрать часть пакета: игнорируемые Gradle-копии вне `mcp` не становятся целями генерации. Изменения границ скрытых/vendor/вложенных модулей, не сохраняющие исходную выборку, отклоняются. Перед применением проверяются исходники и зафиксированные пути/пакеты. `generate.paths` выбирает буквальные пути файлов от каталога модуля или поддеревьев каталогов; `.` означает все исходники, а `mcp` не совпадает с `mcp-copy`. Пути пересекаются с необязательными selectors пакетов. Каждый selector должен совпасть с итоговым исходником хотя бы в одном выбранном модуле. Неизвестные selectors отклоняются до запуска плагинов и записи descriptors, в том числе без плагинов или с `--all`. Необходимые импорты вне этих путей остаются доступными. Эти пути отличаются от plugin `opts.paths`, управляющего раскладкой результатов. diff --git a/content/docs/reference/protobuf-lock.mdx b/content/docs/reference/protobuf-lock.mdx index b52bc0a..1376d50 100644 --- a/content/docs/reference/protobuf-lock.mdx +++ b/content/docs/reference/protobuf-lock.mdx @@ -35,6 +35,10 @@ description: "Specification for protobuf.lock, the generated lockfile securing r "modules[].hash": { description: "Go dirhash.Hash1 digest (h1:...) of the materialized logical snapshot at the locked commit.", type: "string" + }, + "modules[].roots": { + description: "Optional verified fallback import-root directories relative to a metadata-free dependency module. Replayed on cold-cache and frozen operations; does not override authoritative dependency metadata.", + type: "string[]" } }} /> @@ -57,6 +61,8 @@ modules: ## Lifecycle commands +Resolved `roots` are canonical portable relative directories, with `.` allowed. Absolute paths, traversal, backslashes, globs and duplicates are rejected. These fields describe dependency resolution and are generated from unambiguous imports or checked `get --import-root`/migration hints. They are independent of generation `paths` and package selectors. + - easyp get adds a direct requirement, records transitive requirements as indirect, and updates the lock. - easyp mod tidy resolves declared requirements, updates indirect entries and the lock, and preserves an existing lock pin for a requirement that remains unconstrained. - easyp mod update refreshes SemVer dependencies within their current major versions, refreshes still-unconstrained requirements to HEAD, and preserves explicit commit pins. @@ -68,7 +74,7 @@ During tidy, get, and update, every fetch mod download uses the locked commit even after a tag moves, provided that commit remains available. -The hash uses Go's dirhash.Hash1 over the materialized logical snapshot at the commit, with repository-relative paths. Safe internal aliases contribute their resolved bytes under their logical names; Git objects are read directly, without checkout filters. Buf filters apply before hashing and installation. Invalid unused auxiliary links are omitted. Cache identity includes the source, commit and hash. EasyP verifies it on download and when reusing an installed module; corrupt installations are rejected. +The hash uses Go's dirhash.Hash1 over the materialized logical snapshot at the commit, with repository-relative paths. Safe internal aliases contribute their resolved bytes under their logical names; Git objects are read directly, without checkout filters. Buf filters apply before hashing and installation. Invalid unused auxiliary links are omitted. Installed-cache identity includes the source, commit, hash and canonical root selection. EasyP verifies it on download and when reusing an installed module; corrupt installations are rejected. The v1 cache reuses an object store per Git remote. A known exact commit can be fetched without contacting the remote. A cold request first tries a depth-one fetch of the exact commit; if the server rejects that request, EasyP falls back to advertised reachable history. The original commit is still required: HEAD is never substituted. Tag lookups are refreshed separately so cache reuse cannot hide a retag. A commit absent from cache can still require access to its source. diff --git a/content/docs/reference/protobuf-lock.ru.mdx b/content/docs/reference/protobuf-lock.ru.mdx index 97edc09..c1492d4 100644 --- a/content/docs/reference/protobuf-lock.ru.mdx +++ b/content/docs/reference/protobuf-lock.ru.mdx @@ -35,6 +35,10 @@ description: "Спецификация файла protobuf.lock, автомат "modules[].hash": { description: "Дайджест Go dirhash.Hash1 (h1:...) для материализованного логического снимка зафиксированного коммита.", type: "string" + }, + "modules[].roots": { + description: "Необязательные проверенные fallback-каталоги корней импортов от каталога зависимости без метаданных. Используются на холодном кеше и в frozen; не переопределяют корни из метаданных зависимости.", + type: "string[]" } }} /> @@ -57,6 +61,8 @@ modules: ## Команды жизненного цикла +Разрешённые `roots` — канонические переносимые относительные каталоги; `.` допустим. Абсолютные пути, выход через `..`, обратные слеши, globs и дубликаты отклоняются. Эти поля описывают результат резолва зависимости: они создаются по однозначным импортам или проверенным подсказкам `get --import-root`/мигратора. Они не зависят от фильтров генерации `paths` и пакетов. + - easyp get добавляет прямое требование, записывает транзитивные требования как indirect и обновляет lock. - easyp mod tidy разрешает объявленные требования, обновляет indirect-записи и lock. Для требования, оставшегося без ограничений версии, сохраняет прежний коммит из lock. - easyp mod update обновляет SemVer-зависимости в пределах текущей мажорной версии, освежает всё ещё неограниченные требования до HEAD и сохраняет явные хеши коммитов. @@ -68,7 +74,7 @@ modules: mod download использует коммит из lock даже после переноса тега, если этот коммит доступен. -hash вычисляется через Go dirhash.Hash1 по материализованному логическому снимку коммита с путями относительно репозитория. Безопасные внутренние алиасы добавляют разрешённые байты под своими логическими именами; Git-объекты читаются напрямую, без checkout-фильтров. Buf-фильтры применяются до хеширования и установки. Некорректные неиспользуемые служебные ссылки пропускаются. Ключ кеша включает источник, commit и hash. Хеш проверяется и при скачивании, и при повторном использовании установленного модуля; повреждённая установка отклоняется. +hash вычисляется через Go dirhash.Hash1 по материализованному логическому снимку коммита с путями относительно репозитория. Безопасные внутренние алиасы добавляют разрешённые байты под своими логическими именами; Git-объекты читаются напрямую, без checkout-фильтров. Buf-фильтры применяются до хеширования и установки. Некорректные неиспользуемые служебные ссылки пропускаются. Ключ установленного кеша включает источник, commit, hash и канонический набор корней. Хеш проверяется и при скачивании, и при повторном использовании установленного модуля; повреждённая установка отклоняется. Для каждого Git remote кеш v1 повторно использует хранилище объектов. Известный точный коммит можно получить без обращения к remote. При холодном запросе сначала выполняется shallow-загрузка точного коммита с глубиной один; если сервер её отклоняет, используется доступная история объявленных ссылок. Всё равно требуется исходный коммит: HEAD вместо него не подставляется. Проверки тегов обновляются отдельно, поэтому кеш не скрывает перенос тега. Отсутствующий в кеше коммит всё ещё может потребовать доступа к источнику. From fdda01d0e908a7c74b367b0c043307a3ed5fab9f Mon Sep 17 00:00:00 2001 From: Khasbulat Abdullin Date: Thu, 8 Oct 2026 01:38:19 +0300 Subject: [PATCH 2/3] docs: explain intrinsic root resolution and checked tidy repairs --- content/docs/cli/package-manager/index.mdx | 10 +++++++++- content/docs/cli/package-manager/index.ru.mdx | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/content/docs/cli/package-manager/index.mdx b/content/docs/cli/package-manager/index.mdx index e0e5a82..e57b5b4 100644 --- a/content/docs/cli/package-manager/index.mdx +++ b/content/docs/cli/package-manager/index.mdx @@ -37,7 +37,7 @@ Major versions use Go-style identities: v0/v1 are unsuffixed; v2+ requires match Roots normally come from the pinned dependency's `protobuf.mod`, Buf or legacy EasyP config. A native manifest with omitted roots still declares `.`. Invalid metadata is an error. -For an already declared dependency without root metadata, resolution can identify roots from a unique match between imports and tracked proto files. `import "svc.proto"` can match `api/svc/v1/svc.proto` under root `api/svc/v1`. Ambiguous layouts require an explicit hint: +For an already declared dependency without root metadata, resolution identifies roots only from imports inside that dependency. If `api/service/v1/a.proto` imports `service/v1/b.proto`, the matching dependency file `api/service/v1/b.proto` establishes root `api`. External consumer imports only validate the resolved namespace; they never choose its roots. Without enough internal evidence, the default `.` remains or an explicit hint is required: ~~~bash easyp get --import-root api/svc/v1 gitlab/products/svc @@ -57,6 +57,14 @@ plugins: [] Resolved roots determine protobuf filenames. Module-local `paths` and `packages` restrict generation; paths refer to the external module directory. Add your local module to `modules` when both should generate. Root selection does not rewrite source imports or require a generation filter repeating the root. +## Root changes during dependency updates + +When a new revision introduces authoritative roots, EasyP compares their protobuf filenames with the prior pinned fallback namespace. This also covers the metadata-free default `.`, even when the old lock omits `roots`. Moving physical directories while keeping the same import names is valid. A namespace shift stops implicit update before writing manifest/lock and reports old/new revisions, roots and representative renamed imports. + +To accept the new revision, change its requirement in `protobuf.mod` and run `easyp mod tidy`. Tidy updates consumer import declarations when the old and new pinned namespaces prove one source binding, including when another file has taken the old import name. It validates the proposed imports before committing source edits and manifest/lock together, then reports applied renames. Comments, line endings and unrelated strings remain intact. Tidy uses declared versions; it does not upgrade them by itself. + +An ambiguous mapping or deleted imported source stops before project writes and explains which import needs attention. Dependencies and cached source files are never rewritten. Review generation selectors and SDK output paths separately. If imports are already adjusted, explicitly adopt with `easyp get --import-root api gitlab/products/svc@`, or keep the prior version. Producer metadata remains authoritative; hints must match it and import/integrity checks still pass. + ## Commands | Command | Behavior | diff --git a/content/docs/cli/package-manager/index.ru.mdx b/content/docs/cli/package-manager/index.ru.mdx index 0356bc9..53af722 100644 --- a/content/docs/cli/package-manager/index.ru.mdx +++ b/content/docs/cli/package-manager/index.ru.mdx @@ -37,7 +37,7 @@ require ( Обычно roots берутся из закреплённого `protobuf.mod`, Buf или legacy-конфига EasyP зависимости. Native-манифест без явного roots всё равно задаёт корень `.`. Некорректные метаданные вызывают ошибку. -Для уже объявленной зависимости без метаданных корней резолвер может определить roots по однозначному соответствию импортов отслеживаемым proto-файлам. `import "svc.proto"` соответствует `api/svc/v1/svc.proto` при корне `api/svc/v1`. Неоднозначные варианты требуют явной подсказки: +Для уже объявленной зависимости без метаданных корней резолвер определяет roots только по импортам внутри самой зависимости. Если `api/service/v1/a.proto` импортирует `service/v1/b.proto`, файл зависимости `api/service/v1/b.proto` задаёт root `api`. Импорты внешнего потребителя только проверяют разрешённое пространство имён и не выбирают его roots. Если внутренних данных недостаточно, сохраняется корень `.` либо требуется явная подсказка: ~~~bash easyp get --import-root api/svc/v1 gitlab/products/svc @@ -57,6 +57,14 @@ plugins: [] Разрешённые roots определяют protobuf-имена файлов. Module-local `paths` и `packages` ограничивают генерацию; paths считаются от каталога внешнего модуля. Для совместной генерации добавьте в `modules` и свой локальный модуль. Выбор корней не переписывает исходные импорты и не требует повторять root в фильтре генерации. +## Изменение корней при обновлении зависимости + +Если новая ревизия задаёт собственные корни, EasyP сравнивает protobuf-имена с fallback-пространством прежней закреплённой ревизии. Это касается и корня `.` модуля без метаданных, даже если старый lock не содержит `roots`. Перемещение физических каталогов при сохранении import-имён допустимо. Смена пространства имён останавливает неявное обновление до записи manifest/lock; ошибка показывает прежнюю и новую ревизии, roots и примеры переименованных импортов. + +Чтобы принять новую ревизию, измените её `require` в `protobuf.mod` и выполните `easyp mod tidy`. Tidy обновляет import-декларации потребителя, если прежнее и новое закреплённые пространства имён доказывают однозначную связь с исходным контрактом, в том числе когда старое имя занял другой файл. Команда проверяет предложенные импорты до совместной записи исходников и manifest/lock, затем показывает выполненные замены. Комментарии, переводы строк и остальные строковые значения сохраняются. Tidy использует объявленные версии и сам их не повышает. + +Неоднозначное соответствие или удалённый импортируемый исходник останавливают запись с объяснением проблемного импорта. Исходники зависимостей и кеша не переписываются. Отдельно проверьте selectors генерации и выходные пути SDK. Если импорты уже исправлены, явно примите root командой `easyp get --import-root api gitlab/products/svc@<новая-версия>` либо сохраните прежнюю версию. Метаданные производителя сохраняют приоритет; подсказка должна совпадать с ними, а проверки импортов и целостности продолжают действовать. + ## Команды | Команда | Поведение | From 99b3bcb46116675bd537091c261ae6b85577728d Mon Sep 17 00:00:00 2001 From: Khasbulat Abdullin Date: Thu, 8 Oct 2026 05:06:50 +0300 Subject: [PATCH 3/3] docs: clarify root coordinates and migration scope --- content/docs/cli/package-manager/index.mdx | 4 ++-- content/docs/cli/package-manager/index.ru.mdx | 4 ++-- content/docs/migration/easyp-v0.mdx | 2 +- content/docs/migration/easyp-v0.ru.mdx | 2 +- content/docs/reference/protobuf-lock.mdx | 2 +- content/docs/reference/protobuf-lock.ru.mdx | 2 +- content/docs/reference/protobuf-mod.mdx | 2 +- content/docs/reference/protobuf-mod.ru.mdx | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/content/docs/cli/package-manager/index.mdx b/content/docs/cli/package-manager/index.mdx index e57b5b4..d3a9bb6 100644 --- a/content/docs/cli/package-manager/index.mdx +++ b/content/docs/cli/package-manager/index.mdx @@ -43,7 +43,7 @@ For an already declared dependency without root metadata, resolution identifies easyp get --import-root api/svc/v1 gitlab/products/svc ~~~ -Repeat `--import-root` for multiple module-relative directories. Hints must remain inside the external module and agree with authoritative roots. Verified fallback roots are recorded in the dependency's `protobuf.lock` entry. Frozen and cold-cache operations replay that choice; resolution failures leave the manifest and lock unchanged. +Repeat `--import-root` for multiple directories. Fetched Git hints are relative to the pinned repository snapshot: for `repo/sub/protobuf.mod` declaring `roots proto`, use `--import-root sub/proto`. Local replacement hints are relative to the replacement directory. Producer roots remain relative to their declaring manifest and are rebased by the Git adapter. Hints must stay within the source boundary and agree with authoritative roots. Verified fallback roots are recorded in the dependency's `protobuf.lock` entry. Frozen and cold-cache operations replay that choice; resolution failures leave the manifest and lock unchanged. To generate the required dependency, select its identity in `easyp.gen.yaml`: @@ -91,7 +91,7 @@ Commit protobuf.mod and protobuf.lock for repeatable b ## Dependencies using Buf or older EasyP -A Git dependency may declare its proto roots in buf.work.yaml, Buf v1 or v2 buf.yaml, or an older EasyP easyp.yaml. Older EasyP protobuf.mod requirements are also read transitively. If none of those files exists, its repository root is used. This compatibility applies to dependency metadata; the consuming project uses v1 protobuf.mod. +A Git dependency may declare its proto roots in buf.work.yaml, Buf v1 or v2 buf.yaml, or an older EasyP easyp.yaml. Older EasyP protobuf.mod requirements are also read transitively. Without root metadata, dependency-internal import evidence or checked hints may establish fallback roots; otherwise its repository root is used. Recorded fallback roots are replayed from protobuf.lock. This compatibility applies to dependency metadata; the consuming project uses v1 protobuf.mod. When adapting an older easyp.yaml, both deps and generation Git inputs contribute requirements. Exact source/version duplicates are removed; different minimums remain visible to MVS, and malformed deps fail explicitly. A matching native protobuf.mod takes precedence. Only metadata is read; dependency plugins are never executed. diff --git a/content/docs/cli/package-manager/index.ru.mdx b/content/docs/cli/package-manager/index.ru.mdx index 53af722..0752726 100644 --- a/content/docs/cli/package-manager/index.ru.mdx +++ b/content/docs/cli/package-manager/index.ru.mdx @@ -43,7 +43,7 @@ require ( easyp get --import-root api/svc/v1 gitlab/products/svc ~~~ -Для нескольких каталогов модуля повторите `--import-root`. Подсказки должны оставаться внутри внешнего модуля и согласовываться с корнями из его метаданных. Проверенные fallback-корни записываются в запись зависимости в `protobuf.lock`. Frozen и холодный кеш используют этот выбор; ошибки оставляют manifest и lock неизменными. +Для нескольких каталогов повторите `--import-root`. У загруженной Git-зависимости путь считается от закреплённого снимка репозитория: для `repo/sub/protobuf.mod` с `roots proto` используйте `--import-root sub/proto`. У локальной замены путь считается от каталога замены. Корни производителя остаются относительными к объявляющему manifest; Git-адаптер приводит их к координатам снимка. Подсказки должны оставаться внутри границы источника и согласовываться с его метаданными. Проверенные fallback-корни записываются в запись зависимости в `protobuf.lock`. Frozen и холодный кеш используют этот выбор; ошибки оставляют manifest и lock неизменными. Для генерации объявленной зависимости укажите её идентификатор в `easyp.gen.yaml`: @@ -91,7 +91,7 @@ easyp generate ## Зависимости на Buf или старом EasyP -Git-зависимость может объявлять корни .proto через buf.work.yaml, Buf v1/v2 buf.yaml или старый EasyP easyp.yaml. Транзитивные требования из старого EasyP protobuf.mod также читаются. Если ни одного такого файла нет, корнем считается каталог репозитория. Совместимость относится к метаданным зависимости; проект-потребитель использует v1 protobuf.mod. +Git-зависимость может объявлять корни .proto через buf.work.yaml, Buf v1/v2 buf.yaml или старый EasyP easyp.yaml. Транзитивные требования из старого EasyP protobuf.mod также читаются. Без метаданных корни могут определяться по внутренним импортам зависимости или проверенной подсказке; иначе используется каталог репозитория. Записанные fallback roots воспроизводятся из protobuf.lock. Совместимость относится к метаданным зависимости; проект-потребитель использует v1 protobuf.mod. При адаптации старого easyp.yaml требования берутся и из deps, и из Git-входов генерации. Точные дубликаты источник/версия удаляются, разные минимумы сохраняются для MVS; некорректные deps вызывают ошибку. Совпадающий нативный protobuf.mod имеет приоритет. Читаются только метаданные, плагины зависимости не запускаются. diff --git a/content/docs/migration/easyp-v0.mdx b/content/docs/migration/easyp-v0.mdx index 7a2b6d7..a00c2be 100644 --- a/content/docs/migration/easyp-v0.mdx +++ b/content/docs/migration/easyp-v0.mdx @@ -116,7 +116,7 @@ A full commit SHA is preserved, including a full SHA embedded in an old pseudo-v Git's annotated-tag spelling, such as `v0.4.0^{}`, is accepted for a full SemVer tag in the historical lock. The tag, commit and original hash are still verified, and the old lock stays byte-identical. Peeled branches, abbreviated refs, repeated suffixes and pseudo-version-shaped peeled tags are rejected. -Released v0 installers archived Git's *.proto pathspec and stripped legacy root prefixes before hashing. Migration reproduces that archive at the pinned revision; it also retains verification of the existing whole-tree hash format. Git archive attributes that omit or alter proto files require manual migration because a native checkout would change the contract. +Released v0 installers archived Git's *.proto pathspec and stripped legacy root prefixes before hashing. Migration reproduces that archive at the pinned revision; it also retains verification of the existing whole-tree hash format. Omitted selected or reachable proto sources and changes to verified archive bytes require manual migration. An unused export-ignore source outside a verified filtered Git selection is permitted when historical hash, target names and reachable bindings match. A whole input that would gain an extra target still fails. The v1 content hash is then calculated independently over the materialized logical snapshot. Old and new hashes cover different path layouts and cannot be copied or compared as interchangeable values. A missing historical dependency pin is not replaced with current HEAD. diff --git a/content/docs/migration/easyp-v0.ru.mdx b/content/docs/migration/easyp-v0.ru.mdx index 0d4e777..fddac24 100644 --- a/content/docs/migration/easyp-v0.ru.mdx +++ b/content/docs/migration/easyp-v0.ru.mdx @@ -116,7 +116,7 @@ plugins: Запись аннотированного Git-тега вроде `v0.4.0^{}` допустима для полного SemVer-тега в историческом lock. Тег, commit и исходный хеш по-прежнему проверяются, а старый lock сохраняется побайтово. Peeled-ветки, сокращённые refs, повторные суффиксы и peeled-теги в форме псевдоверсии отклоняются. -Выпущенные версии v0 архивировали Git-pathspec *.proto и убирали legacy-префиксы корней перед вычислением хеша. Мигратор воспроизводит этот архив в закреплённой ревизии; проверка существующего формата хеша полного дерева тоже сохраняется. Git-атрибуты архива, исключающие или изменяющие proto-файлы, требуют ручной миграции: native checkout изменил бы контракт. +Выпущенные версии v0 архивировали Git-pathspec *.proto и убирали legacy-префиксы корней перед вычислением хеша. Мигратор воспроизводит этот архив в закреплённой ревизии; проверка существующего формата хеша полного дерева тоже сохраняется. Пропуск выбранного или достижимого proto-источника и изменение проверенных архивных байтов требуют ручной миграции. Неиспользуемый источник с export-ignore вне проверенной выборки Git допустим, если исторический hash, имена targets и достижимые связи совпадают. Целый input, который получил бы лишний target, по-прежнему отклоняется. После проверки новый хеш v1 рассчитывается независимо по материализованному логическому снимку. Старый и новый хеши относятся к разным раскладкам путей; их нельзя просто копировать или считать взаимозаменяемыми. Отсутствующий исторический pin не заменяется текущим HEAD. diff --git a/content/docs/reference/protobuf-lock.mdx b/content/docs/reference/protobuf-lock.mdx index 1376d50..6110a9f 100644 --- a/content/docs/reference/protobuf-lock.mdx +++ b/content/docs/reference/protobuf-lock.mdx @@ -37,7 +37,7 @@ description: "Specification for protobuf.lock, the generated lockfile securing r type: "string" }, "modules[].roots": { - description: "Optional verified fallback import-root directories relative to a metadata-free dependency module. Replayed on cold-cache and frozen operations; does not override authoritative dependency metadata.", + description: "Optional verified fallback import-root directories relative to a metadata-free dependency's pinned Git repository snapshot. Replayed on cold-cache and frozen operations; does not override authoritative dependency metadata.", type: "string[]" } }} diff --git a/content/docs/reference/protobuf-lock.ru.mdx b/content/docs/reference/protobuf-lock.ru.mdx index c1492d4..94f6c8c 100644 --- a/content/docs/reference/protobuf-lock.ru.mdx +++ b/content/docs/reference/protobuf-lock.ru.mdx @@ -37,7 +37,7 @@ description: "Спецификация файла protobuf.lock, автомат type: "string" }, "modules[].roots": { - description: "Необязательные проверенные fallback-каталоги корней импортов от каталога зависимости без метаданных. Используются на холодном кеше и в frozen; не переопределяют корни из метаданных зависимости.", + description: "Необязательные проверенные fallback-каталоги корней импортов от закреплённого снимка Git-репозитория зависимости без метаданных. Используются на холодном кеше и в frozen; не переопределяют корни из метаданных зависимости.", type: "string[]" } }} diff --git a/content/docs/reference/protobuf-mod.mdx b/content/docs/reference/protobuf-mod.mdx index bce19a0..347b473 100644 --- a/content/docs/reference/protobuf-mod.mdx +++ b/content/docs/reference/protobuf-mod.mdx @@ -89,7 +89,7 @@ The rule applies to declared module identities, requirements, replacement source The major suffix is logical and is not included in the tag prefix: v2/v2.0.0 is not the release tag for repo/v2. Both lightweight and annotated tags work. The manifest at an allowed location must declare the exact requested identity; finding a tag alone is insufficient. -repo and repo/v2 can coexist as distinct module, lock and replacement identities. MVS chooses the highest requested minimum per identity. You must provide distinct protobuf import paths yourself: EasyP never renames packages or imports, and duplicate import paths still fail. Same-major updates, exact SHA/tag agreement, immutable tags, local replacement lock preservation and frozen verification continue to apply. +repo and repo/v2 can coexist as distinct module, lock and replacement identities. MVS chooses the highest requested minimum per identity. Major-version identities do not rename protobuf packages or disambiguate import paths; the author must provide distinct paths, and duplicates still fail. Checked mod tidy can repair consumer import declarations after a verified dependency namespace change; see [root changes during updates](/docs/cli/package-manager). Same-major updates, exact SHA/tag agreement, immutable tags, local replacement lock preservation and frozen verification continue to apply. The pre-module +incompatible exception is supported only for unsuffixed v2+ revisions without a native protobuf.mod. EasyP reads the underlying tag without the suffix and verifies metadata on the exact fetched or cached commit before accepting the lock entry. It rejects native manifests even when the marker is present. Legacy updates retain the marker; local replacements remain unversioned overlays and never publish their graph to the lock. Migration never silently renames a source or changes its version. diff --git a/content/docs/reference/protobuf-mod.ru.mdx b/content/docs/reference/protobuf-mod.ru.mdx index 9418b3e..d3ab318 100644 --- a/content/docs/reference/protobuf-mod.ru.mdx +++ b/content/docs/reference/protobuf-mod.ru.mdx @@ -89,7 +89,7 @@ v0 и v1 используют один путь без суффикса. Для Мажорный суффикс логический и не входит в префикс тега: v2/v2.0.0 не является тегом релиза repo/v2. Поддерживаются обычные и аннотированные теги. Манифест в допустимом каталоге должен объявлять точный запрошенный идентификатор; одного совпадения тега недостаточно. -repo и repo/v2 могут сосуществовать как разные идентификаторы модулей, записей lock и замен. MVS выбирает максимум запрошенных минимумов для каждого имени отдельно. Различные protobuf import paths задаёт автор: EasyP не переименовывает пакеты и импорты, а совпадение путей импорта остаётся ошибкой. Обновления внутри major, точное согласование SHA/тега, неизменность тегов, сохранение lock при локальных заменах и frozen-проверки сохраняются. +repo и repo/v2 могут сосуществовать как разные идентификаторы модулей, записей lock и замен. MVS выбирает максимум запрошенных минимумов для каждого имени отдельно. Идентичность major не переименовывает protobuf-пакеты и не устраняет коллизии import paths: различные пути задаёт автор, а совпадение остаётся ошибкой. Проверенный mod tidy может исправить import-декларации потребителя после подтверждённой смены пространства имён зависимости; см. [изменение корней при обновлении](/ru/docs/cli/package-manager). Обновления внутри major, точное согласование SHA/тега, неизменность тегов, сохранение lock при локальных заменах и frozen-проверки сохраняются. Домодульное исключение +incompatible поддерживается только для v2+ без суффикса пути и без нативного protobuf.mod в выбранной ревизии. EasyP читает исходный Git-тег без этой метки и проверяет метаданные точного скачанного или кешированного коммита до принятия записи lock. При наличии нативного manifest метка не обходит проверку. Обновления старого модуля сохраняют метку; локальные замены остаются неверсионируемым наложением и не записывают свой граф в lock. Миграция не переименовывает источник и не меняет версию молча.