Перейти к содержанию

Проверки организации проекта

Проект может включить проверки через .embraion/organization.yaml. Проверка только читает исходники и метаданные Unity: она не меняет файлы. Каждая находка содержит путь, код правила и описание; в инкрементальном режиме также указан статус new или preexisting. Если конфигурации нет, результат — skipped.

exclude:
  - Assets/Vendor/**
  - Assets/Generated/**

namespaces:
  enabled: true
  rules:
    - path: Assets/Project/Runtime
      namespace: Example.Project
      require_declaration: true
      exceptions:
        - path: Assets/Project/Runtime/Interop
          namespace: Example.Interop
        - path: Assets/Project/Runtime/GlobalTypes
          allow_missing: true

assemblies:
  enabled: true
  enforce_platforms: true
  roots: [Assets/Project]
  path_rules:
    - {path: Assets/Project/Runtime, layer: Runtime}
    - {path: Assets/Project/Editor, layer: Editor}
    - {path: Assets/Project/Tests, layer: Tests}
  allowed_edges:
    - {from: Example.Project.Runtime, to: Example.Project.EditorBridge}

unity_meta:
  enabled: true
  roots: [Assets/Project]
  require_for_extensions: [.cs, .asmdef]
  check_move_identity: true

Каждый вид проверки необязателен и отключается отдельно. Пути обозначают каталоги относительно корня репозитория; в exclude допускаются шаблоны с *. Правила пространств имён следует задавать только для кода, принадлежащего проекту. Пространство имён может совпадать с заданным префиксом или продолжать его через точку. Отсутствие объявления допустимо, если не задано require_declaration. Исключение может задать другой префикс либо разрешить отсутствие объявления. При поиске объявления обычные комментарии и строки маскируются. Это ограниченный лексический анализ, а не компилятор C#: сложные варианты raw/interpolated strings и ветки препроцессора могут потребовать проверки компилятором.

Правила сборок применяются к существующим .asmdef внутри roots: отдельная сборка для каждого каталога не требуется. Для каждой найденной сборки должен определяться слой из path_rules. Ссылки Unity разрешаются по имени либо по GUID:<32 шестнадцатеричных символа> из соседнего файла .asmdef.meta. Проверяются неразрешённые ссылки GUID, повторяющиеся имена сборок и GUID метаданных, циклы и запрещённые зависимости слоёв. Ссылки по имени вне настроенных корней могут вести к пакетам и не считаются ошибкой. По умолчанию Runtime может ссылаться на Runtime, Editor — на Runtime и Editor, Tests — на все три слоя. allowed_edges разрешает конкретную пару имён сборок. При enforce_platforms (включено по умолчанию) сборка Editor должна объявлять includePlatforms: [Editor]; ссылки между найденными сборками проверяются на совместимость включённых и исключённых платформ. Для сложных ограничений платформ и defineConstraints может потребоваться проектная проверка компилятором.

Проверка метаданных ищет GUID в .meta и требует соседний .meta для заданных расширений. require_for_all вместо этого требует .meta для каждого файла внутри roots, кроме файлов в каталогах, имя которых начинается с точки или заканчивается на ~, файлов с такими именами и исключённых путей: Unity их не импортирует. check_orphans сообщает meta_orphan для .meta, у которого нет файла или каталога ресурса; собственный <root>.meta корня тоже учитывается. Инкрементальная проверка обнаруживает изменение GUID по существующему пути. При обнаруженном Git-переименовании ресурса исходный GUID сравнивается с GUID по новому пути; совпадения имени файла недостаточно. Для перемещений без общей истории Git подтвердить сохранение идентичности нельзя. Деревья стороннего или генерируемого кода можно исключить.

Имена файлов

Необязательная секция filenames проверяет имена файлов:

filenames:
  roots: [docs, tools]          # "." — весь репозиторий
  extensions: [.md, .yaml, .json]
  allow: [NOTICE.md]
  suffixes:
    - {path: docs/decisions, suffix: .adr.md}
  case_collisions: true

unity_meta:
  roots: [Assets/Project]
  require_for_all: true
  check_orphans: true

Проверяются только файлы внутри roots с расширением из extensions. Имя до расширения пишется в нижнем регистре через дефис (kebab-case) и может заканчиваться числовой версией, например migration-1.0.0.md (filename_style); расширение из списка, записанное в верхнем регистре, — это filename_extension_case. Стандартные имена экосистем, менеджеров пакетов и AI hosts, например README.md, CHANGELOG.md, AGENTS.md, SKILL.md и package.json, встроены; allow добавляет точные имена файлов, а имена, начинающиеся с точки, например .gitignore, пропускаются. Суффикс host допускается только непосредственно в своём каталоге, и идентификатор перед ним всё равно должен быть в kebab-case. Встроены .agent.md в .github/agents, .instructions.md в .github/instructions и .prompt.md в .github/prompts; suffixes добавляет другие. Сгенерированные профили .claude/agents/embraion--<role>-<12 hex-символов>.md используют зарезервированное пространство имён и не проверяются. case_collisions (включено по умолчанию) сообщает filename_collision для путей во всём списке файлов, которые отличаются только регистром.

Проверки имён, require_for_all и check_orphans используют список файлов: для рабочего дерева — отслеживаемые Git и неотслеживаемые, но не игнорируемые файлы, для ссылки — дерево коммита.

Запуск проверки

embraion organization check выполняет полную проверку рабочего дерева. Для инкрементальной проверки передайте базовую ссылку Git и, при необходимости, ссылку на конечный коммит. Обе должны разрешаться в коммиты. Находки сравниваются с полной базовой картиной; проверка завершается ошибкой только при новых нарушениях. Параметр --include-worktree добавляет текущие отслеживаемые и неотслеживаемые файлы, иначе оценивается конечный коммит. Ответ содержит идентификаторы обоих коммитов. Недоступная база вызывает ошибку, а не успешный результат. С --require-config отсутствие конфигурации даёт ошибку вместо skipped. Символьные ссылки не читаются, внутренние файлы Git пропускаются, объём сканирования ограничен, а указатели Git LFS не принимаются за исходный код.

Проверка не создаёт .meta, не переписывает C# и .asmdef и не перемещает файлы.