Хотя на Хабре уже проскакивали статьи о создании гемов, они либо содержат устаревшую, либо неполную информацию.
Как же на самом деле надо создавать, развивать и публиковать свои гемы?
Современный подход заключается в использовании Bundler совместно с другими инструментами, такими, как YARD и RSpec-2.
Создание базовой структуры
Итак, чтобы создать новый гем, достаточно выполнить команду
bundle gem YOUR-GEM-NAME
После этого вы получите базовую структуру Вашего нового гема в каталоге YOUR-GEM-NAME с уже готовыми командами для построения гема, его инсталляции и публикации в rubygems:
cd YOUR-GEM-NAME rake -T rake build # Build newgem-0.0.1.gem into the pkg directory rake install # Build and install YOUR-GEM-NAME-0.0.1.gem into system gems rake release # Create tag v0.0.1 and build and push YOUR-GEM-NAME-0.0.1.gem to Ru...
Важно отметить, что исходный библиотечный код не должен замусоривать глобальное пространство имен. Пожалуйста, располагайте все ваши классы внутри класса или модуля с именем, предложенным Bundler, в подкаталоге lib/YOUR-GEM-NAME, подключаяя их из файла lib/YOUR-GEM-NAME.rb. Старайтесь не использовать autoload, так как эта возможность объявлена устаревшей для Ruby 2.0.
По возможности все файлы документации должны использовать разметку Markdown (желательно наличие файла README.md).
Документирование кода
Современным инструментом документирования кода является YARD в режиме markdown с использованием модуля redcarpet для поддержки подсветки кода с использованием синтаксиса GitHub. При этом Вы автоматически получаете публкацию документации на rubydoc.info (пример).
Подключить его достаточно просто:
- Добавляем зависимость времени разработки:
s.add_development_dependency "redcarpet", "~> 1.17" s.add_development_dependency "yard", "~> 0.7.5"
Если используем ruby версии 1.8, то желательно также использовать также гем ripper, который добавит полезный функционал для YARD. Подключить его лучше через Gemfile:
gem "ripper", :platforms => :ruby_18, :group => :development
- Выполняем установку гемов
bundle install
- Настраиваем YARD, создав файл .yardopts с таким содержимым:
--markup markdown --markup-provider redcarpet --charset utf-8 --readme README.md - README.md LICENSE
Здесь после однострочного дефиса мы указываем список файлов, которые надо дополнительно включить в документацию (обычно readme и лицензию).
- И добавляем задачу rake yard для генерации документации в Rakefile:
require 'yard' YARD::Rake::YardocTask.new
Теперь по команде rake yard мы получим полную документацию по библиотеке в каталоге doc.
Кстати, не забудьте добавить doc/, .yardoc/ и Gemfile.lock в .gitignore.
Начинаем писать спеки
Лично я предпочитаю использовать для спеков RSpec 2 совместно с RR. Добавим соответствующие зависимости в gemspec:
s.add_development_dependency "rspec-core", "~> 2.0" s.add_development_dependency "rspec-expectations", "~> 2.0" s.add_development_dependency "rr", "~> 1.0"
Выполняем установку гемов и создание базовых файлов RSpec 2
bundle install bundle exec rspec --init
Добавляем задачу rake spec в Rakefile:
require 'rspec/core/rake_task' RSpec::Core::RakeTask.new
И просим использовать по умолчанию RR в spec/spec_helper.rb:
config.mock_with :rr
Все, теперь можно писать спеки и код.
Немного об исполняемых файлах
Файлы, которые Вы кладете в каталог bin вашего гема, при инсталляции гема инсталлируются как исполняемые файлы целевой операционной системы.
Здесь есть маленький нюанс: в разных операционных системах эта инсталляция происходит по-разному, и иногда ваши исполняемые файлы запускаются вовсе не из подкаталога bin вашего гема, на что вы могли случайно настроиться.
В связи с этим, наилучшей практикой при создании исполняемого файла является перенос всей логики в библиотеку, с тем, чтобы бинарный файл your-gem-exec выглядел где-то так:
require 'rubygems' # не нужно для ruby 1.9 и выше require 'your-gem' require 'your-gem/exec'
К тому-же такой подход означает, что большую часть логики можно будет покрыть спеками.
Автор: akzhan