Skip to content

Commit 6f04ee4

Browse files
authored
Merge pull request #19563 from botantony/python-shebang
shebangs: fix broken shebangs like `#!python`
2 parents 81bf90b + 41f3a7b commit 6f04ee4

File tree

6 files changed

+74
-6
lines changed

6 files changed

+74
-6
lines changed

Library/Homebrew/language/node.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ module Shebang
9696
module_function
9797

9898
# A regex to match potential shebang permutations.
99-
NODE_SHEBANG_REGEX = %r{^#! ?/usr/bin/(?:env )?node( |$)}
99+
NODE_SHEBANG_REGEX = %r{^#! ?(?:/usr/bin/(?:env )?)?node( |$)}
100100

101101
# The length of the longest shebang matching `SHEBANG_REGEX`.
102102
NODE_SHEBANG_MAX_LENGTH = T.let("#! /usr/bin/env node ".length, Integer)

Library/Homebrew/language/perl.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module Shebang
1515
module_function
1616

1717
# A regex to match potential shebang permutations.
18-
PERL_SHEBANG_REGEX = %r{^#! ?/usr/bin/(?:env )?perl( |$)}
18+
PERL_SHEBANG_REGEX = %r{^#! ?(?:/usr/bin/(?:env )?)?perl( |$)}
1919

2020
# The length of the longest shebang matching `SHEBANG_REGEX`.
2121
PERL_SHEBANG_MAX_LENGTH = T.let("#! /usr/bin/env perl ".length, Integer)

Library/Homebrew/language/python.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ module Shebang
112112
module_function
113113

114114
# A regex to match potential shebang permutations.
115-
PYTHON_SHEBANG_REGEX = %r{^#! ?/usr/bin/(?:env )?python(?:[23](?:\.\d{1,2})?)?( |$)}
115+
PYTHON_SHEBANG_REGEX = %r{^#! ?(?:/usr/bin/(?:env )?)?python(?:[23](?:\.\d{1,2})?)?( |$)}
116116

117117
# The length of the longest shebang matching `SHEBANG_REGEX`.
118118
PYTHON_SHEBANG_MAX_LENGTH = T.let("#! /usr/bin/env pythonx.yyy ".length, Integer)

Library/Homebrew/test/language/node/shebang_spec.rb

+21-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
RSpec.describe Language::Node::Shebang do
77
let(:file) { Tempfile.new("node-shebang") }
8+
let(:broken_file) { Tempfile.new("node-shebang") }
89
let(:f) do
910
f = {}
1011

@@ -40,9 +41,16 @@
4041
c
4142
EOS
4243
file.flush
44+
broken_file.write <<~EOS
45+
#!node
46+
a
47+
b
48+
c
49+
EOS
50+
broken_file.flush
4351
end
4452

45-
after { file.unlink }
53+
after { [file, broken_file].each(&:unlink) }
4654

4755
describe "#detected_node_shebang" do
4856
it "can be used to replace Node shebangs" do
@@ -57,6 +65,18 @@
5765
EOS
5866
end
5967

68+
it "can fix broken shebang like `#!node`" do
69+
allow(Formulary).to receive(:factory).with(f[:node18].name).and_return(f[:node18])
70+
Utils::Shebang.rewrite_shebang described_class.detected_node_shebang(f[:versioned_node_dep]), broken_file.path
71+
72+
expect(File.read(broken_file)).to eq <<~EOS
73+
#!#{HOMEBREW_PREFIX/"opt/node@18/bin/node"}
74+
a
75+
b
76+
c
77+
EOS
78+
end
79+
6080
it "errors if formula doesn't depend on node" do
6181
expect { Utils::Shebang.rewrite_shebang described_class.detected_node_shebang(f[:no_deps]), file.path }
6282
.to raise_error(ShebangDetectionError, "Cannot detect Node shebang: formula does not depend on Node.")

Library/Homebrew/test/language/perl/shebang_spec.rb

+27-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
RSpec.describe Language::Perl::Shebang do
77
let(:file) { Tempfile.new("perl-shebang") }
8+
let(:broken_file) { Tempfile.new("perl-shebang") }
89
let(:f) do
910
f = {}
1011

@@ -39,9 +40,16 @@
3940
c
4041
EOS
4142
file.flush
43+
broken_file.write <<~EOS
44+
#!perl
45+
a
46+
b
47+
c
48+
EOS
49+
broken_file.flush
4250
end
4351

44-
after { file.unlink }
52+
after { [file, broken_file].each(&:unlink) }
4553

4654
describe "#detected_perl_shebang" do
4755
it "can be used to replace Perl shebangs when depends_on \"perl\" is used" do
@@ -74,6 +82,24 @@
7482
EOS
7583
end
7684

85+
it "can fix broken shebang like `#!perl`" do
86+
allow(Formulary).to receive(:factory).with(f[:perl].name).and_return(f[:perl])
87+
Utils::Shebang.rewrite_shebang described_class.detected_perl_shebang(f[:uses_from_macos]), broken_file.path
88+
89+
expected_shebang = if OS.mac?
90+
"/usr/bin/perl#{MacOS.preferred_perl_version}"
91+
else
92+
HOMEBREW_PREFIX/"opt/perl/bin/perl"
93+
end
94+
95+
expect(File.read(broken_file)).to eq <<~EOS
96+
#!#{expected_shebang}
97+
a
98+
b
99+
c
100+
EOS
101+
end
102+
77103
it "errors if formula doesn't depend on perl" do
78104
expect { Utils::Shebang.rewrite_shebang described_class.detected_perl_shebang(f[:no_deps]), file.path }
79105
.to raise_error(ShebangDetectionError, "Cannot detect Perl shebang: formula does not depend on Perl.")

Library/Homebrew/test/language/python/shebang_spec.rb

+23-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
RSpec.describe Language::Python::Shebang do
77
let(:file) { Tempfile.new("python-shebang") }
8+
let(:broken_file) { Tempfile.new("python-shebang") }
89
let(:f) do
910
f = {}
1011

@@ -40,9 +41,16 @@
4041
c
4142
EOS
4243
file.flush
44+
broken_file.write <<~EOS
45+
#!python
46+
a
47+
b
48+
c
49+
EOS
50+
broken_file.flush
4351
end
4452

45-
after { file.unlink }
53+
after { [file, broken_file].each(&:unlink) }
4654

4755
describe "#detected_python_shebang" do
4856
it "can be used to replace Python shebangs" do
@@ -72,6 +80,20 @@
7280
EOS
7381
end
7482

83+
it "can fix broken shebang line `#!python`" do
84+
Utils::Shebang.rewrite_shebang(
85+
described_class.detected_python_shebang(f[:versioned_python_dep],
86+
use_python_from_path: true), broken_file.path
87+
)
88+
89+
expect(File.read(broken_file)).to eq <<~EOS
90+
#!/usr/bin/env python3
91+
a
92+
b
93+
c
94+
EOS
95+
end
96+
7597
it "errors if formula doesn't depend on python" do
7698
expect do
7799
Utils::Shebang.rewrite_shebang(

0 commit comments

Comments
 (0)