为什么 gem 不向 Rails 应用程序添加 rake 任务?

Why is this gem not adding rake tasks to a Rails app?

我们有 a gem which runs via a Rake task. The task is defined in lib/tasks/<namespace>.rake. After reading Rake tasks inside gem not being found I confirmed that the .gemspec includes the file defining the task; there is also a railtie which should be including the tasks as suggested in including rake tasks in gems。然而我们的 Rails 4.1 应用程序似乎没有加载 Rake 任务。

我错过了什么?

我刚刚成功测试了你的 gem,我发现其中的 rake 任务没有问题:

  • 我将 gem_fresh 添加到 Gemfile 和 运行 bundle,安装了 gem
  • 我立即可以在耙子列表中看到耙子:

    $ rake -T outdated
    rake gem_fresh:outdated  # outdated
    
  • 然后我更新了railtie.rb文件以使用load方法加载lib/task/metrics.rake中定义的rake并再次搜索可用的rake:

    # lib/gem_fresh/railtie.rb:
    rake_tasks do
      namespace :gem_fresh do
        desc "outdated"
        task :outdated => :environment do
          GemFresh::Reporter.new.report
        end
      end
    
      load "tasks/metrics.rake"
    end 
    
    $ rake -T outdated
    rake gem_fresh:outdated     # outdated
    rake metrics:outdated_gems  # display outdated gem version metrics
    

所以,我看不出你的 gem 有什么问题。 railtie 中的两种方法(内联 rake 以及使用加载方法)似乎都可以正常工作。我注意到的唯一区别是我在 rails 4.2 上对此进行了测试,但我怀疑这会有所作为。

您是否将 gem 放入您的 Gemfile 中? 如果我从那里删除它,我确实看不到 gem_fresh 耙定义。

问题不在于 gem,而在于它包含在应用程序中的方式。

Gemfile 中,这有效并包括 rake 任务:

gem 'gem_fresh'

这有效,但包括耙任务:

group :development do
  gem 'gem_fresh'
end

这似乎是由于 Bundler 如何在 Rails 应用程序中需要 gems。 From the documentation:

By default, a Rails generated app calls Bundler.require(:default, Rails.env) in your application.rb, which links the groups in your Gemfile to the Rails environment.

如果由于某种原因 Rails.env 参数未评估为包括 :development 组,当我调用 rake -T 时似乎就是这种情况,gem 不会是 Bundler.require-d,并且不会加载 rake 任务。

它不包括 :development 组这一事实似乎是一个奇怪的捆绑器 "gotcha",但至少现在我知道将其移至默认组可以解决问题并且它是gem.

没问题

在我的例子中,需要 gem 的项目有一个 rake 文件,当我更改 rake 文件的名称时,我需要的 gem 具有相同的名称,我可以看到项目中的任务。

my_gem 有 lib/tasks/XXXX.rake,my_proj 也有 lib/tasks/XXXX.rake, 在我将 my_gem XXXX.rake 更改为 YYYY.rake 之后,我设法列出并使用 YYYY.rake

中的任务