СоХабр закрыт.
С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.
Тема статических анализаторов кода изъезжена. Последние полгода практически нет конференции без выступления, посвященного этому вопросу. Но все они рассказывают об анализаторах изнутри, показывают механизмы их работы. При этом забывают грамотно объяснить, для чего они изначально предназначены. Чаще всего рассматривается теоретическая часть работы статических анализаторов, без практической реализации. Поэтому расскажу про цели, которые преследуются статическими анализаторами в реальных командах на коммерческих проектах. А также рассмотрю пример организации работы с различного рода анализаторами в нашей компании.
Это анализ программного кода, проводимый без его запуска. Поэтому ошибки run-time работы программы отловить с его помощью нельзя. Статический анализ работает лишь с текстовым кодом программы, что занимает несколько секунд на запуск, но экономит часы при нахождении багов.
Существует несколько методик, по которым работают анализаторы.
Анализаторы нужны, чтобы находить баги на максимально раннем этапе. В нашем случае — это компиляция проекта. Чем позже будут найдены баги, тем дороже они обойдутся разработчику и бизнесу в целом.
Однако, эта цель слишком общая и не несет особой смысловой нагрузки. Попробуем декомпозировать её на несколько мелких:
Самым популярным на данный момент анализатором кода для Swift является swiftlint. Мы также используем tailor. Первый позволяет создавать свои собственные правила на основе регулярных выражений, что дает возможность реализовать большинство правил из вашего styleguide.
Swiftlint позволяет создавать кастомные правила, которые необходимо поместить в конфигурационный файл .swiftlint.yml, находящийся в вашем проекте. У языка описания кастомных правил есть ряд параметров.
К примеру, в вашей компании вы используете только weak и не используете unowned. Производительность последнего выше, чем первого. Но то, что weak не приведет к падению приложения, для вас более важно. Это легко можно сделать с помощью регулярного выражения и создать кастомное правило.
unowned:
name: "Unowned"
regex: 'unowned'
message: "Please use `weak` instead. "
severity: error
Еще один пример про комментарии. Допустим, вы не пишете хедеры у себя в проекте. Регулярное выражение также идеально с этим справится.
no_header_comments:
name: "Header Comments"
regex: '//\s*Created by.*\s*//\s*Copyright'
match_kinds:
- comment
message: "Template header comments should be removed."
Самая интересная часть заключается в масштабировании и автоматизации процесса статического анализа. Особенно это важно, если проектов несколько и хочется, чтобы все кастомные правила были одинаковы для них. Все анализаторы имеют некий конфигурационный файл, в котором и хранятся настройки. В наших проектах таких файлов три: .swiftlint.yml, .tailor.yml, cpd_script.php.
Последний файл является скриптом, написанным на php. Он запускает анализ файла, выдаваемого детектором копипасты в свифтовом проекте. О его настройке расскажу в следующей статье.
Простейшим вариантом поддержки будет создание отдельного репозитория для данных файлов. Мы делаем вот так. Подключить к проекту можно через submodule. Если настройки в файлах конфигурации обновляются, то достаточно обновить submodule. Тогда в вашем проекте будут актуальные правила.
Кроме этого, вы можете пользоваться некоторыми дополнительными функциями github. Мы используем систему issues для создания новых кастомных правил или обсуждения текущих. Это позволяет понять, почему было отклонено то или иное правило. Удобно отслеживать статус, чтобы вносить изменения в файлы конфигурации.
Эта система прекрасно работает на CI. Его можно настроить таким образом, чтобы все pull requests в вашем проекте нельзя было смержить, если анализаторы нашли хотя бы один недочет в коде.
Статический анализ — один из самых ранних способов нахождения ошибок в приложении. Как следствие, самый дешевый. Надеюсь, что простейшая система для хранения конфигурационных файлов статических анализаторов поможет вам сделать проекты «одинаковыми». А еще позволит найти не один баг до этапа тестирования.
комментарии (1)