CARVIEW |
Navigation Menu
-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Make Windows bin stubs portable #2119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Windows bin stubs portable #2119
Conversation
Nice! @MSP-Greg. Do you have an example/log file that can demonstrate this working and what the final generated binstub is? |
It does.
Below are old and new. Using the old version, I would need to reset all the paths. Also, if one has many ruby versions (I have several hundred, though they're not all unzipped), I can run any bin file by including the full path in the command line. With the old, that won't work... Thanks, Greg New erubis.bat file: @ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"%~dp0ruby.exe" "%~dp0erubis" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"%~dp0ruby.exe" "%~dpn0" %* Old erubis.bat file: @ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"C:\ruby25_64\bin\ruby.exe" "C:/ruby25_64/bin/erubis" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"C:\ruby25_64\bin\ruby.exe" "%~dpn0" %* |
@hsbt - prefer old or new? Or other ruby committers familiar with Windows... Thanks, Greg |
Looking into how rubygems is generating binstubs, maybe we should be implementing a windows version of the rubygems/lib/rubygems/installer.rb Line 553 in e796847
|
I'm sorry, I don't know what you mean by 'to set the executable'... |
Apologies, I'm not sure what the Windows terminology is. I mean the the path to ruby. Either it be |
I'm not familiar with |
I suspect terms are the same. I might say path & file name, or directory & filename.
I've been at windows for a while (I was coding in DOS days). Never looked, and google does not seem to have anything that I could find, at least on microsoft.com. Best description of %~dp0:
So, like Really, the only difference between the old code vs this PR is that after the PR, the directory is resolved at runtime, vs the old code resolves at gem installation time. Hence, not portable... Sorry, I should have phrased it as above when I did the PR... Thanks, Greg |
Just thought of one thing I haven't looked at. With all the CI & local testing I've done (often on gems I don't use), I've often used their bunder setup and ran bundler with a 'install in this folder' parameter (don't recall what it is). Never had any problems. I also know you can install gems in folders other than the default. I assume doing so does not alter where bin files go, it just changes LOAD_PATH? |
Sorry for the ping. If you have a few minutes, another windows opinion might be helpful. This PR changes the gem files in the bin folder. Old & new examples above... Thanks, Greg |
I agree the WinNT part, but have a little concern about non WinNT part. New elbis.bat should be @ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"C:\ruby25_64\bin\ruby.exe" "C:/ruby25_64/bin/erubis" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"%~dp0ruby.exe" "%~dpn0" %* because non WinNT platform (= Win9x) does not recognize BTW, we (ruby itself) don't support Win9x no longer, so simply we may be able to remove non WinNT part. |
You have a seriously good memory. I used original PC's and Apple II's, but I don't remember much. I just looked at the existing code and replaced the directory strings, but @ECHO OFF
@"%~dp0ruby.exe" "%~dpn0" %* is certainly simple. I think I'd concur that win9x support is not needed. I'll update the PR. For non-windows types, I changed my rackup (puma) file to match the above, as it's probably got the most parameters. Works fine. Also, the gem bin file is not Win9x compatible, so this change would be matching it... Thanks, Greg |
Oh, I just remembered! |
I kind of asked about that earlier,.. If If
Agreed? I'm not sure what the typical use case for specifying Thanks, Greg |
Agreed. |
Two more use cases:
So, we've got I'm assuming that |
This comment has been minimized.
This comment has been minimized.
hi! it's been >2 months since the last activity here. can someone let me know what the status of this PR is? thanks! |
Again, what path should be used in the bin files for gems installed with any or all of the following options: I think that the Ruby command should default to the ruby version based on PATH. An normal install should use the Ruby version it's contained in (using |
I think we should default to the equivalent of |
I thought this was mostly a discussion of the window bin files. The only 'standard' for the Ruby installation location might be from the default RubyInstaller setup, but I don't think that's a good assumption. If you have any thoughts on 'standard' use cases for this issue, they'd be helpful. I've been using & coding on Windows since DOS days, and I've got hundreds of Ruby builds on my system, as I occasionally need to manually bisect with the builds. I know how I'd like it to work, but that may not translate well to a beginning Ruby/Rails user... As I see it, the main issue is how to code the path for ruby.exe & and the file it loads. They can be:
Thanks, Greg |
My home development system's motherboard stopped working, so (for the time being), I set up a small notebook for basic work. In the process of doing that, I've got some thoughts that might wrap this up. Assuming we don't require support of Windows previous to Vista, I now feel the stub should be: def windows_stub_script(bindir, bin_file_name)
# All comparisons should be case insensitive
if bindir.downcase == RbConfig::CONFIG["bindir"].downcase
# stub & ruby.exe withing same folder.
<<-TEXT
@ECHO OFF
@"%~dp0ruby.exe" "%~dpn0" %*
TEXT
elsif bindir.downcase.start_with? RbConfig::TOPDIR.downcase
# stub within ruby folder, but not standard bin.
require 'pathname'
from = Pathname.new bindir
to = Pathname.new RbConfig::CONFIG["bindir"]
rel = to.relative_path_from from
<<-TEXT
@ECHO OFF
@"%~dp0#{rel}/ruby.exe" "%~dpn0" %*
TEXT
else
# outside ruby folder, maybe -user-install or bundler.
<<-TEXT
@ECHO OFF
@ruby.exe "%~dpn0" %*
TEXT
end
end Since both Bundler and --user-install separate gems into 'ruby_version' folders, Thoughts? Thanks, Greg |
4372fd2
to
cf980b8
Compare
908b0a5
to
a223249
Compare
Sorry for the ping; I thought your input re this PR would be appreciated. BTW, I noticed you've recently made a few windows specfic core commits (thank you). I've always been bothered by the the .cmd/.bat files (bin stubs) created by RubyGems. I felt they should be portable/reproducible, and I also found them cumbersome to work with. For quite while, I've had scripts to replace them. Anyway, my main use case was for testing across several builds of a given major.minor version (often trunk.) I install gems using the For bin stub locations within There is one issue that this affects, although the issue is also problematic with the current bin stubs, and that is if one tries to install extension gems outside of Off topic - fat binaries:Since many gems repos have limited resources, and often more so re Windows, I'm working on PowerShell scripts to build fat binary gems on Appveyor, as all the build tools are already installed, and no one needs to determine how to cross compile (often needing both DevKit and MSYS2). One thing I expect to do is combine both 32 and 64 builds in one gem file, and adjust the load code to account for that. Obviously, the gem is larger, but since many gems' *.so files aren't stripped, once that's done, the increase in size isn't that great... A good example of the mess that can occur is building EventMachine or Puma, which both build with OpenSSL. EM currently supports Ruby 2.0 thru 2.5. To build it to match the standard Ruby builds, it requires four different OpenSSL packages (two DevKit, two MinGW), and the two builds systems (DevKit & MSYS2 / MinGW). That's just too much for people who normally use MacOS or *nix... Thanks, Greg |
a223249
to
a49d44e
Compare
LGTM. |
☔ The latest upstream changes (presumably #2299) made this pull request unmergeable. Please resolve the merge conflicts. |
a49d44e
to
974c7ae
Compare
The current method hard codes the ruby.exe path into the bin stub. First of all, that is a portability issue. I consider this issue (and the code in the PR) to be divided into three categories, dependent on the relationship of the bin stub folder to
For portability, RubyInstaller, RubyInstaller2 and ruby-loco builds modify these bin stubs by changing the hard coded path to
The code determines a relative path to
Since these bin stub are outside of Of the above three cases, the first two behave exactly like the current code, but result in portable builds. The third case is where ‘desired functionality’ comes into play, but only if one has more than one ruby build installed. Gems with bin stubs behave in different ways. One common behavior is to operate on a standardized file name in the folder it’s launched from (like Gemfile or Rakefile). Since this assumes your path is set to the version of Ruby that you want to run it with, using Another use case is testing with multiple builds/versions of Ruby with the same ABI version. One would often use I could probably come up with more ‘plus’ cases for category 3, and I could probably come with some ‘minus’ use cases also. Summing up, if one has only one Ruby build, this PR works the same as the current code. With multiple builds/versions and a bin stub folder outside of Thanks, Greg |
Sorry, I missed "Can you add reproduction instructions for this problem?" I hope you agree with the above options 1 & 2 above, as with the PR, the current code does not allow the ruby install to be moved (and PATH adjusted accordingly), as the '--user-install` bin stubs are calling ruby in a different path. The PR code does. So we're down to repo'ing option 3. First of all, I may often have several console windows open, but I also have a script that allows me to change Ruby versions, it modifies PATH and also sets the window title. So I'm assuming that users are not going to be prefixing As to option 3 (typically a
Install more that one Ruby build of a given ABI version (say 2.5.0 and 2.5.1). then Or Install both 32 & 64 bit builds of a given ABI version, along with binary gems for each. If you switch between the builds by changing your path, the bin stub will work with the PR's code, with the current code, they will not. I hope this makes sense. Thanks, Greg |
I think Gregs proposal is a pretty good solution. This is the only issue for using Ruby in a portable way on Windows right now. It would be nice if this could be fixed. |
I agree with larskanis, Gregs solution looks good and would have solved my issues from #1402 as well. Thank you Greg! |
I understood. Thanks. |
@bundlerbot r+ |
📌 Commit 974c7ae has been approved by |
Make Windows bin stubs portable # Description: Windows bin stubs for installed gems are not portable due to the fact that the path (at install time) is embedded in the .bat or .cmd file. This patch removes the path and replaces with `%~dp0`, which is the windows cmd variable for the running script's path. It passed tests locally, and I patched a fresh 2.4.3 install with it and updated/installed bundler and rake. I even added a space to the path and all commands correcty ran from a command prompt. See #2111 ______________ # Tasks: - [X] Describe the problem / feature - [ ] Write tests - [X] Write code to solve the problem - [ ] Get code review from coworkers / friends I will abide by the [code of conduct](https://github.com/rubygems/rubygems/blob/master/CODE_OF_CONDUCT.md).
☀️ Test successful - status-travis |
Description:
Windows bin stubs for installed gems are not portable due to the fact that the path (at install time) is embedded in the .bat or .cmd file. This patch removes the path and replaces with
%~dp0
, which is the windows cmd variable for the running script's path.It passed tests locally, and I patched a fresh 2.4.3 install with it and updated/installed bundler and rake. I even added a space to the path and all commands correcty ran from a command prompt.
See #2111
Tasks:
I will abide by the code of conduct.