Pull to refresh

Создание гемов — Руководство

Ruby
Хотя на Хабре уже проскакивали статьи о создании гемов, они либо содержат устаревшую, либо неполную информацию.

Как же на самом деле надо создавать, развивать и публиковать свои гемы?

Современный подход заключается в использовании Bundler совместно с другими инструментами, такими, как Git, YARD и RSpec-2.

Создание базовой структуры


Итак, чтобы создать новый гем, достаточно выполнить команду
bundle gem YOUR-GEM-NAME

Естественно, у Вас до выполнения этой команды уже должен быть установлен гем bundler (gem install bundler).

После этого вы получите базовую структуру Вашего нового гема в каталоге YOUR-GEM-NAME с уже готовыми командами для построения гема, его инсталляции и публикации в rubygems:
cd YOUR-GEM-NAME
rake -T
rake build    # Build YOUR-GEM-NAME-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 (пример).

Подключить его достаточно просто:
  • Добавляем зависимость времени разработки в gemspec:
      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'

К тому-же такой подход означает, что большую часть логики можно будет покрыть спеками.

Контроль версий


Общее правило заключается в использовании Git в качестве репозитория и семантического версионирования при формировании номеров версий гемов. rake release будет автоматически создавать необходимые тэги в репозитории и публиковать гем в rubygems.

Удаление ошибочных версий гемов


Иногда возникает задача удалить какую-либо версию гема с rubygems в связи с проблемами конкретной версии (ошибки в коде или неправильное версионирование). Эта задача выполняется с помощью команды

gem yank gemname -v version

Эта команда по умолчанию не поставляется вместе с rubygems, поэтому для ее использования надо установить гем jeweler.

gem install jeweler
Tags:rubyrubygemsbundleryardrspecgemgemspecrake
Hubs: Ruby
Total votes 32: ↑29 and ↓3+26
Views8.7K

Popular right now