Class: Formula Abstract

Inherits:
Object show all
Extended by:
APIHashable, BuildEnvironment::DSL, Cachable, Forwardable, OnSystem::MacOSAndLinux, Predicable
Includes:
Context, FileUtils, Homebrew::Livecheck::Constants, OnSystem::MacOSAndLinux, Utils::Shebang, Utils::Shell
Defined in:
extend/os/mac/formula.rb,
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 APIHashable

generated_hash!, generating_hash!, generating_hash?

Methods included from Context

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

Methods included from Utils::Shell

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

Methods included from Utils::Shebang

rewrite_shebang

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:



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

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"


3322
3323
3324
# File 'formula.rb', line 3322

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:



3600
3601
3602
# File 'formula.rb', line 3600

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:



3606
3607
3608
# File 'formula.rb', line 3606

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"


2975
# File 'formula.rb', line 2975

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:



3640
3641
3642
# File 'formula.rb', line 3640

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:



3646
3647
3648
# File 'formula.rb', line 3646

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


3224
3225
3226
3227
3228
3229
3230
3231
3232
# File 'formula.rb', line 3224

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"


3015
# File 'formula.rb', line 3015

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" },
]


3000
3001
3002
3003
3004
3005
3006
# File 'formula.rb', line 3000

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


3501
3502
3503
3504
3505
3506
# File 'formula.rb', line 3501

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


3131
3132
3133
# File 'formula.rb', line 3131

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


3313
3314
3315
# File 'formula.rb', line 3313

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


3066
# File 'formula.rb', line 3066

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


3517
3518
3519
3520
3521
# File 'formula.rb', line 3517

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"


3143
3144
3145
# File 'formula.rb', line 3143

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


3206
3207
3208
3209
3210
# File 'formula.rb', line 3206

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"


3108
3109
3110
# File 'formula.rb', line 3108

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"


3118
3119
3120
# File 'formula.rb', line 3118

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


3078
# File 'formula.rb', line 3078

attr_rw :version_scheme

Instance Attribute Details

#alias_nameString? (readonly)

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

Returns:



85
86
87
# File 'formula.rb', line 85

def alias_name
  @alias_name
end

#alias_pathnil, ... (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

Returns:



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

def alias_path
  @alias_path
end

#buildBuildOptions, Tab

The BuildOptions or Tab 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:



184
185
186
# File 'formula.rb', line 184

def build
  @build
end

#buildpathPathname? (readonly)

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

Returns:



160
161
162
# File 'formula.rb', line 160

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)


190
191
192
# File 'formula.rb', line 190

def follow_installed_alias
  @follow_installed_alias
end

#full_alias_nameString? (readonly)

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

Returns:



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

def full_alias_name
  @full_alias_name
end

#full_nameString (readonly)

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

Returns:



91
92
93
# File 'formula.rb', line 91

def full_name
  @full_name
end

#nameString (readonly)

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

Returns:



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

def name
  @name
end

#pathPathname (readonly)

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

Returns:



102
103
104
# File 'formula.rb', line 102

def path
  @path
end

#revisionInteger (readonly)

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

Returns:

  • (Integer)

See Also:



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

def revision
  @revision
end

#testpathPathname? (readonly)

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

Returns:



165
166
167
# File 'formula.rb', line 165

def testpath
  @testpath
end

#version_schemeInteger (readonly)

Used to change version schemes for packages.

Returns:

  • (Integer)

See Also:



155
156
157
# File 'formula.rb', line 155

def version_scheme
  @version_scheme
end

Class Method Details

.[](name) ⇒ Object



2033
2034
2035
# File 'formula.rb', line 2033

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"


3381
3382
3383
3384
# File 'formula.rb', line 3381

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.



3415
3416
3417
# File 'formula.rb', line 3415

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 using --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"


3287
3288
3289
# File 'formula.rb', line 3287

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"


3580
3581
3582
3583
3584
3585
3586
# File 'formula.rb', line 3580

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:



3592
3593
3594
# File 'formula.rb', line 3592

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"


3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
# File 'formula.rb', line 3615

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:



3632
3633
3634
# File 'formula.rb', line 3632

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


3440
3441
3442
# File 'formula.rb', line 3440

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

.freezeObject



2945
2946
2947
2948
2949
2950
2951
2952
2953
# File 'formula.rb', line 2945

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



3247
3248
3249
# File 'formula.rb', line 3247

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.



3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
# File 'formula.rb', line 3660

def ignore_missing_libraries(*libs)
  odisabled "ignore_missing_libraries"
  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.



2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
# File 'formula.rb', line 2919

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
    @loaded_from_api = false
  end
end

.installed_with_alias_path(alias_path) ⇒ Object



1978
1979
1980
1981
1982
# File 'formula.rb', line 1978

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"


3410
3411
3412
# File 'formula.rb', line 3410

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-*"


3654
3655
3656
3657
# File 'formula.rb', line 3654

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)


3021
3022
3023
# File 'formula.rb', line 3021

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:



3453
3454
3455
# File 'formula.rb', line 3453

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:



3357
3358
3359
# File 'formula.rb', line 3357

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"


3373
3374
3375
3376
3377
# File 'formula.rb', line 3373

def plist_options(options)
  odisabled "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)


3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
# File 'formula.rb', line 3538

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.bind(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
        satisfy { MacOS::CLT.installed? }
      end
    end
  when :default_prefix
    lambda do |_|
      T.bind(self, PourBottleCheck)
      reason(+<<~EOS)
        The bottle (and many others) needs to be installed into #{Homebrew::DEFAULT_PREFIX}.
      EOS
      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


3241
3242
3243
3244
3245
# File 'formula.rb', line 3241

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)


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

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


3393
3394
3395
3396
3397
# File 'formula.rb', line 3393

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:



3485
3486
3487
# File 'formula.rb', line 3485

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.



3295
3296
3297
# File 'formula.rb', line 3295

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:



1040
1041
1042
1043
1044
1045
1046
# File 'formula.rb', line 1040

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:



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

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)


1545
1546
1547
# File 'formula.rb', line 1545

def alias_changed?
  installed_alias_target_changed? || supersedes_an_installed_formula?
end

#aliasesArray<String>

All aliases for the formula.

Returns:



548
549
550
551
552
553
554
555
556
# File 'formula.rb', line 548

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

#any_installed_prefixObject



2105
2106
2107
2108
2109
2110
2111
# File 'formula.rb', line 2105

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.



2115
2116
2117
# File 'formula.rb', line 2115

def any_installed_version
  any_installed_keg&.version
end

#bash_completionPathname

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.

Returns:



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

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

#binPathname

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"

Returns:



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

def bin
  prefix/"bin"
end

#bottle_hashObject

Returns the bottle information for a formula.



2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
# File 'formula.rb', line 2428

def bottle_hash
  bottle_spec = T.must(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, no_older_versions: true)
    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)


2822
2823
2824
2825
2826
# File 'formula.rb', line 2822

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:



1281
1282
1283
# File 'formula.rb', line 1281

def caveats
  nil
end

#current_installed_alias_targetObject



1522
1523
1524
# File 'formula.rb', line 1522

def current_installed_alias_target
  Formulary.factory(T.must(installed_alias_name)) if installed_alias_path
end

#deprecated?Boolean

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

Returns:

  • (Boolean)

See Also:



1349
# File 'formula.rb', line 1349

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:



1356
# File 'formula.rb', line 1356

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:



1363
# File 'formula.rb', line 1363

delegate deprecation_reason: :"self.class"

#descObject

The description of the software.

See Also:



421
# File 'formula.rb', line 421

delegate desc: :"self.class"

#deuniversalize_machos(*targets) ⇒ void

This method returns an undefined value.

Replaces a universal binary with its native slice.

If called with no parameters, does this with all compatible universal binaries in a Formula’s Keg.

Parameters:



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

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:



1377
# File 'formula.rb', line 1377

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:



1384
# File 'formula.rb', line 1384

delegate disable_reason: :"self.class"

#disabled?Boolean

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

Returns:

  • (Boolean)

See Also:



1370
# File 'formula.rb', line 1370

delegate disabled?: :"self.class"

#docPathname

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.

Returns:



754
755
756
# File 'formula.rb', line 754

def doc
  share/"doc"/name
end

#elispPathname

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"

Returns:



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

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

#etcPathname

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.

Returns:



956
957
958
# File 'formula.rb', line 956

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

#fetch_bottle_tabvoid

This method returns an undefined value.



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

def fetch_bottle_tab
  return unless bottled?

  T.must(bottle).fetch_tab
end

#fetch_patchesObject



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

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

#fish_completionPathname

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.

Returns:



1018
1019
1020
# File 'formula.rb', line 1018

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

#fish_functionPathname

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.

Returns:



991
992
993
# File 'formula.rb', line 991

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

#frameworksPathname

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.

Returns:



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

def frameworks
  prefix/"Frameworks"
end

#full_installed_alias_nameObject



340
341
342
# File 'formula.rb', line 340

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.



371
372
373
# File 'formula.rb', line 371

def full_installed_specified_name
  full_installed_alias_name || full_name
end

#full_specified_nameObject

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



361
362
363
# File 'formula.rb', line 361

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.

Examples:

Using default values for optional arguments

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

# 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")

Selecting shells and using a different base_name

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

# 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")

Using predefined shell_parameter_format :flag

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

# translates to
(bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions", "--bash")

Using predefined shell_parameter_format :arg

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

# translates to
(bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo",
                                                    "completions", "--shell=bash")

Using predefined shell_parameter_format :none

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

# translates to
(bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions")

Using predefined shell_parameter_format :click

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

# translates to
(zsh_completion/"_foo").write Utils.safe_popen_read({ "SHELL" => "zsh", "_FOO_COMPLETE" => "zsh_source" },
                                                    bin/"foo")

Using custom shell_parameter_format

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

# translates to
(bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo",
                                                    "completions", "--selected-shell=bash")

Parameters:

  • commands (Pathname, String)

    the path to the executable and any passed subcommand(s) to use for generating the completion scripts.

  • 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 to the executable. Takes either a String representing a prefix, or one of [:flag, :arg, :none, :click]. Defaults to plainly passing the shell.



1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
# File 'formula.rb', line 1867

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)


645
646
647
648
649
650
651
652
653
654
655
656
657
658
# File 'formula.rb', line 645

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 < T.must(stable).version
  return false unless fetch_head
  return false unless head&.downloader.is_a?(VCSDownloadStrategy)

  downloader = T.must(head).downloader

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

#homepageObject

The homepage for the software.

See Also:



431
# File 'formula.rb', line 431

delegate homepage: :"self.class"

#includePathname

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"

Returns:



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

def include
  prefix/"include"
end

#infoPathname

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.

Returns:



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

def info
  share/"info"
end

#inreplace(paths, before = nil, after = nil, audit_result = true, &block) ⇒ void

This method returns an undefined value.

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

Parameters:

See Also:



2558
2559
2560
2561
2562
2563
# File 'formula.rb', line 2558

def inreplace(paths, before = nil, after = nil, audit_result = true, &block) # rubocop:disable Style/OptionalBooleanParameter
  Utils::Inreplace.inreplace(paths, before, after, audit_result: audit_result, &block)
rescue Utils::Inreplace::Error => e
  onoe e.to_s
  raise BuildError.new(self, "inreplace", Array(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


2529
# File 'formula.rb', line 2529

def install; end

#installed_alias_nameString?

Returns:



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

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.



326
327
328
329
330
331
332
333
# File 'formula.rb', line 326

def installed_alias_path
  build_tab = build
  path = build_tab.source["path"] if build_tab.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)


1529
1530
1531
1532
1533
1534
# File 'formula.rb', line 1529

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.



366
367
368
# File 'formula.rb', line 366

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:



1289
1290
1291
1292
1293
# File 'formula.rb', line 1289

def keg_only?
  return false unless keg_only_reason

  keg_only_reason.applicable?
end

#kext_prefixPathname

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.

Returns:



946
947
948
# File 'formula.rb', line 946

def kext_prefix
  prefix/"Library/Extensions"
end

#latest_formulaObject

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



1551
1552
1553
# File 'formula.rb', line 1551

def latest_formula
  installed_alias_target_changed? ? current_installed_alias_target : self
end

#latest_head_prefixObject



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

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

#latest_head_versionObject



629
630
631
632
633
634
635
636
637
638
# File 'formula.rb', line 629

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:



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

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

#libPathname

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"

Returns:



784
785
786
# File 'formula.rb', line 784

def lib
  prefix/"lib"
end

#libexecPathname

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"

Returns:



797
798
799
# File 'formula.rb', line 797

def libexec
  prefix/"libexec"
end

#licenseObject

The SPDX ID of the software license.

See Also:



426
# File 'formula.rb', line 426

delegate license: :"self.class"

#linked?Boolean

Is the formula linked?

Returns:

  • (Boolean)


688
689
690
# File 'formula.rb', line 688

def linked?
  linked_keg.symlink?
end

#linked_versionPkgVersion?

PkgVersion of the linked keg for the formula.

Returns:



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

def linked_version
  return unless linked?

  Keg.for(linked_keg).version
end

#livecheckObject

The livecheck specification for the software.

See Also:



436
# File 'formula.rb', line 436

delegate livecheck: :"self.class"

#livecheckable?Object

Is a livecheck specification defined for the software?

See Also:



441
# File 'formula.rb', line 441

delegate livecheckable?: :"self.class"

#loader_pathString

Returns:



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

def loader_path
  "$ORIGIN"
end

#manPathname

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.

Returns:



807
808
809
# File 'formula.rb', line 807

def man
  share/"man"
end

#man1Pathname

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"

Returns:



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

def man1
  man/"man1"
end

#man2Pathname

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.

Returns:



826
827
828
# File 'formula.rb', line 826

def man2
  man/"man2"
end

#man3Pathname

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"

Returns:



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

def man3
  man/"man3"
end

#man4Pathname

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.

Returns:



845
846
847
# File 'formula.rb', line 845

def man4
  man/"man4"
end

#man5Pathname

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.

Returns:



853
854
855
# File 'formula.rb', line 853

def man5
  man/"man5"
end

#man6Pathname

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.

Returns:



861
862
863
# File 'formula.rb', line 861

def man6
  man/"man6"
end

#man7Pathname

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.

Returns:



869
870
871
# File 'formula.rb', line 869

def man7
  man/"man7"
end

#man8Pathname

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.

Returns:



877
878
879
# File 'formula.rb', line 877

def man8
  man/"man8"
end

#migration_needed?Boolean

Returns:

  • (Boolean)


1476
1477
1478
# File 'formula.rb', line 1476

def migration_needed?
  !oldnames_to_migrate.empty? && !rack.exist?
end

#missing_dependencies(hide: nil) ⇒ Object

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



2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
# File 'formula.rb', line 2176

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.



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

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.



2785
2786
2787
# File 'formula.rb', line 2785

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

#new_formula_available?Boolean

Returns:

  • (Boolean)


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

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

#old_installed_formulaeObject



1555
1556
1557
1558
1559
1560
1561
1562
# File 'formula.rb', line 1555

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

#oldnameString?

Deprecated.

Use #oldnames instead.

An old name for the formula.

Returns:



531
532
533
534
# File 'formula.rb', line 531

def oldname
  odeprecated "Formula#oldname", "Formula#oldnames"
  @oldname ||= oldnames.first
end

#oldnamesArray<String>

Old names for the formula.

Returns:



538
539
540
541
542
543
544
# File 'formula.rb', line 538

def oldnames
  @oldnames ||= if tap
    T.must(tap).formula_oldnames.fetch(name, [])
  else
    []
  end
end

#opt_binPathname

Returns:



1150
1151
1152
# File 'formula.rb', line 1150

def opt_bin
  opt_prefix/"bin"
end

#opt_elispPathname

Returns:



1185
1186
1187
# File 'formula.rb', line 1185

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

#opt_frameworksPathname

Returns:



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

def opt_frameworks
  opt_prefix/"Frameworks"
end

#opt_includePathname

Returns:



1155
1156
1157
# File 'formula.rb', line 1155

def opt_include
  opt_prefix/"include"
end

#opt_libPathname

Returns:



1160
1161
1162
# File 'formula.rb', line 1160

def opt_lib
  opt_prefix/"lib"
end

#opt_libexecPathname

Returns:



1165
1166
1167
# File 'formula.rb', line 1165

def opt_libexec
  opt_prefix/"libexec"
end

#opt_pkgsharePathname

Returns:



1180
1181
1182
# File 'formula.rb', line 1180

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:



1145
1146
1147
# File 'formula.rb', line 1145

def opt_prefix
  HOMEBREW_PREFIX/"opt"/name
end

#opt_sbinPathname

Returns:



1170
1171
1172
# File 'formula.rb', line 1170

def opt_sbin
  opt_prefix/"sbin"
end

#opt_sharePathname

Returns:



1175
1176
1177
# File 'formula.rb', line 1175

def opt_share
  opt_prefix/"share"
end

#option_defined?Object

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



597
# File 'formula.rb', line 597

delegate option_defined?: :active_spec

#optlinked?Boolean

Is the formula linked to opt?

Returns:

  • (Boolean)


694
695
696
# File 'formula.rb', line 694

def optlinked?
  opt_prefix.symlink?
end

#pkg_versionPkgVersion

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

Returns:



482
483
484
# File 'formula.rb', line 482

def pkg_version
  PkgVersion.new(version, revision)
end

#pkgetcPathname

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.

Returns:



965
966
967
# File 'formula.rb', line 965

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

#pkgsharePathname

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"

Returns:



918
919
920
# File 'formula.rb', line 918

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


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

def plist
  nil
end

#plist_nameString

The generated launchd #plist service name.

Returns:



1091
1092
1093
# File 'formula.rb', line 1091

def plist_name
  service.plist_name
end

#plist_pathPathname

The generated launchd #plist file path.

Returns:



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

def plist_path
  odisabled "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.



1210
# File 'formula.rb', line 1210

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)


1201
1202
1203
# File 'formula.rb', line 1201

def pour_bottle?
  true
end

#prefix(version = 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.



676
677
678
679
680
681
682
683
684
# File 'formula.rb', line 676

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

#prefix_linked?(version = pkg_version) ⇒ Boolean

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

Returns:

  • (Boolean)


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

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

  linked_keg.resolved_path == versioned_prefix(version)
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" }


526
# File 'formula.rb', line 526

delegate resource: :active_spec

#resourcesObject

The Resources for the currently active SoftwareSpec.



560
# File 'formula.rb', line 560

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:



1746
1747
1748
1749
1750
1751
1752
# File 'formula.rb', line 1746

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



2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
# File 'formula.rb', line 2157

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

#sbinPathname

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.

Returns:



886
887
888
# File 'formula.rb', line 886

def sbin
  prefix/"sbin"
end

#serviceObject

The service specification of the software.



1127
1128
1129
# File 'formula.rb', line 1127

def service
  @service ||= Homebrew::Service.new(self, &self.class.service)
end

#service?Object

Is a service specification defined for the software?

See Also:



446
# File 'formula.rb', line 446

delegate service?: :"self.class"

#service_nameString

The generated service name.

Returns:



1097
1098
1099
# File 'formula.rb', line 1097

def service_name
  service.service_name
end

#sharePathname

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"

Returns:



906
907
908
# File 'formula.rb', line 906

def share
  prefix/"share"
end

#shared_library(name, version = nil) ⇒ String

Shared library names according to platform conventions.

Optionally specify a version to restrict the shared library to a specific version. The special string “*” matches any version.

If name is specified as “*”, match any shared library of any version.

shared_library("foo")      #=> foo.dylib
shared_library("foo", 1)   #=> foo.1.dylib
shared_library("foo", "*") #=> foo.2.dylib, foo.1.dylib, foo.dylib
shared_library("*")        #=> foo.dylib, bar.dylib

Parameters:

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

Returns:



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

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)


1387
1388
1389
# File 'formula.rb', line 1387

def skip_cxxstdlib_check?
  false
end

#specified_nameObject

The name specified to find this formula.



356
357
358
# File 'formula.rb', line 356

def specified_name
  alias_name || name
end

#specified_pathObject

The path that was specified to find this formula.



345
346
347
348
349
350
351
352
353
# File 'formula.rb', line 345

def specified_path
  default_specified_path = Pathname(alias_path) if alias_path.present?
  default_specified_path ||= @unresolved_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:



1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
# File 'formula.rb', line 1682

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>

Standard parameters for cargo builds.

Parameters:

Returns:



1632
1633
1634
# File 'formula.rb', line 1632

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:

Returns:



1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
# File 'formula.rb', line 1648

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:



1624
1625
1626
# File 'formula.rb', line 1624

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:



1674
1675
1676
1677
1678
# File 'formula.rb', line 1674

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:



1696
1697
1698
# File 'formula.rb', line 1696

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

#std_pip_args(prefix: self.prefix, build_isolation: false) ⇒ Array<String>

Standard parameters for pip builds.

Parameters:

  • prefix (String, Pathname, false) (defaults to: self.prefix)
  • build_isolation (Boolean) (defaults to: false)

Returns:



1705
1706
1707
1708
1709
1710
# File 'formula.rb', line 1705

def std_pip_args(prefix: self.prefix, build_isolation: false)
  args = ["--verbose", "--no-deps", "--no-binary=:all:", "--ignore-installed", "--no-compile"]
  args << "--prefix=#{prefix}" if prefix
  args << "--no-build-isolation" unless build_isolation
  args
end

#supersedes_an_installed_formula?Boolean

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

Returns:

  • (Boolean)


1538
1539
1540
# File 'formula.rb', line 1538

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:



2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
# File 'formula.rb', line 2635

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 -= std_configure_args
    when "cabal"
      pretty_args -= std_cabal_v2_args
    when "cargo"
      pretty_args -= std_cargo_args
    when "cmake"
      pretty_args -= std_cmake_args
    when "go"
      pretty_args -= std_go_args
    when "meson"
      pretty_args -= std_meson_args
    when %r{(^|/)(pip|python)(?:[23](?:\.\d{1,2})?)?$}
      pretty_args -= std_pip_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 if (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.to_s, 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:



1116
1117
1118
# File 'formula.rb', line 1116

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

#systemd_timer_pathPathname

The generated systemd timer file path.

Returns:



1122
1123
1124
# File 'formula.rb', line 1122

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:

See Also:



1763
1764
1765
1766
1767
1768
1769
# File 'formula.rb', line 1763

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

#to_sObject



1612
1613
1614
# File 'formula.rb', line 1612

def to_s
  name
end

#update_head_versionvoid

This method returns an undefined value.



462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
# File 'formula.rb', line 462

def update_head_version
  return unless head?

  head_spec = T.must(head)
  return unless head_spec.downloader.is_a?(VCSDownloadStrategy)
  return unless head_spec.downloader.cached_location.exist?

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

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

#varPathname

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

Returns:



973
974
975
# File 'formula.rb', line 973

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:



453
# File 'formula.rb', line 453

delegate version: :active_spec

#versioned_formula?Boolean

If this is a @-versioned formula.

Returns:

  • (Boolean)


488
489
490
# File 'formula.rb', line 488

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

#versioned_formulaeArray<Formula>

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

Returns:



513
514
515
516
517
518
519
# File 'formula.rb', line 513

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 other @-versioned formulae names for any formula (including versioned formulae).

Returns:



494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'formula.rb', line 494

def versioned_formulae_names
  versioned_names = if tap
    name_prefix = name.gsub(/(@[\d.]+)?$/, "")
    T.must(tap).prefix_to_versioned_formulae_names.fetch(name_prefix, [])
  elsif path.exist?
    Pathname.glob(path.to_s.gsub(/(@[\d.]+)?\.rb$/, "@*.rb"))
            .map { |path| path.basename(".rb").to_s }
            .sort
  else
    raise "Either tap or path is required to list versioned formulae"
  end

  versioned_names.reject do |versioned_name|
    versioned_name == name
  end
end

#with_logging(log_type) ⇒ Object

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



1049
1050
1051
1052
1053
1054
1055
# File 'formula.rb', line 1049

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:



2800
2801
2802
2803
2804
2805
2806
2807
2808
# File 'formula.rb', line 2800

def xcodebuild(*args)
  removed = ENV.remove_cc_etc

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

#zsh_completionPathname

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.

Returns:



1009
1010
1011
# File 'formula.rb', line 1009

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

#zsh_functionPathname

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.

Returns:



982
983
984
# File 'formula.rb', line 982

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