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

Сегодня мы рассмотрим, как перенести проверку и применение стиля в clang-формат для языков C, C++, C#, Java, JavaScript, Objective-C и Objective-C++. Далее мы обсудим более продвинутые возможности C++ с использованием clang-tidy и способы интеграции обоих инструментов с рабочими процессами git pull request.

clang-формат

Вы, наверное, слышали о clang-format, так как многие IDE используют его (через libformat) в качестве стандартного решения для форматирования кода. Мы заинтересованы в clang-format по той же причине, чтобы форматировать код единообразно.

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

Выбор стиля

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

Итак, сначала подумайте, к какой из этих двух категорий вы относитесь:

  • У вас нет ранее существовавшего кода или вы не заботитесь о различиях, сгенерированных путем переформатирования кодовой базы.
  • Вы хотите, чтобы стиль кода был близок к текущей кодовой базе, сводя к минимуму различия при переформатировании.

Если вам все равно или у вас еще нет кода, о котором нужно заботиться, я настоятельно рекомендую выбрать один из предопределенных стилей кода: LLVM, Google, Chromium, Mozilla, WebKit, Microsoft или GNU.

Вы также можете использовать один из предопределенных стилей в качестве основы и наложить свои изменения сверху. Например, это мой обычный стиль для C++:

Если вам не все равно, есть несколько инструментов, которые автоматически определяют конфигурацию формата из примеров кода:

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

Кроме того, конечный результат вряд ли будет полностью чистым от различий. Если вы в настоящее время не используете инструмент принудительного соблюдения формата, у вас будут некоторые несоответствия стиля. Будьте готовы погрузиться в настройку, чтобы точно настроить стиль.

Если у вас есть конфигурация, основанная на предопределенном или обнаруженном стиле, сохраните ее в файле .clang-format в корневом каталоге проекта.

предварительная фиксация

Хотя теперь у нас есть стиль кода, нам нужен еще один важный шаг, чтобы уменьшить ручной труд во время проверки кода. Нам нужно автоматически применять стиль кода для каждого фрагмента кода, прежде чем он попадет в наш репозиторий git (обратите внимание, что другие системы управления версиями предлагают очень похожие возможности).

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

Большинство IDE подберут файл .clang-format автоматически, некоторые потребуют от вас включения параметра:

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

Вы можете использовать хук перед фиксацией, но мы будем делать больше с помощью clang-tidy, поэтому вместо этого мы будем использовать фреймворк предварительной фиксации.

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

С этим файлом в корне нашего репозитория все, что нам нужно сделать, это запустить pre-commit install один раз для каждого репозитория, чтобы настроить хуки. После этого, если мы попытаемся зафиксировать файл с неправильным форматированием, он будет автоматически переформатирован, и среда предварительной фиксации сообщит нам об этом, чтобы мы могли проверить diff:

Вы можете ознакомиться с конечным результатом здесь: github.com/HappyCerberus/article-sanity-format.

Поток запросов на вытягивание

Это оставляет нам еще одну линию обороны. Хотя настроить локальное применение на компьютерах разработчиков очень просто (запустив pre-commit install один раз), мы все же хотим гарантировать, что неформатированный код не попадет в репозиторий, если кто-то забудет.

Поскольку речь идет об ограничении ручной работы по проверке кода, мы будем использовать рабочий процесс запроса на вытягивание, а поскольку мы уже используем предварительную фиксацию, мы будем использовать его действие git. Никакой дополнительной настройки не требуется, а pre-commit CI нужно только авторизовать, нажав кнопку Sign in with Github.

После включения запросы на извлечение будут автоматически форматироваться в соответствии с настроенным форматированием кода:

аккуратный

И clang-format, и pre-commit — многоязычные инструменты. В этом разделе мы обсудим clang-tidy, статический анализатор, специфичный для C++.

Возможно, вы знакомы с clang-tidy. Однако вы можете не знать, что clang-tidy предлагает набор легко настраиваемых проверок и исправлений стиля кода. Эти исправления охватывают изменения в коде, выходящие за рамки форматирования, такие как стиль именования (например, CamelCase или змея_case).

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

Первичная проверка, относящаяся к стилю кода, — это читабельность-идентификатор-именование. Эта проверка применяет стиль регистра (например, CamelCase, snake_case), а также префиксы и суффиксы для всех идентификаторов определенной категории (с поддержкой венгерской нотации скоро). Для вдохновения можно поискать готовые стили, например, стиль кода Google.

Наконец, вот проверки, которые либо настраиваются, либо заслуживают рассмотрения, но не применимы повсеместно:

Подключение к предварительной фиксации

Одна из проблем с clang-tidy заключается в том, что для правильной работы требуется база данных компиляции. CMake и Bazel могут выдавать эту информацию автоматически; для других систем сборки вы можете использовать инструмент перехватчика сборки, например Bear. Для простоты я буду демонстрировать интеграцию с помощью CMake:

Локальный рабочий процесс очень похож на простое использование clang-format, с оговоркой, что clang-tidy обычно более многословен:

Недостатком необходимости запуска CMake является то, что мы больше не можем использовать CI перед фиксацией. Вместо этого нам нужно написать собственный экшен на Github. У вас есть несколько вариантов того, как вы хотите, чтобы это работало. Я выбрал действие, которое пытается исправить форматирование и стиль, и если это не удается, оно закрывает запрос на вытягивание.

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

Заключительные замечания и ссылки

Одна из целей этой статьи — вдохновить. Многие проверки можно добавить в структуру предварительной фиксации или напрямую через git-хуки. Однако позаботьтесь о сохранении паритета между ЭК и локальной средой.

Локальные проверки (и особенно автоматические исправления) практически не требуют времени простоя и полностью локализованы для соответствующего разработчика. Эта изоляция позволит вам масштабировать производительность по мере создания набора инструментов проверки стиля.

Ссылки для автоматизации только в формате clang

Ссылки для автоматизации clang-tidy и CMake

Спасибо за чтение

Спасибо за чтение. Я пишу на темы разработки программного обеспечения и языков программирования для серверных частей.

Я также публикую видео на YouTube. У тебя есть вопросы? Напишите мне в Twitter или LinkedIn.