brew/Library/Homebrew/build_environment.rb

83 lines
2.2 KiB
Ruby
Raw Normal View History

rubocop: Use `Sorbet/StrictSigil` as it's better than comments - Previously I thought that comments were fine to discourage people from wasting their time trying to bump things that used `undef` that Sorbet didn't support. But RuboCop is better at this since it'll complain if the comments are unnecessary. - Suggested in https://github.com/Homebrew/brew/pull/18018#issuecomment-2283369501. - I've gone for a mixture of `rubocop:disable` for the files that can't be `typed: strict` (use of undef, required before everything else, etc) and `rubocop:todo` for everything else that should be tried to make strictly typed. There's no functional difference between the two as `rubocop:todo` is `rubocop:disable` with a different name. - And I entirely disabled the cop for the docs/ directory since `typed: strict` isn't going to gain us anything for some Markdown linting config files. - This means that now it's easier to track what needs to be done rather than relying on checklists of files in our big Sorbet issue: ```shell $ git grep 'typed: true # rubocop:todo Sorbet/StrictSigil' | wc -l 268 ``` - And this is confirmed working for new files: ```shell $ git status On branch use-rubocop-for-sorbet-strict-sigils Untracked files: (use "git add <file>..." to include in what will be committed) Library/Homebrew/bad.rb Library/Homebrew/good.rb nothing added to commit but untracked files present (use "git add" to track) $ brew style Offenses: bad.rb:1:1: C: Sorbet/StrictSigil: Sorbet sigil should be at least strict got true. ^^^^^^^^^^^^^ 1340 files inspected, 1 offense detected ```
2024-08-12 10:30:59 +01:00
# typed: true # rubocop:todo Sorbet/StrictSigil
# frozen_string_literal: true
# Settings for the build environment.
class BuildEnvironment
sig { params(settings: Symbol).void }
def initialize(*settings)
@settings = Set.new(settings)
end
sig { params(args: T::Enumerable[Symbol]).returns(T.self_type) }
2014-07-07 09:15:56 -05:00
def merge(*args)
@settings.merge(*args)
2014-07-07 20:03:15 -05:00
self
2014-07-07 09:15:56 -05:00
end
sig { params(option: Symbol).returns(T.self_type) }
def <<(option)
@settings << option
self
end
sig { returns(T::Boolean) }
def std?
@settings.include? :std
end
# DSL for specifying build environment settings.
2017-05-09 23:00:51 +02:00
module DSL
# Initialise @env for each class which may use this DSL (e.g. each formula subclass).
2024-04-30 11:10:23 +02:00
# `env` may never be called and it needs to be initialised before the class is frozen.
def inherited(child)
super
child.instance_eval do
@env = BuildEnvironment.new
end
end
sig { params(settings: Symbol).returns(BuildEnvironment) }
2017-05-09 23:00:51 +02:00
def env(*settings)
@env.merge(settings)
end
end
KEYS = %w[
CC CXX LD OBJC OBJCXX
HOMEBREW_CC HOMEBREW_CXX
CFLAGS CXXFLAGS CPPFLAGS LDFLAGS SDKROOT MAKEFLAGS
CMAKE_PREFIX_PATH CMAKE_INCLUDE_PATH CMAKE_LIBRARY_PATH CMAKE_FRAMEWORK_PATH
MACOSX_DEPLOYMENT_TARGET PKG_CONFIG_PATH PKG_CONFIG_LIBDIR
HOMEBREW_DEBUG HOMEBREW_MAKE_JOBS HOMEBREW_VERBOSE
HOMEBREW_SVN HOMEBREW_GIT
HOMEBREW_SDKROOT
MAKE GIT CPP
ACLOCAL_PATH PATH CPATH
LD_LIBRARY_PATH LD_RUN_PATH LD_PRELOAD LIBRARY_PATH
].freeze
private_constant :KEYS
2016-09-26 01:44:51 +02:00
sig { params(env: T::Hash[String, T.nilable(T.any(String, Pathname))]).returns(T::Array[String]) }
def self.keys(env)
KEYS & env.keys
end
sig { params(env: T::Hash[String, T.nilable(T.any(String, Pathname))], out: IO).void }
def self.dump(env, out = $stdout)
keys = self.keys(env)
keys -= %w[CC CXX OBJC OBJCXX] if env["CC"] == env["HOMEBREW_CC"]
keys.each do |key|
value = env.fetch(key)
string = "#{key}: #{value}"
case key
when "CC", "CXX", "LD"
string << " => #{Pathname.new(value).realpath}" if value.present? && File.symlink?(value)
end
string.freeze
out.puts string
end
end
end