Class: Formula Abstract

Inherits:
Object
  • Object
show all
Extended by:
BuildEnvironment::DSL, Cachable, Forwardable, OnSystem::MacOSAndLinux, Predicable
Includes:
Context, FileUtils, Homebrew::Livecheck::Constants, OnSystem::MacOSAndLinux, Utils::Inreplace, Utils::Shebang, Utils::Shell
Defined in:
extend/os/linux/formula.rb,
formula.rb

Overview

This class is abstract.

A formula provides instructions and metadata for Homebrew to install a piece of software. Every Homebrew formula is a Formula. All subclasses of Formula (and all Ruby classes) have to be named UpperCase and not-use-dashes. A formula specified in this-formula.rb should have a class named ThisFormula. Homebrew does enforce that the name of the file and the class correspond. Make sure you check with brew search that the name is free!

class Wget < Formula
  homepage "https://www.gnu.org/software/wget/"
  url "https://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz"
  sha256 "52126be8cf1bddd7536886e74c053ad7d0ed2aa89b4b630f76785bac21695fcd"

  def install
    system "./configure", "--prefix=#{prefix}"
    system "make", "install"
  end
end

Constant Summary

Constants included from Homebrew::Livecheck::Constants

Homebrew::Livecheck::Constants::LATEST_VERSION

Constants included from Utils::Shell

Utils::Shell::SHELL_PROFILE_MAP, Utils::Shell::UNSAFE_SHELL_CHAR

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from OnSystem::MacOSAndLinux

included

Methods included from BuildEnvironment::DSL

env, inherited

Methods included from Cachable

cache, clear_cache

Methods included from Predicable

attr_predicate

Methods included from Context

current, current=, #debug?, #quiet?, #verbose?, #with_context

Methods included from Utils::Shell

csh_quote, export_value, from_path, parent, preferred, prepend_path_in_profile, profile, set_variable_in_profile, sh_quote

Methods included from Utils::Shebang

rewrite_shebang

Methods included from Utils::Inreplace

inreplace, inreplace_pairs

Class Attribute Details

.bottle(&block) ⇒ void

This method returns an undefined value.

Adds a bottle SoftwareSpec. This provides a pre-built binary package built by the Homebrew maintainers for you. It will be installed automatically if there is a binary package for your platform and you haven’t passed or previously used any options on this formula.

If you maintain your own repository, you can add your own bottle links. You can ignore this block entirely if submitting to Homebrew/homebrew-core. It’ll be handled for you by the Brew Test Bot.

bottle do
  root_url "https://example.com" # Optional root to calculate bottle URLs.
  rebuild 1 # Marks the old bottle as outdated without bumping the version/revision of the formula.
  # Optionally specify the HOMEBREW_CELLAR in which the bottles were built.
  sha256 cellar: "/brew/Cellar", catalina:    "ef65c759c5097a36323fa9c77756468649e8d1980a3a4e05695c05e39568967c"
  sha256 cellar: :any,           mojave:      "28f4090610946a4eb207df102d841de23ced0d06ba31cb79e040d883906dcd4f"
  sha256                         high_sierra: "91dd0caca9bd3f38c439d5a7b6f68440c4274945615fae035ff0a369264b8a2f"
end

Homebrew maintainers aim to bottle all formulae that require compilation.

Formulae that can be installed without compilation should be tagged with:

bottle :unneeded

Formulae which should not be bottled should be tagged with:

bottle :disable, "reasons"

Parameters:

See Also:



2956
2957
2958
# File 'formula.rb', line 2956

def bottle(&block)
  stable.bottle(&block)
end

.deprecated_option(hash) ⇒ Object

Deprecated options are used to rename options and migrate users who used them to newer ones. They are mostly used for migrating non-with options (e.g. enable-debug) to with options (e.g. with-debug).

deprecated_option "enable-debug" => "with-debug"


3103
3104
3105
# File 'formula.rb', line 3103

def deprecated_option(hash)
  specs.each { |spec| spec.deprecated_option(hash) }
end

.deprecation_dateObject (readonly)

The date that this Formula was or becomes deprecated. Returns nil if no date is specified.

Returns:

  • Date

See Also:



3380
3381
3382
# File 'formula.rb', line 3380

def deprecation_date
  @deprecation_date
end

.deprecation_reasonnil, ... (readonly)

The reason for deprecation of a Formula.

Returns:

  • (nil)

    if no reason was provided or the formula is not deprecated.

  • (String, Symbol)

See Also:



3386
3387
3388
# File 'formula.rb', line 3386

def deprecation_reason
  @deprecation_reason
end

.desc=(value) ⇒ Object (writeonly)

A one-line description of the software. Used by users to get an overview of the software and Homebrew maintainers. Shows when running brew info.

desc "Example formula"


2765
# File 'formula.rb', line 2765

attr_rw :desc

.disable_dateObject (readonly)

The date that this Formula was or becomes disabled. Returns nil if no date is specified.

Returns:

  • Date

See Also:



3420
3421
3422
# File 'formula.rb', line 3420

def disable_date
  @disable_date
end

.disable_reasonString, Symbol (readonly)

The reason this Formula is disabled. Returns nil if no reason was provided or the formula is not disabled.

Returns:

See Also:



3426
3427
3428
# File 'formula.rb', line 3426

def disable_reason
  @disable_reason
end

.head(val = nil, specs = {}, &block) ⇒ Object

Adds a head SoftwareSpec. This can be installed by passing the --HEAD option to allow installing software directly from a branch of a version-control repository. If called as a method this provides just the url for the SoftwareSpec. If a block is provided you can also add depends_on and Patches just to the head SoftwareSpec. The download strategies (e.g. :using =>) are the same as for url. master is the default branch and doesn’t need stating with a branch: parameter.

head "https://we.prefer.https.over.git.example.com/.git"
head "https://example.com/.git", branch: "name_of_branch"

or (if autodetect fails):

head "https://hg.is.awesome.but.git.has.won.example.com/", using: :hg


3005
3006
3007
3008
3009
3010
3011
3012
3013
# File 'formula.rb', line 3005

def head(val = nil, specs = {}, &block)
  if block
    @head.instance_eval(&block)
  elsif val
    @head.url(val, specs)
  else
    @head
  end
end

.homepage=(value) ⇒ Object (writeonly)

The homepage for the software. Used by users to get more information about the software and Homebrew maintainers as a point of contact for e.g. submitting patches. Can be opened with running brew home.

homepage "https://www.example.com"


2805
# File 'formula.rb', line 2805

attr_rw :homepage

.license(args = nil) ⇒ Object

The SPDX ID of the open-source license that the formula uses. Shows when running brew info. Use :any_of, :all_of or :with to describe complex license expressions. :any_of should be used when the user can choose which license to use. :all_of should be used when the user must use all licenses. :with should be used to specify a valid SPDX exception. Add + to an identifier to indicate that the formulae can be licensed under later versions of the same license.

license "BSD-2-Clause"
license "EPL-1.0+"
license any_of: ["MIT", "GPL-2.0-only"]
license all_of: ["MIT", "GPL-2.0-only"]
license "GPL-2.0-only" => { with: "LLVM-exception" }
license :public_domain
license any_of: [
  "MIT",
  :public_domain,
  all_of: ["0BSD", "Zlib", "Artistic-1.0+"],
  "Apache-2.0" => { with: "LLVM-exception" },
]


2790
2791
2792
2793
2794
2795
2796
# File 'formula.rb', line 2790

def license(args = nil)
  if args.nil?
    @licenses
  else
    @licenses = args
  end
end

.livecheck(&block) ⇒ Object

Livecheck can be used to check for newer versions of the software. This method evaluates the DSL specified in the livecheck block of the Formula (if it exists) and sets the instance variables of a Livecheck object accordingly. This is used by brew livecheck to check for newer versions of the software.

livecheck do
  skip "Not maintained"
  url "https://example.com/foo/releases"
  regex /foo-(\d+(?:\.\d+)+)\.tar/
end


3283
3284
3285
3286
3287
3288
# File 'formula.rb', line 3283

def livecheck(&block)
  return @livecheck unless block

  @livecheckable = true
  @livecheck.instance_eval(&block)
end

.mirror(val) ⇒ Object

Additional URLs for the stable version of the formula. These are only used if the url fails to download. It’s optional and there can be more than one. Generally we add them when the main url is unreliable. If url is really unreliable then we may swap the mirror and url.

mirror "https://in.case.the.host.is.down.example.com"
mirror "https://in.case.the.mirror.is.down.example.com


2912
2913
2914
# File 'formula.rb', line 2912

def mirror(val)
  stable.mirror(val)
end

.option(name, description = "") ⇒ Object

Options can be used as arguments to brew install. To switch features on/off: "with-something" or "with-otherthing". To use other software: "with-other-software" or "without-foo". Note that for depends_on that are :optional or :recommended, options are generated automatically.

There are also some special options:

  • :universal: build a universal binary/library (e.g. on newer Intel Macs this means a combined x86_64/x86 binary/library).
option "with-spam", "The description goes here without a dot at the end"
option "with-qt", "Text here overwrites what's autogenerated by 'depends_on "qt" => :optional'"
option :universal


3094
3095
3096
# File 'formula.rb', line 3094

def option(name, description = "")
  specs.each { |spec| spec.option(name, description) }
end

.revision=(value) ⇒ Object (writeonly)

Used for creating new Homebrew versions of software without new upstream versions. For example, if we bump the major version of a library that this Formula depends_on then we may need to update the revision of this Formula to install a new version linked against the new library version. 0 if unset.

revision 1


2854
# File 'formula.rb', line 2854

attr_rw :revision

.service(&block) ⇒ Object

Service can be used to define services. This method evaluates the DSL specified in the service block of the Formula (if it exists) and sets the instance variables of a Service object accordingly. This is used by brew install to generate a service file.

service do
  run [opt_bin/"foo"]
end


3299
3300
3301
3302
3303
# File 'formula.rb', line 3299

def service(&block)
  return @service_block unless block

  @service_block = block
end

.sha256(val) ⇒ Object

To verify the cached download’s integrity and security we verify the SHA-256 hash matches what we’ve declared in the Formula. To quickly fill this value you can leave it blank and run brew fetch --force and it’ll tell you the currently valid value.

sha256 "2a2ba417eebaadcb4418ee7b12fe2998f26d6e6f7fda7983412ff66a741ab6f7"


2924
2925
2926
# File 'formula.rb', line 2924

def sha256(val)
  stable.sha256(val)
end

.stable(&block) ⇒ Object

Allows adding depends_on and Patches just to the stable SoftwareSpec. This is required instead of using a conditional. It is preferable to also pull the url and sha256 into the block if one is added.

stable do
  url "https://example.com/foo-1.0.tar.gz"
  sha256 "2a2ba417eebaadcb4418ee7b12fe2998f26d6e6f7fda7983412ff66a741ab6f7"

  depends_on "libxml2"
  depends_on "libffi"
end


2987
2988
2989
2990
2991
# File 'formula.rb', line 2987

def stable(&block)
  return @stable unless block

  @stable.instance_eval(&block)
end

.url(val, specs = {}) ⇒ Object

The URL used to download the source for the stable version of the formula. We prefer https for security and proxy reasons. If not inferable, specify the download strategy with using: ....

  • :git, :hg, :svn, :bzr, :fossil, :cvs,
  • :curl (normal file download, will also extract)
  • :nounzip (without extracting)
  • :post (download via an HTTP POST)
url "https://packed.sources.and.we.prefer.https.example.com/archive-1.2.3.tar.bz2"
url "https://some.dont.provide.archives.example.com",
    using:    :git,
    tag:      "1.2.3",
    revision: "db8e4de5b2d6653f66aea53094624468caad15d2"


2889
2890
2891
# File 'formula.rb', line 2889

def url(val, specs = {})
  stable.url(val, specs)
end

.version(val = nil) ⇒ Object

The version string for the stable version of the formula. The version is autodetected from the URL and/or tag so only needs to be declared if it cannot be autodetected correctly.

version "1.2-final"


2899
2900
2901
# File 'formula.rb', line 2899

def version(val = nil)
  stable.version(val)
end

.version_scheme=(value) ⇒ Object (writeonly)

Used for creating new Homebrew version schemes. For example, if we want to change version scheme from one to another, then we may need to update version_scheme of this Formula to be able to use new version scheme, e.g. to move from 20151020 scheme to 1.0.0 we need to increment version_scheme. Without this, the prior scheme will always equate to a higher version. 0 if unset.

version_scheme 1


2866
# File 'formula.rb', line 2866

attr_rw :version_scheme

Instance Attribute Details

#alias_nameObject (readonly)

The name of the alias that was used to identify this Formula. e.g. another-name-for-this-formula



83
84
85
# File 'formula.rb', line 83

def alias_name
  @alias_name
end

#alias_pathObject (readonly)

The path to the alias that was used to identify this Formula. e.g. /usr/local/Library/Taps/homebrew/homebrew-core/Aliases/another-name-for-this-formula



79
80
81
# File 'formula.rb', line 79

def alias_path
  @alias_path
end

#buildBuildOptions

The BuildOptions for this Formula. Lists the arguments passed and any options in the Formula. Note that these may differ at different times during the installation of a Formula. This is annoying but the result of state that we’re trying to eliminate.

Returns:



168
169
170
# File 'formula.rb', line 168

def build
  @build
end

#buildpathObject (readonly)

The current working directory during builds. Will only be non-nil inside #install.



147
148
149
# File 'formula.rb', line 147

def buildpath
  @buildpath
end

#follow_installed_aliasBoolean Also known as: follow_installed_alias?

Whether this formula should be considered outdated if the target of the alias it was installed with has since changed. Defaults to true.

Returns:

  • (Boolean)


174
175
176
# File 'formula.rb', line 174

def follow_installed_alias
  @follow_installed_alias
end

#full_alias_nameObject (readonly)

The fully-qualified alias referring to this Formula. For core formula it’s the same as #alias_name. e.g. homebrew/tap-name/another-name-for-this-formula



93
94
95
# File 'formula.rb', line 93

def full_alias_name
  @full_alias_name
end

#full_nameObject (readonly)

The fully-qualified name of this Formula. For core formula it’s the same as #name. e.g. homebrew/tap-name/this-formula



88
89
90
# File 'formula.rb', line 88

def full_name
  @full_name
end

#nameObject (readonly)

The name of this Formula. e.g. this-formula



75
76
77
# File 'formula.rb', line 75

def name
  @name
end

#pathObject (readonly)

The full path to this Formula. e.g. /usr/local/Library/Taps/homebrew/homebrew-core/Formula/this-formula.rb



97
98
99
# File 'formula.rb', line 97

def path
  @path
end

#revisionObject (readonly)

Used for creating new Homebrew versions of software without new upstream versions.

See Also:



139
140
141
# File 'formula.rb', line 139

def revision
  @revision
end

#testpathObject (readonly)

The current working directory during tests. Will only be non-nil inside test.



151
152
153
# File 'formula.rb', line 151

def testpath
  @testpath
end

#version_schemeObject (readonly)

Used to change version schemes for packages.

See Also:



143
144
145
# File 'formula.rb', line 143

def version_scheme
  @version_scheme
end

Class Method Details

.[](name) ⇒ Object



1932
1933
1934
# File 'formula.rb', line 1932

def self.[](name)
  Formulary.factory(name)
end

.conflicts_with(*names) ⇒ Object

One or more formulae that conflict with this one and why.

conflicts_with "imagemagick", because: "both install `convert` binaries"


3163
3164
3165
3166
# File 'formula.rb', line 3163

def conflicts_with(*names)
  opts = names.last.is_a?(Hash) ? names.pop : {}
  names.each { |name| conflicts << FormulaConflict.new(name, opts[:because]) }
end

.cxxstdlib_check(check_type) ⇒ Object

Pass :skip to this method to disable post-install stdlib checking.



3197
3198
3199
# File 'formula.rb', line 3197

def cxxstdlib_check(check_type)
  define_method(:skip_cxxstdlib_check?) { true } if check_type == :skip
end

.depends_on(dep) ⇒ Object

The dependencies for this formula. Use strings for the names of other formulae. Homebrew provides some :special Requirements for stuff that needs extra handling (often changing some ENV vars or deciding whether to use the system provided version).

:build means this dependency is only needed during build.

depends_on "cmake" => :build

:test means this dependency is only needed during testing.

depends_on "node" => :test

:recommended dependencies are built by default. But a --without-... option is generated to opt-out.

depends_on "readline" => :recommended

:optional dependencies are NOT built by default unless the auto-generated --with-... option is passed.

depends_on "glib" => :optional

If you need to specify that another formula has to be built with/out certain options (note, no -- needed before the option):

depends_on "zeromq" => "with-pgm"
depends_on "qt" => ["with-qtdbus", "developer"] # Multiple options.

Optional and enforce that “boost” is built with --with-c++11.

depends_on "boost" => [:optional, "with-c++11"]

If a dependency is only needed in certain cases:

depends_on "sqlite" if MacOS.version >= :catalina
depends_on xcode: :build # If the formula really needs full Xcode to compile.
depends_on macos: :mojave # Needs at least macOS Mojave (10.14) to run.

It is possible to only depend on something if build.with? or build.without? "another_formula":

depends_on "postgresql" if build.without? "sqlite"


3068
3069
3070
# File 'formula.rb', line 3068

def depends_on(dep)
  specs.each { |spec| spec.depends_on(dep) }
end

.deprecate!(date:, because:) ⇒ Object

Deprecates a Formula (on the given date) so a warning is shown on each installation. If the date has not yet passed the formula will not be deprecated.

deprecate! date: "2020-08-27", because: :unmaintained
deprecate! date: "2020-08-27", because: "has been replaced by foo"


3360
3361
3362
3363
3364
3365
3366
# File 'formula.rb', line 3360

def deprecate!(date:, because:)
  @deprecation_date = Date.parse(date)
  return if @deprecation_date > Date.today

  @deprecation_reason = because
  @deprecated = true
end

.deprecated?Boolean

Whether this Formula is deprecated (i.e. warns on installation). Defaults to false.

Returns:

  • (Boolean)

See Also:



3372
3373
3374
# File 'formula.rb', line 3372

def deprecated?
  @deprecated == true
end

.disable!(date:, because:) ⇒ Object

Disables a Formula (on the given date) so it cannot be installed. If the date has not yet passed the formula will be deprecated instead of disabled.

disable! date: "2020-08-27", because: :does_not_build
disable! date: "2020-08-27", because: "has been replaced by foo"


3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
# File 'formula.rb', line 3395

def disable!(date:, because:)
  @disable_date = Date.parse(date)

  if @disable_date > Date.today
    @deprecation_reason = because
    @deprecated = true
    return
  end

  @disable_reason = because
  @disabled = true
end

.disabled?Boolean

Whether this Formula is disabled (i.e. cannot be installed). Defaults to false.

Returns:

  • (Boolean)

See Also:



3412
3413
3414
# File 'formula.rb', line 3412

def disabled?
  @disabled == true
end

.fails_with(compiler, &block) ⇒ Object

Marks the Formula as failing with a particular compiler so it will fall back to others. For Apple compilers, this should be in the format:

fails_with :clang do
  build 600
  cause "multiple configure and compile errors"
end

The block may be omitted, and if present the build may be omitted; if so, then the compiler will not be allowed for all versions.

major_version should be the major release number only, for instance ‘7’ for the GCC 7 series (7.0, 7.1, etc.). If version or the block is omitted, then the compiler will not be allowed for all compilers in that series.

For example, if a bug is only triggered on GCC 7.1 but is not encountered on 7.2:

fails_with :gcc => '7' do
  version '7.1'
end


3222
3223
3224
# File 'formula.rb', line 3222

def fails_with(compiler, &block)
  specs.each { |spec| spec.fails_with(compiler, &block) }
end

.freezeObject



2735
2736
2737
2738
2739
2740
2741
2742
2743
# File 'formula.rb', line 2735

def freeze
  specs.each(&:freeze)
  @livecheck.freeze
  @conflicts.freeze
  @skip_clean_paths.freeze
  @link_overwrite_paths.freeze
  @allowed_missing_libraries.freeze
  super
end

.go_resource(name, &block) ⇒ Object



3028
3029
3030
# File 'formula.rb', line 3028

def go_resource(name, &block)
  specs.each { |spec| spec.go_resource(name, &block) }
end

.ignore_missing_libraries(*libs) ⇒ Object

Permit links to certain libraries that don’t exist. Available on Linux only.



3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
# File 'formula.rb', line 3440

def ignore_missing_libraries(*libs)
  unless Homebrew::SimulateSystem.simulating_or_running_on_linux?
    raise FormulaSpecificationError, "#{__method__} is available on Linux only"
  end

  libraries = libs.flatten
  if libraries.any? { |x| !x.is_a?(String) && !x.is_a?(Regexp) }
    raise FormulaSpecificationError, "#{__method__} can handle Strings and Regular Expressions only"
  end

  allowed_missing_libraries.merge(libraries)
end

.inherited(child) ⇒ Object

Initialise instance variables for each subclass. These need to be initialised before the class is frozen, and some DSL may never be called so it can’t be done lazily.



2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
# File 'formula.rb', line 2710

def inherited(child)
  super
  child.instance_eval do
    # Ensure this is synced with `freeze`
    @stable = SoftwareSpec.new(flags: build_flags)
    @head = HeadSoftwareSpec.new(flags: build_flags)
    @livecheck = Livecheck.new(self)
    @conflicts = []
    @skip_clean_paths = Set.new
    @link_overwrite_paths = Set.new
    @allowed_missing_libraries = Set.new
  end
end

.installed_with_alias_path(alias_path) ⇒ Object



1877
1878
1879
1880
1881
# File 'formula.rb', line 1877

def self.installed_with_alias_path(alias_path)
  return [] if alias_path.nil?

  installed.select { |f| f.installed_alias_path == alias_path }
end

.keg_only(reason, explanation = "") ⇒ Object

Software that will not be symlinked into the brew --prefix and will only live in its Cellar. Other formulae can depend on it and Homebrew will add the necessary includes, libraries, and other paths while building that other formula.

Keg-only formulae are not in your PATH and are not seen by compilers if you build your own software outside of Homebrew. This way, we don’t shadow software provided by macOS.

keg_only :provided_by_macos
keg_only :versioned_formulae
keg_only "because I want it so"


3192
3193
3194
# File 'formula.rb', line 3192

def keg_only(reason, explanation = "")
  @keg_only_reason = KegOnlyReason.new(reason, explanation)
end

Permit overwriting certain files while linking.

Sometimes we accidentally install files outside prefix. Once we fix that, users will get a link conflict error. Overwrite those files with:

link_overwrite "bin/foo", "lib/bar"
link_overwrite "share/man/man1/baz-*"


3434
3435
3436
3437
# File 'formula.rb', line 3434

def link_overwrite(*paths)
  paths.flatten!
  link_overwrite_paths.merge(paths)
end

.livecheckable?Boolean

Whether a livecheck specification is defined or not. It returns true when a livecheck block is present in the Formula and false otherwise, and is used by livecheck.

Returns:

  • (Boolean)


2810
2811
2812
# File 'formula.rb', line 2810

def livecheckable?
  @livecheckable == true
end

.needs(*standards) ⇒ Object

Marks the Formula as needing a certain standard, so Homebrew will fall back to other compilers if the default compiler does not implement that standard.

We generally prefer to depends_on a desired compiler and to explicitly use that compiler in a formula’s #install block, rather than implicitly finding a suitable compiler with needs.

See Also:

  • #fails_with


3235
3236
3237
# File 'formula.rb', line 3235

def needs(*standards)
  specs.each { |spec| spec.needs(*standards) }
end

.patch(strip = :p1, src = nil, &block) ⇒ Object

External patches can be declared using resource-style blocks.

patch do
  url "https://example.com/example_patch.diff"
  sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2"
end

A strip level of -p1 is assumed. It can be overridden using a symbol argument:

patch :p0 do
  url "https://example.com/example_patch.diff"
  sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2"
end

Patches can be declared in stable and head blocks. This form is preferred over using conditionals.

stable do
  patch do
    url "https://example.com/example_patch.diff"
    sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2"
  end
end

Embedded (__END__) patches are declared like so:

patch :DATA
patch :p0, :DATA

Patches can also be embedded by passing a string. This makes it possible to provide multiple embedded patches while making only some of them conditional.

patch :p0, "..."

See Also:



3138
3139
3140
# File 'formula.rb', line 3138

def patch(strip = :p1, src = nil, &block)
  specs.each { |spec| spec.patch(strip, src, &block) }
end

.plist_options(options) ⇒ Object

Deprecated.

Please use Homebrew::Service#require_root instead.

Defines launchd plist handling.

Does your plist need to be loaded at startup?

plist_options startup: true

Or only when necessary or desired by the user?

plist_options manual: "foo"

Or perhaps you’d like to give the user a choice? Ooh fancy.

plist_options startup: true, manual: "foo start"


3154
3155
3156
3157
3158
3159
# File 'formula.rb', line 3154

def plist_options(options)
  # TODO: Deprecate
  # odeprecated "plist_options", "service.require_root"
  @plist_startup = options[:startup]
  @plist_manual = options[:manual]
end

.pour_bottle?(only_if: nil, &block) ⇒ Boolean

Defines whether the Formula’s bottle can be used on the given Homebrew installation.

For example, if the bottle requires the Xcode CLT to be installed a Formula would declare:

pour_bottle? do
  reason "The bottle needs the Xcode CLT to be installed."
  satisfy { MacOS::CLT.installed? }
end

If satisfy returns false then a bottle will not be used and instead the Formula will be built from source and reason will be printed.

Alternatively, a preset reason can be passed as a symbol:

pour_bottle? only_if: :clt_installed

Returns:

  • (Boolean)


3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
# File 'formula.rb', line 3320

def pour_bottle?(only_if: nil, &block)
  @pour_bottle_check = PourBottleCheck.new(self)

  if only_if.present? && block.present?
    raise ArgumentError, "Do not pass both a preset condition and a block to `pour_bottle?`"
  end

  block ||= case only_if
  when :clt_installed
    lambda do |_|
      on_macos do
        T.cast(self, PourBottleCheck).reason(+<<~EOS)
          The bottle needs the Apple Command Line Tools to be installed.
            You can install them, if desired, with:
              xcode-select --install
        EOS
        T.cast(self, PourBottleCheck).satisfy { MacOS::CLT.installed? }
      end
    end
  when :default_prefix
    lambda do |_|
      T.cast(self, PourBottleCheck).reason(+<<~EOS)
        The bottle (and many others) needs to be installed into #{Homebrew::DEFAULT_PREFIX}.
      EOS
      T.cast(self, PourBottleCheck).satisfy { HOMEBREW_PREFIX.to_s == Homebrew::DEFAULT_PREFIX }
    end
  else
    raise ArgumentError, "Invalid preset `pour_bottle?` condition" if only_if.present?
  end

  @pour_bottle_check.instance_eval(&block)
end

.resource(name, klass = Resource, &block) ⇒ Object

Additional downloads can be defined as resources and accessed in the install method. Resources can also be defined inside a stable or head block. This mechanism replaces ad-hoc “subformula” classes.

resource "additional_files" do
  url "https://example.com/additional-stuff.tar.gz"
  sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2"
end


3022
3023
3024
3025
3026
# File 'formula.rb', line 3022

def resource(name, klass = Resource, &block)
  specs.each do |spec|
    spec.resource(name, klass, &block) unless spec.resource_defined?(name)
  end
end

.service?Boolean

Whether a service specification is defined or not. It returns true when a service block is present in the Formula and false otherwise, and is used by service.

Returns:

  • (Boolean)


2817
2818
2819
# File 'formula.rb', line 2817

def service?
  @service_block.present?
end

.skip_clean(*paths) ⇒ Object

Skip cleaning paths in a formula.

Sometimes the formula cleaner breaks things. Preserve cleaned paths with:

skip_clean "bin/foo", "lib/bar"

Keep .la files with:

skip_clean :la


3175
3176
3177
3178
3179
# File 'formula.rb', line 3175

def skip_clean(*paths)
  paths.flatten!
  # Specifying :all is deprecated and will become an error
  skip_clean_paths.merge(paths)
end

.test(&block) ⇒ Boolean

A test is required for new formulae and makes us happy. The block will create, run in and delete a temporary directory.

We want tests that don’t require any user input and test the basic functionality of the application. For example, foo build-foo input.foo is a good test and foo --version or foo --help are bad tests. However, a bad test is better than no test at all.

(testpath/"test.file").write <<~EOS
  writing some test file, if you need to
EOS
assert_equal "OK", shell_output("test_command test.file").strip

Need complete control over stdin, stdout?

require "open3"
Open3.popen3("#{bin}/example", "argument") do |stdin, stdout, _|
  stdin.write("some text")
  stdin.close
  assert_equal "result", stdout.read
end

The test will fail if it returns false, or if an exception is raised. Failed assertions and failed system commands will raise exceptions.

Returns:

  • (Boolean)

See Also:



3267
3268
3269
# File 'formula.rb', line 3267

def test(&block)
  define_method(:test, &block)
end

.uses_from_macos(dep, bounds = {}) ⇒ Object

Indicates use of dependencies provided by macOS. On macOS this is a no-op (as we use the provided system libraries) unless :since specifies a minimum macOS version. On Linux this will act as depends_on.



3076
3077
3078
# File 'formula.rb', line 3076

def uses_from_macos(dep, bounds = {})
  specs.each { |spec| spec.uses_from_macos(dep, bounds) }
end

Instance Method Details

#active_log_prefixString

The prefix, if any, to use in filenames for logging current activity.

Returns:



956
957
958
959
960
961
962
# File 'formula.rb', line 956

def active_log_prefix
  if active_log_type
    "#{active_log_type}."
  else
    ""
  end
end

#add_global_deps_to_spec(spec) ⇒ void

This method returns an undefined value.

Parameters:



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'extend/os/linux/formula.rb', line 29

def add_global_deps_to_spec(spec)
  return unless DevelopmentTools.needs_build_formulae?

  @global_deps ||= begin
    dependency_collector = spec.dependency_collector
    related_formula_names = Set.new([
      name,
      *aliases,
      *versioned_formulae_names,
    ])
    [
      dependency_collector.gcc_dep_if_needed(related_formula_names),
      dependency_collector.glibc_dep_if_needed(related_formula_names),
    ].compact.freeze
  end
  @global_deps.each { |dep| spec.dependency_collector.add(dep) }
end

#alias_changed?Boolean

Has the alias used to install the formula changed, or are different formulae already installed with this alias?

Returns:

  • (Boolean)


1440
1441
1442
# File 'formula.rb', line 1440

def alias_changed?
  installed_alias_target_changed? || supersedes_an_installed_formula?
end

#aliasesObject

All aliases for the formula.



502
503
504
505
506
507
508
509
510
# File 'formula.rb', line 502

def aliases
  @aliases ||= if tap
    tap.alias_reverse_table[full_name].to_a.map do |a|
      a.split("/").last
    end
  else
    []
  end
end

#any_installed_prefixObject



1989
1990
1991
1992
1993
1994
1995
# File 'formula.rb', line 1989

def any_installed_prefix
  if optlinked? && opt_prefix.exist?
    opt_prefix
  elsif (latest_installed_prefix = installed_prefixes.last)
    latest_installed_prefix
  end
end

#any_installed_versionObject

Returns the PkgVersion for this formula if it is installed. If not, return nil.



1999
2000
2001
# File 'formula.rb', line 1999

def any_installed_version
  any_installed_keg&.version
end

#bash_completionObject

The directory where the formula’s Bash completion files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



920
921
922
# File 'formula.rb', line 920

def bash_completion
  prefix/"etc/bash_completion.d"
end

#binObject

The directory where the formula’s binaries should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

Need to install into the #bin but the makefile doesn’t mkdir -p prefix/bin?

bin.mkpath

No make install available?

bin.install "binary1"


692
693
694
# File 'formula.rb', line 692

def bin
  prefix/"bin"
end

#bottle_hashObject

Returns the bottle information for a formula



2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
# File 'formula.rb', line 2240

def bottle_hash
  bottle_spec = stable.bottle_specification
  hash = {
    "rebuild"  => bottle_spec.rebuild,
    "root_url" => bottle_spec.root_url,
    "files"    => {},
  }
  bottle_spec.collector.each_tag do |tag|
    tag_spec = bottle_spec.collector.specification_for(tag)
    os_cellar = tag_spec.cellar
    os_cellar = os_cellar.inspect if os_cellar.is_a?(Symbol)

    checksum = tag_spec.checksum.hexdigest
    filename = Bottle::Filename.create(self, tag, bottle_spec.rebuild)
    path, = Utils::Bottles.path_resolved_basename(bottle_spec.root_url, name, checksum, filename)
    url = "#{bottle_spec.root_url}/#{path}"

    hash["files"][tag.to_sym] = {
      "cellar" => os_cellar,
      "url"    => url,
      "sha256" => checksum,
    }
  end
  hash
end

#bottle_tab_attributesHash

Returns:

  • (Hash)


2613
2614
2615
2616
2617
# File 'formula.rb', line 2613

def bottle_tab_attributes
  return {} unless bottled?

  T.must(bottle).tab_attributes
end

#caveatsString?

Warn the user about any Homebrew-specific issues or quirks for this package. These should not contain setup instructions that would apply to installation through a different package manager on a different OS.

def caveats
  <<~EOS
    Are optional. Something the user must be warned about?
  EOS
end
def caveats
  s = <<~EOS
    Print some important notice to the user when `brew info [formula]` is
    called or when brewing a formula.
    This is optional. You can use all the vars like #{version} here.
  EOS
  s += "Some issue only on older systems" if MacOS.version < :el_capitan
  s
end

Returns:



1190
1191
1192
# File 'formula.rb', line 1190

def caveats
  nil
end

#current_installed_alias_targetObject



1420
1421
1422
# File 'formula.rb', line 1420

def current_installed_alias_target
  Formulary.factory(installed_alias_path) if installed_alias_path
end

#deprecated?Boolean

Whether this Formula is deprecated (i.e. warns on installation). Defaults to false.

Returns:

  • (Boolean)

See Also:



1257
# File 'formula.rb', line 1257

delegate deprecated?: :"self.class"

#deprecation_dateObject

The date that this Formula was or becomes deprecated. Returns nil if no date is specified.

Returns:

  • Date

See Also:



1264
# File 'formula.rb', line 1264

delegate deprecation_date: :"self.class"

#deprecation_reasonString, Symbol

The reason this Formula is deprecated. Returns nil if no reason is specified or the formula is not deprecated.

Returns:

See Also:



1271
# File 'formula.rb', line 1271

delegate deprecation_reason: :"self.class"

#descObject

The description of the software.

See Also:



394
# File 'formula.rb', line 394

delegate desc: :"self.class"

#deuniversalize_machos(*targets) ⇒ void

This method returns an undefined value.

Parameters:



26
# File 'extend/os/linux/formula.rb', line 26

def deuniversalize_machos(*targets); end

#disable_dateObject

The date that this Formula was or becomes disabled. Returns nil if no date is specified.

Returns:

  • Date

See Also:



1285
# File 'formula.rb', line 1285

delegate disable_date: :"self.class"

#disable_reasonString, Symbol

The reason this Formula is disabled. Returns nil if no reason is specified or the formula is not disabled.

Returns:

See Also:



1292
# File 'formula.rb', line 1292

delegate disable_reason: :"self.class"

#disabled?Boolean

Whether this Formula is disabled (i.e. cannot be installed). Defaults to false.

Returns:

  • (Boolean)

See Also:



1278
# File 'formula.rb', line 1278

delegate disabled?: :"self.class"

#docObject

The directory where the formula’s documentation should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



699
700
701
# File 'formula.rb', line 699

def doc
  share/"doc"/name
end

#elispObject

The directory where Emacs Lisp files should be installed, with the formula name appended to avoid linking conflicts.

To install an Emacs mode included with a software package:

elisp.install "contrib/emacs/example-mode.el"


856
857
858
# File 'formula.rb', line 856

def elisp
  prefix/"share/emacs/site-lisp"/name
end

#etcObject

The directory where the formula’s configuration files should be installed. Anything using etc.install will not overwrite other files on e.g. upgrades but will write a new file named *.default. This directory is not inside the HOMEBREW_CELLAR so it persists across upgrades.



881
882
883
# File 'formula.rb', line 881

def etc
  (HOMEBREW_PREFIX/"etc").extend(InstallRenamed)
end

#fetch_bottle_tabvoid

This method returns an undefined value.



2606
2607
2608
2609
2610
# File 'formula.rb', line 2606

def fetch_bottle_tab
  return unless bottled?

  T.must(bottle).fetch_tab
end

#fetch_patchesObject



2601
2602
2603
# File 'formula.rb', line 2601

def fetch_patches
  patchlist.select(&:external?).each(&:fetch)
end

#fish_completionObject

The directory where the formula’s fish completion files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



936
937
938
# File 'formula.rb', line 936

def fish_completion
  share/"fish/vendor_completions.d"
end

#fish_functionObject

The directory where the formula’s fish function files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



912
913
914
# File 'formula.rb', line 912

def fish_function
  share/"fish/vendor_functions.d"
end

#frameworksObject

The directory where the formula’s Frameworks should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only. This is not symlinked into HOMEBREW_PREFIX.



864
865
866
# File 'formula.rb', line 864

def frameworks
  prefix/"Frameworks"
end

#full_installed_alias_nameObject



316
317
318
# File 'formula.rb', line 316

def full_installed_alias_name
  full_name_with_optional_tap(installed_alias_name)
end

#full_installed_specified_nameObject

The name (including tap) specified to install this formula.



347
348
349
# File 'formula.rb', line 347

def full_installed_specified_name
  full_installed_alias_name || full_name
end

#full_specified_nameObject

The name (including tap) specified to find this formula.



337
338
339
# File 'formula.rb', line 337

def full_specified_name
  full_alias_name || full_name
end

#generate_completions_from_executable(*commands, base_name: name, shells: [:bash, :zsh, :fish], shell_parameter_format: nil) ⇒ void

This method returns an undefined value.

Generate shell completions for a formula for bash, zsh, and fish, using the formula’s executable.

to use for generating the completion scripts. to the executable. Takes either a String representing a prefix, or one of [:flag, :arg, :none, :click]. Defaults to plainly passing the shell.

translates to

(bash_completion/”foo”).write Utils.safe_popen_read({ “SHELL” => “bash” }, bin/”foo”, “completions”, “bash”)

(zsh_completion/”_foo”).write Utils.safe_popen_read({ “SHELL” => “zsh” }, bin/”foo”, “completions”, “zsh”)

(fish_completion/”foo.fish”).write Utils.safe_popen_read({ “SHELL” => “fish” }, bin/”foo”, “completions”, “fish”)

translates to

(bash_completion/”bar”).write Utils.safe_popen_read({ “SHELL” => “bash” }, bin/”foo”, “completions”, “bash”)

(zsh_completion/”_bar”).write Utils.safe_popen_read({ “SHELL” => “zsh” }, bin/”foo”, “completions”, “zsh”)

translates to

(bash_completion/”foo”).write Utils.safe_popen_read({ “SHELL” => “bash” }, bin/”foo”, “completions”, “–bash”)

translates to

(bash_completion/”foo”).write Utils.safe_popen_read({ “SHELL” => “bash” }, bin/”foo”, “completions”, “–shell=bash”)

translates to

(bash_completion/”foo”).write Utils.safe_popen_read({ “SHELL” => “bash” }, bin/”foo”, “completions”)

translates to

(zsh_completion/”_foo”).write Utils.safe_popen_read({ “SHELL” => “zsh”, “_FOO_COMPLETE” => “zsh_source” }, bin/”foo”)

translates to

(bash_completion/”foo”).write Utils.safe_popen_read({ “SHELL” => “bash” }, bin/”foo”, “completions”, “–selected-shell=bash”)

Examples:

Using default values for optional arguments

generate_completions_from_executable(bin/"foo", "completions")

Selecting shells and using a different base_name

generate_completions_from_executable(bin/"foo", "completions", shells: [:bash, :zsh], base_name: "bar")

Using predefined shell_parameter_format :flag

generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: :flag, shells: [:bash])

Using predefined shell_parameter_format :arg

generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: :arg, shells: [:bash])

Using predefined shell_parameter_format :none

generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: :none, shells: [:bash])

Using predefined shell_parameter_format :click

generate_completions_from_executable(bin/"foo", shell_parameter_format: :click, shells: [:zsh])

Using custom shell_parameter_format

generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: "--selected-shell=",
                                     shells: [:bash])

Parameters:

  • commands (Pathname, String)

    the path to the executable and any passed subcommand(s)

  • base_name (String) (defaults to: name)

    the base name of the generated completion script. Defaults to the formula name.

  • shells (Array<Symbol>) (defaults to: [:bash, :zsh, :fish])

    the shells to generate completion scripts for. Defaults to [:bash, :zsh, :fish].

  • shell_parameter_format (Symbol, String, nil) (defaults to: nil)

    specify how shells should each be passed



1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
# File 'formula.rb', line 1751

def generate_completions_from_executable(*commands,
                                         base_name: name,
                                         shells: [:bash, :zsh, :fish],
                                         shell_parameter_format: nil)
  completion_script_path_map = {
    bash: bash_completion/base_name,
    zsh:  zsh_completion/"_#{base_name}",
    fish: fish_completion/"#{base_name}.fish",
  }

  shells.each do |shell|
    popen_read_env = { "SHELL" => shell.to_s }
    script_path = completion_script_path_map[shell]
    shell_parameter = if shell_parameter_format.nil?
      shell.to_s
    elsif shell_parameter_format == :flag
      "--#{shell}"
    elsif shell_parameter_format == :arg
      "--shell=#{shell}"
    elsif shell_parameter_format == :none
      nil
    elsif shell_parameter_format == :click
      prog_name = File.basename(commands.first.to_s).upcase.tr("-", "_")
      popen_read_env["_#{prog_name}_COMPLETE"] = "#{shell}_source"
      nil
    else
      "#{shell_parameter_format}#{shell}"
    end

    popen_read_args = %w[]
    popen_read_args << commands
    popen_read_args << shell_parameter if shell_parameter.present?
    popen_read_args.flatten!

    popen_read_options = {}
    popen_read_options[:err] = :err unless ENV["HOMEBREW_STDERR"]

    script_path.dirname.mkpath
    script_path.write Utils.safe_popen_read(popen_read_env, *popen_read_args, **popen_read_options)
  end
end

#head_version_outdated?(version, fetch_head: false) ⇒ Boolean

Returns:

  • (Boolean)


594
595
596
597
598
599
600
601
602
603
604
605
606
607
# File 'formula.rb', line 594

def head_version_outdated?(version, fetch_head: false)
  tab = Tab.for_keg(prefix(version))

  return true if tab.version_scheme < version_scheme
  return true if stable && tab.stable_version && tab.stable_version < stable.version
  return false unless fetch_head
  return false unless head&.downloader.is_a?(VCSDownloadStrategy)

  downloader = head.downloader

  with_context quiet: true do
    downloader.commit_outdated?(version.version.commit)
  end
end

#homepageObject

The homepage for the software.

See Also:



404
# File 'formula.rb', line 404

delegate homepage: :"self.class"

#includeObject

The directory where the formula’s headers should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

include.install "example.h"


709
710
711
# File 'formula.rb', line 709

def include
  prefix/"include"
end

#infoObject

The directory where the formula’s info files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



716
717
718
# File 'formula.rb', line 716

def info
  share/"info"
end

#inreplace(paths, before = nil, after = nil, audit_result = true) ⇒ Object

Sometimes we have to change a bit before we install. Mostly we prefer a patch, but if you need the prefix of this formula in the patch you have to resort to inreplace, because in the patch you don’t have access to any variables defined by the formula, as only HOMEBREW_PREFIX is available in the embedded patch.

inreplace supports regular expressions:

inreplace "somefile.cfg", /look[for]what?/, "replace by #{bin}/tool"

inreplace supports blocks:

inreplace "Makefile" do |s|
  s.gsub! "/usr/local", HOMEBREW_PREFIX.to_s
end


2356
2357
2358
2359
2360
2361
# File 'formula.rb', line 2356

def inreplace(paths, before = nil, after = nil, audit_result = true) # rubocop:disable Style/OptionalBooleanParameter
  super(paths, before, after, audit_result)
rescue Utils::Inreplace::Error => e
  onoe e.to_s
  raise BuildError.new(self, "inreplace", paths, {})
end

#installObject

This method is overridden in Formula subclasses to provide the installation instructions. The sources (from url) are downloaded, hash-checked and then Homebrew changes into a temporary directory where the archive is unpacked or repository cloned.

def install
  system "./configure", "--prefix=#{prefix}"
  system "make", "install"
end


2336
# File 'formula.rb', line 2336

def install; end

#installed_alias_nameString?

Returns:



312
313
314
# File 'formula.rb', line 312

def installed_alias_name
  File.basename(installed_alias_path) if installed_alias_path
end

#installed_alias_pathObject

The alias path that was used to install this formula, if it exists. Can differ from #alias_path, which is the alias used to find the formula, and is specified to this instance.



303
304
305
306
307
308
309
# File 'formula.rb', line 303

def installed_alias_path
  path = build.source["path"] if build.is_a?(Tab)
  return unless path&.match?(%r{#{HOMEBREW_TAP_DIR_REGEX}/Aliases}o)
  return unless File.symlink?(path)

  path
end

#installed_alias_target_changed?Boolean

Has the target of the alias used to install this formula changed? Returns false if the formula wasn’t installed with an alias.

Returns:

  • (Boolean)


1426
1427
1428
1429
1430
1431
# File 'formula.rb', line 1426

def installed_alias_target_changed?
  target = current_installed_alias_target
  return false unless target

  target.name != name
end

#installed_specified_nameObject

The name specified to install this formula.



342
343
344
# File 'formula.rb', line 342

def installed_specified_name
  installed_alias_name || name
end

#keg_only?Boolean

Rarely, you don’t want your library symlinked into the main prefix. See gettext.rb for an example.

Returns:

  • (Boolean)

See Also:



1197
1198
1199
1200
1201
# File 'formula.rb', line 1197

def keg_only?
  return false unless keg_only_reason

  keg_only_reason.applicable?
end

#kext_prefixObject

The directory where the formula’s kernel extensions should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only. This is not symlinked into HOMEBREW_PREFIX.



872
873
874
# File 'formula.rb', line 872

def kext_prefix
  prefix/"Library/Extensions"
end

#latest_formulaObject

If the alias has changed value, return the new formula. Otherwise, return self.



1446
1447
1448
# File 'formula.rb', line 1446

def latest_formula
  installed_alias_target_changed? ? current_installed_alias_target : self
end

#latest_head_prefixObject



589
590
591
592
# File 'formula.rb', line 589

def latest_head_prefix
  head_version = latest_head_version
  prefix(head_version) if head_version
end

#latest_head_versionObject



578
579
580
581
582
583
584
585
586
587
# File 'formula.rb', line 578

def latest_head_version
  head_versions = installed_prefixes.map do |pn|
    pn_pkgversion = PkgVersion.parse(pn.basename.to_s)
    pn_pkgversion if pn_pkgversion.head?
  end.compact

  head_versions.max_by do |pn_pkgversion|
    [Tab.for_keg(prefix(pn_pkgversion)).source_modified_time, pn_pkgversion.revision]
  end
end

#launchd_service_pathPathname

The generated launchd service file path.

Returns:



1027
1028
1029
# File 'formula.rb', line 1027

def launchd_service_path
  opt_prefix/"#{plist_name}.plist"
end

#libObject

The directory where the formula’s libraries should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

lib.install "example.dylib"


726
727
728
# File 'formula.rb', line 726

def lib
  prefix/"lib"
end

#libexecObject

The directory where the formula’s binaries should be installed. This is not symlinked into HOMEBREW_PREFIX. It is commonly used to install files that we do not wish to be symlinked into HOMEBREW_PREFIX from one of the other directories and instead manually create symlinks or wrapper scripts into e.g. #bin.

libexec.install "foo.jar"
bin.write_jar_script libexec/"foo.jar", "foo"


738
739
740
# File 'formula.rb', line 738

def libexec
  prefix/"libexec"
end

#licenseObject

The SPDX ID of the software license.

See Also:



399
# File 'formula.rb', line 399

delegate license: :"self.class"

#linked?Boolean

Is the formula linked?

Returns:

  • (Boolean)


636
637
638
# File 'formula.rb', line 636

def linked?
  linked_keg.symlink?
end

#linked_versionPkgVersion?

PkgVersion of the linked keg for the formula.

Returns:



654
655
656
657
658
# File 'formula.rb', line 654

def linked_version
  return unless linked?

  Keg.for(linked_keg).version
end

#livecheckObject

The livecheck specification for the software.

See Also:



409
# File 'formula.rb', line 409

delegate livecheck: :"self.class"

#livecheckable?Object

Is a livecheck specification defined for the software?

See Also:



414
# File 'formula.rb', line 414

delegate livecheckable?: :"self.class"

#loader_pathString

Returns:



21
22
23
# File 'extend/os/linux/formula.rb', line 21

def loader_path
  "$ORIGIN"
end

#manObject

The root directory where the formula’s manual pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only. Often one of the more specific man functions should be used instead, e.g. #man1.



747
748
749
# File 'formula.rb', line 747

def man
  share/"man"
end

#man1Object

The directory where the formula’s man1 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

man1.install "example.1"


757
758
759
# File 'formula.rb', line 757

def man1
  man/"man1"
end

#man2Object

The directory where the formula’s man2 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



764
765
766
# File 'formula.rb', line 764

def man2
  man/"man2"
end

#man3Object

The directory where the formula’s man3 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

man3.install "man.3"


774
775
776
# File 'formula.rb', line 774

def man3
  man/"man3"
end

#man4Object

The directory where the formula’s man4 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



781
782
783
# File 'formula.rb', line 781

def man4
  man/"man4"
end

#man5Object

The directory where the formula’s man5 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



788
789
790
# File 'formula.rb', line 788

def man5
  man/"man5"
end

#man6Object

The directory where the formula’s man6 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



795
796
797
# File 'formula.rb', line 795

def man6
  man/"man6"
end

#man7Object

The directory where the formula’s man7 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



802
803
804
# File 'formula.rb', line 802

def man7
  man/"man7"
end

#man8Object

The directory where the formula’s man8 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



809
810
811
# File 'formula.rb', line 809

def man8
  man/"man8"
end

#migration_needed?Boolean

Returns:

  • (Boolean)


1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
# File 'formula.rb', line 1368

def migration_needed?
  return false unless oldname
  return false if rack.exist?

  old_rack = HOMEBREW_CELLAR/oldname
  return false unless old_rack.directory?
  return false if old_rack.subdirs.empty?

  tap == Tab.for_keg(old_rack.subdirs.min).tap
end

#missing_dependencies(hide: nil) ⇒ Object

Returns a list of formulae depended on by this formula that aren’t installed.



2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
# File 'formula.rb', line 2060

def missing_dependencies(hide: nil)
  hide ||= []
  runtime_formula_dependencies.select do |f|
    hide.include?(f.name) || f.installed_prefixes.empty?
  end
# If we're still getting unavailable formulae at this stage the best we can
# do is just return no results.
rescue FormulaUnavailableError
  []
end

#mkdir(name, &block) ⇒ Object

A version of FileUtils.mkdir that also changes to that folder in a block.



2582
2583
2584
2585
2586
2587
# File 'formula.rb', line 2582

def mkdir(name, &block)
  result = FileUtils.mkdir_p(name)
  return result unless block

  FileUtils.chdir(name, &block)
end

#mktemp(prefix = name, opts = {}, &block) ⇒ Object

Create a temporary directory then yield. When the block returns, recursively delete the temporary directory. Passing opts[:retain] or calling do |staging| ... staging.retain! in the block will skip the deletion and retain the temporary directory’s contents.



2576
2577
2578
# File 'formula.rb', line 2576

def mktemp(prefix = name, opts = {}, &block)
  Mktemp.new(prefix, opts).run(&block)
end

#new_formula_available?Boolean

Returns:

  • (Boolean)


1416
1417
1418
# File 'formula.rb', line 1416

def new_formula_available?
  installed_alias_target_changed? && !latest_formula.latest_version_installed?
end

#old_installed_formulaeObject



1450
1451
1452
1453
1454
1455
1456
1457
# File 'formula.rb', line 1450

def old_installed_formulae
  # If this formula isn't the current target of the alias,
  # it doesn't make sense to say that other formulae are older versions of it
  # because we don't know which came first.
  return [] if alias_path.nil? || installed_alias_target_changed?

  self.class.installed_with_alias_path(alias_path).reject { |f| f.name == name }
end

#oldnameObject

An old name for the formula.



494
495
496
497
498
499
# File 'formula.rb', line 494

def oldname
  @oldname ||= if tap
    formula_renames = tap.formula_renames
    formula_renames.to_a.rassoc(name).first if formula_renames.value?(name)
  end
end

#opt_binPathname

Returns:



1069
1070
1071
# File 'formula.rb', line 1069

def opt_bin
  opt_prefix/"bin"
end

#opt_elispPathname

Returns:



1104
1105
1106
# File 'formula.rb', line 1104

def opt_elisp
  opt_prefix/"share/emacs/site-lisp"/name
end

#opt_frameworksPathname

Returns:



1109
1110
1111
# File 'formula.rb', line 1109

def opt_frameworks
  opt_prefix/"Frameworks"
end

#opt_includePathname

Returns:



1074
1075
1076
# File 'formula.rb', line 1074

def opt_include
  opt_prefix/"include"
end

#opt_libPathname

Returns:



1079
1080
1081
# File 'formula.rb', line 1079

def opt_lib
  opt_prefix/"lib"
end

#opt_libexecPathname

Returns:



1084
1085
1086
# File 'formula.rb', line 1084

def opt_libexec
  opt_prefix/"libexec"
end

#opt_pkgsharePathname

Returns:



1099
1100
1101
# File 'formula.rb', line 1099

def opt_pkgshare
  opt_prefix/"share"/name
end

#opt_prefixPathname

A stable path for this formula, when installed. Contains the formula name but no version number. Only the active version will be linked here if multiple versions are installed.

This is the preferred way to refer to a formula in plists or from another formula, as the path is stable even when the software is updated.

args << "--with-readline=#{Formula["readline"].opt_prefix}" if build.with? "readline"

Returns:



1064
1065
1066
# File 'formula.rb', line 1064

def opt_prefix
  HOMEBREW_PREFIX/"opt"/name
end

#opt_sbinPathname

Returns:



1089
1090
1091
# File 'formula.rb', line 1089

def opt_sbin
  opt_prefix/"sbin"
end

#opt_sharePathname

Returns:



1094
1095
1096
# File 'formula.rb', line 1094

def opt_share
  opt_prefix/"share"
end

#option_defined?Object

If a named option is defined for the currently active SoftwareSpec.



548
# File 'formula.rb', line 548

delegate option_defined?: :active_spec

#optlinked?Boolean

Is the formula linked to opt?

Returns:

  • (Boolean)


641
642
643
# File 'formula.rb', line 641

def optlinked?
  opt_prefix.symlink?
end

#pkg_versionPkgVersion

The PkgVersion for this formula with version and #revision information.

Returns:



446
447
448
# File 'formula.rb', line 446

def pkg_version
  PkgVersion.new(version, revision)
end

#pkgetcObject

A subdirectory of etc with the formula name suffixed. e.g. $HOMEBREW_PREFIX/etc/openssl@1.1 Anything using pkgetc.install will not overwrite other files on e.g. upgrades but will write a new file named *.default.



889
890
891
# File 'formula.rb', line 889

def pkgetc
  (HOMEBREW_PREFIX/"etc"/name).extend(InstallRenamed)
end

#pkgshareObject

The directory where the formula’s shared files should be installed, with the name of the formula appended to avoid linking conflicts. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

pkgshare.install "examples"


847
848
849
# File 'formula.rb', line 847

def pkgshare
  prefix/"share"/name
end

#plistObject

Deprecated.

Please use Homebrew::Service instead.

This method can be overridden to provide a plist.

def plist; <<~EOS
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
    <key>Label</key>
      <string>#{plist_name}</string>
    <key>ProgramArguments</key>
    <array>
      <string>#{opt_bin}/example</string>
      <string>--do-this</string>
    </array>
    <key>RunAtLoad</key>
    <true />
    <key>KeepAlive</key>
    <true />
    <key>StandardErrorPath</key>
    <string>/dev/null</string>
    <key>StandardOutPath</key>
    <string>/dev/null</string>
  </dict>
  </plist>
  EOS
end


1001
1002
1003
# File 'formula.rb', line 1001

def plist
  nil
end

#plist_nameString

The generated launchd #plist service name.

Returns:



1007
1008
1009
# File 'formula.rb', line 1007

def plist_name
  "homebrew.mxcl.#{name}"
end

#plist_pathPathname

The generated launchd #plist file path.

Returns:



1019
1020
1021
1022
1023
# File 'formula.rb', line 1019

def plist_path
  # TODO: Add deprecation
  # odeprecated "formula.plist_path", "formula.launchd_service_path"
  launchd_service_path
end

#post_installvoid

This method returns an undefined value.

Can be overridden to run commands on both source and bottle installation.



1129
# File 'formula.rb', line 1129

def post_install; end

#pour_bottle?Boolean

Indicates that this formula supports bottles. (Not necessarily that one should be used in the current installation run.) Can be overridden to selectively disable bottles from formulae. Defaults to true so overridden version does not have to check if bottles are supported. Replaced by pour_bottle?’s satisfy method if it is specified.

Returns:

  • (Boolean)


1120
1121
1122
# File 'formula.rb', line 1120

def pour_bottle?
  true
end

#prefix(v = pkg_version) ⇒ Object

The directory in the cellar that the formula is installed to. This directory points to #opt_prefix if it exists and if ##prefix is not called from within the same formula’s #install or #post_install methods. Otherwise, return the full path to the formula’s versioned cellar.



625
626
627
628
629
630
631
632
633
# File 'formula.rb', line 625

def prefix(v = pkg_version)
  versioned_prefix = versioned_prefix(v)
  if !@prefix_returns_versioned_prefix && v == pkg_version &&
     versioned_prefix.directory? && Keg.new(versioned_prefix).optlinked?
    opt_prefix
  else
    versioned_prefix
  end
end

#prefix_linked?(v = pkg_version) ⇒ Boolean

If a formula’s linked keg points to the prefix.

Returns:

  • (Boolean)


646
647
648
649
650
# File 'formula.rb', line 646

def prefix_linked?(v = pkg_version)
  return false unless linked?

  linked_keg.resolved_path == versioned_prefix(v)
end

#resourceObject

A named Resource for the currently active SoftwareSpec. Additional downloads can be defined as #resources. Resource#stage will create a temporary directory and yield to a block.

resource("additional_files").stage { bin.install "my/extra/tool" }


491
# File 'formula.rb', line 491

delegate resource: :active_spec

#resourcesObject

The Resources for the currently active SoftwareSpec.



514
# File 'formula.rb', line 514

def_delegator :"active_spec.resources", :values, :resources

#rpath(source: bin, target: lib) ⇒ String

Executable/Library RPATH according to platform conventions.

Optionally specify a source or target depending on the location of the file containing the RPATH command and where its target is located.


rpath #=> "@loader_path/../lib"
rpath(target: frameworks) #=> "@loader_path/../Frameworks"
rpath(source: libexec/"bin") #=> "@loader_path/../../lib"

Parameters:

Returns:



1628
1629
1630
1631
1632
1633
1634
# File 'formula.rb', line 1628

def rpath(source: bin, target: lib)
  unless target.to_s.start_with?(HOMEBREW_PREFIX)
    raise "rpath `target` should only be used for paths inside HOMEBREW_PREFIX!"
  end

  "#{loader_path}/#{target.relative_path_from(source)}"
end

#runtime_installed_formula_dependentsObject



2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
# File 'formula.rb', line 2041

def runtime_installed_formula_dependents
  # `any_installed_keg` and `runtime_dependencies` `select`s ensure
  # that we don't end up with something `Formula#runtime_dependencies` can't
  # read from a `Tab`.
  Formula.cache[:runtime_installed_formula_dependents] ||= {}
  Formula.cache[:runtime_installed_formula_dependents][full_name] ||= Formula.installed
                                                                             .select(&:any_installed_keg)
                                                                             .select(&:runtime_dependencies)
                                                                             .select do |f|
    f.runtime_formula_dependencies.any? do |dep|
      full_name == dep.full_name
    rescue
      name == dep.name
    end
  end
end

#sbinObject

The directory where the formula’s sbin binaries should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only. Generally we try to migrate these to #bin instead.



817
818
819
# File 'formula.rb', line 817

def sbin
  prefix/"sbin"
end

#serviceObject

The service specification of the software.



1044
1045
1046
1047
1048
# File 'formula.rb', line 1044

def service
  return unless service?

  Homebrew::Service.new(self, &self.class.service)
end

#service?Object

Is a service specification defined for the software?

See Also:



419
# File 'formula.rb', line 419

delegate service?: :"self.class"

#service_nameString

The generated service name.

Returns:



1013
1014
1015
# File 'formula.rb', line 1013

def service_name
  "homebrew.#{name}"
end

#shareObject

The directory where the formula’s shared files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

Need a custom directory?

(share/"concept").mkpath

Installing something into another custom directory?

(share/"concept2").install "ducks.txt"

Install ./example_code/simple/ones to share/demos:

(share/"demos").install "example_code/simple/ones"

Install ./example_code/simple/ones to share/demos/examples:

(share/"demos").install "example_code/simple/ones" => "examples"


836
837
838
# File 'formula.rb', line 836

def share
  prefix/"share"
end

#shared_library(name, version = nil) ⇒ String

Parameters:

  • name (String)
  • version (String, Integer, nil) (defaults to: nil)

Returns:



11
12
13
14
15
16
17
18
# File 'extend/os/linux/formula.rb', line 11

def shared_library(name, version = nil)
  suffix = if version == "*" || (name == "*" && version.blank?)
    "{,.*}"
  elsif version.present?
    ".#{version}"
  end
  "#{name}.so#{suffix}"
end

#skip_cxxstdlib_check?Boolean

Returns:

  • (Boolean)


1295
1296
1297
# File 'formula.rb', line 1295

def skip_cxxstdlib_check?
  false
end

#specified_nameObject

The name specified to find this formula.



332
333
334
# File 'formula.rb', line 332

def specified_name
  alias_name || name
end

#specified_pathObject

The path that was specified to find this formula.



321
322
323
324
325
326
327
328
329
# File 'formula.rb', line 321

def specified_path
  default_specified_path = Pathname(alias_path) if alias_path.present?
  default_specified_path ||= path

  return default_specified_path if default_specified_path.presence&.exist?
  return local_bottle_path if local_bottle_path.presence&.exist?

  default_specified_path
end

#std_cabal_v2_argsArray<String>

Standard parameters for cabal-v2 builds.

Returns:



1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
# File 'formula.rb', line 1574

def std_cabal_v2_args
  env = T.cast(ENV, T.any(Stdenv, Superenv))

  # cabal-install's dependency-resolution backtracking strategy can
  # easily need more than the default 2,000 maximum number of
  # "backjumps," since Hackage is a fast-moving, rolling-release
  # target. The highest known needed value by a formula was 43,478
  # for git-annex, so 100,000 should be enough to avoid most
  # gratuitous backjumps build failures.
  ["--jobs=#{env.make_jobs}", "--max-backjumps=100000", "--install-method=copy", "--installdir=#{bin}"]
end

#std_cargo_args(root: prefix, path: ".") ⇒ Array<String, Pathname>

Standard parameters for cargo builds.

Parameters:

Returns:



1524
1525
1526
# File 'formula.rb', line 1524

def std_cargo_args(root: prefix, path: ".")
  ["--locked", "--root", root, "--path", path]
end

#std_cmake_args(install_prefix: prefix, install_libdir: "lib", find_framework: "LAST") ⇒ Array<String>

Standard parameters for CMake builds.

Setting CMAKE_FIND_FRAMEWORK to “LAST” tells CMake to search for our libraries before trying to utilize Frameworks, many of which will be from 3rd party installs.

Parameters:

  • install_prefix (String, Pathname) (defaults to: prefix)
  • install_libdir (String) (defaults to: "lib")
  • find_framework (String) (defaults to: "LAST")

Returns:



1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
# File 'formula.rb', line 1540

def std_cmake_args(install_prefix: prefix, install_libdir: "lib", find_framework: "LAST")
  args = %W[
    -DCMAKE_INSTALL_PREFIX=#{install_prefix}
    -DCMAKE_INSTALL_LIBDIR=#{install_libdir}
    -DCMAKE_BUILD_TYPE=Release
    -DCMAKE_FIND_FRAMEWORK=#{find_framework}
    -DCMAKE_VERBOSE_MAKEFILE=ON
    -Wno-dev
    -DBUILD_TESTING=OFF
  ]

  # Avoid false positives for clock_gettime support on 10.11.
  # CMake cache entries for other weak symbols may be added here as needed.
  args << "-DHAVE_CLOCK_GETTIME:INTERNAL=0" if MacOS.version == "10.11" && MacOS::Xcode.version >= "8.0"

  # Ensure CMake is using the same SDK we are using.
  args << "-DCMAKE_OSX_SYSROOT=#{MacOS.sdk_for_formula(self).path}" if MacOS.sdk_root_needed?

  args
end

#std_configure_argsArray<String>

Standard parameters for configure builds.

Returns:



1518
1519
1520
# File 'formula.rb', line 1518

def std_configure_args
  ["--disable-debug", "--disable-dependency-tracking", "--prefix=#{prefix}", "--libdir=#{lib}"]
end

#std_go_args(output: bin/name, ldflags: nil) ⇒ Array<String>

Standard parameters for Go builds.

Parameters:

Returns:



1566
1567
1568
1569
1570
# File 'formula.rb', line 1566

def std_go_args(output: bin/name, ldflags: nil)
  args = ["-trimpath", "-o=#{output}"]
  args += ["-ldflags=#{Array(ldflags).join(" ")}"] if ldflags
  args
end

#std_meson_argsArray<String>

Standard parameters for meson builds.

Returns:



1588
1589
1590
# File 'formula.rb', line 1588

def std_meson_args
  ["--prefix=#{prefix}", "--libdir=#{lib}", "--buildtype=release", "--wrap-mode=nofallback"]
end

#supersedes_an_installed_formula?Boolean

Is this formula the target of an alias used to install an old formula?

Returns:

  • (Boolean)


1434
1435
1436
# File 'formula.rb', line 1434

def supersedes_an_installed_formula?
  old_installed_formulae.any?
end

#system(cmd, *args) ⇒ void

This method returns an undefined value.

To call out to the system, we use the system method and we prefer you give the args separately as in the line below, otherwise a subshell has to be opened first.

system "./bootstrap.sh", "--arg1", "--prefix=#{prefix}"

For CMake and other build systems we have some necessary defaults in e.g. #std_cmake_args:

system "cmake", ".", *std_cmake_args

If the arguments given to configure (or make or cmake) are depending on options defined above, we usually make a list first and then use the args << if <condition> to append each:

args = ["--with-option1", "--with-option2"]
args << "--without-gcc" if ENV.compiler == :clang

# Most software still uses `configure` and `make`.
# Check with `./configure --help` for what our options are.
system "./configure", "--disable-debug", "--disable-dependency-tracking",
                      "--disable-silent-rules", "--prefix=#{prefix}",
                      *args # our custom arg list (needs `*` to unpack)

# If there is a "make install" available, please use it!
system "make", "install"

Parameters:



2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
# File 'formula.rb', line 2432

def system(cmd, *args)
  verbose_using_dots = Homebrew::EnvConfig.verbose_using_dots?

  # remove "boring" arguments so that the important ones are more likely to
  # be shown considering that we trim long ohai lines to the terminal width
  pretty_args = args.dup
  unless verbose?
    case cmd
    when "./configure"
      pretty_args -= %w[--disable-dependency-tracking --disable-debug --disable-silent-rules]
    when "cargo"
      pretty_args -= std_cargo_args
    when "cmake"
      pretty_args -= std_cmake_args
    when "go"
      pretty_args -= std_go_args
    end
  end
  pretty_args.each_index do |i|
    pretty_args[i] = "import setuptools..." if pretty_args[i].to_s.start_with? "import setuptools"
  end
  ohai "#{cmd} #{pretty_args * " "}".strip

  @exec_count ||= 0
  @exec_count += 1
  logfn = format("#{logs}/#{active_log_prefix}%02<exec_count>d.%<cmd_base>s",
                 exec_count: @exec_count,
                 cmd_base:   File.basename(cmd).split.first)
  logs.mkpath

  File.open(logfn, "w") do |log|
    log.puts Time.now, "", cmd, args, ""
    log.flush

    if verbose?
      rd, wr = IO.pipe
      begin
        pid = fork do
          rd.close
          log.close
          exec_cmd(cmd, args, wr, logfn)
        end
        wr.close

        if verbose_using_dots
          last_dot = Time.at(0)
          while (buf = rd.gets)
            log.puts buf
            # make sure dots printed with interval of at least 1 min.
            next unless (Time.now - last_dot) > 60

            print "."
            $stdout.flush
            last_dot = Time.now
          end
          puts
        else
          while (buf = rd.gets)
            log.puts buf
            puts buf
          end
        end
      ensure
        rd.close
      end
    else
      pid = fork do
        exec_cmd(cmd, args, log, logfn)
      end
    end

    Process.wait(T.must(pid))

    $stdout.flush

    unless $CHILD_STATUS.success?
      log_lines = Homebrew::EnvConfig.fail_log_lines

      log.flush
      if !verbose? || verbose_using_dots
        puts "Last #{log_lines} lines from #{logfn}:"
        Kernel.system "/usr/bin/tail", "-n", log_lines, logfn
      end
      log.puts

      require "system_config"
      require "build_environment"

      env = ENV.to_hash

      SystemConfig.dump_verbose_config(log)
      log.puts
      BuildEnvironment.dump env, log

      raise BuildError.new(self, cmd, args, env)
    end
  end
end

#systemd_service_pathPathname

The generated systemd service file path.

Returns:



1033
1034
1035
# File 'formula.rb', line 1033

def systemd_service_path
  opt_prefix/"#{service_name}.service"
end

#systemd_timer_pathPathname

The generated systemd timer file path.

Returns:



1039
1040
1041
# File 'formula.rb', line 1039

def systemd_timer_path
  opt_prefix/"#{service_name}.timer"
end

#timeTime

Creates a new Time object for use in the formula as the build time.

Returns:

  • (Time)

See Also:



1645
1646
1647
1648
1649
1650
1651
# File 'formula.rb', line 1645

def time
  if ENV["SOURCE_DATE_EPOCH"].present?
    Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc
  else
    Time.now.utc
  end
end

#to_recursive_bottle_hash(top_level: true) ⇒ Object

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Generate a hash to be used to install a formula from a JSON file



2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
# File 'formula.rb', line 2215

def to_recursive_bottle_hash(top_level: true)
  bottle = bottle_hash

  bottles = bottle["files"].to_h do |tag, file|
    info = { "url" => file["url"] }
    info["sha256"] = file["sha256"] if tap.name != "homebrew/core"
    [tag.to_s, info]
  end

  hash = {
    "name"        => name,
    "pkg_version" => pkg_version,
    "rebuild"     => bottle["rebuild"],
    "bottles"     => bottles,
  }

  return hash unless top_level

  hash["dependencies"] = declared_runtime_dependencies.map do |dep|
    dep.to_formula.to_recursive_bottle_hash(top_level: false)
  end
  hash
end

#to_sObject



1506
1507
1508
# File 'formula.rb', line 1506

def to_s
  name
end

#update_head_versionObject



428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'formula.rb', line 428

def update_head_version
  return unless head?
  return unless head.downloader.is_a?(VCSDownloadStrategy)
  return unless head.downloader.cached_location.exist?

  path = if ENV["HOMEBREW_ENV"]
    ENV.fetch("PATH")
  else
    PATH.new(ORIGINAL_PATHS)
  end

  with_env(PATH: path) do
    head.version.update_commit(head.downloader.last_commit)
  end
end

#varObject

The directory where the formula’s variable files should be installed. This directory is not inside the HOMEBREW_CELLAR so it persists across upgrades.



896
897
898
# File 'formula.rb', line 896

def var
  HOMEBREW_PREFIX/"var"
end

#versionObject

The version for the currently active SoftwareSpec. The version is autodetected from the URL and/or tag so only needs to be declared if it cannot be autodetected correctly.

See Also:



426
# File 'formula.rb', line 426

delegate version: :active_spec

#versioned_formula?Boolean

If this is a @-versioned formula.

Returns:

  • (Boolean)


452
453
454
# File 'formula.rb', line 452

def versioned_formula?
  name.include?("@")
end

#versioned_formulaeArray<Formula>

Returns any @-versioned Formula objects for any Formula (including versioned formulae).

Returns:



478
479
480
481
482
483
484
# File 'formula.rb', line 478

def versioned_formulae
  versioned_formulae_names.map do |name|
    Formula[name]
  rescue FormulaUnavailableError
    nil
  end.compact.sort_by(&:version).reverse
end

#versioned_formulae_namesArray<String>

Returns any @-versioned formulae names for any formula (including versioned formulae).

Returns:



458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'formula.rb', line 458

def versioned_formulae_names
  versioned_paths = if tap
    # Faster path, due to `tap.versioned_formula_files` caching.
    name_prefix = "#{name.gsub(/(@[\d.]+)?$/, "")}@"
    tap.versioned_formula_files.select do |file|
      file.basename.to_s.start_with?(name_prefix)
    end
  else
    Pathname.glob(path.to_s.gsub(/(@[\d.]+)?\.rb$/, "@*.rb"))
  end

  versioned_paths.map do |versioned_path|
    next if versioned_path == path

    versioned_path.basename(".rb").to_s
  end.compact.sort
end

#with_logging(log_type) ⇒ Object

Runs a block with the given log type in effect for its duration.



965
966
967
968
969
970
971
# File 'formula.rb', line 965

def with_logging(log_type)
  old_log_type = @active_log_type
  @active_log_type = log_type
  yield
ensure
  @active_log_type = old_log_type
end

#xcodebuild(*args) ⇒ void

This method returns an undefined value.

Runs xcodebuild without Homebrew’s compiler environment variables set.

Parameters:



2591
2592
2593
2594
2595
2596
2597
2598
2599
# File 'formula.rb', line 2591

def xcodebuild(*args)
  removed = ENV.remove_cc_etc

  begin
    T.unsafe(self).system("xcodebuild", *args)
  ensure
    ENV.update(removed)
  end
end

#zsh_completionObject

The directory where the formula’s zsh completion files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



928
929
930
# File 'formula.rb', line 928

def zsh_completion
  share/"zsh/site-functions"
end

#zsh_functionObject

The directory where the formula’s zsh function files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.



904
905
906
# File 'formula.rb', line 904

def zsh_function
  share/"zsh/site-functions"
end