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

Но если вы убеждены, что код должен форматироваться, и форматироваться автоматически, в первую очередь добро пожаловать 🙂 этот пост сделан для вас (и на будущее для меня, если понадобится 😄)

В этом посте я собираюсь поговорить конкретно о форматировании кода C++, но его также можно использовать для форматирования языков C, Java, JavaScript, Objective-C, Protobuf и C#. Почему С++, спросите вы? Без особой причины, кроме того, что это язык, который я использую почти каждый день 🙂

Достаточно для вступления, давайте перейдем к центру темы!

Как форматировать код C++?

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

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

Почему именно этот, спросите вы?! 🤔

Что ж, если вы собираете код на C++, вы, вероятно, сталкивались с компилятором clang, который представляет собой компилятор с открытым исходным кодом для языков программирования семейства C. Я не буду подробно рассказывать о проекте clang, но в рамках этого проекта есть инструмент clang-format, который используется для форматирования кода C++.

Это означает, что clang-format активно поддерживается, и это действительно здорово! Более того, clang-format позволяет форматировать не только код C++! В настоящее время он позволяет форматировать языки C, C++, Java, JavaScript, Objective-C, Protobuf и C#. Так что даже если вы не используете C++, все равно есть шанс, что этот инструмент может вам пригодиться. В оставшейся части этой статьи, каждый раз, когда я буду говорить об использовании clang-format для форматирования кода C++, вы можете подумать, что он может сделать то же самое для других языков.

Это также позволяет вам настроить форматирование, чтобы иметь то, которое вам нравится для ваших проектов, и вы можете интегрировать его во множество других инструментов!

По всем этим причинам давайте посмотрим, как его использовать на самом деле 😃

Как это работает ?

Хороший вопрос ! Для тех, кто когда-либо использовал cmake-format (инструмент для форматирования кода Cmake), он работает почти так же (даже если clang-format был создан раньше 😆).

После установки вы можете использовать его в своем терминале для форматирования файла:

clang-format -i myfile.cpp

Довольно прямолинейно, не так ли?! Опция -i позволяет clang-format записывать отформатированную версию файла Cmake на место, что означает, что после запуска этой команды ваш файл теперь отформатирован 😃

С этим инструментом доступно множество опций, и я не буду вдаваться в подробности, но предлагаю вам посмотреть их на его GitHub 😉

Кроме того, вы можете создать свой файл конфигурации, который вы можете назвать .clang-format, если хотите, чтобы указать, как вы хотите, чтобы некоторые элементы отображались в ваших файлах C++ в папке.

Таким образом, вы можете форматировать код C++ и настраивать его форматирование! Как это здорово?! 😃

Вы меня убедили! Как я могу получить его на моей машине, теперь?

Лучший способ установить clang-format — использовать менеджер пакетов. Конечно, вы можете собрать его из исходников llvm, но это займет много времени и, вероятно, потребует отдельной статьи. Так что менеджер пакетов - это путь.

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

Или вы можете установить его с помощью pip( https://pypi.org/project/clang-format/) в любой системе, которую вы хотите: pip install clang-format.

Как автоматически форматировать репозиторий?

Теперь, когда мы знаем, как установить clang-format и использовать его для форматирования файла, давайте посмотрим, как автоматически форматировать все файлы C++ в репозитории (для другого языка вы можете использовать аналогичный метод и адаптировать только несколько символов).

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

Для этого можно использовать простую командную строку, объединив команды find и clang-format, например:

find . \( -name '*.hpp' -o -name '*.cpp' \) -exec clang-format -i {} \;

Эта команда просматривает все папки и подпапки с вашего текущего положения и ищет файлы с расширением .hpp или .cpp файлов. Затем он поместит все эти файлы вместо {} и запустит команду clang-format -i со всеми файлами. Если вы используете другое расширение для файлов, вы можете добавить или удалить их, используя все файлы, которые вы хотите отформатировать, в командной строке!

И вуаля, он у вас есть! Одна строка, вы можете отформатировать их все 😉

И это еще не все!

Однострочная команда для форматирования всех файлов C++ хороша, но я должен сказать, что эту строку нелегко запомнить. Эта проблема может помешать людям использовать его, потому что они не хотят просматривать документацию, чтобы найти ее снова, чтобы вставить ее в свой терминал. И мы не можем злиться на них за это, если они могут, люди всегда будут сопротивляться изменениям, поэтому, если вы будете учить такую ​​линию, не убедившись в пользе форматирования, вы ее не выучите.

Так что делать ? У нас только одна линия? Можем ли мы сделать это проще?

И да, мы можем! 😉👍

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

format:
  set -f
  find . \( -name '*.hpp' -o -name '*.cpp' \) -exec clang-format -i {} \;
  set +f

И теперь все, что нужно будет сделать людям, это запустить make format, и все форматирование будет происходить без необходимости заучивать сложную строку.

Это на самом деле сильнее, чем это! Если по какой-то причине вам нужно изменить инструмент, который вы используете для форматирования файлов C++, все, что вам нужно сделать, это изменить Makefile, и ваши коллеги даже не будут беспокоиться об этом, так как команда make format по-прежнему будет что они должны будут сделать! Кроме того, если вы хотите, вы также можете добавить другие инструменты форматирования для другого языка в Makefile, чтобы команда make format фактически форматировала все ваши исходные файлы, независимо от их языка !!! 😍

Я также должен упомянуть, что, чтобы помочь интегрировать его в ваш рабочий процесс, clang-format также можно включить во множество других инструментов, таких как Vim, Emacs, BBEdit, CLion, Visual Studio. , и, возможно, многое другое, если вы их ищете. 😉

Давайте принудительно форматируем по умолчанию!

Теперь у нас есть простая для запоминания команда, которая позволяет нам форматировать код C++. Всем доволен, пользуйтесь. Все, ну на самом деле нет, есть один раз, когда вы забыли, и код был интегрирован в проект, и теперь у всех есть конфликты форматирования. Или то время, когда новый стажер не знал он (или она), что эта команда существует. Или те сотрудники, которые хотят использовать, но все равно забывают, так как у них еще нет привычки

По этой причине, а может и по многим другим, вы должны форматировать по умолчанию. Но что я имею в виду? 🤔 Это просто, вы должны сделать невозможным или, по крайней мере, очень трудным для кого-либо не форматировать свой код и интегрировать этот неформатированный код в производство или даже дойти до код-ревью!

Как мы это делаем ? Ну, на самом деле есть две вещи, которые вы можете сделать.

Хук перед фиксацией

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

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

Вы можете найти здесь, пример хука перед коммитом, который может помочь вам создать свой собственный 😉

проверка КИ

Еще один способ принудительно отформатировать файлы в вашем репозитории — создать проверку на системе CI/CD, такой как Travis.

Если вы не знакомы с концепцией непрерывной интеграции, рекомендую ознакомиться с ней, она действительно принесет пользу вам и вашей команде. Для тех, кто знает, что такое система CI/CD, такая как Travis, продолжим.

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

  • Получение clang-format в системе, если она еще не установлена
  • Выполнение команды форматирования make format
  • Проверка того, что форматирование не изменило никаких файлов

Если мы сможем реализовать их все, мы выиграем 🙂

На самом деле, у нас уже есть 2 из них! Мы знаем, что можем установить clang-format с помощью pip! Это первая победа 😉 И запустить команду make format так же просто, как выполнить любую другую команду в системе CI/CD.

Итак, все, что нам осталось, это проверить, изменился ли один файл после форматирования, что будет означать, что человек не форматировал свой код до фиксации или отправки в CI. И для этого тоже есть командная строка 😉

git diff --exit-code

Эта команда проверит разницу между файлами в вашем репозитории и вернет 0 (= успех), если изменений не обнаружено, и что-то еще (= сбой), если в файле есть изменения.

И вуаля, у нас есть 3 шага 😃

Чтобы немного помочь, вы найдете под этой строкой содержимое GitHub Action, которое делает именно это! Поскольку GitHub Actions теперь доступен, я думаю, что любому будет проще интегрировать его таким образом. 😉

name: C/C++ CI
  on: [push]
  jobs:
    build:
      runs-on: windows-2016
      steps:
      - uses: actions/checkout@v1
      - name: Running cpp formatting
        run: make format
      - name: Checking formatting
        run: git diff --exit-code

Нет необходимости устанавливать clang-format, так как он уже установлен по умолчанию в системе, предоставляемой GitHub Action \o/

Вывод

В заключение скажу, что писать эту статью было довольно весело. Я искренне надеюсь, что вы получили такое же удовольствие от чтения, как и я от написания 🙂

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

А до тех пор получайте удовольствие, учась, развиваясь и прекрасно проводя время. 😄

Первоначально опубликовано на http://10xlearner.com 5 декабря 2019 г.