Skip to content

Commit

Permalink
cleaner: rewrite pkg-config file Cellar paths and keg-only
Browse files Browse the repository at this point in the history
  • Loading branch information
cho-m committed Oct 4, 2024
1 parent 8389f50 commit 8add1db
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
43 changes: 43 additions & 0 deletions Library/Homebrew/cleaner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def clean
observe_file_removal info_dir_file
end

rewrite_pkgconfig
rewrite_shebangs
clean_python_metadata

Expand Down Expand Up @@ -153,6 +154,48 @@ def clean_dir(directory)
end
end

sig { void }
def rewrite_pkgconfig
basepath = @formula.prefix.realpath
pc_files = %w[lib share].flat_map do |subdir|
pc_dir = basepath/subdir/"pkgconfig"
next [] if !pc_dir.exist? || @formula.skip_clean?(basepath/subdir) || @formula.skip_clean?(pc_dir)

pc_dir.glob("*.pc").reject { |pc_file| @formula.skip_clean?(pc_file) }
end
return if pc_files.empty?

# TODO: Add support for `brew unlink`-ed formulae and check on recursive dependencies
deps_pc_files = @formula.deps
.filter_map { |dep| dep.to_formula if !dep.build? && !dep.test? }
.select(&:keg_only?)
.flat_map { |f| f.opt_prefix.glob("{lib,share}/pkgconfig/*.pc") }
.to_h { |pc_file| [pc_file.basename(".pc").to_s.downcase, pc_file.to_s] }

Check warning on line 173 in Library/Homebrew/cleaner.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cleaner.rb#L172-L173

Added lines #L172 - L173 were not covered by tests
deps_pc_modules_pattern = deps_pc_files.keys.map { |mod| Regexp.escape(mod) }.join("|")

pc_files.each do |pc_file|
modified_lines = pc_file.each_line.map do |line|
rewrote_prefix = line.gsub!(@formula.prefix.realpath.to_s, @formula.opt_prefix.to_s).present?
next [line, rewrote_prefix] if deps_pc_files.empty? || !line.start_with?(/Requires(?:\.private)?:/)

# pkgconf's pc.5 man page defines dependency list ABNF syntax as:
#
# > package-list = *WSP *( package-spec *( package-sep ) )
# > package-sep = WSP / ","
# > package-spec = package-key [ ver-op package-version ]
# > ver-op = "<" / "<=" / "=" / "!=" / ">=" / ">"
#
# A simplified regular expression is used to lookahead/lookbehind for common
# separator characters to extract the modules used in Requires/Requires.private
rewrote_module = line.gsub!(/(?<=[:,\s])(#{deps_pc_modules_pattern})(?=[<=>!,\s])/io, deps_pc_files).present?
[line, rewrote_prefix || rewrote_module]

Check warning on line 191 in Library/Homebrew/cleaner.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cleaner.rb#L190-L191

Added lines #L190 - L191 were not covered by tests
end
next if modified_lines.none?(&:second)

pc_file.atomic_write(modified_lines.map(&:first).join)
end
end

sig { void }
def rewrite_shebangs
require "language/node"
Expand Down
44 changes: 44 additions & 0 deletions Library/Homebrew/test/cleaner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,50 @@

expect(file.read).to eq "brew\n"
end

it "modifies Cellar prefix in pkg-config files" do
file = f.lib/"pkgconfig/test.pc"
file.dirname.mkpath
file.write <<~EOS
prefix=#{f.prefix}
includedir=#{f.include}
libdir=#{f.lib}
Name: test
Description: test module
Version: 1.2.3
Cflags: -I${includedir}
EOS

cleaner.clean

expect(file.read).to eq <<~EOS
prefix=#{f.opt_prefix}
includedir=#{f.opt_include}
libdir=#{f.opt_lib}
Name: test
Description: test module
Version: 1.2.3
Cflags: -I${includedir}
EOS
end

it "does not modify pkg-config files with no rewrites" do
file = f.lib/"pkgconfig/test.pc"
file.dirname.mkpath
file.write <<~EOS
prefix=#{f.opt_prefix}
includedir=${prefix}/include
Name: test
Description: test module
Version: 1.2.3
Cflags: -I${includedir}
EOS
start_mtime = file.mtime

cleaner.clean

expect(file.mtime).to eq start_mtime
end
end

describe "::skip_clean" do
Expand Down

0 comments on commit 8add1db

Please sign in to comment.