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_stubThis stub considers
%~dp0as 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 (e.g. by using Bundler or
gem install --install-diror--bindir).RubyGems batch files can’t use
%~dp0to determine Ruby in those cases, which is why these batchfile stubs contains onlyruby.exein them.The problem, as you indicated, is that
ruby.exewill be found fromPATH, which contains your global Ruby installation and not the isolated one you’re working on.A quick fix will be prepend the
PATHwith the directory of this isolated Ruby:You can put that in a batch file like
setenv.batthat 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 execwill work as it will usePATHto 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.