Skip to content

Commit a1a1c90

Browse files
soda92hsbt
authored andcommitted
[rubygems/rubygems] add loading support on Windows
ruby/rubygems@04574ba59a
1 parent b600c95 commit a1a1c90

File tree

2 files changed

+37
-38
lines changed

2 files changed

+37
-38
lines changed

lib/bundler/cli/exec.rb

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ def run
1919
validate_cmd!
2020
SharedHelpers.set_bundle_environment
2121
if bin_path = Bundler.which(cmd)
22-
if !Bundler.settings[:disable_exec_load] && ruby_shebang?(bin_path)
23-
return kernel_load(bin_path, *args)
22+
if !Bundler.settings[:disable_exec_load] && directly_loadable?(bin_path)
23+
bin_path.delete_suffix!(".bat") if Gem.win_platform?
24+
kernel_load(bin_path, *args)
25+
else
26+
bin_path = "./" + bin_path unless File.absolute_path?(bin_path)
27+
kernel_exec(bin_path, *args)
2428
end
25-
bin_path = "./" + bin_path unless File.absolute_path?(bin_path)
26-
kernel_exec(bin_path, *args)
2729
else
2830
# exec using the given command
2931
kernel_exec(cmd, *args)
@@ -69,6 +71,29 @@ def process_title(file, args)
6971
"#{file} #{args.join(" ")}".strip
7072
end
7173

74+
def directly_loadable?(file)
75+
if Gem.win_platform?
76+
script_wrapper?(file)
77+
else
78+
ruby_shebang?(file)
79+
end
80+
end
81+
82+
def script_wrapper?(file)
83+
script_file = file.delete_suffix(".bat")
84+
return false unless File.exist?(script_file)
85+
86+
if File.zero?(script_file)
87+
Bundler.ui.warn "#{script_file} is empty"
88+
return false
89+
end
90+
91+
header = File.open(file, "r") {|f| f.read(32) }
92+
ruby_exe = "#{RbConfig::CONFIG["RUBY_INSTALL_NAME"]}#{RbConfig::CONFIG["EXEEXT"]}"
93+
ruby_exe = "ruby.exe" if ruby_exe.empty?
94+
header.include?(ruby_exe)
95+
end
96+
7297
def ruby_shebang?(file)
7398
possibilities = [
7499
"#!/usr/bin/env ruby\n",

spec/bundler/commands/exec_spec.rb

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -661,8 +661,6 @@
661661

662662
describe "with gems bundled for deployment" do
663663
it "works when calling bundler from another script" do
664-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
665-
666664
gemfile <<-G
667665
source "https://gem.repo1"
668666
@@ -739,8 +737,7 @@ def bin_path(a,b,c)
739737
RUBY
740738

741739
before do
742-
bundled_app(path).open("w") {|f| f << executable }
743-
bundled_app(path).chmod(0o755)
740+
create_file(bundled_app(path), executable)
744741

745742
install_gemfile <<-G
746743
source "https://gem.repo1"
@@ -765,8 +762,6 @@ def bin_path(a,b,c)
765762
subject { bundle "exec #{path} arg1 arg2", raise_on_error: false }
766763

767764
it "runs" do
768-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
769-
770765
subject
771766
expect(exitstatus).to eq(exit_code)
772767
expect(err).to eq(expected_err)
@@ -778,8 +773,6 @@ def bin_path(a,b,c)
778773

779774
context "with exit 0" do
780775
it "runs" do
781-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
782-
783776
subject
784777
expect(exitstatus).to eq(exit_code)
785778
expect(err).to eq(expected_err)
@@ -791,8 +784,6 @@ def bin_path(a,b,c)
791784
let(:exit_code) { 99 }
792785

793786
it "runs" do
794-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
795-
796787
subject
797788
expect(exitstatus).to eq(exit_code)
798789
expect(err).to eq(expected_err)
@@ -831,7 +822,12 @@ def bin_path(a,b,c)
831822
let(:expected) { "" }
832823

833824
it "runs" do
834-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
825+
# it's empty, so `create_file` won't add executable permission and bat scripts on Windows
826+
bundled_app(path).chmod(0o755)
827+
path.sub_ext(".bat").write <<~SCRIPT if Gem.win_platform?
828+
@ECHO OFF
829+
@"ruby.exe" "%~dpn0" %*
830+
SCRIPT
835831

836832
subject
837833
expect(exitstatus).to eq(exit_code)
@@ -844,12 +840,10 @@ def bin_path(a,b,c)
844840
let(:executable) { super() << "\nraise 'ERROR'" }
845841
let(:exit_code) { 1 }
846842
let(:expected_err) do
847-
/\Abundler: failed to load command: #{Regexp.quote(path.to_s)} \(#{Regexp.quote(path.to_s)}\)\n#{Regexp.quote(path.to_s)}:10:in [`']<top \(required\)>': ERROR \(RuntimeError\)/
843+
/\Abundler: failed to load command: #{Regexp.quote(path.to_s)} \(#{Regexp.quote(path.to_s)}\)\n#{Regexp.quote(path.to_s)}:[0-9]+:in [`']<top \(required\)>': ERROR \(RuntimeError\)/
848844
end
849845

850846
it "runs like a normally executed executable" do
851-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
852-
853847
subject
854848
expect(exitstatus).to eq(exit_code)
855849
expect(err).to match(expected_err)
@@ -864,8 +858,6 @@ def bin_path(a,b,c)
864858
let(:expected) { super() }
865859

866860
it "runs" do
867-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
868-
869861
subject
870862
expect(exitstatus).to eq(exit_code)
871863
expect(err).to eq(expected_err)
@@ -877,8 +869,6 @@ def bin_path(a,b,c)
877869
let(:shebang) { "#!#{Gem.ruby}" }
878870

879871
it "runs" do
880-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
881-
882872
subject
883873
expect(exitstatus).to eq(exit_code)
884874
expect(err).to eq(expected_err)
@@ -909,8 +899,6 @@ def bin_path(a,b,c)
909899
EOS
910900

911901
it "runs" do
912-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
913-
914902
subject
915903
expect(exitstatus).to eq(exit_code)
916904
expect(err).to eq(expected_err)
@@ -933,8 +921,6 @@ def bin_path(a,b,c)
933921
let(:expected) { "" }
934922

935923
it "prints proper suggestion" do
936-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
937-
938924
subject
939925
expect(exitstatus).to eq(exit_code)
940926
expect(err).to include("Run `bundle install --gemfile CustomGemfile` to install missing gems.")
@@ -947,8 +933,6 @@ def bin_path(a,b,c)
947933
let(:exit_code) { 1 }
948934

949935
it "runs" do
950-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
951-
952936
subject
953937
expect(exitstatus).to eq(exit_code)
954938
expect(err).to eq(expected_err)
@@ -971,8 +955,6 @@ def bin_path(a,b,c)
971955
end
972956

973957
it "runs" do
974-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
975-
976958
subject
977959
expect(exitstatus).to eq(exit_code)
978960
expect(err).to eq(expected_err)
@@ -995,8 +977,6 @@ def bin_path(a,b,c)
995977
EOS
996978

997979
it "runs" do
998-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
999-
1000980
subject
1001981
expect(exitstatus).to eq(exit_code)
1002982
expect(err).to eq(expected_err)
@@ -1013,8 +993,6 @@ def bin_path(a,b,c)
1013993
EOS
1014994

1015995
it "runs" do
1016-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
1017-
1018996
subject
1019997
expect(exitstatus).to eq(exit_code)
1020998
expect(err).to eq(expected_err)
@@ -1031,8 +1009,6 @@ def bin_path(a,b,c)
10311009
EOS
10321010

10331011
it "runs" do
1034-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
1035-
10361012
subject
10371013
expect(exitstatus).to eq(exit_code)
10381014
expect(err).to eq(expected_err)
@@ -1173,8 +1149,6 @@ def require(path)
11731149

11741150
context "when gemfile and path are configured", :ruby_repo do
11751151
before do
1176-
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
1177-
11781152
build_repo2 do
11791153
build_gem "rails", "6.1.0" do |s|
11801154
s.executables = "rails"

0 commit comments

Comments
 (0)