2019-04-19 15:38:03 +09:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2014-06-26 19:06:31 -05:00
|
|
|
class Keg
|
2019-04-19 15:38:03 +09:00
|
|
|
PREFIX_PLACEHOLDER = "@@HOMEBREW_PREFIX@@"
|
|
|
|
CELLAR_PLACEHOLDER = "@@HOMEBREW_CELLAR@@"
|
|
|
|
REPOSITORY_PLACEHOLDER = "@@HOMEBREW_REPOSITORY@@"
|
2013-12-04 22:37:57 -06:00
|
|
|
|
2016-10-23 23:48:07 -04:00
|
|
|
Relocation = Struct.new(:old_prefix, :old_cellar, :old_repository,
|
|
|
|
:new_prefix, :new_cellar, :new_repository) do
|
|
|
|
# Use keyword args instead of positional args for initialization
|
|
|
|
def initialize(**kwargs)
|
|
|
|
super(*members.map { |k| kwargs[k] })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-07-09 13:52:05 +01:00
|
|
|
def fix_dynamic_linkage
|
2015-09-11 16:32:14 +08:00
|
|
|
symlink_files.each do |file|
|
|
|
|
link = file.readlink
|
|
|
|
# Don't fix relative symlinks
|
|
|
|
next unless link.absolute?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2017-04-05 09:00:11 +01:00
|
|
|
link_starts_cellar = link.to_s.start_with?(HOMEBREW_CELLAR.to_s)
|
|
|
|
link_starts_prefix = link.to_s.start_with?(HOMEBREW_PREFIX.to_s)
|
|
|
|
next if !link_starts_cellar && !link_starts_prefix
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2017-04-02 10:26:05 -07:00
|
|
|
new_src = link.relative_path_from(file.parent)
|
|
|
|
file.unlink
|
|
|
|
FileUtils.ln_s(new_src, file)
|
2015-09-11 16:32:14 +08:00
|
|
|
end
|
2010-05-10 00:19:14 +01:00
|
|
|
end
|
2016-09-23 18:13:48 +02:00
|
|
|
alias generic_fix_dynamic_linkage fix_dynamic_linkage
|
2010-05-10 00:19:14 +01:00
|
|
|
|
2016-10-23 23:48:07 -04:00
|
|
|
def relocate_dynamic_linkage(_relocation)
|
2016-07-09 13:52:05 +01:00
|
|
|
[]
|
2015-09-11 18:55:46 +08:00
|
|
|
end
|
2013-10-31 01:08:57 -07:00
|
|
|
|
2016-10-10 12:02:12 -04:00
|
|
|
def replace_locations_with_placeholders
|
2016-10-23 23:48:07 -04:00
|
|
|
relocation = Relocation.new(
|
2018-11-02 17:18:07 +00:00
|
|
|
old_prefix: HOMEBREW_PREFIX.to_s,
|
|
|
|
old_cellar: HOMEBREW_CELLAR.to_s,
|
2016-10-23 23:48:07 -04:00
|
|
|
old_repository: HOMEBREW_REPOSITORY.to_s,
|
2018-11-02 17:18:07 +00:00
|
|
|
new_prefix: PREFIX_PLACEHOLDER,
|
|
|
|
new_cellar: CELLAR_PLACEHOLDER,
|
2017-02-12 15:06:54 +00:00
|
|
|
new_repository: REPOSITORY_PLACEHOLDER,
|
2016-10-23 23:48:07 -04:00
|
|
|
)
|
|
|
|
relocate_dynamic_linkage(relocation)
|
|
|
|
replace_text_in_files(relocation)
|
2016-10-10 12:02:12 -04:00
|
|
|
end
|
|
|
|
|
2016-10-25 03:41:35 -04:00
|
|
|
def replace_placeholders_with_locations(files, skip_linkage: false)
|
2016-10-23 23:48:07 -04:00
|
|
|
relocation = Relocation.new(
|
2018-11-02 17:18:07 +00:00
|
|
|
old_prefix: PREFIX_PLACEHOLDER,
|
|
|
|
old_cellar: CELLAR_PLACEHOLDER,
|
2016-10-23 23:48:07 -04:00
|
|
|
old_repository: REPOSITORY_PLACEHOLDER,
|
2018-11-02 17:18:07 +00:00
|
|
|
new_prefix: HOMEBREW_PREFIX.to_s,
|
|
|
|
new_cellar: HOMEBREW_CELLAR.to_s,
|
2017-02-12 15:06:54 +00:00
|
|
|
new_repository: HOMEBREW_REPOSITORY.to_s,
|
2016-10-23 23:48:07 -04:00
|
|
|
)
|
2016-10-25 03:41:35 -04:00
|
|
|
relocate_dynamic_linkage(relocation) unless skip_linkage
|
2016-10-23 23:48:07 -04:00
|
|
|
replace_text_in_files(relocation, files: files)
|
2016-10-10 12:02:12 -04:00
|
|
|
end
|
|
|
|
|
2016-10-23 23:48:07 -04:00
|
|
|
def replace_text_in_files(relocation, files: nil)
|
2016-10-09 19:43:55 -04:00
|
|
|
files ||= text_files | libtool_files
|
2015-07-23 16:29:37 +08:00
|
|
|
|
2016-10-09 19:43:55 -04:00
|
|
|
changed_files = []
|
2016-10-10 12:02:12 -04:00
|
|
|
files.map(&path.method(:join)).group_by { |f| f.stat.ino }.each_value do |first, *rest|
|
2014-03-27 14:17:13 -05:00
|
|
|
s = first.open("rb", &:read)
|
2016-10-23 23:48:07 -04:00
|
|
|
|
|
|
|
replacements = {
|
2018-11-02 17:18:07 +00:00
|
|
|
relocation.old_prefix => relocation.new_prefix,
|
|
|
|
relocation.old_cellar => relocation.new_cellar,
|
2016-10-23 23:48:07 -04:00
|
|
|
relocation.old_repository => relocation.new_repository,
|
|
|
|
}
|
2018-04-10 18:15:16 +08:00
|
|
|
changed = s.gsub!(Regexp.union(replacements.keys.sort_by(&:length).reverse), replacements)
|
2015-11-20 14:40:28 +00:00
|
|
|
next unless changed
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-11-01 12:58:38 -04:00
|
|
|
changed_files += [first, *rest].map { |file| file.relative_path_from(path) }
|
2015-11-20 14:40:28 +00:00
|
|
|
|
2014-04-05 23:07:28 -05:00
|
|
|
begin
|
2014-03-27 21:42:09 -05:00
|
|
|
first.atomic_write(s)
|
2014-09-25 14:34:28 -05:00
|
|
|
rescue SystemCallError
|
2014-04-05 23:07:28 -05:00
|
|
|
first.ensure_writable do
|
|
|
|
first.open("wb") { |f| f.write(s) }
|
|
|
|
end
|
|
|
|
else
|
2016-09-17 15:32:44 +01:00
|
|
|
rest.each { |file| FileUtils.ln(first, file, force: true) }
|
2015-11-20 14:40:28 +00:00
|
|
|
end
|
2013-10-31 01:08:57 -07:00
|
|
|
end
|
2016-10-09 19:43:55 -04:00
|
|
|
changed_files
|
2013-03-11 18:56:26 +00:00
|
|
|
end
|
|
|
|
|
2016-09-17 15:17:27 +01:00
|
|
|
def detect_cxx_stdlibs(_options = {})
|
2016-07-09 13:52:05 +01:00
|
|
|
[]
|
2013-10-06 01:51:31 -07:00
|
|
|
end
|
|
|
|
|
2017-04-02 09:04:49 -07:00
|
|
|
def recursive_fgrep_args
|
|
|
|
# for GNU grep; overridden for BSD grep on OS X
|
|
|
|
"-lr"
|
|
|
|
end
|
|
|
|
alias generic_recursive_fgrep_args recursive_fgrep_args
|
|
|
|
|
2015-08-03 13:09:07 +01:00
|
|
|
def each_unique_file_matching(string)
|
2017-12-11 15:32:57 -08:00
|
|
|
Utils.popen_read("fgrep", recursive_fgrep_args, string, to_s) do |io|
|
2013-12-17 20:46:42 -06:00
|
|
|
hardlinks = Set.new
|
|
|
|
|
|
|
|
until io.eof?
|
|
|
|
file = Pathname.new(io.readline.chomp)
|
|
|
|
next if file.symlink?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2013-12-17 20:46:42 -06:00
|
|
|
yield file if hardlinks.add? file.stat.ino
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-06-26 19:06:31 -05:00
|
|
|
def lib
|
2017-06-01 16:06:51 +02:00
|
|
|
path/"lib"
|
2014-06-26 19:06:31 -05:00
|
|
|
end
|
2012-09-04 10:49:14 -05:00
|
|
|
|
2020-06-03 17:30:15 +02:00
|
|
|
def libexec
|
|
|
|
path/"libexec"
|
|
|
|
end
|
|
|
|
|
2015-07-14 11:56:34 -07:00
|
|
|
def text_files
|
|
|
|
text_files = []
|
2017-12-11 15:32:57 -08:00
|
|
|
return text_files unless which("file") && which("xargs")
|
2016-07-29 15:53:05 -06:00
|
|
|
|
2016-08-02 03:11:27 +01:00
|
|
|
# file has known issues with reading files on other locales. Has
|
|
|
|
# been fixed upstream for some time, but a sufficiently new enough
|
|
|
|
# file with that fix is only available in macOS Sierra.
|
2017-03-12 19:44:01 +00:00
|
|
|
# https://bugs.gw.com/view.php?id=292
|
2016-08-02 03:11:27 +01:00
|
|
|
with_custom_locale("C") do
|
2016-10-12 11:37:34 -04:00
|
|
|
files = Set.new path.find.reject { |pn|
|
2016-10-12 11:35:37 +01:00
|
|
|
next true if pn.symlink?
|
|
|
|
next true if pn.directory?
|
2017-05-06 15:54:56 -07:00
|
|
|
next false if pn.basename.to_s == "orig-prefix.txt" # for python virtualenvs
|
2017-10-01 09:52:29 -07:00
|
|
|
next true if pn == self/".brew/#{name}.rb"
|
2016-10-12 11:35:37 +01:00
|
|
|
next true if Metafiles::EXTENSIONS.include?(pn.extname)
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-10-12 11:35:37 +01:00
|
|
|
if pn.text_executable?
|
|
|
|
text_files << pn
|
|
|
|
next true
|
|
|
|
end
|
|
|
|
false
|
2016-10-10 21:46:19 -04:00
|
|
|
}
|
2017-12-11 15:32:57 -08:00
|
|
|
output, _status = Open3.capture2("xargs -0 file --no-dereference --print0",
|
2016-10-12 11:37:34 -04:00
|
|
|
stdin_data: files.to_a.join("\0"))
|
2016-10-15 21:21:08 -07:00
|
|
|
# `file` output sometimes contains data from the file, which may include
|
|
|
|
# invalid UTF-8 entities, so tell Ruby this is just a bytestring
|
|
|
|
output.force_encoding(Encoding::ASCII_8BIT)
|
2016-10-12 11:37:34 -04:00
|
|
|
output.each_line do |line|
|
2016-10-15 21:21:08 -07:00
|
|
|
path, info = line.split("\0", 2)
|
2016-10-15 23:52:55 -07:00
|
|
|
# `file` sometimes prints more than one line of output per file;
|
|
|
|
# subsequent lines do not contain a null-byte separator, so `info`
|
|
|
|
# will be `nil` for those lines
|
|
|
|
next unless info
|
2016-10-15 21:21:08 -07:00
|
|
|
next unless info.include?("text")
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-10-12 11:37:34 -04:00
|
|
|
path = Pathname.new(path)
|
|
|
|
next unless files.include?(path)
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-10-12 11:37:34 -04:00
|
|
|
text_files << path
|
2015-07-20 12:06:13 +01:00
|
|
|
end
|
2013-10-31 01:08:57 -07:00
|
|
|
end
|
|
|
|
|
2015-07-14 11:56:34 -07:00
|
|
|
text_files
|
2015-07-10 19:51:43 +08:00
|
|
|
end
|
2015-07-23 16:29:37 +08:00
|
|
|
|
|
|
|
def libtool_files
|
|
|
|
libtool_files = []
|
|
|
|
|
2016-04-24 22:06:14 +01:00
|
|
|
path.find do |pn|
|
2020-09-11 10:29:21 +01:00
|
|
|
next if pn.symlink? || pn.directory? || !Keg::LIBTOOL_EXTENSIONS.include?(pn.extname)
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2015-07-23 16:29:37 +08:00
|
|
|
libtool_files << pn
|
2016-04-24 22:06:14 +01:00
|
|
|
end
|
2015-07-23 16:29:37 +08:00
|
|
|
libtool_files
|
|
|
|
end
|
2015-09-11 16:32:14 +08:00
|
|
|
|
|
|
|
def symlink_files
|
|
|
|
symlink_files = []
|
|
|
|
path.find do |pn|
|
|
|
|
symlink_files << pn if pn.symlink?
|
|
|
|
end
|
|
|
|
|
|
|
|
symlink_files
|
|
|
|
end
|
2016-07-09 13:52:05 +01:00
|
|
|
|
2016-09-17 15:17:27 +01:00
|
|
|
def self.file_linked_libraries(_file, _string)
|
2016-07-09 13:52:05 +01:00
|
|
|
[]
|
|
|
|
end
|
2018-06-22 16:56:37 -07:00
|
|
|
|
|
|
|
def self.relocation_formulae
|
|
|
|
[]
|
|
|
|
end
|
2018-10-01 16:36:03 -07:00
|
|
|
|
|
|
|
def self.bottle_dependencies
|
|
|
|
relocation_formulae
|
|
|
|
end
|
2010-05-10 00:19:14 +01:00
|
|
|
end
|
2016-07-09 13:52:05 +01:00
|
|
|
|
|
|
|
require "extend/os/keg_relocate"
|