diff --git a/Library/Homebrew/cleaner.rb b/Library/Homebrew/cleaner.rb index cf3e84586c631..0ae87b0bcfb42 100644 --- a/Library/Homebrew/cleaner.rb +++ b/Library/Homebrew/cleaner.rb @@ -58,7 +58,7 @@ def clean end rewrite_shebangs - remove_pip_direct_url + clean_python_metadata prune end @@ -165,25 +165,27 @@ def rewrite_shebangs end end - # Remove non-reproducible pip direct_url.json which records the /tmp build directory + # Remove non-reproducible pip direct_url.json which records the /tmp build directory. + # Remove RECORD files to prevent changes to the installed Python package. + # Modify INSTALLER to provide information that files are managed by brew. + # + # @see https://packaging.python.org/en/latest/specifications/recording-installed-packages/ sig { void } - def remove_pip_direct_url + def clean_python_metadata basepath = @formula.prefix.realpath basepath.find do |path| Find.prune if @formula.skip_clean?(path) next if path.directory? || path.symlink? - next if path.basename.to_s != "direct_url.json" next if path.parent.extname != ".dist-info" - odebug "Removing #{path}" - path.unlink - - record = path.parent/"RECORD" - next unless record.file? - - odebug "Modifying #{record}" - @formula.inreplace record, %r{^.*/direct_url\.json,.*$\n?}, "", false + case path.basename.to_s + when "direct_url.json", "RECORD" + observe_file_removal path + when "INSTALLER" + odebug "Modifying #{path} contents from #{path.read.chomp} to brew" + path.atomic_write("brew\n") + end end end end diff --git a/Library/Homebrew/test/cleaner_spec.rb b/Library/Homebrew/test/cleaner_spec.rb index 0c02b81256d96..f5f51a29418b0 100644 --- a/Library/Homebrew/test/cleaner_spec.rb +++ b/Library/Homebrew/test/cleaner_spec.rb @@ -155,6 +155,52 @@ expect(arch_file).not_to exist expect(name_file).to exist end + + it "removes '*.dist-info/direct_url.json' files" do + dir = f.lib/"python3.12/site-packages/test.dist-info" + file = dir/"direct_url.json" + unrelated_file = dir/"METADATA" + unrelated_dir_file = f.lib/"direct_url.json" + + dir.mkpath + touch file + touch unrelated_file + touch unrelated_dir_file + + cleaner.clean + + expect(file).not_to exist + expect(unrelated_file).to exist + expect(unrelated_dir_file).to exist + end + + it "removes '*.dist-info/RECORD' files" do + dir = f.lib/"python3.12/site-packages/test.dist-info" + file = dir/"RECORD" + unrelated_file = dir/"METADATA" + unrelated_dir_file = f.lib/"RECORD" + + dir.mkpath + touch file + touch unrelated_file + touch unrelated_dir_file + + cleaner.clean + + expect(file).not_to exist + expect(unrelated_file).to exist + expect(unrelated_dir_file).to exist + end + + it "modifies '*.dist-info/INSTALLER' files" do + file = f.lib/"python3.12/site-packages/test.dist-info/INSTALLER" + file.dirname.mkpath + file.write "pip\n" + + cleaner.clean + + expect(file.read).to eq "brew\n" + end end describe "::skip_clean" do