Ruby: доступ к задаче грабли из драгоценного камня без Rails

Я знаю, что задачи Rake могут быть определены в нескольких местах в камне Ruby:

  • внутри Rakefile
  • внутри tasks/*.rake
  • внутри lib/tasks/*.rake

Я читал, что первые два должны использоваться, когда задачи должны выполняться на самом камне. Похоже, что третий вариант должен быть выбран, когда требуемые задачи будут общедоступными.

Есть много обучающих онлайн-демонстраций, демонстрирующих множество методов для загрузки задач Rake из драгоценного камня с использованием Rails, а именно с помощью Rails::RailTie.

Тем не менее, я хотел бы найти способ использования задач создания драгоценных камней в другом драгоценном камне, не требуя Rails.

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

UPDATE

Я попытался создать файл bin/my-gem, чтобы сделать доступным в системе для выполнения задач Rake из my-gem. Я добавил следующее внутри:

#!/usr/bin/env ruby
require 'rubygems'
require 'rake'
task=ARGV[0]
spec = Gem::Specification.find_by_name('dsi_core')
Dir["#{spec.gem_dir}/lib/tasks/*.rake"].each {|file| puts file and Rake::load_rakefile(file)}
Rake::Task.clear # Avoid tasks being loaded several times in dev mode
Rake::Task[task].reenable # Support re-execution of a task.
Rake::Task[task].invoke

Часть содержимого была основана на этом сообщении SO.

К сожалению, я делаю что-то не так, потому что после установки gem, а затем my-gem mytask с mytask, определенного в lib/test.rake, выводится следующее:

/var/lib/gems/1.8/gems/rake-0.9.2/lib/rake/task_manager.rb:49:in `[]': Don't know how to build task 'mytest' (RuntimeError)
    from /var/lib/gems/1.8/gems/rake-0.9.2/lib/rake/task.rb:298:in `[]'
    from /var/lib/gems/1.8/gems/my_gem-0.0.1/bin/my_gem:8
    from /usr/local/bin/my_gem:19:in `load'
    from /usr/local/bin/my_gem:19

Ответ 1

Я нашел тело решения здесь. Я изменил его для поддержки спецификации задач с аргументами и добавил поддержку cucumber.

Итак..

Внутри вашего драгоценного камня создайте bin/my_gem

Вставьте script внизу этого сообщения в него. См. Комментарии для примера использования.

Ваши задачи rake должны быть в вашем Rakefile.

В качестве альтернативы добавьте свои задачи, например. на lib/tasks/*.rake, затем добавьте следующее в свой Rakefile:

Dir.glob('lib/tasks/*.rake').each {|r| import r}

Здесь секретный соус:

#!/usr/bin/env ruby

# Run rake tasks and cucumber features
# from my_gem once it installed.
#
# Example:
#
#   my_gem rake some-task
#   my_gem rake some-task[args]
#   my_gem cucumber feature1 feature2
#
# Note: cucumber features have '.feature' appended automatically,
#       no need for you to do it ;)
#
# Author:: N David Brown
gem_dir = File.expand_path("..",File.dirname(__FILE__))
$LOAD_PATH.unshift gem_dir# Look in gem directory for resources first.
exec_type = ARGV[0]
if exec_type == 'rake' then
    require 'rake'
    require 'pp'
    pwd=Dir.pwd
    Dir.chdir(gem_dir) # We'll load rakefile from the gem dir.
    Rake.application.init
    Rake.application.load_rakefile
    Dir.chdir(pwd) # Revert to original pwd for any path args passed to task.
    Rake.application.invoke_task(ARGV[1])
elsif exec_type == 'cucumber' then
    require 'cucumber'
    features = ARGV[1,].map{|feature| "#{gem_dir}/features/#{feature}.feature"}.join(' ')
    runtime = Cucumber::Runtime.new 
    runtime.load_programming_language('rb') 
    pwd=Dir.pwd
    Dir.chdir(gem_dir) # We'll load features from the gem dir.
    Cucumber::Cli::Main.new([features]).execute!(runtime)
    Dir.chdir(pwd) # Revert to original pwd for convenience.
end

Бинго!: -)

Ответ 2

Этот пост дал мне несколько намеков, но, возможно, для других, которые сталкиваются с этим, я боролся с некоторыми проблемами зависимости. Я, наконец, решил, как это сделать с bin/binstub и не требует rakefile. Мое решение опубликовано по другому вопросу SO.