Ruby:从没有Rails的gem访问rake任务

我知道可以在Ruby gem中的许多地方定义Rake任务:

  • 在Rakefile里面
  • 内部tasks/*.rake
  • lib/tasks/*.rake

我已经读过,当要在gem本身执行任务时,应该使用前两个。 当希望公开任务时,似乎应该选择第三种选择。

网上有许多教程演示了使用Rails从gem加载Rake任务的各种方法,即利用Rails::RailTie

但是,我想找到一种在不需要Rails的情况下在另一个gem中使用依赖gem的任务的方法。

有一个简单的解决方案吗? 有人会善意地描述正确的方法,或概述哪些方法可行?

UPDATE

我已经尝试创建一个文件bin/my-gem ,以便在系统上用于从my-gem执行Rake任务。 我把以下内容放在里面;

 #!/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 

部分内容基于此SOpost 。

遗憾的是我做错了,因为在安装gem之后运行my-gem mytask并在lib/test.rake定义了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 

我在这里找到了解决方案的主体。 我修改它以支持带参数的任务规范并增加对cucumber支持。

所以..

在你的gem中创建bin/my_gem

将此post底部的脚本粘贴到其中。 有关示例用法,请参阅注释

您的rake任务必须在您的Rakefile

或者,将您的任务添加到lib/tasks/*.rake Rakefile然后将以下内容添加到您的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's 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's 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's dir. Cucumber::Cli::Main.new([features]).execute!(runtime) Dir.chdir(pwd) # Revert to original pwd for convenience. end 

答对了! 🙂

这篇文章给了我一些提示,但也许对其他人而言,我遇到了一些依赖性问题。 我终于弄清楚如何用bin / binstub做这个,而不需要rakefile。 我的解决方案发布在另一个SO问题上。