Ruby: Настройка окружения
Теория: Структура гемов и проектов
Bundler появился в Ruby значительно позже RubyGems. Из-за этого устройство библиотек (гемов) и проектов немного отличается. В этом уроке мы немного заглянем внутрь гемов, чтобы понять принципы их работы. Изучим команду bundle gem, которая создает структуру для нового гема и которая, с небольшими модификациями, подходит для своих проектов. Она в себя уже включает настроенный линтер, тесты и интеграцию с Github Actions.
Для работы прикладных проектов в Ruby ничего кроме Bundler не нужно. Достаточно создать Gemfile, указать зависимости и подключить Bundler в своем коде. Дальше можно не отвлекаться и писать прикладной код.
Для гемов все чуть сложнее. У гемов есть метаданные, например, версия, имя, описание и т.п. У гемов есть зависимости, которые должны учитываться RubyGems при установке. Для всего этого нужен специальный файл, называемый спецификацией гема. Кроме того, у гемов есть определенные соглашения по организации кода, которые важны для удобной работы c require.
Гем можно создать полностью руками, но лучше воспользоваться готовой командой bundle gem, которая сделает все сама. Ниже мы пройдемся по всем этапам создания гема и изучим организацию кода внутри. Все это поможет понять работу Ruby и научит эффективно организовывать разработку как гемов, так и своих проектов.
bundle gem
Начнем с генерации. Для этого запустим команду bundle gem, которая задаст несколько вопросов и затем создаст директорию с названием гема и нужными файлами внутри.
Спецификация
Спецификация гема описывается Ruby кодом. Внутри нее что-то уже заполнено автоматически, но есть места где стоит TODO. Их нужно заполнить, иначе с кодом не получится работать, он начнет просить заполнения.
Для работы с гемом нужно сделать две вещи:
- Заполнить summary и description. Для простоты просто сотрите TODO.
- Все остальные TODO закомментировать включая homepage_uri, который ссылается на homepage
Зависимости
RubyGems в своей работе опирается только на спецификацию гема. Сюда входят и зависимости. То есть все что нужно для работы гема, должно быть указано в gemspec-файле:
Здесь же указывались и зависимости для разработки, но с появлением Bundler это изменилось. Все зависимости, необходимые во время разработки и тестирования, переехали в Gemfile.
И чтобы не дублировать зависимости самого гема, в Bundler добавили функцию gemspec (в примере выше), которая подтягивает рантайм-зависимости из спецификации в Gemfile.
Следующий шаг в разработке гема — установка зависимостей. Для этого выполняется команда bin/setup:
После установки зависимостей можно начинать разрабатывать, запускать линтер, тесты и другие команды. Начнем с линтера. У Rubocop есть свой исполняемый файл rubocop. Каким образом его запустить? Правильный способ через команду bundle exec. Эта команда запускает исполняемые файлы из зависимостей текущего проекта игнорируя глобально установленные программы.
Точно так же запускаются любые другие утилиты, которые устанавливаются как зависимости в проект.
Rake
Еще один важный элемент экосистемы Ruby - Rake. Rake это Ruby + Make, фреймворк для описания и запуска разнообразных задач связанных с проектом. Список доступных задач можно посмотреть через утилиту rake:
Эти задачи не встроены в rake, они добавлены, во время генерации гема, в файл Rakefile.
Часть задач подгружается из гемов, но некоторые описаны прямо здесь, например запуск тестов. Rubocop тоже присутствует здесь, то есть линтер можно запускать и так:
Rake важная часть экосистемы Ruby. Практически ни один проект не обходится без него. Например, в Rails из коробки идет несколько десятков таких команд. Плюс всегда можно написать свои.
Структура проекта
Код гема находится в директории lib и организован определенным образом:
Внутри lib лежит Ruby-файл и директория по имени гема. Ruby-файл hexletgem.rb содержит входной модуль в гем, в нашем случае он называется Hexletgem:
Именно через этот модуль пользователи гема будут получать доступ к его содержимому. Это важное соглашение, которое позволяет интуитивным образом понимать, как можно взаимодействовать с гемом после его включения в проект:
Директория lib/hexletgem содержит файл version.rb в котором указана версия гема:
Все остальные файлы с кодом располагают рядом с этим файлом, внутри директории hexletgem и ее поддиректориях.
Превращение гема в проект
Генерация гема создает удобную структуру не только для разработки гемов, но и для прикладных проектов. Для готовности нужно сделать два шага:
- Удалить файл с версией
- Удалить gemspec-файл

