From 98a53e4781f20e2ab769eae6ac02e2ac59d1175b Mon Sep 17 00:00:00 2001 From: Carlo Cabrera <30379873+carlocab@users.noreply.github.com> Date: Sat, 13 Aug 2022 01:11:09 +0800 Subject: [PATCH] language/python: support `python3` from PATH in `#detected_python_shebang` Some formulae are flexible about the version of Python3 that they use. However, when we use `#detected_python_shebang` on these formulae, they become coupled to the specific version of Python3 declared in the formula. This is harmful because 1. it prevents us from using `uses_from_macos "python"` even in formulae where we should be able to 2. it forces us to rebuild the formula whenever we make changes to the Python dependency when nothing but the shebang would have changed as a consequence of the rebuild For an example of this, see Homebrew/homebrew-core#107905. I'd also like to do this to get rid of some really terrible hacks we have in `glib-utils` as a means of decoupling `glib` from the specific versioned Python dependency it used to have. See Homebrew/homebrew-core#103916, or Homebrew/homebrew-core#106045 for a proposal to give the same treatment to `gobject-introspection`. --- Library/Homebrew/language/python.rb | 20 ++++++++++++------- .../test/language/python/shebang_spec.rb | 15 ++++++++++++-- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb index c0297a85cb..f01e733e31 100644 --- a/Library/Homebrew/language/python.rb +++ b/Library/Homebrew/language/python.rb @@ -103,16 +103,22 @@ module Language ) end - def detected_python_shebang(formula = self) - python_deps = formula.deps.map(&:name).grep(/^python(@.*)?$/) + def detected_python_shebang(formula = self, use_python_from_path: false) + python_path = if use_python_from_path + "/usr/bin/env python3" + else + python_deps = formula.deps.map(&:name).grep(/^python(@.*)?$/) - raise ShebangDetectionError.new("Python", "formula does not depend on Python") if python_deps.empty? - if python_deps.length > 1 - raise ShebangDetectionError.new("Python", "formula has multiple Python dependencies") + raise ShebangDetectionError.new("Python", "formula does not depend on Python") if python_deps.empty? + if python_deps.length > 1 + raise ShebangDetectionError.new("Python", "formula has multiple Python dependencies") + end + + python_dep = python_deps.first + Formula[python_dep].opt_bin/python_dep.sub("@", "") end - python_dep = python_deps.first - python_shebang_rewrite_info(Formula[python_dep].opt_bin/python_dep.sub("@", "")) + python_shebang_rewrite_info(python_path) end end diff --git a/Library/Homebrew/test/language/python/shebang_spec.rb b/Library/Homebrew/test/language/python/shebang_spec.rb index 4fa44b83f3..96cb94257f 100644 --- a/Library/Homebrew/test/language/python/shebang_spec.rb +++ b/Library/Homebrew/test/language/python/shebang_spec.rb @@ -21,7 +21,7 @@ describe Language::Python::Shebang do before do file.write <<~EOS - #!/usr/bin/env python3 + #!/usr/bin/python2 a b c @@ -34,7 +34,7 @@ describe Language::Python::Shebang do describe "#detected_python_shebang" do it "can be used to replace Python shebangs" do expect(Formulary).to receive(:factory).with(python_f.name).and_return(python_f) - Utils::Shebang.rewrite_shebang described_class.detected_python_shebang(f), file + Utils::Shebang.rewrite_shebang described_class.detected_python_shebang(f, use_python_from_path: false), file expect(File.read(file)).to eq <<~EOS #!#{HOMEBREW_PREFIX}/opt/python@3.11/bin/python3.11 @@ -43,5 +43,16 @@ describe Language::Python::Shebang do c EOS end + + it "can be pointed to a `python3` in PATH" do + Utils::Shebang.rewrite_shebang described_class.detected_python_shebang(f, use_python_from_path: true), file + + expect(File.read(file)).to eq <<~EOS + #!/usr/bin/env python3 + a + b + c + EOS + end end end