是否有宝石规格。name 必须等于 gem 常量名称吗?

Jon*_*son 3 gem rubygems ruby-on-rails gemspecs ruby-on-rails-3.2

tl;博士

我试图将更大的应用程序的一部分作为可安装的引擎。引擎将以不同的形式存在,每一种都包含在自己的宝石中。我无法让 gem 名称与引擎常量名称不同。

细节

提取的部分包含用于注册、身份验证和会话处理的逻辑。该应用程序被世界不同地区的客户使用,对使用该产品的最终客户有不同的要求和规定。这促使我们为每个监管区域的这些需求创建单独的模块。它们当前位于 lib 目录中,并且根据配置加载不同的实现。

引擎的目标是安装适当的引擎,路由文件将所有相关调用路由到引擎。

由于我们有几个这样的注册模块,而且还有更多,我们需要为这些变体维护几个 gem。我正在尝试使 gems 具有不同的名称(auth_A、auth_B 等),但包含的引擎具有相同的内容名称 Auth::Engine。

这样我们就可以在 Gemfile 中包含正确的 gem,其余的就可以正常工作,因为无论运行什么版本,它应该路由到的端点总是相同的。

问题

我遇到的问题是我无法让 gem 具有一个名称而引擎具有另一个名称...

如果我生成一个新的引擎名称 auth,则可以将其安装在主应用程序中。如果我然后将 gem 名称和包含文件夹更改为 auth_a 并更新主机应用程序 Gemfile 它停止工作,我可以很好地捆绑,但是当我尝试启动主机应用程序时,它在连接到安装引擎时失败,抱怨 Auth::引擎是一个未定义的常量。

我的,稍微编辑了一下,gemspec 看起来像这样:

$:.push File.expand_path("../lib", __FILE__)

# Maintain your gem's version:
require "auth/version"

# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
  s.name        = "auth_a"
  s.version     = Auth::VERSION
  s.authors     = ["Jonas Schubert Erlandsson"]
  s.email       = ["jonas.schubert.erlandsson@xxxxxx.com"]
  s.homepage    = "http://some.page.on/the/internet.html"
  s.summary     = "Authentication module for A"
  s.description = "This engine, when mounted in Host app, handles registration, account update, login and logout of users."

  s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
  s.test_files = Dir["test/**/*"]

  s.add_dependency "rails", "~> 3.2.13"
end
Run Code Online (Sandbox Code Playgroud)

我从生成的脚手架中唯一改变的是s.name = "auth_a". 主机应用程序 Gemfile 中的相关行:gem 'auth_a', path: "../auth_a"...

我查看了整个源代码树,试图找到它从 gem 名称推断名称的位置,但我看不到它。我不知道我错过了什么,并且 gem 规范文档对此也没有太大帮助......我不认为 gem 名称绑定到 gem 的常量名称,但也许我是错误的?你能覆盖它吗?还是我错过了其他东西?

Jon*_*son 5

对此的答案是简单地将其添加到主机应用程序 Gemfile: 中的行中gem 'auth_a', path: "../auth_a", require: 'auth'。

所以看起来它默认为 require ,即自动加载,一个基于 gem 名称的常量,但 require 调用告诉它需要什么。

希望它也能帮助其他人:)