Skip to content

Commit

Permalink
shebang: raise error if no rewriting
Browse files Browse the repository at this point in the history
  • Loading branch information
branchvincent committed Feb 1, 2022
1 parent 397afb6 commit 7e6be5e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
30 changes: 30 additions & 0 deletions Library/Homebrew/test/utils/shebang_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# typed: false
# frozen_string_literal: true

require "utils/shebang"

describe Utils::Shebang do
let(:file) { Tempfile.new("shebang") }

before do
file.write "#!/usr/bin/python"
file.flush
end

after { file.unlink }

describe "rewrite_shebang" do
it "rewrites a shebang" do
rewrite_info = Utils::Shebang::RewriteInfo.new(/^#!.*python$/, 25, "new_shebang")
described_class.rewrite_shebang rewrite_info, file
expect(File.read(file)).to eq "#!new_shebang"
end

it "raises an error if no rewriting occurs" do
rewrite_info = Utils::Shebang::RewriteInfo.new(/^#!.*perl$/, 25, "new_shebang")
expect {
described_class.rewrite_shebang rewrite_info, file
}.to raise_error("No matching files found to rewrite shebang")
end
end
end
4 changes: 4 additions & 0 deletions Library/Homebrew/utils/shebang.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,17 @@ def initialize(regex, max_length, replacement)
# @api public
sig { params(rewrite_info: RewriteInfo, paths: T::Array[T.any(String, Pathname)]).void }
def rewrite_shebang(rewrite_info, *paths)
found = T.let(false, T::Boolean)
paths.each do |f|
f = Pathname(f)
next unless f.file?
next unless rewrite_info.regex.match?(f.read(rewrite_info.max_length))

Utils::Inreplace.inreplace f.to_s, rewrite_info.regex, "#!#{rewrite_info.replacement}"
found = true
end

raise "No matching files found to rewrite shebang" unless found
end
end
end

1 comment on commit 7e6be5e

@joshgoebel
Copy link

@joshgoebel joshgoebel commented on 7e6be5e Feb 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This badly breaks many packages that pass a large list of paths (one at a time) and do not expect them all to succeed. Such as glib...:

      bin.find { |f|
        rewrite_shebang detected_python_shebang, f
      }

The files it loops over:

/usr/local/Cellar/glib/2.70.3/bin
/usr/local/Cellar/glib/2.70.3/bin/gdbus
/usr/local/Cellar/glib/2.70.3/bin/gdbus-codegen
/usr/local/Cellar/glib/2.70.3/bin/gio
/usr/local/Cellar/glib/2.70.3/bin/gio-querymodules
/usr/local/Cellar/glib/2.70.3/bin/glib-compile-resources
/usr/local/Cellar/glib/2.70.3/bin/glib-compile-schemas
/usr/local/Cellar/glib/2.70.3/bin/glib-genmarshal
/usr/local/Cellar/glib/2.70.3/bin/glib-gettextize
/usr/local/Cellar/glib/2.70.3/bin/glib-mkenums
/usr/local/Cellar/glib/2.70.3/bin/gobject-query
/usr/local/Cellar/glib/2.70.3/bin/gresource
/usr/local/Cellar/glib/2.70.3/bin/gsettings
/usr/local/Cellar/glib/2.70.3/bin/gtester
/usr/local/Cellar/glib/2.70.3/bin/gtester-report

This will fail on the very first item because it's a path, not a file...

Please sign in to comment.