简体   繁体   中英

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 ). For example, gem.bat (note the last line)

@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 . For example, 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). But, many gems (bundler, rake, etc) are trying to execute in a non-existent system 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?

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? Am I just doing it wrong? Should I require a system Ruby and then using Bundler or something to isolate it?

I'm one of the maintainers of RubyInstaller project, which is the one that produced the first batch files you shown.

When Ruby is compiled, we replace the generated batch files that Ruby builds with our own batch_stub

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.

Gems can be installed anywhere, not only inside Ruby's tree (eg by using Bundler or gem install --install-dir or --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.

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.

A quick fix will be prepend the PATH with the directory of this isolated 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).

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.

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.

Hope this explains why the batch files generated by RubyGems differ from the ones generated by RubyInstaller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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