Carlo Cabrera 601bf83fee
linkage: add --strict flag to detect opportunistic linkage
There was a previous discussion about making `brew linkage --test` fail
for unrequested dependencies (#9172). I'm not sure what the outcome of
that was, but it still seems like a good idea to try to help us find
cases of opportunistic linkage as they happen rather than when they
cause CI failures in another PR sometime later.

Let's do this by adding a `--strict` flag to `brew linkage --test`. My
intention is for `brew linkage --test --strict` failures to be warnings
rather than errors in CI, which should mitigate some of the concerns
about doing this that were raised in #9172.
2021-11-19 18:14:38 +08:00

63 lines
1.9 KiB
Ruby

# typed: true
# frozen_string_literal: true
require "cache_store"
require "linkage_checker"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def linkage_args
Homebrew::CLI::Parser.new do
description <<~EOS
Check the library links from the given <formula> kegs. If no <formula> are
provided, check all kegs. Raises an error if run on uninstalled formulae.
EOS
switch "--test",
description: "Show only missing libraries and exit with a non-zero status if any missing "\
"libraries are found."
switch "--strict",
depends_on: "--test",
description: "Exit with a non-zero status if any undeclared dependencies with linkage are found."
switch "--reverse",
description: "For every library that a keg references, print its dylib path followed by the "\
"binaries that link to it."
switch "--cached",
description: "Print the cached linkage values stored in `HOMEBREW_CACHE`, set by a previous "\
"`brew linkage` run."
named_args :installed_formula
end
end
def linkage
args = linkage_args.parse
CacheStoreDatabase.use(:linkage) do |db|
kegs = if args.named.to_default_kegs.empty?
Formula.installed.map(&:any_installed_keg).reject(&:nil?)
else
args.named.to_default_kegs
end
kegs.each do |keg|
ohai "Checking #{keg.name} linkage" if kegs.size > 1
result = LinkageChecker.new(keg, cache_db: db)
if args.test?
result.display_test_output(strict: args.strict?)
Homebrew.failed = true if result.broken_library_linkage?(strict: args.strict?)
elsif args.reverse?
result.display_reverse_output
else
result.display_normal_output
end
end
end
end
end