Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More bottling HOMEBREW_LIBRARY changes #10044

Merged
merged 2 commits into from Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 12 additions & 2 deletions Library/Homebrew/dev-cmd/bottle.rb
Expand Up @@ -254,7 +254,6 @@ def bottle_formula(f, args:)
tar_path = Pathname.pwd/tar_filename

prefix = HOMEBREW_PREFIX.to_s
repository = HOMEBREW_REPOSITORY.to_s
cellar = HOMEBREW_CELLAR.to_s

ohai "Bottling #{filename}..."
Expand Down Expand Up @@ -326,13 +325,24 @@ def bottle_formula(f, args:)
ignores << %r{#{Regexp.escape(HOMEBREW_CELLAR)}/#{go_regex}/[\d.]+/libexec}
end

repository_reference = if HOMEBREW_PREFIX == HOMEBREW_REPOSITORY
HOMEBREW_LIBRARY
else
HOMEBREW_REPOSITORY
end.to_s
if keg_contain?(repository_reference, keg, ignores, args: args)
odie "Bottle contains non-relocatable reference to #{repository_reference}!"
end

relocatable = true
if args.skip_relocation?
skip_relocation = true
else
relocatable = false if keg_contain?(prefix_check, keg, ignores, formula_and_runtime_deps_names, args: args)
relocatable = false if keg_contain?(repository, keg, ignores, args: args)
relocatable = false if keg_contain?(cellar, keg, ignores, formula_and_runtime_deps_names, args: args)
if keg_contain?(HOMEBREW_LIBRARY.to_s, keg, ignores, formula_and_runtime_deps_names, args: args)
relocatable = false
end
if prefix != prefix_check
relocatable = false if keg_contain_absolute_symlink_starting_with?(prefix, keg, args: args)
relocatable = false if keg_contain?("#{prefix}/etc", keg, ignores, args: args)
Expand Down
25 changes: 0 additions & 25 deletions Library/Homebrew/formula_cellar_checks.rb
Expand Up @@ -7,10 +7,6 @@
#
# @api private
module FormulaCellarChecks
# If the location of HOMEBREW_LIBRARY changes
# keg_relocate.rb, test/global_spec.rb, and this constant need to change.
REPOSITORY_AND_NOT_LIBRARY_REGEX = %r{#{HOMEBREW_REPOSITORY}(?!/Library/)}.freeze

def check_env_path(bin)
# warn the user if stuff was installed outside of their PATH
return unless bin.directory?
Expand Down Expand Up @@ -211,26 +207,6 @@ def check_python_packages(lib, deps)
EOS
end

def check_repository_references(prefix)
return if HOMEBREW_PREFIX != HOMEBREW_REPOSITORY
return unless prefix.directory?

keg = Keg.new(prefix)

matches = []
keg.each_unique_file_matching(HOMEBREW_REPOSITORY) do |f|
matches << f.relative_path_from(keg.to_path) if f.read.match? REPOSITORY_AND_NOT_LIBRARY_REGEX
end

return if matches.empty?

<<~EOS
Files were found with references to the Homebrew repository directory
that are outside of the Library directory. The offending files are:
#{matches * "\n "}
EOS
end

def check_shim_references(prefix)
return unless prefix.directory?

Expand Down Expand Up @@ -316,7 +292,6 @@ def audit_installed
problem_if_output(check_elisp_dirname(formula.share, formula.name))
problem_if_output(check_elisp_root(formula.share, formula.name))
problem_if_output(check_python_packages(formula.lib, formula.deps))
problem_if_output(check_repository_references(formula.prefix))
problem_if_output(check_shim_references(formula.prefix))
problem_if_output(check_plist(formula.prefix, formula.plist))
problem_if_output(check_python_symlinks(formula.name, formula.keg_only?))
Expand Down
1 change: 1 addition & 0 deletions Library/Homebrew/formula_installer.rb
Expand Up @@ -175,6 +175,7 @@ def pour_bottle?(output_warning: false)

bottle = formula.bottle_specification
unless bottle.compatible_locations?
# TODO: delete HOMEBREW_REPOSITORY reference after Homebrew 2.7.0 is released.
if output_warning
opoo <<~EOS
Building #{formula.full_name} from source as the bottle needs:
Expand Down
54 changes: 31 additions & 23 deletions Library/Homebrew/keg_relocate.rb
Expand Up @@ -5,13 +5,15 @@ class Keg
PREFIX_PLACEHOLDER = "@@HOMEBREW_PREFIX@@"
CELLAR_PLACEHOLDER = "@@HOMEBREW_CELLAR@@"
REPOSITORY_PLACEHOLDER = "@@HOMEBREW_REPOSITORY@@"
LIBRARY_PLACEHOLDER = "@@HOMEBREW_LIBRARY@@"
Copy link
Member

@sjackman sjackman Dec 18, 2020

Choose a reason for hiding this comment

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

One last comment. There is no technical benefit that I see to introducing a new placeholder, @@HOMEBREW_LIBRARY@@. This one line could be changed to LIBRARY_PLACEHOLDER = "@@HOMEBREW_REPOSITORY@@/Library", and this PR would function identically without the need for introducing a new placeholder.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it would be nice to be able to drop @@HOMEBREW_REPOSITORY@@ entirely, eventually.

Copy link
Member

Choose a reason for hiding this comment

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

Every placeholder needs to be supported indefinitely, so that Homebrew can pour old bottles. So there's a Muller's ratchet of complexity at play here. If there's no technical reason to add a new placeholder, I'd err on the side of not adding one. I don't feel super strongly about this, but my preference is not to introduce new placeholders that aren't strictly needed.


# If the location of HOMEBREW_LIBRARY changes
# formula_cellar_checks.rb, test/global_spec.rb, and this constant need to change.
LIBRARY_PLACEHOLDER = "@@HOMEBREW_REPOSITORY@@/Library"
# TODO: delete this after Homebrew 2.7.0 is released.
REPOSITORY_LIBRARY_PLACEHOLDER = "#{REPOSITORY_PLACEHOLDER}/Library"

Relocation = Struct.new(:old_prefix, :old_cellar, :old_repository, :old_library,
:new_prefix, :new_cellar, :new_repository, :new_library) do
:new_prefix, :new_cellar, :new_repository, :new_library,
# TODO: delete these after Homebrew 2.7.0 is released.
:old_repository_library, :new_repository_library) do
# Use keyword args instead of positional args for initialization.
def initialize(**kwargs)
super(*members.map { |k| kwargs[k] })
Expand Down Expand Up @@ -43,27 +45,34 @@ def replace_locations_with_placeholders
relocation = Relocation.new(
old_prefix: HOMEBREW_PREFIX.to_s,
old_cellar: HOMEBREW_CELLAR.to_s,
old_repository: HOMEBREW_REPOSITORY.to_s,
old_library: HOMEBREW_LIBRARY.to_s,
new_prefix: PREFIX_PLACEHOLDER,
new_cellar: CELLAR_PLACEHOLDER,
# TODO: delete these after Homebrew 2.7.0 is released.
old_library: HOMEBREW_LIBRARY.to_s,
new_library: REPOSITORY_LIBRARY_PLACEHOLDER,
old_repository: HOMEBREW_REPOSITORY.to_s,
new_repository: REPOSITORY_PLACEHOLDER,
new_library: LIBRARY_PLACEHOLDER,
# TODO: add these after Homebrew 2.7.0 is released.
# old_library: HOMEBREW_LIBRARY.to_s,
# new_library: LIBRARY_PLACEHOLDER,
)
relocate_dynamic_linkage(relocation)
replace_text_in_files(relocation)
end

def replace_placeholders_with_locations(files, skip_linkage: false)
relocation = Relocation.new(
old_prefix: PREFIX_PLACEHOLDER,
old_cellar: CELLAR_PLACEHOLDER,
old_repository: REPOSITORY_PLACEHOLDER,
old_library: LIBRARY_PLACEHOLDER,
new_prefix: HOMEBREW_PREFIX.to_s,
new_cellar: HOMEBREW_CELLAR.to_s,
new_repository: HOMEBREW_REPOSITORY.to_s,
new_library: HOMEBREW_LIBRARY.to_s,
old_prefix: PREFIX_PLACEHOLDER,
old_cellar: CELLAR_PLACEHOLDER,
old_repository: REPOSITORY_PLACEHOLDER,
old_library: LIBRARY_PLACEHOLDER,
new_prefix: HOMEBREW_PREFIX.to_s,
new_cellar: HOMEBREW_CELLAR.to_s,
new_repository: HOMEBREW_REPOSITORY.to_s,
new_library: HOMEBREW_LIBRARY.to_s,
# TODO: delete these after Homebrew 2.7.0 is released.
old_repository_library: REPOSITORY_LIBRARY_PLACEHOLDER,
new_repository_library: HOMEBREW_LIBRARY.to_s,
)
relocate_dynamic_linkage(relocation) unless skip_linkage
replace_text_in_files(relocation, files: files)
Expand All @@ -77,16 +86,15 @@ def replace_text_in_files(relocation, files: nil)
s = first.open("rb", &:read)

replacements = {
relocation.old_prefix => relocation.new_prefix,
relocation.old_cellar => relocation.new_cellar,
}
relocation.old_prefix => relocation.new_prefix,
relocation.old_cellar => relocation.new_cellar,
relocation.old_library => relocation.new_library,
# TODO: delete this after Homebrew 2.7.0 is released.
relocation.old_repository_library => relocation.new_repository_library,
}.compact
# when HOMEBREW_PREFIX == HOMEBREW_REPOSITORY we should use HOMEBREW_PREFIX for all relocations to avoid
# being unable to differentiate between them.
if HOMEBREW_PREFIX == HOMEBREW_REPOSITORY
replacements[relocation.old_library] = relocation.new_library
else
replacements[relocation.old_repository] = relocation.new_repository
end
replacements[relocation.old_repository] = relocation.new_repository if HOMEBREW_PREFIX != HOMEBREW_REPOSITORY
MikeMcQuaid marked this conversation as resolved.
Show resolved Hide resolved
changed = s.gsub!(Regexp.union(replacements.keys.sort_by(&:length).reverse), replacements)
next unless changed

Expand Down
1 change: 1 addition & 0 deletions Library/Homebrew/software_spec.rb
Expand Up @@ -389,6 +389,7 @@ def compatible_locations?
# Only check the repository matches if the prefix is the default.
# This is because the bottle DSL does not allow setting a custom repository
# but does allow setting a custom prefix.
# TODO: delete this after Homebrew 2.7.0 is released.
compatible_repository = if Homebrew.default_prefix?(prefix)
repository == HOMEBREW_REPOSITORY.to_s
else
Expand Down
6 changes: 0 additions & 6 deletions Library/Homebrew/test/global_spec.rb
Expand Up @@ -8,10 +8,4 @@
.and not_to_output.to_stderr
.and be_a_success
end

# If the location of HOMEBREW_LIBRARY changes
# keg_relocate.rb, formula_cellar_checks.rb, and this test need to change.
it "ensures that HOMEBREW_LIBRARY=HOMEBREW_REPOSITORY/Library" do
expect(HOMEBREW_LIBRARY.to_s).to eq("#{HOMEBREW_REPOSITORY}/Library")
end
end