Crystal Programming. Введение на основе проекта в создание эффективных, безопасных и читаемых веб-приложений и приложений CLI - Джордж Дитрих
Однако бывают случаи, когда вы можете не захотеть автоматически переформатировать код, а просто определить, является ли он допустимым. В этом случае вы можете передать опцию --check, которая заставит команду возвращать ненулевой код выхода, если в код были внесены какие-либо изменения. Это может быть полезно в сценариях/рабочих процессах автоматизации, которые используют коды завершения, чтобы определить, была ли команда успешной.
Помимо проверки правильности форматирования кода, неплохо было бы также линстовать его. Линтинг позволит выявить любые запахи кода или идиоматические проблемы, которые необходимо решить. Давайте посмотрим на это дальше!
Линтинг-код
Статический анализ — это анализ исходного кода программы с целью выявления проблем в коде без необходимости фактического выполнения программы. Этот процесс в основном используется для обнаружения проблем безопасности, стилистических или неидиоматических проблем с кодом.
Эти инструменты статического анализа не являются чем-то новым для языков программирования. Однако типизированная природа Crystal позволяет справиться с большей частью того, с чем может справиться внешний инструмент статического анализа, не требуя ничего, кроме самого компилятора. Хотя компилятор будет обнаруживать ошибки, связанные с типом, он не будет обнаруживать более идиоматические проблемы, такие как запах кода или использование неоптимальных методов.
В Crystal доступен инструмент статического анализа https://github.com/crystal-ameba/ameba. Этот инструмент обычно устанавливается как зависимость разработки, добавляя его в файл shard.yml и затем запуская shards install:
development_dependencies:
ameba:
github: crystal-ameba/ameba
version: ~> 1.0
После установки Ameba создаст и выведет себя в папку bin/ вашего проекта, которую затем можно будет запустить через ./bin/ameba. При выполнении Ameba просмотрит все ваши файлы Crystal, проверяя на наличие проблем. Давайте создадим тестовый файл, чтобы продемонстрировать, как это работает:
1. Создайте новый каталог и новый файл shard.yml в нем. Самый простой способ сделать это — run shards init, который создаст файл за вас.
2. Затем добавьте Ameba в качестве зависимости разработки и run shards install.
3. Наконец, создайте в этой папке еще один файл со следующим содержимым:
[1, 2, 3].each_with_index do |idx, v|
PP v
end
def foo
return "foo"
end
4. Затем мы можем запустить Ameba и увидеть примерно следующий результат:
Inspecting 2 files
F.
test.cr:1:31
[W] Lint/UnusedArgument: Unused argument 'idx'. If it's necessary, use '_' as an argument name to indicate that it won't be used.
> [1, 2, 3].each_with_index do |idx, v|
^
test.cr:6:3
[C] Style/RedundantReturn: Redundant 'return' detected
> return "foo"
^----------^
Finished in 2.88 milliseconds
2 inspected, 2 failure
Ameba проверила наш тестовый файл и, хотя сам код валидный, обнаружила некоторые ошибки. Эти ошибки не относятся к тому типу вещей, которые могут помешать выполнению кода, а в большей степени связаны с его общей ремонтопригодностью и читабельностью. Вывод Ameba отображает каждую ошибку, включая ее тип, в каком файле/строке/столбце находится ошибка и к какой категории она относится.
Подобно проверке формата, Ameba также вернет ненулевой код выхода, если обнаружена хотя бы одна ошибка. С другой стороны, Ameba должна быть более настраиваемой, чем форматтер. Например, вы можете настроить ограничения по умолчанию, отключить/включить определенные правила или подавить ошибки в самом коде.
Теперь, когда мы знаем, как обеспечить правильное форматирование нашего кода и отсутствие проблем с его качеством, мы можем перейти к автоматизации всех этих процессов.
Непрерывная интеграция с GitHub Actions
Непрерывная интеграция предполагает автоматизацию рабочих процессов, которые происходят централизованно и обеспечивают различные аспекты написания кода. Что именно он делает, зависит от вас, но наиболее распространенным вариантом использования является сборка, тестирование и анализ кода по мере внесения изменений. Этот процесс обеспечивает автоматизированный способ гарантировать, что в репозиторий вашего проекта будет добавлен только действительный код.
Для этого можно использовать множество провайдеров; однако, учитывая, что GitHub является наиболее вероятным местом размещения вашего проекта, и поскольку у него уже есть хорошие инструменты для Crystal, мы собираемся использовать GitHub Actions для наших нужд непрерывной интеграции.
Прежде чем мы приступим к настройке наших рабочих процессов, мы должны сначала подумать обо всем, что мы от них хотим. Основываясь на том, что мы сделали в последних нескольких главах, я составил следующий список:
1. Убедитесь, что код отформатирован правильно.
2. Убедитесь, что стандарты кодирования соответствуют коду через Ameba.
3. Убедитесь, что наши тесты пройдены.
4. Развертывайте документацию при выпуске новой версии.
Что касается шага 3, есть несколько дополнительных улучшений, которые мы могли бы сделать, чтобы улучшить его, например, запуск на разных платформах или тестирование ночной сборки Crystal, последняя из которых может быть отличным способом получения предупреждений о предстоящих критических изменениях или регрессии, которые, возможно, потребуется исправить или сообщить о них, что в конечном итоге приводит к гораздо более стабильному коду, поскольку вы не пытаетесь исправить проблему в день выхода нового выпуска Crystal.
Работа на нескольких платформах также может быть хорошим способом обнаружить проблемы до того, как они попадут в производство. Однако в зависимости от того, что делает ваше приложение, это может не понадобиться. Например, если вы пишете веб-приложение, которое будет работать только на сервере Linux, нет смысла также тестировать его на macOS. С другой стороны, если вы создаете проект на основе CLI, который будет распространяться на различные платформы, то тестирование на каждой поддерживаемой платформе является хорошей идеей.
В связи с тем, что существует множество различных поставщиков, которые мы могли бы использовать, существует также множество способов настроить каждый рабочий процесс, который в конечном итоге выполняет одно и то же. Рабочие процессы, описанные в этой главе, — это то, что, по моему мнению, лучше всего соответствует моим потребностям/желаниям. Не стесняйтесь настраивать их по мере необходимости, чтобы они наилучшим образом соответствовали вашим потребностям.
Форматирование, стандарты кодирования и тесты
Для начала давайте сначала создадим наш файл рабочего процесса. GitHub ожидает определенную структуру каталогов, поэтому обязательно следуйте инструкциям. Вы можете либо создать новый сегмент для тестирования, либо добавить его в существующий проект:
1. Создайте папку .github в корне вашего проекта, например, на том же уровне, что и shard.yml.
2. В этой папке создайте еще одну папку под названием workflows.
3. Наконец, создайте файл с именем ci.yml. Файл можно было бы назвать как угодно, но, учитывая, что он будет содержать все наши задания