Перейти к содержимому

Приёмка чужого проекта - инвентарь, правки ядра, карта рисков

Принимаем проект, который писали до нас: стенд, инвентарь, правки ядра, обработчики и карта рисков вместо приговора.

Механика

Приёмку делают на копии, а не на боевом сайте. Первое действие - поднять стенд, второе - собрать инвентарь, и только третье - что-то менять; порядок здесь важнее скорости, потому что чужой проект всегда сложнее, чем выглядит.

Свой код проекта живёт в четырёх местах сразу. Каталог для своего кода, старая папка обработчиков ядра, шаблоны и компоненты - причём и в правильном каталоге, и в каталоге платформы, куда их клали раньше.

Правки ядра - главный риск любого чужого проекта. Обновление затирает их молча, и сайт ломается ровно в тот момент, когда его нельзя ломать: обычно на обновлении ради безопасности или новой версии языка.

Вмешательства в поведение платформы видны списками, а не чтением кода. Обработчики событий и задания по расписанию перечисляются запросами, и это быстрее, чем читать чужой код в поисках подписок.

Прямые запросы к таблицам и логика в шаблонах - не преступление сами по себе. Это места, которые ломаются при обновлении структуры и при переносе, поэтому их выписывают, а не переписывают сразу.

Итог приёмки - не приговор «плохой код», а карта рисков с ценой. Что чинить до первого обновления, что переписать при следующей задаче в этой области и чего не трогать вовсе, пока оно работает.

Отдельная часть приёмки - доступы и внешние связи. Cron, почта, обмен с учётной системой, платёжные системы и внешние ключи живут вне репозитория, и без них картина проекта неполная.

Шаги

  1. Поднять стенд из копии и отрезать на нём боевые интеграции и почту.
  2. Снять инвентарь: редакция, версии модулей, сторонние решения, версия языка.
  3. Найти правки ядра сравнением с эталоном той же версии и записать их списком.
  4. Выписать обработчики событий и задания по расписанию вместе с источниками.
  5. Найти прямые запросы к базе, записи из шаблонов и код вне своего каталога.
  6. Собрать карту рисков и согласовать с заказчиком очередь работ по ней.

Код

Снимаем инвентарь модулей:

use Bitrix\Main\ModuleManager;
foreach (ModuleManager::getInstalledModules() as $module) {
printf("%-28s %s\n", $module['ID'], ModuleManager::getVersion($module['ID']));
}
// сторонние решения видно по точке в имени: vendor.solution
// версия модуля ядра показывает, насколько давно проект обновляли

Инвентарь отвечает на первый вопрос заказчика: можно ли обновляться. Разброс версий модулей и старое ядро означают, что обновление станет отдельным проектом, а не задачей на полчаса.

Ищем правки ядра:

Окно терминала
# эталон той же версии: распаковать чистый дистрибутив рядом и сравнить
diff -rq /tmp/bitrix-clean/bitrix/modules/main bitrix/modules/main | head -20
# ту же задачу решает контроль целостности файлов в проактивной защите

Правленое ядро находят до первого обновления, а не после. Список таких файлов - самая ценная часть приёмки: каждый из них однажды исчезнет вместе с логикой, которую в него добавили.

Выписываем обработчики событий:

$manager = \Bitrix\Main\EventManager::getInstance();
foreach (['OnBeforeProlog', 'OnPageStart', 'OnEndBufferContent'] as $event) {
foreach ($manager->findEventHandlers('main', $event) as $handler) {
printf("%-18s %s\n", $event, $handler['TO_NAME'] ?? $handler['TO_MODULE_ID']);
}
}
// то же самое смотрят по событиям инфоблоков, заказов и пользователей

Обработчик на событии, случающемся на каждой странице, объясняет половину странностей проекта. Он же чаще всего оказывается причиной медленной работы, о которой заказчик рассказывает как о свойстве платформы.

Смотрим задания по расписанию:

$rs = CAgent::GetList(['NEXT_EXEC' => 'ASC'], ['ACTIVE' => 'Y']);
while ($agent = $rs->Fetch()) {
printf("%-12s %-52s %s\n", $agent['MODULE_ID'], $agent['NAME'], $agent['NEXT_EXEC']);
}
// агент, падающий каждую минуту, - обычная находка приёмки

Ищем код вне своего каталога:

Окно терминала
ls bitrix/php_interface/ 2>/dev/null # старое место обработчиков проекта
ls bitrix/templates/ | grep -v '^\.' # шаблоны сайта в каталоге платформы
ls bitrix/components/ | grep -v bitrix # свои компоненты рядом с чужими
# всё, что лежит здесь, обновление затирает без предупреждения

Каталог для своего кода появился не сразу, и на старых проектах его нет вовсе. Перенос туда - отдельная задача с проверкой каждого пути, а не операция копирования, поэтому её планируют, а не делают в первый день.

Находим прямые запросы и записи из шаблонов:

Окно терминала
grep -rn '\$DB->Query\|mysqli_query' local/ bitrix/templates/ | wc -l
grep -rln 'CIBlockElement::Add\|->save()' bitrix/templates/ local/templates/ | head
# запись данных прямо из шаблона переносят в свой код при первой же правке

Читаем журнал ошибок до того, как читать код:

Окно терминала
tail -50 bitrix/modules/error.log # журнал платформы, если он включён
grep -c "" bitrix/modules/error.log # объём: тысячи строк говорят сами за себя

Журнал показывает живые проблемы, а не потенциальные. Проект, который сыплет ошибками каждую минуту, лечат до любых улучшений: пока журнал шумит, новые ошибки в нём не видны.

Собираем карту рисков:

| Находка | Риск | Когда чинить |
|---|---|---|
| Правки в модуле инфоблоков | обновление затрёт логику | до первого обновления |
| Записи из шаблона каталога | ломается при переносе | при следующей правке витрины |
| Агент решения падает | забивает журнал | на этой неделе |

Карта рисков - это разговор с заказчиком на его языке. Она отвечает не на вопрос «хорош ли код», а на вопрос «что случится и когда», и именно поэтому по ней принимают решения о деньгах и сроках.

Ограничения

Приёмка даёт карту, но не диагноз по каждой задаче. Она показывает, где проект рискует сломаться, а разбираться в конкретной логике всё равно придётся при первой же задаче в этой области.

Сравнение с эталонным дистрибутивом даёт ложные срабатывания на файлах кэша и на загрузках. Часть отличий - следы штатных обновлений и кэш, поэтому сравнивают каталоги модулей, а не весь проект, и проверяют находки глазами.

Тяжёлые проверки целостности не запускают на боевом сайте в рабочее время. Контроль целостности файлов и монитор качества нагружают сервер заметно, и на живом магазине их включают в спокойное время или не включают вовсе.

Часть сторонних решений держится на активной подписке и без неё не обновляется. Истёкшая лицензия решения означает отсутствие обновлений и поддержки, и это отдельная строка в карте рисков, а не техническая мелочь.

Без доступа к боевому серверу картина проекта останется заведомо неполной и приблизительной. Задания по расписанию, настройки почты, конфигурация веб-сервера и внешние ключи живут вне репозитория, и их приходится запрашивать отдельно.

Переписывать весь чужой проект сразу нельзя практически ни при каких обстоятельствах и сроках. Проект приносит деньги в текущем виде, поэтому работы ставят в очередь по риску и по стоимости, а не по личному отношению к чужому коду.

Типичные проблемы

После обновления платформы пропала часть логики.

Логика была дописана прямо в файлы ядра, и обновление их перезаписало. Правки ядра выписывают при приёмке и переносят в свой код.

Правки в шаблонах исчезают после обновления.

Шаблоны и компоненты лежат в каталоге платформы, а не в каталоге проекта. Их переносят с проверкой путей, а не копированием.

Сайт медленный без видимой причины.

На событии, случающемся на каждой странице, висит тяжёлый обработчик чужого решения. Списки обработчиков событий смотрят раньше, чем берутся за профилирование страниц и запросов.

Журнал ошибок растёт на мегабайты в сутки.

Задание по расписанию падает при каждом запуске и пишет ошибку в журнал. Его находят в списке заданий по времени следующего запуска.

После обновления структуры перестали работать отчёты.

Отчёты собраны прямыми запросами к таблицам платформы, в обход её штатных интерфейсов и правил. Такие места выписывают при приёмке и переводят на API постепенно.

Часть сайта не находится поиском и не видна в меню.

Страницы лежат статическими файлами вне структуры разделов, вне меню и вне поиска сайта. Их либо заводят в структуру, либо переносят в инфоблок.

Частые вопросы

С чего начать приёмку чужого проекта?

С копии на стенде и инвентаря: редакция, версии модулей, сторонние решения, версия языка. Правки начинают только после того, как картина собрана, иначе первая же правка ломает то, о чём никто не знал.

Как найти изменённые файлы ядра?

Сравнить каталог модулей с чистым дистрибутивом той же версии либо запустить контроль целостности файлов в проактивной защите. Ложные срабатывания на кэше и загрузках проверяют глазами.

Что делать, если папки для своего кода в проекте нет?

Планировать перенос отдельной задачей с проверкой каждого пути, а не копировать каталоги в первый день. До переноса любое обновление платформы способно затереть чужие правки.

Стоит ли переписывать проект целиком?

Почти никогда: проект приносит деньги в текущем виде, а переписывание останавливает развитие на месяцы. Работы ставят в очередь по риску, начиная с того, что сломается при ближайшем обновлении.

Что показать заказчику по итогам приёмки?

Карту рисков: находка, что случится, когда чинить и сколько это стоит. Список замечаний к качеству кода без последствий и сроков заказчику ни о чём не говорит.

Смежное

Первоисточник