简体   繁体   English

RubyGems是否创建了宝石批处理文件错误或者我错过了什么?

[英]Is RubyGems creating the gem batch file wrong or am I missing something?

There are some batch files in the Ruby installation that reference this Ruby exe ( $~dp0ruby.exe ). Ruby安装中有一些批处理文件引用了这个 Ruby exe( $~dp0ruby.exe )。 For example, gem.bat (note the last line) 例如, gem.bat (注意最后一行)

@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
ECHO.This version of Ruby has not been built with support for Windows 95/98/Me.
GOTO :EOF
:WinNT
@"%~dp0ruby.exe" "%~dpn0" %*

But, some gems get a batch file that references the system Ruby ( ruby.exe ), whichever one is on the PATH . 但是,一些gem获得了一个引用系统 Ruby( ruby.exe )的批处理文件,无论哪个都在PATH For example, bundle.bat 例如, bundle.bat

@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"ruby.exe" "C:/Ruby192/bin/bundle" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"ruby.exe" "%~dpn0" %*

I have an isolated Ruby environment for a .NET project (where it's unlikely that the developers or build agents have a system Ruby). 我有一个用于.NET项目的独立Ruby环境(开发人员或构建代理不太可能拥有系统Ruby)。 But, many gems (bundler, rake, etc) are trying to execute in a non-existent system Ruby. 但是,许多宝石(bundler,rake等)都试图在一个不存在的系统Ruby中执行。

C:\
  Ruby192\            <-- System Ruby, would be here
    bin\                  and this bin would be in the
      bundle.bat          PATH
      gem.bat
      ruby.exe

  <some-other-path>\  <-- An isolated environment, in
    Ruby\                 my problem, this is deployed 
      bin\                to a build agent
        bundle.bat
        gem.bat
        ruby.exe

What gives? 是什么赋予了? Is this a defect in the way that rubygems creates the batch file? 这是rubygems 创建批处理文件的方式的缺陷吗?

def windows_stub_script(bindir, bin_file_name)
  ruby = File.basename(Gem.ruby).chomp('"')
  return <<-TEXT
@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"#{ruby}" "%~dpn0" %*
TEXT
end

What's the thinking of not referencing the ruby.exe that you used to gem install this gem? 有什么想法没有引用你用于gem install这个gem的ruby.exe Am I just doing it wrong? 我只是做错了吗? Should I require a system Ruby and then using Bundler or something to isolate it? 我应该需要一个系统Ruby,然后使用Bundler或其他东西来隔离它吗?

I'm one of the maintainers of RubyInstaller project, which is the one that produced the first batch files you shown. 我是RubyInstaller项目的维护者之一,该项目生成了您显示的第一批文件。

When Ruby is compiled, we replace the generated batch files that Ruby builds with our own batch_stub 编译Ruby时,我们用自己的batch_stub替换Ruby生成的生成的批处理文件

This stub considers %~dp0 as the place where Ruby's executable is, relative to this batch file, because we know these batch files will be along the executable. 这个存根认为%~dp0是Ruby的可执行文件相对于这个批处理文件的地方,因为我们知道这些批处理文件将沿着可执行文件。

Gems can be installed anywhere, not only inside Ruby's tree (eg by using Bundler or gem install --install-dir or --bindir ). Gems可以安装在任何地方,不仅可以安装在Ruby的树中(例如使用Bundler或gem install --install-dir--bindir )。

RubyGems batch files can't use %~dp0 to determine Ruby in those cases, which is why these batchfile stubs contains only ruby.exe in them. 在这些情况下,RubyGems批处理文件不能使用%~dp0来确定Ruby,这就是为什么这些批处理文件存根中包含ruby.exe的原因。

The problem, as you indicated, is that ruby.exe will be found from PATH , which contains your global Ruby installation and not the isolated one you're working on. 正如您所指出的,问题是可以从PATH找到ruby.exe ,它包含您的全局Ruby安装,而不是您正在处理的孤立的安装。

A quick fix will be prepend the PATH with the directory of this isolated Ruby: 快速修复将在PATH前面加上这个孤立的Ruby的目录:

SET PATH=C:\<some-other-path>\Ruby\bin;%PATH%

You can put that in a batch file like setenv.bat that adjust the environment prior execution of Ruby (or as startup script). 您可以将它放在像setenv.bat这样的批处理文件中,在执行Ruby之前调整环境(或作为启动脚本)。

The other alternative is use something like gem-exefy , which will replace the batch files for executable stubs and will use the Ruby dlls found relative to it, so will use the isolated version instead of the global one. 另一种选择是使用类似gem-exefy的东西,它将替换可执行存根的批处理文件,并将使用相对于它找到的Ruby dll,因此将使用隔离版本而不是全局版本。

For homework I'm not sure if bundle exec will work as it will use PATH to look for the executable to run, so can't tell you in detail. 对于家庭作业,我不确定bundle exec是否会工作,因为它将使用PATH来查找要运行的可执行文件,因此无法详细告诉您。

Hope this explains why the batch files generated by RubyGems differ from the ones generated by RubyInstaller. 希望这能解释为什么RubyGems生成的批处理文件与RubyInstaller生成的批处理文件不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM